Finally bring in what was produced during Google SoC 2005:
Add functions to rename objects and to move a subdisk from one drive to another. Obtained from: Chris Jones <chris.jones@ualberta.ca> Sponsored by: Google Summer of Code 2005 MFC in: 1 week
This commit is contained in:
parent
c62f97f558
commit
57335408d4
@ -502,12 +502,18 @@ gv_config(struct gctl_req *req, struct g_class *mp, char const *verb)
|
||||
} else if (!strcmp(verb, "create")) {
|
||||
gv_create(gp, req);
|
||||
|
||||
} else if (!strcmp(verb, "move")) {
|
||||
gv_move(gp, req);
|
||||
|
||||
} else if (!strcmp(verb, "parityop")) {
|
||||
gv_parityop(gp, req);
|
||||
|
||||
} else if (!strcmp(verb, "remove")) {
|
||||
gv_remove(gp, req);
|
||||
|
||||
} else if (!strcmp(verb, "rename")) {
|
||||
gv_rename(gp, req);
|
||||
|
||||
} else if (!strcmp(verb, "start")) {
|
||||
gv_start_obj(gp, req);
|
||||
|
||||
|
@ -33,6 +33,7 @@
|
||||
|
||||
/* geom_vinum_drive.c */
|
||||
void gv_config_new_drive(struct gv_drive *);
|
||||
void gv_drive_modify(struct gv_drive *);
|
||||
void gv_save_config_all(struct gv_softc *);
|
||||
void gv_save_config(struct g_consumer *, struct gv_drive *,
|
||||
struct gv_softc *);
|
||||
@ -48,8 +49,16 @@ void gv_ls(struct g_geom *, struct gctl_req *, struct sbuf *);
|
||||
void gv_lv(struct g_geom *, struct gctl_req *, struct sbuf *);
|
||||
void gv_list(struct g_geom *, struct gctl_req *);
|
||||
|
||||
/* geom_vinum_move.c */
|
||||
void gv_move(struct g_geom *, struct gctl_req *);
|
||||
|
||||
/* geom_vinum_rename.c */
|
||||
void gv_rename(struct g_geom *, struct gctl_req *);
|
||||
|
||||
/* geom_vinum_rm.c */
|
||||
void gv_remove(struct g_geom *, struct gctl_req *);
|
||||
int gv_rm_sd(struct gv_softc *sc, struct gctl_req *req,
|
||||
struct gv_sd *s, int flags);
|
||||
|
||||
/* geom_vinum_state.c */
|
||||
int gv_sdstatemap(struct gv_plex *);
|
||||
|
@ -49,7 +49,6 @@ __FBSDID("$FreeBSD$");
|
||||
|
||||
static void gv_drive_dead(void *, int);
|
||||
static void gv_drive_worker(void *);
|
||||
void gv_drive_modify(struct gv_drive *);
|
||||
|
||||
void
|
||||
gv_config_new_drive(struct gv_drive *d)
|
||||
|
213
sys/geom/vinum/geom_vinum_move.c
Normal file
213
sys/geom/vinum/geom_vinum_move.c
Normal file
@ -0,0 +1,213 @@
|
||||
/*-
|
||||
* Copyright (c) 2005 Chris Jones
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed for the FreeBSD Project by Chris Jones
|
||||
* thanks to the support of Google's Summer of Code program and
|
||||
* mentoring by Lukas Ertl.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/libkern.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
|
||||
#include <geom/geom.h>
|
||||
#include <geom/vinum/geom_vinum_var.h>
|
||||
#include <geom/vinum/geom_vinum.h>
|
||||
#include <geom/vinum/geom_vinum_share.h>
|
||||
|
||||
static int gv_move_sd(struct gv_softc *, struct gctl_req *,
|
||||
struct gv_sd *, char *, int);
|
||||
|
||||
void
|
||||
gv_move(struct g_geom *gp, struct gctl_req *req)
|
||||
{
|
||||
struct gv_softc *sc;
|
||||
struct gv_sd *s;
|
||||
char buf[20], *destination, *object;
|
||||
int *argc, err, *flags, i, type;
|
||||
|
||||
sc = gp->softc;
|
||||
|
||||
argc = gctl_get_paraml(req, "argc", sizeof(*argc));
|
||||
flags = gctl_get_paraml(req, "flags", sizeof(*flags));
|
||||
destination = gctl_get_param(req, "destination", NULL);
|
||||
if (destination == NULL) {
|
||||
gctl_error(req, "no destination given");
|
||||
return;
|
||||
}
|
||||
if (gv_object_type(sc, destination) != GV_TYPE_DRIVE) {
|
||||
gctl_error(req, "destination '%s' is not a drive", destination);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* We start with 1 here, because argv[0] on the command line is the
|
||||
* destination drive.
|
||||
*/
|
||||
for (i = 1; i < *argc; i++) {
|
||||
snprintf(buf, sizeof(buf), "argv%d", i);
|
||||
object = gctl_get_param(req, buf, NULL);
|
||||
if (object == NULL)
|
||||
continue;
|
||||
|
||||
type = gv_object_type(sc, object);
|
||||
if (type != GV_TYPE_SD) {
|
||||
gctl_error(req, "you can only move subdisks; "
|
||||
"'%s' isn't one", object);
|
||||
return;
|
||||
}
|
||||
|
||||
s = gv_find_sd(sc, object);
|
||||
if (s == NULL) {
|
||||
gctl_error(req, "unknown subdisk '%s'", object);
|
||||
return;
|
||||
}
|
||||
err = gv_move_sd(sc, req, s, destination, *flags);
|
||||
if (err)
|
||||
return;
|
||||
}
|
||||
|
||||
gv_save_config_all(sc);
|
||||
}
|
||||
|
||||
/* Move a subdisk. */
|
||||
static int
|
||||
gv_move_sd(struct gv_softc *sc, struct gctl_req *req, struct gv_sd *cursd, char *destination, int flags)
|
||||
{
|
||||
struct gv_drive *d;
|
||||
struct gv_sd *newsd, *s, *s2;
|
||||
struct gv_plex *p;
|
||||
struct g_consumer *cp;
|
||||
char errstr[ERRBUFSIZ];
|
||||
int err;
|
||||
|
||||
g_topology_assert();
|
||||
KASSERT(cursd != NULL, ("gv_move_sd: NULL cursd"));
|
||||
|
||||
cp = cursd->consumer;
|
||||
|
||||
if (cp->acr || cp->acw || cp->ace) {
|
||||
gctl_error(req, "subdisk '%s' is busy", cursd->name);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (!(flags && GV_FLAG_F)) {
|
||||
gctl_error(req, "-f flag not passed; move would be "
|
||||
"destructive");
|
||||
return (-1);
|
||||
}
|
||||
|
||||
d = gv_find_drive(sc, destination);
|
||||
if (d == NULL) {
|
||||
gctl_error(req, "destination drive '%s' not found",
|
||||
destination);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
if (d == cursd->drive_sc) {
|
||||
gctl_error(req, "subdisk '%s' already on drive '%s'",
|
||||
cursd->name, destination);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* XXX: Does it have to be part of a plex? */
|
||||
p = gv_find_plex(sc, cursd->plex);
|
||||
if (p == NULL) {
|
||||
gctl_error(req, "subdisk '%s' is not part of a plex",
|
||||
cursd->name);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* Stale the old subdisk. */
|
||||
err = gv_set_sd_state(cursd, GV_SD_STALE,
|
||||
GV_SETSTATE_FORCE | GV_SETSTATE_CONFIG);
|
||||
if (err) {
|
||||
gctl_error(req, "could not set the subdisk '%s' to state "
|
||||
"'stale'", cursd->name);
|
||||
return (err);
|
||||
}
|
||||
|
||||
/*
|
||||
* Create new subdisk. Ideally, we'd use gv_new_sd, but that requires
|
||||
* us to create a string for it to parse, which is silly.
|
||||
* TODO: maybe refactor gv_new_sd such that this is no longer the case.
|
||||
*/
|
||||
newsd = g_malloc(sizeof(struct gv_sd), M_WAITOK | M_ZERO);
|
||||
newsd->plex_offset = cursd->plex_offset;
|
||||
newsd->size = cursd->size;
|
||||
newsd->drive_offset = -1;
|
||||
strncpy(newsd->name, cursd->name, GV_MAXSDNAME);
|
||||
strncpy(newsd->drive, destination, GV_MAXDRIVENAME);
|
||||
strncpy(newsd->plex, cursd->plex, GV_MAXPLEXNAME);
|
||||
newsd->state = GV_SD_STALE;
|
||||
newsd->vinumconf = cursd->vinumconf;
|
||||
|
||||
err = gv_sd_to_drive(sc, d, newsd, errstr, ERRBUFSIZ);
|
||||
if (err) {
|
||||
/* XXX not enough free space? */
|
||||
gctl_error(req, errstr);
|
||||
g_free(newsd);
|
||||
return (err);
|
||||
}
|
||||
|
||||
/* Replace the old sd by the new one. */
|
||||
g_detach(cp);
|
||||
LIST_FOREACH_SAFE(s, &p->subdisks, in_plex, s2) {
|
||||
if (s == cursd) {
|
||||
p->sdcount--;
|
||||
p->size -= s->size;
|
||||
err = gv_rm_sd(sc, req, s, 0);
|
||||
if (err)
|
||||
return (err);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
gv_sd_to_plex(p, newsd, 1);
|
||||
|
||||
/* Creates the new providers.... */
|
||||
gv_drive_modify(d);
|
||||
|
||||
/* And reconnect the consumer ... */
|
||||
newsd->consumer = cp;
|
||||
err = g_attach(cp, newsd->provider);
|
||||
if (err) {
|
||||
g_destroy_consumer(cp);
|
||||
gctl_error(req, "proposed move would create a loop in GEOM "
|
||||
"config");
|
||||
return (err);
|
||||
}
|
||||
|
||||
LIST_INSERT_HEAD(&sc->subdisks, newsd, sd);
|
||||
|
||||
gv_save_config_all(sc);
|
||||
|
||||
return (0);
|
||||
}
|
284
sys/geom/vinum/geom_vinum_rename.c
Normal file
284
sys/geom/vinum/geom_vinum_rename.c
Normal file
@ -0,0 +1,284 @@
|
||||
/*-
|
||||
* Copyright (c) 2005 Chris Jones
|
||||
* All rights reserved.
|
||||
*
|
||||
* This software was developed for the FreeBSD Project by Chris Jones
|
||||
* thanks to the support of Google's Summer of Code program and
|
||||
* mentoring by Lukas Ertl.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/libkern.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
|
||||
#include <geom/geom.h>
|
||||
#include <geom/vinum/geom_vinum_var.h>
|
||||
#include <geom/vinum/geom_vinum.h>
|
||||
#include <geom/vinum/geom_vinum_share.h>
|
||||
|
||||
static int gv_rename_drive(struct gv_softc *, struct gctl_req *,
|
||||
struct gv_drive *, char *, int);
|
||||
static int gv_rename_plex(struct gv_softc *, struct gctl_req *,
|
||||
struct gv_plex *, char *, int);
|
||||
static int gv_rename_sd(struct gv_softc *, struct gctl_req *,
|
||||
struct gv_sd *, char *, int);
|
||||
static int gv_rename_vol(struct gv_softc *, struct gctl_req *,
|
||||
struct gv_volume *, char *, int);
|
||||
|
||||
void
|
||||
gv_rename(struct g_geom *gp, struct gctl_req *req)
|
||||
{
|
||||
struct gv_softc *sc;
|
||||
struct gv_volume *v;
|
||||
struct gv_plex *p;
|
||||
struct gv_sd *s;
|
||||
struct gv_drive *d;
|
||||
char *newname, *object;
|
||||
int err, *flags, type;
|
||||
|
||||
sc = gp->softc;
|
||||
|
||||
flags = gctl_get_paraml(req, "flags", sizeof(*flags));
|
||||
|
||||
newname = gctl_get_param(req, "newname", NULL);
|
||||
if (newname == NULL) {
|
||||
gctl_error(req, "no new name given");
|
||||
return;
|
||||
}
|
||||
|
||||
object = gctl_get_param(req, "object", NULL);
|
||||
if (object == NULL) {
|
||||
gctl_error(req, "no object given");
|
||||
return;
|
||||
}
|
||||
|
||||
type = gv_object_type(sc, object);
|
||||
switch (type) {
|
||||
case GV_TYPE_VOL:
|
||||
v = gv_find_vol(sc, object);
|
||||
if (v == NULL) {
|
||||
gctl_error(req, "unknown volume '%s'", object);
|
||||
return;
|
||||
}
|
||||
err = gv_rename_vol(sc, req, v, newname, *flags);
|
||||
if (err)
|
||||
return;
|
||||
break;
|
||||
case GV_TYPE_PLEX:
|
||||
p = gv_find_plex(sc, object);
|
||||
if (p == NULL) {
|
||||
gctl_error(req, "unknown plex '%s'", object);
|
||||
return;
|
||||
}
|
||||
err = gv_rename_plex(sc, req, p, newname, *flags);
|
||||
if (err)
|
||||
return;
|
||||
break;
|
||||
case GV_TYPE_SD:
|
||||
s = gv_find_sd(sc, object);
|
||||
if (s == NULL) {
|
||||
gctl_error(req, "unknown subdisk '%s'", object);
|
||||
return;
|
||||
}
|
||||
err = gv_rename_sd(sc, req, s, newname, *flags);
|
||||
if (err)
|
||||
return;
|
||||
break;
|
||||
case GV_TYPE_DRIVE:
|
||||
d = gv_find_drive(sc, object);
|
||||
if (d == NULL) {
|
||||
gctl_error(req, "unknown drive '%s'", object);
|
||||
return;
|
||||
}
|
||||
err = gv_rename_drive(sc, req, d, newname, *flags);
|
||||
if (err)
|
||||
return;
|
||||
break;
|
||||
default:
|
||||
gctl_error(req, "unknown object '%s'", object);
|
||||
return;
|
||||
}
|
||||
|
||||
gv_save_config_all(sc);
|
||||
}
|
||||
|
||||
static int
|
||||
gv_rename_drive(struct gv_softc *sc, struct gctl_req *req, struct gv_drive *d, char *newname, int flags)
|
||||
{
|
||||
struct gv_sd *s;
|
||||
|
||||
g_topology_assert();
|
||||
KASSERT(d != NULL, ("gv_rename_drive: NULL d"));
|
||||
|
||||
if (gv_object_type(sc, newname) != -1) {
|
||||
gctl_error(req, "drive name '%s' already in use", newname);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
strncpy(d->name, newname, GV_MAXDRIVENAME);
|
||||
|
||||
/* XXX can we rename providers here? */
|
||||
|
||||
LIST_FOREACH(s, &d->subdisks, from_drive)
|
||||
strncpy(s->drive, d->name, GV_MAXDRIVENAME);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
gv_rename_plex(struct gv_softc *sc, struct gctl_req *req, struct gv_plex *p, char *newname, int flags)
|
||||
{
|
||||
struct gv_sd *s;
|
||||
char plexnumber[GV_MAXPLEXNAME], *pplexnumber;
|
||||
char oldplexname[GV_MAXPLEXNAME], *poldplexname;
|
||||
int err;
|
||||
|
||||
pplexnumber = plexnumber;
|
||||
poldplexname = oldplexname;
|
||||
|
||||
g_topology_assert();
|
||||
KASSERT(p != NULL, ("gv_rename_plex: NULL p"));
|
||||
|
||||
if (gv_object_type(sc, newname) != -1) {
|
||||
gctl_error(req, "plex name '%s' already in use", newname);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
strncpy(oldplexname, p->name, GV_MAXPLEXNAME);
|
||||
strsep(&poldplexname, ".");
|
||||
strncpy(plexnumber, p->name, GV_MAXPLEXNAME);
|
||||
strsep(&pplexnumber, ".");
|
||||
if (strcmp(poldplexname, pplexnumber)) {
|
||||
gctl_error(req, "current and proposed plex numbers (%s, %s) "
|
||||
"do not match", pplexnumber, poldplexname);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
strncpy(p->name, newname, GV_MAXPLEXNAME);
|
||||
|
||||
/* XXX can we rename providers here? */
|
||||
|
||||
/* Fix up references and potentially rename subdisks. */
|
||||
LIST_FOREACH(s, &p->subdisks, in_plex) {
|
||||
strncpy(s->plex, p->name, GV_MAXPLEXNAME);
|
||||
if (flags && GV_FLAG_R) {
|
||||
char newsdname[GV_MAXSDNAME];
|
||||
char oldsdname[GV_MAXSDNAME];
|
||||
char *poldsdname = oldsdname;
|
||||
strncpy(oldsdname, s->name, GV_MAXSDNAME);
|
||||
strsep(&poldsdname, ".");
|
||||
strsep(&poldsdname, ".");
|
||||
snprintf(newsdname, GV_MAXSDNAME, "%s.%s", p->name,
|
||||
poldsdname);
|
||||
err = gv_rename_sd(sc, req, s, newsdname, flags);
|
||||
if (err)
|
||||
return (err);
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* gv_rename_sd: renames a subdisk. Note that the 'flags' argument is ignored,
|
||||
* since there are no structures below a subdisk. Similarly, we don't have to
|
||||
* clean up any references elsewhere to the subdisk's name.
|
||||
*/
|
||||
static int
|
||||
gv_rename_sd(struct gv_softc *sc, struct gctl_req *req, struct gv_sd *s, char * newname, int flags)
|
||||
{
|
||||
char newsdnumber[GV_MAXSDNAME], *pnewsdnumber;
|
||||
char oldsdnumber[GV_MAXSDNAME], *poldsdnumber;
|
||||
|
||||
pnewsdnumber = newsdnumber;
|
||||
poldsdnumber = oldsdnumber;
|
||||
|
||||
g_topology_assert();
|
||||
KASSERT(s != NULL, ("gv_rename_sd: NULL s"));
|
||||
|
||||
if (gv_object_type(sc, newname) != -1) {
|
||||
gctl_error(req, "subdisk name %s already in use", newname);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
strncpy(oldsdnumber, s->name, GV_MAXSDNAME);
|
||||
strsep(&poldsdnumber, ".");
|
||||
strsep(&poldsdnumber, ".");
|
||||
strncpy(newsdnumber, newname, GV_MAXSDNAME);
|
||||
strsep(&pnewsdnumber, ".");
|
||||
strsep(&pnewsdnumber, ".");
|
||||
if (strcmp(pnewsdnumber, poldsdnumber)) {
|
||||
gctl_error(req, "current and proposed sd numbers (%s, %s) do "
|
||||
"not match", poldsdnumber, pnewsdnumber);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
strncpy(s->name, newname, GV_MAXSDNAME);
|
||||
|
||||
/* XXX: can we rename providers here? */
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
gv_rename_vol(struct gv_softc *sc, struct gctl_req *req, struct gv_volume *v, char *newname, int flags)
|
||||
{
|
||||
struct gv_plex *p;
|
||||
int err;
|
||||
|
||||
g_topology_assert();
|
||||
KASSERT(v != NULL, ("gv_rename_vol: NULL v"));
|
||||
|
||||
if (gv_object_type(sc, newname) != -1) {
|
||||
gctl_error(req, "volume name %s already in use", newname);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* Rename the volume. */
|
||||
strncpy(v->name, newname, GV_MAXVOLNAME);
|
||||
|
||||
/* Fix up references and potentially rename plexes. */
|
||||
LIST_FOREACH(p, &v->plexes, in_volume) {
|
||||
strncpy(p->volume, v->name, GV_MAXVOLNAME);
|
||||
if (flags && GV_FLAG_R) {
|
||||
char newplexname[GV_MAXPLEXNAME];
|
||||
char oldplexname[GV_MAXPLEXNAME];
|
||||
char *poldplexname = oldplexname;
|
||||
strncpy(oldplexname, p->name, GV_MAXPLEXNAME);
|
||||
strsep(&poldplexname, ".");
|
||||
snprintf(newplexname, GV_MAXPLEXNAME, "%s.%s",
|
||||
v->name, poldplexname);
|
||||
err = gv_rename_plex(sc, req, p, newplexname, flags);
|
||||
if (err)
|
||||
return err;
|
||||
}
|
||||
}
|
||||
|
||||
return (0);
|
||||
}
|
@ -43,8 +43,6 @@ static int gv_rm_drive(struct gv_softc *, struct gctl_req *,
|
||||
struct gv_drive *, int);
|
||||
static int gv_rm_plex(struct gv_softc *, struct gctl_req *,
|
||||
struct gv_plex *, int);
|
||||
static int gv_rm_sd(struct gv_softc *, struct gctl_req *, struct gv_sd *,
|
||||
int);
|
||||
static int gv_rm_vol(struct gv_softc *, struct gctl_req *,
|
||||
struct gv_volume *, int);
|
||||
|
||||
@ -240,7 +238,7 @@ gv_rm_plex(struct gv_softc *sc, struct gctl_req *req, struct gv_plex *p, int fla
|
||||
}
|
||||
|
||||
/* Remove a subdisk. */
|
||||
static int
|
||||
int
|
||||
gv_rm_sd(struct gv_softc *sc, struct gctl_req *req, struct gv_sd *s, int flags)
|
||||
{
|
||||
struct g_provider *pp;
|
||||
|
@ -6,6 +6,7 @@ KMOD= geom_vinum
|
||||
SRCS= geom_vinum_drive.c geom_vinum.c geom_vinum_plex.c \
|
||||
geom_vinum_volume.c geom_vinum_subr.c geom_vinum_raid5.c \
|
||||
geom_vinum_share.c geom_vinum_list.c geom_vinum_rm.c \
|
||||
geom_vinum_init.c geom_vinum_state.c
|
||||
geom_vinum_init.c geom_vinum_state.c geom_vinum_rename.c \
|
||||
geom_vinum_move.c
|
||||
|
||||
.include <bsd.kmod.mk>
|
||||
|
Loading…
Reference in New Issue
Block a user