Changeset View
Changeset View
Standalone View
Standalone View
sys/geom/multipath/g_multipath.c
Show First 20 Lines • Show All 945 Lines • ▼ Show 20 Lines | |||||
g_multipath_ctl_add_name(struct gctl_req *req, struct g_class *mp, | g_multipath_ctl_add_name(struct gctl_req *req, struct g_class *mp, | ||||
const char *name) | const char *name) | ||||
{ | { | ||||
struct g_multipath_softc *sc; | struct g_multipath_softc *sc; | ||||
struct g_geom *gp; | struct g_geom *gp; | ||||
struct g_consumer *cp; | struct g_consumer *cp; | ||||
struct g_provider *pp; | struct g_provider *pp; | ||||
const char *mpname; | const char *mpname; | ||||
static const char devpf[6] = _PATH_DEV; | |||||
int error; | int error; | ||||
g_topology_assert(); | g_topology_assert(); | ||||
mpname = gctl_get_asciiparam(req, "arg0"); | mpname = gctl_get_providername(req, "arg0"); | ||||
if (mpname == NULL) { | if (mpname == NULL) | ||||
gctl_error(req, "No 'arg0' argument"); | |||||
return; | return; | ||||
} | |||||
gp = g_multipath_find_geom(mp, mpname); | gp = g_multipath_find_geom(mp, mpname); | ||||
if (gp == NULL) { | if (gp == NULL) { | ||||
gctl_error(req, "Device %s is invalid", mpname); | gctl_error(req, "Device %s is invalid", mpname); | ||||
return; | return; | ||||
} | } | ||||
sc = gp->softc; | sc = gp->softc; | ||||
if (strncmp(name, devpf, 5) == 0) | |||||
name += 5; | |||||
pp = g_provider_by_name(name); | pp = g_provider_by_name(name); | ||||
if (pp == NULL) { | if (pp == NULL) { | ||||
gctl_error(req, "Provider %s is invalid", name); | gctl_error(req, "Provider %s is invalid", name); | ||||
return; | return; | ||||
} | } | ||||
/* | /* | ||||
* Check to make sure parameters match. | * Check to make sure parameters match. | ||||
Show All 28 Lines | |||||
static void | static void | ||||
g_multipath_ctl_prefer(struct gctl_req *req, struct g_class *mp) | g_multipath_ctl_prefer(struct gctl_req *req, struct g_class *mp) | ||||
{ | { | ||||
struct g_geom *gp; | struct g_geom *gp; | ||||
struct g_multipath_softc *sc; | struct g_multipath_softc *sc; | ||||
struct g_consumer *cp; | struct g_consumer *cp; | ||||
const char *name, *mpname; | const char *name, *mpname; | ||||
static const char devpf[6] = _PATH_DEV; | |||||
int *nargs; | int *nargs; | ||||
g_topology_assert(); | g_topology_assert(); | ||||
mpname = gctl_get_asciiparam(req, "arg0"); | mpname = gctl_get_providername(req, "arg0"); | ||||
if (mpname == NULL) { | if (mpname == NULL) | ||||
gctl_error(req, "No 'arg0' argument"); | |||||
return; | return; | ||||
} | |||||
gp = g_multipath_find_geom(mp, mpname); | gp = g_multipath_find_geom(mp, mpname); | ||||
if (gp == NULL) { | if (gp == NULL) { | ||||
gctl_error(req, "Device %s is invalid", mpname); | gctl_error(req, "Device %s is invalid", mpname); | ||||
return; | return; | ||||
} | } | ||||
sc = gp->softc; | sc = gp->softc; | ||||
nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs)); | nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs)); | ||||
if (nargs == NULL) { | if (nargs == NULL) { | ||||
gctl_error(req, "No 'nargs' argument"); | gctl_error(req, "No 'nargs' argument"); | ||||
return; | return; | ||||
} | } | ||||
if (*nargs != 2) { | if (*nargs != 2) { | ||||
gctl_error(req, "missing device"); | gctl_error(req, "missing device"); | ||||
return; | return; | ||||
} | } | ||||
name = gctl_get_asciiparam(req, "arg1"); | name = gctl_get_providername(req, "arg1"); | ||||
if (name == NULL) { | if (name == NULL) | ||||
gctl_error(req, "No 'arg1' argument"); | |||||
return; | return; | ||||
} | |||||
if (strncmp(name, devpf, 5) == 0) { | |||||
name += 5; | |||||
} | |||||
LIST_FOREACH(cp, &gp->consumer, consumer) { | LIST_FOREACH(cp, &gp->consumer, consumer) { | ||||
if (cp->provider != NULL | if (cp->provider != NULL | ||||
&& strcmp(cp->provider->name, name) == 0) | && strcmp(cp->provider->name, name) == 0) | ||||
break; | break; | ||||
} | } | ||||
if (cp == NULL) { | if (cp == NULL) { | ||||
Show All 20 Lines | |||||
} | } | ||||
static void | static void | ||||
g_multipath_ctl_add(struct gctl_req *req, struct g_class *mp) | g_multipath_ctl_add(struct gctl_req *req, struct g_class *mp) | ||||
{ | { | ||||
struct g_geom *gp; | struct g_geom *gp; | ||||
const char *mpname, *name; | const char *mpname, *name; | ||||
mpname = gctl_get_asciiparam(req, "arg0"); | mpname = gctl_get_providername(req, "arg0"); | ||||
if (mpname == NULL) { | if (mpname == NULL) | ||||
gctl_error(req, "No 'arg0' argument"); | |||||
return; | return; | ||||
} | |||||
gp = g_multipath_find_geom(mp, mpname); | gp = g_multipath_find_geom(mp, mpname); | ||||
if (gp == NULL) { | if (gp == NULL) { | ||||
gctl_error(req, "Device %s not found", mpname); | gctl_error(req, "Device %s not found", mpname); | ||||
return; | return; | ||||
} | } | ||||
name = gctl_get_asciiparam(req, "arg1"); | name = gctl_get_providername(req, "arg1"); | ||||
if (name == NULL) { | if (name == NULL) | ||||
gctl_error(req, "No 'arg1' argument"); | |||||
return; | return; | ||||
} | |||||
g_multipath_ctl_add_name(req, mp, name); | g_multipath_ctl_add_name(req, mp, name); | ||||
} | } | ||||
static void | static void | ||||
g_multipath_ctl_create(struct gctl_req *req, struct g_class *mp) | g_multipath_ctl_create(struct gctl_req *req, struct g_class *mp) | ||||
{ | { | ||||
struct g_multipath_metadata md; | struct g_multipath_metadata md; | ||||
struct g_multipath_softc *sc; | struct g_multipath_softc *sc; | ||||
struct g_geom *gp; | struct g_geom *gp; | ||||
const char *mpname, *name; | const char *mpname, *name; | ||||
char param[16]; | char param[16]; | ||||
int *nargs, i, *val; | int *nargs, i, *val; | ||||
g_topology_assert(); | g_topology_assert(); | ||||
nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs)); | nargs = gctl_get_paraml(req, "nargs", sizeof(*nargs)); | ||||
if (*nargs < 2) { | if (*nargs < 2) { | ||||
gctl_error(req, "wrong number of arguments."); | gctl_error(req, "wrong number of arguments."); | ||||
return; | return; | ||||
} | } | ||||
mpname = gctl_get_asciiparam(req, "arg0"); | mpname = gctl_get_providername(req, "arg0"); | ||||
if (mpname == NULL) { | if (mpname == NULL) | ||||
gctl_error(req, "No 'arg0' argument"); | |||||
return; | return; | ||||
} | |||||
gp = g_multipath_find_geom(mp, mpname); | gp = g_multipath_find_geom(mp, mpname); | ||||
if (gp != NULL) { | if (gp != NULL) { | ||||
gctl_error(req, "Device %s already exist", mpname); | gctl_error(req, "Device %s already exist", mpname); | ||||
return; | return; | ||||
} | } | ||||
memset(&md, 0, sizeof(md)); | memset(&md, 0, sizeof(md)); | ||||
strlcpy(md.md_magic, G_MULTIPATH_MAGIC, sizeof(md.md_magic)); | strlcpy(md.md_magic, G_MULTIPATH_MAGIC, sizeof(md.md_magic)); | ||||
Show All 14 Lines | if (gp == NULL) { | ||||
gctl_error(req, "GEOM_MULTIPATH: cannot create geom %s/%s\n", | gctl_error(req, "GEOM_MULTIPATH: cannot create geom %s/%s\n", | ||||
md.md_name, md.md_uuid); | md.md_name, md.md_uuid); | ||||
return; | return; | ||||
} | } | ||||
sc = gp->softc; | sc = gp->softc; | ||||
for (i = 1; i < *nargs; i++) { | for (i = 1; i < *nargs; i++) { | ||||
snprintf(param, sizeof(param), "arg%d", i); | snprintf(param, sizeof(param), "arg%d", i); | ||||
name = gctl_get_asciiparam(req, param); | name = gctl_get_providername(req, param); | ||||
if (name == NULL) | |||||
continue; | |||||
g_multipath_ctl_add_name(req, mp, name); | g_multipath_ctl_add_name(req, mp, name); | ||||
} | } | ||||
if (sc->sc_ndisks != (*nargs - 1)) | if (sc->sc_ndisks != (*nargs - 1)) | ||||
g_multipath_destroy(gp); | g_multipath_destroy(gp); | ||||
} | } | ||||
static void | static void | ||||
g_multipath_ctl_configure(struct gctl_req *req, struct g_class *mp) | g_multipath_ctl_configure(struct gctl_req *req, struct g_class *mp) | ||||
{ | { | ||||
struct g_multipath_softc *sc; | struct g_multipath_softc *sc; | ||||
struct g_geom *gp; | struct g_geom *gp; | ||||
struct g_consumer *cp; | struct g_consumer *cp; | ||||
struct g_provider *pp; | struct g_provider *pp; | ||||
struct g_multipath_metadata md; | struct g_multipath_metadata md; | ||||
const char *name; | const char *name; | ||||
int error, *val; | int error, *val; | ||||
g_topology_assert(); | g_topology_assert(); | ||||
name = gctl_get_asciiparam(req, "arg0"); | name = gctl_get_providername(req, "arg0"); | ||||
if (name == NULL) { | if (name == NULL) | ||||
gctl_error(req, "No 'arg0' argument"); | |||||
return; | return; | ||||
} | |||||
gp = g_multipath_find_geom(mp, name); | gp = g_multipath_find_geom(mp, name); | ||||
if (gp == NULL) { | if (gp == NULL) { | ||||
gctl_error(req, "Device %s is invalid", name); | gctl_error(req, "Device %s is invalid", name); | ||||
return; | return; | ||||
} | } | ||||
sc = gp->softc; | sc = gp->softc; | ||||
val = gctl_get_paraml(req, "active_active", sizeof(*val)); | val = gctl_get_paraml(req, "active_active", sizeof(*val)); | ||||
if (val != NULL && *val != 0) | if (val != NULL && *val != 0) | ||||
Show All 25 Lines | |||||
g_multipath_ctl_fail(struct gctl_req *req, struct g_class *mp, int fail) | g_multipath_ctl_fail(struct gctl_req *req, struct g_class *mp, int fail) | ||||
{ | { | ||||
struct g_multipath_softc *sc; | struct g_multipath_softc *sc; | ||||
struct g_geom *gp; | struct g_geom *gp; | ||||
struct g_consumer *cp; | struct g_consumer *cp; | ||||
const char *mpname, *name; | const char *mpname, *name; | ||||
int found; | int found; | ||||
mpname = gctl_get_asciiparam(req, "arg0"); | mpname = gctl_get_providername(req, "arg0"); | ||||
if (mpname == NULL) { | if (mpname == NULL) | ||||
gctl_error(req, "No 'arg0' argument"); | |||||
return; | return; | ||||
} | |||||
gp = g_multipath_find_geom(mp, mpname); | gp = g_multipath_find_geom(mp, mpname); | ||||
if (gp == NULL) { | if (gp == NULL) { | ||||
gctl_error(req, "Device %s not found", mpname); | gctl_error(req, "Device %s not found", mpname); | ||||
return; | return; | ||||
} | } | ||||
sc = gp->softc; | sc = gp->softc; | ||||
name = gctl_get_asciiparam(req, "arg1"); | name = gctl_get_providername(req, "arg1"); | ||||
if (name == NULL) { | if (name == NULL) | ||||
gctl_error(req, "No 'arg1' argument"); | |||||
return; | return; | ||||
} | |||||
found = 0; | found = 0; | ||||
mtx_lock(&sc->sc_mtx); | mtx_lock(&sc->sc_mtx); | ||||
LIST_FOREACH(cp, &gp->consumer, consumer) { | LIST_FOREACH(cp, &gp->consumer, consumer) { | ||||
if (cp->provider != NULL && | if (cp->provider != NULL && | ||||
strcmp(cp->provider->name, name) == 0 && | strcmp(cp->provider->name, name) == 0 && | ||||
(cp->index & MP_LOST) == 0) { | (cp->index & MP_LOST) == 0) { | ||||
found = 1; | found = 1; | ||||
Show All 22 Lines | |||||
{ | { | ||||
struct g_multipath_softc *sc; | struct g_multipath_softc *sc; | ||||
struct g_geom *gp; | struct g_geom *gp; | ||||
struct g_consumer *cp, *cp1; | struct g_consumer *cp, *cp1; | ||||
const char *mpname, *name; | const char *mpname, *name; | ||||
uintptr_t *cnt; | uintptr_t *cnt; | ||||
int found; | int found; | ||||
mpname = gctl_get_asciiparam(req, "arg0"); | mpname = gctl_get_providername(req, "arg0"); | ||||
if (mpname == NULL) { | if (mpname == NULL) | ||||
gctl_error(req, "No 'arg0' argument"); | |||||
return; | return; | ||||
} | |||||
gp = g_multipath_find_geom(mp, mpname); | gp = g_multipath_find_geom(mp, mpname); | ||||
if (gp == NULL) { | if (gp == NULL) { | ||||
gctl_error(req, "Device %s not found", mpname); | gctl_error(req, "Device %s not found", mpname); | ||||
return; | return; | ||||
} | } | ||||
sc = gp->softc; | sc = gp->softc; | ||||
name = gctl_get_asciiparam(req, "arg1"); | name = gctl_get_providername(req, "arg1"); | ||||
if (name == NULL) { | if (name == NULL) | ||||
gctl_error(req, "No 'arg1' argument"); | |||||
return; | return; | ||||
} | |||||
found = 0; | found = 0; | ||||
mtx_lock(&sc->sc_mtx); | mtx_lock(&sc->sc_mtx); | ||||
LIST_FOREACH_SAFE(cp, &gp->consumer, consumer, cp1) { | LIST_FOREACH_SAFE(cp, &gp->consumer, consumer, cp1) { | ||||
if (cp->provider != NULL && | if (cp->provider != NULL && | ||||
strcmp(cp->provider->name, name) == 0 && | strcmp(cp->provider->name, name) == 0 && | ||||
(cp->index & MP_LOST) == 0) { | (cp->index & MP_LOST) == 0) { | ||||
found = 1; | found = 1; | ||||
Show All 39 Lines | |||||
g_multipath_ctl_stop(struct gctl_req *req, struct g_class *mp) | g_multipath_ctl_stop(struct gctl_req *req, struct g_class *mp) | ||||
{ | { | ||||
struct g_geom *gp; | struct g_geom *gp; | ||||
const char *name; | const char *name; | ||||
int error; | int error; | ||||
g_topology_assert(); | g_topology_assert(); | ||||
name = gctl_get_asciiparam(req, "arg0"); | name = gctl_get_providername(req, "arg0"); | ||||
if (name == NULL) { | if (name == NULL) | ||||
gctl_error(req, "No 'arg0' argument"); | |||||
return; | return; | ||||
} | |||||
gp = g_multipath_find_geom(mp, name); | gp = g_multipath_find_geom(mp, name); | ||||
if (gp == NULL) { | if (gp == NULL) { | ||||
gctl_error(req, "Device %s is invalid", name); | gctl_error(req, "Device %s is invalid", name); | ||||
return; | return; | ||||
} | } | ||||
error = g_multipath_destroy(gp); | error = g_multipath_destroy(gp); | ||||
if (error != 0 && error != EINPROGRESS) | if (error != 0 && error != EINPROGRESS) | ||||
gctl_error(req, "failed to stop %s (err=%d)", name, error); | gctl_error(req, "failed to stop %s (err=%d)", name, error); | ||||
} | } | ||||
static void | static void | ||||
g_multipath_ctl_destroy(struct gctl_req *req, struct g_class *mp) | g_multipath_ctl_destroy(struct gctl_req *req, struct g_class *mp) | ||||
{ | { | ||||
struct g_geom *gp; | struct g_geom *gp; | ||||
struct g_multipath_softc *sc; | struct g_multipath_softc *sc; | ||||
struct g_consumer *cp; | struct g_consumer *cp; | ||||
struct g_provider *pp; | struct g_provider *pp; | ||||
const char *name; | const char *name; | ||||
uint8_t *buf; | uint8_t *buf; | ||||
int error; | int error; | ||||
g_topology_assert(); | g_topology_assert(); | ||||
name = gctl_get_asciiparam(req, "arg0"); | name = gctl_get_providername(req, "arg0"); | ||||
if (name == NULL) { | if (name == NULL) | ||||
gctl_error(req, "No 'arg0' argument"); | |||||
return; | return; | ||||
} | |||||
gp = g_multipath_find_geom(mp, name); | gp = g_multipath_find_geom(mp, name); | ||||
if (gp == NULL) { | if (gp == NULL) { | ||||
gctl_error(req, "Device %s is invalid", name); | gctl_error(req, "Device %s is invalid", name); | ||||
return; | return; | ||||
} | } | ||||
sc = gp->softc; | sc = gp->softc; | ||||
if (sc->sc_uuid[0] != 0 && sc->sc_active != NULL) { | if (sc->sc_uuid[0] != 0 && sc->sc_active != NULL) { | ||||
Show All 25 Lines | |||||
g_multipath_ctl_rotate(struct gctl_req *req, struct g_class *mp) | g_multipath_ctl_rotate(struct gctl_req *req, struct g_class *mp) | ||||
{ | { | ||||
struct g_geom *gp; | struct g_geom *gp; | ||||
const char *name; | const char *name; | ||||
int error; | int error; | ||||
g_topology_assert(); | g_topology_assert(); | ||||
name = gctl_get_asciiparam(req, "arg0"); | name = gctl_get_providername(req, "arg0"); | ||||
if (name == NULL) { | if (name == NULL) | ||||
gctl_error(req, "No 'arg0' argument"); | |||||
return; | return; | ||||
} | |||||
gp = g_multipath_find_geom(mp, name); | gp = g_multipath_find_geom(mp, name); | ||||
if (gp == NULL) { | if (gp == NULL) { | ||||
gctl_error(req, "Device %s is invalid", name); | gctl_error(req, "Device %s is invalid", name); | ||||
return; | return; | ||||
} | } | ||||
error = g_multipath_rotate(gp); | error = g_multipath_rotate(gp); | ||||
if (error != 0) { | if (error != 0) { | ||||
gctl_error(req, "failed to rotate %s (err=%d)", name, error); | gctl_error(req, "failed to rotate %s (err=%d)", name, error); | ||||
} | } | ||||
} | } | ||||
static void | static void | ||||
g_multipath_ctl_getactive(struct gctl_req *req, struct g_class *mp) | g_multipath_ctl_getactive(struct gctl_req *req, struct g_class *mp) | ||||
{ | { | ||||
struct sbuf *sb; | struct sbuf *sb; | ||||
struct g_geom *gp; | struct g_geom *gp; | ||||
struct g_multipath_softc *sc; | struct g_multipath_softc *sc; | ||||
struct g_consumer *cp; | struct g_consumer *cp; | ||||
const char *name; | const char *name; | ||||
int empty; | int empty; | ||||
sb = sbuf_new_auto(); | sb = sbuf_new_auto(); | ||||
g_topology_assert(); | g_topology_assert(); | ||||
name = gctl_get_asciiparam(req, "arg0"); | name = gctl_get_providername(req, "arg0"); | ||||
if (name == NULL) { | if (name == NULL) | ||||
gctl_error(req, "No 'arg0' argument"); | |||||
return; | return; | ||||
} | |||||
gp = g_multipath_find_geom(mp, name); | gp = g_multipath_find_geom(mp, name); | ||||
if (gp == NULL) { | if (gp == NULL) { | ||||
gctl_error(req, "Device %s is invalid", name); | gctl_error(req, "Device %s is invalid", name); | ||||
return; | return; | ||||
} | } | ||||
sc = gp->softc; | sc = gp->softc; | ||||
if (sc->sc_active_active == 1) { | if (sc->sc_active_active == 1) { | ||||
empty = 1; | empty = 1; | ||||
▲ Show 20 Lines • Show All 97 Lines • Show Last 20 Lines |