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;
+}
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);
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;
+}
+
extern char *
uevent_get_dm_name(struct uevent *uev)
{
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);
char *uevent_get_dm_name(struct uevent *uev);
#endif /* _UEVENT_H */
r += add_key(keys, "fail", FAIL, 0);
r += add_key(keys, "resize", RESIZE, 0);
r += add_key(keys, "reset", RESET, 0);
+ r += add_key(keys, "reload", RELOAD, 0);
r += add_key(keys, "disablequeueing", DISABLEQ, 0);
r += add_key(keys, "restorequeueing", RESTOREQ, 0);
r += add_key(keys, "paths", PATHS, 0);
add_handler(RESUME+MAP, NULL);
add_handler(RESIZE+MAP, NULL);
add_handler(RESET+MAP, NULL);
+ add_handler(RELOAD+MAP, NULL);
add_handler(DISABLEQ+MAP, NULL);
add_handler(RESTOREQ+MAP, NULL);
add_handler(DISABLEQ+MAPS, NULL);
__FAIL,
__RESIZE,
__RESET,
+ __RELOAD,
__DISABLEQ,
__RESTOREQ,
__PATHS,
#define FAIL (1 << __FAIL)
#define RESIZE (1 << __RESIZE)
#define RESET (1 << __RESET)
+#define RELOAD (1 << __RELOAD)
#define DISABLEQ (1 << __DISABLEQ)
#define RESTOREQ (1 << __RESTOREQ)
#define PATHS (1 << __PATHS)
return rc;
}
+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)
{
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_disable_queueing(void * v, char ** reply, int * len, void * data);
int cli_disable_all_queueing(void * v, char ** reply, int * len, void * data);
int cli_restore_queueing(void * v, char ** reply, int * len, void * data);
}
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;
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);
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(RESET+MAP, cli_reassign);
set_handler_callback(REINSTATE+PATH, cli_reinstate);
set_handler_callback(FAIL+PATH, cli_fail);