Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Evergreen:11.1:Test
multipath-tools
multipath-tools-reload-map-for-ro-changes
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File multipath-tools-reload-map-for-ro-changes of Package multipath-tools
commit 3b88c4374cf2a204e14ffdaf85b2dbfdc4a1391a Author: Hannes Reinecke <hare@suse.de> Date: Thu Dec 4 14:20:06 2008 +0100 Reload map for device read-only setting changes Whenever the read-only setting for a device changes we have to reload the map. This patch implements the required cli command and also a uevent handler if a uevent with 'DISK_RO=' setting has been received. References: 440959 Signed-off-by: Hannes Reinecke <hare@suse.de> diff --git a/libmultipath/configure.c b/libmultipath/configure.c index 3903b28..68178c3 100644 --- a/libmultipath/configure.c +++ b/libmultipath/configure.c @@ -672,3 +672,40 @@ out: return NULL; } +extern int reload_map(struct vectors *vecs, struct multipath *mpp) +{ + char params[PARAMS_SIZE]; + int r; + + update_mpp_paths(mpp, vecs->pathvec); + + params[0] = '\0'; + if (setup_map(mpp, params, PARAMS_SIZE)) { + condlog(0, "%s: failed to setup map", mpp->alias); + return 1; + } + select_action(mpp, vecs->mpvec, 1); + + r = domap(mpp, params); + if (r == DOMAP_FAIL || r == DOMAP_RETRY) { + condlog(3, "%s: domap (%u) failure " + "for reload map", mpp->alias, r); + return 1; + } + if (mpp->no_path_retry != NO_PATH_RETRY_UNDEF) { + if (mpp->no_path_retry == NO_PATH_RETRY_FAIL) + dm_queue_if_no_path(mpp->alias, 0); + else + dm_queue_if_no_path(mpp->alias, 1); + } + if (mpp->pg_timeout != PGTIMEOUT_UNDEF) { + if (mpp->pg_timeout == -PGTIMEOUT_NONE) + dm_set_pg_timeout(mpp->alias, 0); + else + dm_set_pg_timeout(mpp->alias, mpp->pg_timeout); + } + + return 0; +} + + diff --git a/libmultipath/configure.h b/libmultipath/configure.h index ec2800d..d0c06f2 100644 --- a/libmultipath/configure.h +++ b/libmultipath/configure.h @@ -28,4 +28,5 @@ int domap (struct multipath * mpp, char * params); int reinstate_paths (struct multipath *mpp); int coalesce_paths (struct vectors *vecs, vector curmp, char * refwwid, int force_reload); char * get_refwwid (char * dev, enum devtypes dev_type, vector pathvec); +int reload_map(struct vectors *vecs, struct multipath *mpp); diff --git a/libmultipath/uevent.c b/libmultipath/uevent.c index 13986da..19a71ad 100644 --- a/libmultipath/uevent.c +++ b/libmultipath/uevent.c @@ -341,3 +341,23 @@ uevent_get_minor(struct uevent *uev) return minor; } +extern int +uevent_get_disk_ro(struct uevent *uev) +{ + char *p, *q; + int i, ro = -1; + + for (i = 0; uev->envp[i] != NULL; i++) { + if (!strncmp(uev->envp[i], "DISK_RO", 6) && strlen(uev->envp[i]) > 7) { + p = uev->envp[i] + 8; + ro = strtoul(p, &q, 10); + if (p == q) { + condlog(2, "invalid read_only setting '%s'", p); + ro = -1; + } + break; + } + } + return ro; +} + diff --git a/libmultipath/uevent.h b/libmultipath/uevent.h index 43d163b..ec6450b 100644 --- a/libmultipath/uevent.h +++ b/libmultipath/uevent.h @@ -23,5 +23,6 @@ int uevent_listen(int (*store_uev)(struct uevent *, void * trigger_data), void * trigger_data); int uevent_get_major(struct uevent *uev); int uevent_get_minor(struct uevent *uev); +int uevent_get_disk_ro(struct uevent *uev); #endif /* _UEVENT_H */ diff --git a/multipathd/cli.c b/multipathd/cli.c index 2545e89..acc8cab 100644 --- a/multipathd/cli.c +++ b/multipathd/cli.c @@ -156,6 +156,7 @@ load_keys (void) r += add_key(keys, "reinstate", REINSTATE, 0); r += add_key(keys, "fail", FAIL, 0); r += add_key(keys, "resize", RESIZE, 0); + r += add_key(keys, "reload", RELOAD, 0); r += add_key(keys, "paths", PATHS, 0); r += add_key(keys, "maps", MAPS, 0); r += add_key(keys, "multipaths", MAPS, 0); @@ -427,6 +428,8 @@ cli_init (void) { add_handler(RECONFIGURE, NULL); add_handler(SUSPEND+MAP, NULL); add_handler(RESUME+MAP, NULL); + add_handler(RESIZE+MAP, NULL); + add_handler(RELOAD+MAP, NULL); add_handler(REINSTATE+PATH, NULL); add_handler(FAIL+PATH, NULL); diff --git a/multipathd/cli.h b/multipathd/cli.h index be14395..1fa4862 100644 --- a/multipathd/cli.h +++ b/multipathd/cli.h @@ -8,6 +8,7 @@ enum { __REINSTATE, __FAIL, __RESIZE, + __RELOAD, __PATHS, __MAPS, __PATH, @@ -33,6 +34,7 @@ enum { #define REINSTATE (1 << __REINSTATE) #define FAIL (1 << __FAIL) #define RESIZE (1 << __RESIZE) +#define RELOAD (1 << __RELOAD) #define PATHS (1 << __PATHS) #define MAPS (1 << __MAPS) #define PATH (1 << __PATH) diff --git a/multipathd/cli_handlers.c b/multipathd/cli_handlers.c index 4f639b6..819dd87 100644 --- a/multipathd/cli_handlers.c +++ b/multipathd/cli_handlers.c @@ -460,6 +460,28 @@ out: return err; } +int +cli_reload(void *v, char **reply, int *len, void *data) +{ + struct vectors * vecs = (struct vectors *)data; + char * mapname = get_keyparam(v, MAP); + struct multipath *mpp; + int minor; + + condlog(2, "%s: reload map (operator)", mapname); + if (sscanf(mapname, "dm-%d", &minor) == 1) + mpp = find_mp_by_minor(vecs->mpvec, minor); + else + mpp = find_mp_by_alias(vecs->mpvec, mapname); + + if (!mpp) { + condlog(0, "%s: invalid map name. cannot reload", mapname); + return 1; + } + + return reload_map(vecs, mpp); +} + int resize_map(struct multipath *mpp, unsigned long long size, struct vectors * vecs) { diff --git a/multipathd/cli_handlers.h b/multipathd/cli_handlers.h index b65f259..6e92a07 100644 --- a/multipathd/cli_handlers.h +++ b/multipathd/cli_handlers.h @@ -17,6 +17,7 @@ int cli_del_map (void * v, char ** reply, int * len, void * data); int cli_switch_group(void * v, char ** reply, int * len, void * data); int cli_reconfigure(void * v, char ** reply, int * len, void * data); int cli_resize(void * v, char ** reply, int * len, void * data); +int cli_reload(void * v, char ** reply, int * len, void * data); int cli_suspend(void * v, char ** reply, int * len, void * data); int cli_resume(void * v, char ** reply, int * len, void * data); int cli_reinstate(void * v, char ** reply, int * len, void * data); diff --git a/multipathd/main.c b/multipathd/main.c index 444494e..c60d075 100644 --- a/multipathd/main.c +++ b/multipathd/main.c @@ -572,6 +572,43 @@ out: } static int +uev_update_path (struct uevent *uev, struct vectors * vecs) +{ + struct sysfs_device * dev; + int retval, ro; + + dev = sysfs_device_get(uev->devpath); + if (!dev) { + condlog(2, "%s: not found in sysfs", uev->devpath); + return 1; + } + ro = uevent_get_disk_ro(uev); + + if (ro >= 0) { + struct path * pp; + + condlog(2, "%s: update path write_protect to '%d' (uevent)", + uev->kernel, ro); + pp = find_path_by_dev(vecs->pathvec, uev->kernel); + if (!pp) { + condlog(0, "%s: spurious uevent, path not found", + uev->kernel); + return 1; + } + if (pp->mpp) + retval = reload_map(vecs, pp->mpp); + + condlog(2, "%s: map %s reloaded (retval %d)", + uev->kernel, pp->mpp->alias, retval); + + } + + sysfs_device_put(dev); + + return retval; +} + +static int map_discovery (struct vectors * vecs) { struct multipath * mpp; @@ -688,6 +725,10 @@ uev_trigger (struct uevent * uev, void * trigger_data) r = uev_remove_path(uev, vecs); goto out; } + if (!strncmp(uev->action, "change", 6)) { + r = uev_update_path(uev, vecs); + goto out; + } out: unlock(vecs->lock); @@ -731,6 +772,7 @@ uxlsnrloop (void * ap) set_handler_callback(SUSPEND+MAP, cli_suspend); set_handler_callback(RESUME+MAP, cli_resume); set_handler_callback(RESIZE+MAP, cli_resize); + set_handler_callback(RELOAD+MAP, cli_reload); set_handler_callback(REINSTATE+PATH, cli_reinstate); set_handler_callback(FAIL+PATH, cli_fail);
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor