Changeset View
Changeset View
Standalone View
Standalone View
sys/geom/concat/g_concat.c
Show First 20 Lines • Show All 863 Lines • ▼ Show 20 Lines | g_concat_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; | ||||
} | } | ||||
bzero(&md, sizeof(md)); | bzero(&md, sizeof(md)); | ||||
strlcpy(md.md_magic, G_CONCAT_MAGIC, sizeof(md.md_magic)); | strlcpy(md.md_magic, G_CONCAT_MAGIC, sizeof(md.md_magic)); | ||||
md.md_version = G_CONCAT_VERSION; | md.md_version = G_CONCAT_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_id = arc4random(); | md.md_id = arc4random(); | ||||
md.md_no = 0; | md.md_no = 0; | ||||
md.md_all = *nargs - 1; | md.md_all = *nargs - 1; | ||||
/* This field is not important here. */ | /* This field is not important here. */ | ||||
md.md_provsize = 0; | md.md_provsize = 0; | ||||
/* Check all providers are valid */ | /* Check all providers are valid */ | ||||
Show All 12 Lines | g_concat_ctl_create(struct gctl_req *req, struct g_class *mp) | ||||
sc = gp->softc; | sc = gp->softc; | ||||
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); | ||||
imp: Is this safe? I know it's a pre-existing thing, but is different than the others.
Alternatively… | |||||
Done Inline ActionsThis particular one is safe (the parameters passed in line 887-889; if the parameter was omitted, gctl_get_provider would have returned NULL and we have bailed out early). delphij: This particular one is safe (the parameters passed in line 887-889; if the parameter was… | |||||
Done Inline Actions
No, this is not guaranteed. I see this MPASS more of an invariant (because we already checked that for each parameters provided, there was a GEOM provider, which is stronger than parameter has contents) The assertion here is probably to silent some static analyzers ("hey, for other gctl_get_asciiparam callers you always checked if the return was not NULL, why did you skip here"). delphij: > can the callers assume this i s always != NULL and we can remove some tests
No, this is not… | |||||
sbuf_printf(sb, " %s", name); | sbuf_printf(sb, " %s", name); | ||||
continue; | continue; | ||||
} | } | ||||
if (g_concat_add_disk(sc, pp, no - 1) != 0) { | if (g_concat_add_disk(sc, pp, no - 1) != 0) { | ||||
G_CONCAT_DEBUG(1, "Disk %u (%s) not attached to %s.", | G_CONCAT_DEBUG(1, "Disk %u (%s) not attached to %s.", | ||||
no, pp->name, gp->name); | no, pp->name, gp->name); | ||||
sbuf_printf(sb, " %s", pp->name); | sbuf_printf(sb, " %s", pp->name); | ||||
continue; | continue; | ||||
Show All 9 Lines | |||||
} | } | ||||
static struct g_concat_softc * | static struct g_concat_softc * | ||||
g_concat_find_device(struct g_class *mp, const char *name) | g_concat_find_device(struct g_class *mp, const char *name) | ||||
{ | { | ||||
struct g_concat_softc *sc; | struct g_concat_softc *sc; | ||||
struct g_geom *gp; | struct g_geom *gp; | ||||
if (strncmp(name, _PATH_DEV, strlen(_PATH_DEV)) == 0) | |||||
name += strlen(_PATH_DEV); | |||||
LIST_FOREACH(gp, &mp->geom, geom) { | LIST_FOREACH(gp, &mp->geom, geom) { | ||||
sc = gp->softc; | sc = gp->softc; | ||||
if (sc == NULL) | if (sc == NULL) | ||||
continue; | continue; | ||||
if (strcmp(sc->sc_name, name) == 0) | if (strcmp(sc->sc_name, name) == 0) | ||||
return (sc); | return (sc); | ||||
} | } | ||||
return (NULL); | return (NULL); | ||||
Show All 22 Lines | g_concat_ctl_destroy(struct gctl_req *req, struct g_class *mp) | ||||
force = gctl_get_paraml(req, "force", sizeof(*force)); | force = gctl_get_paraml(req, "force", sizeof(*force)); | ||||
if (force == NULL) { | if (force == NULL) { | ||||
gctl_error(req, "No '%s' argument.", "force"); | gctl_error(req, "No '%s' argument.", "force"); | ||||
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_concat_find_device(mp, name); | sc = g_concat_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; | ||||
} | } | ||||
error = g_concat_destroy(sc, *force); | error = g_concat_destroy(sc, *force); | ||||
if (error != 0) { | if (error != 0) { | ||||
gctl_error(req, "Cannot destroy device %s (error=%d).", | gctl_error(req, "Cannot destroy device %s (error=%d).", | ||||
sc->sc_name, error); | sc->sc_name, error); | ||||
return; | return; | ||||
} | } | ||||
} | } | ||||
} | } | ||||
static struct g_concat_disk * | static struct g_concat_disk * | ||||
g_concat_find_disk(struct g_concat_softc *sc, const char *name) | g_concat_find_disk(struct g_concat_softc *sc, const char *name) | ||||
{ | { | ||||
struct g_concat_disk *disk; | struct g_concat_disk *disk; | ||||
sx_assert(&sc->sc_disks_lock, SX_LOCKED); | sx_assert(&sc->sc_disks_lock, SX_LOCKED); | ||||
if (strncmp(name, "/dev/", 5) == 0) | name = g_canonical_name(name); | ||||
name += 5; | |||||
TAILQ_FOREACH(disk, &sc->sc_disks, d_next) { | TAILQ_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 20 Lines • Show All 68 Lines • ▼ Show 20 Lines | if (*nargs != 2) { | ||||
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; | ||||
} | } | ||||
cname = gctl_get_asciiparam(req, "arg0"); | cname = gctl_get_devname(req, "arg0"); | ||||
if (cname == NULL) { | if (cname == NULL) | ||||
gctl_error(req, "No 'arg%u' argument.", 0); | |||||
return; | return; | ||||
} | |||||
sc = g_concat_find_device(mp, cname); | sc = g_concat_find_device(mp, cname); | ||||
if (sc == NULL) { | if (sc == NULL) { | ||||
gctl_error(req, "No such device: %s.", cname); | gctl_error(req, "No such device: %s.", cname); | ||||
return; | return; | ||||
} | } | ||||
if (sc->sc_provider == NULL) { | if (sc->sc_provider == NULL) { | ||||
/* | /* | ||||
* this won't race with g_concat_remove_disk as both | * this won't race with g_concat_remove_disk as both | ||||
* are holding the topology lock | * are holding the topology lock | ||||
*/ | */ | ||||
gctl_error(req, "Device not active, can't append: %s.", cname); | gctl_error(req, "Device not active, can't append: %s.", cname); | ||||
return; | return; | ||||
} | } | ||||
G_CONCAT_DEBUG(1, "Appending to %s:", cname); | G_CONCAT_DEBUG(1, "Appending to %s:", cname); | ||||
sx_xlock(&sc->sc_disks_lock); | sx_xlock(&sc->sc_disks_lock); | ||||
gp = sc->sc_geom; | gp = sc->sc_geom; | ||||
fcp = LIST_FIRST(&gp->consumer); | fcp = LIST_FIRST(&gp->consumer); | ||||
name = gctl_get_asciiparam(req, "arg1"); | name = gctl_get_devname(req, "arg1"); | ||||
if (name == NULL) { | if (name == NULL) | ||||
gctl_error(req, "No 'arg%u' argument.", 1); | |||||
goto fail; | goto fail; | ||||
} | |||||
if (strncmp(name, "/dev/", strlen("/dev/")) == 0) | |||||
name += strlen("/dev/"); | |||||
pp = g_provider_by_name(name); | pp = g_provider_by_name(name); | ||||
if (pp == NULL) { | if (pp == NULL) { | ||||
G_CONCAT_DEBUG(1, "Disk %s is invalid.", name); | G_CONCAT_DEBUG(1, "Disk %s is invalid.", name); | ||||
gctl_error(req, "Disk %s is invalid.", name); | gctl_error(req, "Disk %s is invalid.", name); | ||||
goto fail; | goto fail; | ||||
} | } | ||||
G_CONCAT_DEBUG(1, "Appending %s to this", name); | G_CONCAT_DEBUG(1, "Appending %s to this", name); | ||||
▲ Show 20 Lines • Show All 152 Lines • Show Last 20 Lines |
Is this safe? I know it's a pre-existing thing, but is different than the others.
Alternatively, can the callers assume this i s always != NULL and we can remove some tests?