Changeset View
Changeset View
Standalone View
Standalone View
sys/geom/mirror/g_mirror_ctl.c
Show First 20 Lines • Show All 125 Lines • ▼ Show 20 Lines | |||||
} | } | ||||
static struct g_mirror_disk * | static struct g_mirror_disk * | ||||
g_mirror_find_disk(struct g_mirror_softc *sc, const char *name) | g_mirror_find_disk(struct g_mirror_softc *sc, const char *name) | ||||
{ | { | ||||
struct g_mirror_disk *disk; | struct g_mirror_disk *disk; | ||||
sx_assert(&sc->sc_lock, SX_XLOCKED); | sx_assert(&sc->sc_lock, SX_XLOCKED); | ||||
if (strncmp(name, _PATH_DEV, 5) == 0) | |||||
name += 5; | |||||
LIST_FOREACH(disk, &sc->sc_disks, d_next) { | LIST_FOREACH(disk, &sc->sc_disks, d_next) { | ||||
if (disk->d_consumer == NULL) | if (disk->d_consumer == NULL) | ||||
continue; | continue; | ||||
if (disk->d_consumer->provider == NULL) | if (disk->d_consumer->provider == NULL) | ||||
continue; | continue; | ||||
if (strcmp(disk->d_consumer->provider->name, name) == 0) | if (strcmp(disk->d_consumer->provider->name, name) == 0) | ||||
return (disk); | return (disk); | ||||
} | } | ||||
Show All 16 Lines | g_mirror_ctl_configure(struct gctl_req *req, struct g_class *mp) | ||||
if (nargs == NULL) { | if (nargs == NULL) { | ||||
gctl_error(req, "No '%s' argument.", "nargs"); | gctl_error(req, "No '%s' argument.", "nargs"); | ||||
return; | return; | ||||
} | } | ||||
if (*nargs != 1 && *nargs != 2) { | if (*nargs != 1 && *nargs != 2) { | ||||
gctl_error(req, "Invalid number of arguments."); | gctl_error(req, "Invalid number of arguments."); | ||||
return; | return; | ||||
} | } | ||||
name = gctl_get_asciiparam(req, "arg0"); | name = gctl_get_devname(req, "arg0"); | ||||
if (name == NULL) { | if (name == NULL) | ||||
gctl_error(req, "No 'arg%u' argument.", 0); | |||||
return; | return; | ||||
} | |||||
balancep = gctl_get_asciiparam(req, "balance"); | balancep = gctl_get_asciiparam(req, "balance"); | ||||
if (balancep == NULL) { | if (balancep == NULL) { | ||||
gctl_error(req, "No '%s' argument.", "balance"); | gctl_error(req, "No '%s' argument.", "balance"); | ||||
return; | return; | ||||
} | } | ||||
autosync = gctl_get_paraml(req, "autosync", sizeof(*autosync)); | autosync = gctl_get_paraml(req, "autosync", sizeof(*autosync)); | ||||
if (autosync == NULL) { | if (autosync == NULL) { | ||||
gctl_error(req, "No '%s' argument.", "autosync"); | gctl_error(req, "No '%s' argument.", "autosync"); | ||||
Show All 34 Lines | gctl_error(req, "Priority range is 0 to 255, %jd given", | ||||
*priority); | *priority); | ||||
return; | return; | ||||
} | } | ||||
/* | /* | ||||
* Since we have a priority, we also need a provider now. | * Since we have a priority, we also need a provider now. | ||||
* Note: be WARNS safe, by always assigning prov and only throw an | * Note: be WARNS safe, by always assigning prov and only throw an | ||||
* error if *priority != -1. | * error if *priority != -1. | ||||
*/ | */ | ||||
prov = gctl_get_asciiparam(req, "arg1"); | prov = gctl_get_devname(req, "arg1"); | ||||
if (*priority > -1) { | if (*priority > -1) { | ||||
if (prov == NULL) { | if (prov == NULL) { | ||||
gctl_error(req, "Priority needs a disk name"); | gctl_error(req, "Priority needs a disk name"); | ||||
return; | return; | ||||
} | } | ||||
do_priority = 1; | do_priority = 1; | ||||
} | } | ||||
if (*autosync && *noautosync) { | if (*autosync && *noautosync) { | ||||
▲ Show 20 Lines • Show All 156 Lines • ▼ Show 20 Lines | g_mirror_ctl_create(struct gctl_req *req, struct g_class *mp) | ||||
} | } | ||||
if (*nargs <= 2) { | if (*nargs <= 2) { | ||||
gctl_error(req, "Too few arguments."); | gctl_error(req, "Too few arguments."); | ||||
return; | return; | ||||
} | } | ||||
strlcpy(md.md_magic, G_MIRROR_MAGIC, sizeof(md.md_magic)); | strlcpy(md.md_magic, G_MIRROR_MAGIC, sizeof(md.md_magic)); | ||||
md.md_version = G_MIRROR_VERSION; | md.md_version = G_MIRROR_VERSION; | ||||
name = gctl_get_asciiparam(req, "arg0"); | name = gctl_get_devname(req, "arg0"); | ||||
if (name == NULL) { | if (name == NULL) | ||||
gctl_error(req, "No 'arg%u' argument.", 0); | |||||
return; | return; | ||||
} | |||||
strlcpy(md.md_name, name, sizeof(md.md_name)); | strlcpy(md.md_name, name, sizeof(md.md_name)); | ||||
md.md_mid = arc4random(); | md.md_mid = arc4random(); | ||||
md.md_all = *nargs - 1; | md.md_all = *nargs - 1; | ||||
md.md_genid = 0; | md.md_genid = 0; | ||||
md.md_syncid = 1; | md.md_syncid = 1; | ||||
md.md_sync_offset = 0; | md.md_sync_offset = 0; | ||||
val = gctl_get_paraml(req, "slice", sizeof(*val)); | val = gctl_get_paraml(req, "slice", sizeof(*val)); | ||||
if (val == NULL) { | if (val == NULL) { | ||||
▲ Show 20 Lines • Show All 83 Lines • ▼ Show 20 Lines | err2: | ||||
sx_xlock(&sc->sc_lock); | sx_xlock(&sc->sc_lock); | ||||
sc->sc_flags |= G_MIRROR_DEVICE_FLAG_TASTING; | sc->sc_flags |= G_MIRROR_DEVICE_FLAG_TASTING; | ||||
sb = sbuf_new_auto(); | sb = sbuf_new_auto(); | ||||
sbuf_printf(sb, "Can't attach disk(s) to %s:", gp->name); | sbuf_printf(sb, "Can't attach disk(s) to %s:", gp->name); | ||||
for (attached = 0, no = 1; no < *nargs; no++) { | for (attached = 0, no = 1; no < *nargs; no++) { | ||||
snprintf(param, sizeof(param), "arg%u", no); | snprintf(param, sizeof(param), "arg%u", no); | ||||
pp = gctl_get_provider(req, param); | pp = gctl_get_provider(req, param); | ||||
if (pp == NULL) { | if (pp == NULL) { | ||||
name = gctl_get_asciiparam(req, param); | name = gctl_get_devname(req, param); | ||||
MPASS(name != NULL); | MPASS(name != NULL); | ||||
sbuf_printf(sb, " %s", name); | sbuf_printf(sb, " %s", name); | ||||
continue; | continue; | ||||
} | } | ||||
md.md_did = arc4random(); | md.md_did = arc4random(); | ||||
md.md_priority = no - 1; | md.md_priority = no - 1; | ||||
if (g_mirror_add_disk(sc, pp, &md) != 0) { | if (g_mirror_add_disk(sc, pp, &md) != 0) { | ||||
G_MIRROR_DEBUG(1, "Disk %u (%s) not attached to %s.", | G_MIRROR_DEBUG(1, "Disk %u (%s) not attached to %s.", | ||||
Show All 30 Lines | g_mirror_ctl_rebuild(struct gctl_req *req, struct g_class *mp) | ||||
if (nargs == NULL) { | if (nargs == NULL) { | ||||
gctl_error(req, "No '%s' argument.", "nargs"); | gctl_error(req, "No '%s' argument.", "nargs"); | ||||
return; | return; | ||||
} | } | ||||
if (*nargs < 2) { | if (*nargs < 2) { | ||||
gctl_error(req, "Too few arguments."); | gctl_error(req, "Too few arguments."); | ||||
return; | return; | ||||
} | } | ||||
name = gctl_get_asciiparam(req, "arg0"); | name = gctl_get_devname(req, "arg0"); | ||||
if (name == NULL) { | if (name == NULL) | ||||
gctl_error(req, "No 'arg%u' argument.", 0); | |||||
return; | return; | ||||
} | |||||
sc = g_mirror_find_device(mp, name); | sc = g_mirror_find_device(mp, name); | ||||
if (sc == NULL) { | if (sc == NULL) { | ||||
gctl_error(req, "No such device: %s.", name); | gctl_error(req, "No such device: %s.", name); | ||||
return; | return; | ||||
} | } | ||||
for (i = 1; i < (u_int)*nargs; i++) { | for (i = 1; i < (u_int)*nargs; i++) { | ||||
snprintf(param, sizeof(param), "arg%u", i); | snprintf(param, sizeof(param), "arg%u", i); | ||||
name = gctl_get_asciiparam(req, param); | name = gctl_get_devname(req, param); | ||||
if (name == NULL) { | if (name == NULL) | ||||
gctl_error(req, "No 'arg%u' argument.", i); | |||||
continue; | continue; | ||||
} | |||||
disk = g_mirror_find_disk(sc, name); | disk = g_mirror_find_disk(sc, name); | ||||
if (disk == NULL) { | if (disk == NULL) { | ||||
gctl_error(req, "No such provider: %s.", name); | gctl_error(req, "No such provider: %s.", name); | ||||
continue; | continue; | ||||
} | } | ||||
if (g_mirror_ndisks(sc, G_MIRROR_DISK_STATE_ACTIVE) == 1 && | if (g_mirror_ndisks(sc, G_MIRROR_DISK_STATE_ACTIVE) == 1 && | ||||
disk->d_state == G_MIRROR_DISK_STATE_ACTIVE) { | disk->d_state == G_MIRROR_DISK_STATE_ACTIVE) { | ||||
/* | /* | ||||
▲ Show 20 Lines • Show All 73 Lines • ▼ Show 20 Lines | if (inactive == NULL) { | ||||
gctl_error(req, "No '%s' argument.", "inactive"); | gctl_error(req, "No '%s' argument.", "inactive"); | ||||
return; | return; | ||||
} | } | ||||
hardcode = gctl_get_paraml(req, "hardcode", sizeof(*hardcode)); | hardcode = gctl_get_paraml(req, "hardcode", sizeof(*hardcode)); | ||||
if (hardcode == NULL) { | if (hardcode == NULL) { | ||||
gctl_error(req, "No '%s' argument.", "hardcode"); | gctl_error(req, "No '%s' argument.", "hardcode"); | ||||
return; | return; | ||||
} | } | ||||
name = gctl_get_asciiparam(req, "arg0"); | name = gctl_get_devname(req, "arg0"); | ||||
if (name == NULL) { | if (name == NULL) | ||||
gctl_error(req, "No 'arg%u' argument.", 0); | |||||
return; | return; | ||||
} | |||||
sc = g_mirror_find_launched_device(mp, name, M_WAITOK); | sc = g_mirror_find_launched_device(mp, name, M_WAITOK); | ||||
if (sc == NULL) { | if (sc == NULL) { | ||||
gctl_error(req, "No such device: %s.", name); | gctl_error(req, "No such device: %s.", name); | ||||
return; | return; | ||||
} | } | ||||
if (g_mirror_ndisks(sc, -1) < sc->sc_ndisks) { | if (g_mirror_ndisks(sc, -1) < sc->sc_ndisks) { | ||||
gctl_error(req, "Not all disks connected."); | gctl_error(req, "Not all disks connected."); | ||||
sx_xunlock(&sc->sc_lock); | sx_xunlock(&sc->sc_lock); | ||||
▲ Show 20 Lines • Show All 138 Lines • ▼ Show 20 Lines | g_mirror_ctl_remove(struct gctl_req *req, struct g_class *mp) | ||||
if (nargs == NULL) { | if (nargs == NULL) { | ||||
gctl_error(req, "No '%s' argument.", "nargs"); | gctl_error(req, "No '%s' argument.", "nargs"); | ||||
return; | return; | ||||
} | } | ||||
if (*nargs < 2) { | if (*nargs < 2) { | ||||
gctl_error(req, "Too few arguments."); | gctl_error(req, "Too few arguments."); | ||||
return; | return; | ||||
} | } | ||||
name = gctl_get_asciiparam(req, "arg0"); | name = gctl_get_devname(req, "arg0"); | ||||
if (name == NULL) { | if (name == NULL) | ||||
gctl_error(req, "No 'arg%u' argument.", 0); | |||||
return; | return; | ||||
} | |||||
sc = g_mirror_find_device(mp, name); | sc = g_mirror_find_device(mp, name); | ||||
if (sc == NULL) { | if (sc == NULL) { | ||||
gctl_error(req, "No such device: %s.", name); | gctl_error(req, "No such device: %s.", name); | ||||
return; | return; | ||||
} | } | ||||
if (g_mirror_ndisks(sc, -1) < sc->sc_ndisks) { | if (g_mirror_ndisks(sc, -1) < sc->sc_ndisks) { | ||||
sx_xunlock(&sc->sc_lock); | sx_xunlock(&sc->sc_lock); | ||||
gctl_error(req, "Not all disks connected. Try 'forget' command " | gctl_error(req, "Not all disks connected. Try 'forget' command " | ||||
"first."); | "first."); | ||||
return; | return; | ||||
} | } | ||||
active = g_mirror_ndisks(sc, G_MIRROR_DISK_STATE_ACTIVE); | active = g_mirror_ndisks(sc, G_MIRROR_DISK_STATE_ACTIVE); | ||||
for (i = 1; i < (u_int)*nargs; i++) { | for (i = 1; i < (u_int)*nargs; i++) { | ||||
snprintf(param, sizeof(param), "arg%u", i); | snprintf(param, sizeof(param), "arg%u", i); | ||||
name = gctl_get_asciiparam(req, param); | name = gctl_get_devname(req, param); | ||||
if (name == NULL) { | if (name == NULL) | ||||
gctl_error(req, "No 'arg%u' argument.", i); | |||||
continue; | continue; | ||||
} | |||||
disk = g_mirror_find_disk(sc, name); | disk = g_mirror_find_disk(sc, name); | ||||
if (disk == NULL) { | if (disk == NULL) { | ||||
gctl_error(req, "No such provider: %s.", name); | gctl_error(req, "No such provider: %s.", name); | ||||
continue; | continue; | ||||
} | } | ||||
if (disk->d_state == G_MIRROR_DISK_STATE_ACTIVE) { | if (disk->d_state == G_MIRROR_DISK_STATE_ACTIVE) { | ||||
if (active > 1) | if (active > 1) | ||||
active--; | active--; | ||||
Show All 24 Lines | g_mirror_ctl_resize(struct gctl_req *req, struct g_class *mp) | ||||
if (nargs == NULL) { | if (nargs == NULL) { | ||||
gctl_error(req, "No '%s' argument.", "nargs"); | gctl_error(req, "No '%s' argument.", "nargs"); | ||||
return; | return; | ||||
} | } | ||||
if (*nargs != 1) { | if (*nargs != 1) { | ||||
gctl_error(req, "Missing device."); | gctl_error(req, "Missing device."); | ||||
return; | return; | ||||
} | } | ||||
name = gctl_get_asciiparam(req, "arg0"); | name = gctl_get_devname(req, "arg0"); | ||||
if (name == NULL) { | if (name == NULL) | ||||
gctl_error(req, "No 'arg%u' argument.", 0); | |||||
return; | return; | ||||
} | |||||
s = gctl_get_asciiparam(req, "size"); | s = gctl_get_asciiparam(req, "size"); | ||||
if (s == NULL) { | if (s == NULL) { | ||||
gctl_error(req, "No '%s' argument.", "size"); | gctl_error(req, "No '%s' argument.", "size"); | ||||
return; | return; | ||||
} | } | ||||
mediasize = strtouq(s, &x, 0); | mediasize = strtouq(s, &x, 0); | ||||
if (*x != '\0' || mediasize == 0) { | if (*x != '\0' || mediasize == 0) { | ||||
gctl_error(req, "Invalid '%s' argument.", "size"); | gctl_error(req, "Invalid '%s' argument.", "size"); | ||||
▲ Show 20 Lines • Show All 47 Lines • ▼ Show 20 Lines | g_mirror_ctl_deactivate(struct gctl_req *req, struct g_class *mp) | ||||
if (nargs == NULL) { | if (nargs == NULL) { | ||||
gctl_error(req, "No '%s' argument.", "nargs"); | gctl_error(req, "No '%s' argument.", "nargs"); | ||||
return; | return; | ||||
} | } | ||||
if (*nargs < 2) { | if (*nargs < 2) { | ||||
gctl_error(req, "Too few arguments."); | gctl_error(req, "Too few arguments."); | ||||
return; | return; | ||||
} | } | ||||
name = gctl_get_asciiparam(req, "arg0"); | name = gctl_get_devname(req, "arg0"); | ||||
if (name == NULL) { | if (name == NULL) | ||||
gctl_error(req, "No 'arg%u' argument.", 0); | |||||
return; | return; | ||||
} | |||||
sc = g_mirror_find_device(mp, name); | sc = g_mirror_find_device(mp, name); | ||||
if (sc == NULL) { | if (sc == NULL) { | ||||
gctl_error(req, "No such device: %s.", name); | gctl_error(req, "No such device: %s.", name); | ||||
return; | return; | ||||
} | } | ||||
active = g_mirror_ndisks(sc, G_MIRROR_DISK_STATE_ACTIVE); | active = g_mirror_ndisks(sc, G_MIRROR_DISK_STATE_ACTIVE); | ||||
for (i = 1; i < (u_int)*nargs; i++) { | for (i = 1; i < (u_int)*nargs; i++) { | ||||
snprintf(param, sizeof(param), "arg%u", i); | snprintf(param, sizeof(param), "arg%u", i); | ||||
name = gctl_get_asciiparam(req, param); | name = gctl_get_devname(req, param); | ||||
if (name == NULL) { | if (name == NULL) | ||||
gctl_error(req, "No 'arg%u' argument.", i); | |||||
continue; | continue; | ||||
} | |||||
disk = g_mirror_find_disk(sc, name); | disk = g_mirror_find_disk(sc, name); | ||||
if (disk == NULL) { | if (disk == NULL) { | ||||
gctl_error(req, "No such provider: %s.", name); | gctl_error(req, "No such provider: %s.", name); | ||||
continue; | continue; | ||||
} | } | ||||
if (disk->d_state == G_MIRROR_DISK_STATE_ACTIVE) { | if (disk->d_state == G_MIRROR_DISK_STATE_ACTIVE) { | ||||
if (active > 1) | if (active > 1) | ||||
active--; | active--; | ||||
Show All 31 Lines | g_mirror_ctl_forget(struct gctl_req *req, struct g_class *mp) | ||||
} | } | ||||
if (*nargs < 1) { | if (*nargs < 1) { | ||||
gctl_error(req, "Missing device(s)."); | gctl_error(req, "Missing device(s)."); | ||||
return; | return; | ||||
} | } | ||||
for (i = 0; i < (u_int)*nargs; i++) { | for (i = 0; i < (u_int)*nargs; i++) { | ||||
snprintf(param, sizeof(param), "arg%u", i); | snprintf(param, sizeof(param), "arg%u", i); | ||||
name = gctl_get_asciiparam(req, param); | name = gctl_get_devname(req, param); | ||||
if (name == NULL) { | if (name == NULL) | ||||
gctl_error(req, "No 'arg%u' argument.", i); | |||||
return; | return; | ||||
} | |||||
sc = g_mirror_find_device(mp, name); | sc = g_mirror_find_device(mp, name); | ||||
if (sc == NULL) { | if (sc == NULL) { | ||||
gctl_error(req, "No such device: %s.", name); | gctl_error(req, "No such device: %s.", name); | ||||
return; | return; | ||||
} | } | ||||
if (g_mirror_ndisks(sc, -1) == sc->sc_ndisks) { | if (g_mirror_ndisks(sc, -1) == sc->sc_ndisks) { | ||||
sx_xunlock(&sc->sc_lock); | sx_xunlock(&sc->sc_lock); | ||||
G_MIRROR_DEBUG(1, | G_MIRROR_DEBUG(1, | ||||
Show All 35 Lines | g_mirror_ctl_stop(struct gctl_req *req, struct g_class *mp, int wipe) | ||||
} | } | ||||
if (*force) | if (*force) | ||||
how = G_MIRROR_DESTROY_HARD; | how = G_MIRROR_DESTROY_HARD; | ||||
else | else | ||||
how = G_MIRROR_DESTROY_SOFT; | how = G_MIRROR_DESTROY_SOFT; | ||||
for (i = 0; i < (u_int)*nargs; i++) { | for (i = 0; i < (u_int)*nargs; i++) { | ||||
snprintf(param, sizeof(param), "arg%u", i); | snprintf(param, sizeof(param), "arg%u", i); | ||||
name = gctl_get_asciiparam(req, param); | name = gctl_get_devname(req, param); | ||||
if (name == NULL) { | if (name == NULL) | ||||
gctl_error(req, "No 'arg%u' argument.", i); | |||||
return; | return; | ||||
} | |||||
sc = g_mirror_find_device(mp, name); | sc = g_mirror_find_device(mp, name); | ||||
if (sc == NULL) { | if (sc == NULL) { | ||||
gctl_error(req, "No such device: %s.", name); | gctl_error(req, "No such device: %s.", name); | ||||
return; | return; | ||||
} | } | ||||
g_cancel_event(sc); | g_cancel_event(sc); | ||||
if (wipe) | if (wipe) | ||||
sc->sc_flags |= G_MIRROR_DEVICE_FLAG_WIPE; | sc->sc_flags |= G_MIRROR_DEVICE_FLAG_WIPE; | ||||
▲ Show 20 Lines • Show All 55 Lines • Show Last 20 Lines |