uev->envp[i] = NULL;
condlog(3, "uevent '%s' from '%s'", uev->action, uev->devpath);
+ uev->kernel = strrchr(uev->devpath, '/');
+ if (uev->kernel)
+ uev->kernel++;
/* print payload environment */
for (i = 0; uev->envp[i] != NULL; i++)
- condlog(3, "%s", uev->envp[i]);
+ condlog(5, "%s", uev->envp[i]);
/*
* Queue uevent and poke service pthread.
return 1;
}
+
+extern int
+uevent_get_major(struct uevent *uev)
+{
+ char *p, *q;
+ int i, major = -1;
+
+ for (i = 0; uev->envp[i] != NULL; i++) {
+ if (!strncmp(uev->envp[i], "MAJOR", 5) && strlen(uev->envp[i]) > 6) {
+ p = uev->envp[i] + 6;
+ major = strtoul(p, &q, 10);
+ if (p == q) {
+ condlog(2, "invalid major '%s'", p);
+ major = -1;
+ }
+ break;
+ }
+ }
+ return major;
+}
+
+extern int
+uevent_get_minor(struct uevent *uev)
+{
+ char *p, *q;
+ int i, minor = -1;
+
+ for (i = 0; uev->envp[i] != NULL; i++) {
+ if (!strncmp(uev->envp[i], "MINOR", 5) && strlen(uev->envp[i]) > 6) {
+ p = uev->envp[i] + 6;
+ minor = strtoul(p, &q, 10);
+ if (p == q) {
+ condlog(2, "invalid minor '%s'", p);
+ minor = -1;
+ }
+ break;
+ }
+ }
+ return minor;
+}
+
+extern char *
+uevent_get_dm_name(struct uevent *uev)
+{
+ char *p = NULL;
+ int i;
+
+ for (i = 0; uev->envp[i] != NULL; i++) {
+ if (!strncmp(uev->envp[i], "DM_NAME", 6) &&
+ strlen(uev->envp[i]) > 7) {
+ p = MALLOC(strlen(uev->envp[i] + 8) + 1);
+ strcpy(p, uev->envp[i] + 8);
+ break;
+ }
+ }
+ return p;
+}
{
struct vectors * vecs = (struct vectors *)data;
char * param = get_keyparam(v, MAP);
- int minor;
+ int major, minor;
char dev_path[PATH_SIZE];
- struct sysfs_device *sysdev;
+ char *alias;
+ int rc;
condlog(2, "%s: add map (operator)", param);
condlog(2, "%s: not a device mapper table", param);
return 0;
}
- sprintf(dev_path,"/block/dm-%d", minor);
- sysdev = sysfs_device_get(dev_path);
- if (!sysdev) {
- condlog(2, "%s: not found in sysfs", param);
+ major = dm_get_major(param);
+ if (major < 0) {
+ condlog(2, "%s: not a device mapper table", param);
+ return 0;
+ }
+ sprintf(dev_path,"dm-%d", minor);
+ alias = dm_mapname(major, minor);
+ if (!alias) {
+ condlog(2, "%s: mapname not found for %d:%d",
+ param, major, minor);
return 0;
}
- return ev_add_map(sysdev, vecs);
+ rc = ev_add_map(dev_path, alias, vecs);
+ FREE(alias);
+ return rc;
}
int
{
struct vectors * vecs = (struct vectors *)data;
char * param = get_keyparam(v, MAP);
+ int major, minor;
+ char dev_path[PATH_SIZE];
+ char *alias;
+ int rc;
condlog(2, "%s: remove map (operator)", param);
-
- return ev_remove_map(param, vecs);
+ minor = dm_get_minor(param);
+ if (minor < 0) {
+ condlog(2, "%s: not a device mapper table", param);
+ return 0;
+ }
+ major = dm_get_major(param);
+ if (major < 0) {
+ condlog(2, "%s: not a device mapper table", param);
+ return 0;
+ }
+ sprintf(dev_path,"dm-%d", minor);
+ alias = dm_mapname(major, minor);
+ if (!alias) {
+ condlog(2, "%s: mapname not found for %d:%d",
+ param, major, minor);
+ return 0;
+ }
+ rc = ev_remove_map(param, alias, minor, vecs);
+ FREE(alias);
+ return rc;
}
int resize_map(struct multipath *mpp, unsigned long long size,
#include <configure.h>
#include <prio.h>
#include <pgpolicies.h>
+#include <uevent.h>
#include "main.h"
#include "pidfile.h"
}
static int
-uev_add_map (struct sysfs_device * dev, struct vectors * vecs)
+uev_add_map (struct uevent * uev, struct vectors * vecs)
{
- condlog(2, "%s: add map (uevent)", dev->kernel);
- return ev_add_map(dev, vecs);
+ char *alias;
+ int major = -1, minor = -1, rc;
+
+ condlog(2, "%s: add map (uevent)", uev->kernel);
+ alias = uevent_get_dm_name(uev);
+ if (!alias) {
+ condlog(3, "%s: No DM_NAME in uevent", uev->kernel);
+ major = uevent_get_major(uev);
+ minor = uevent_get_minor(uev);
+ alias = dm_mapname(major, minor);
+ if (!alias) {
+ condlog(2, "%s: mapname not found for %d:%d",
+ uev->kernel, major, minor);
+ return 1;
+ }
+ }
+ rc = ev_add_map(uev->kernel, alias, vecs);
+ FREE(alias);
+ return rc;
}
int
-ev_add_map (struct sysfs_device * dev, struct vectors * vecs)
+ev_add_map (char * dev, char * alias, struct vectors * vecs)
{
- char * alias;
- int major, minor;
char * refwwid;
struct multipath * mpp;
int map_present;
int r = 1;
- alias = dm_mapname(major, minor);
-
- if (!alias)
- return 1;
-
map_present = dm_map_present(alias);
if (map_present && dm_type(alias, TGT_MPATH) <= 0) {
condlog(4, "%s: not a multipath map", alias);
- FREE(alias);
return 0;
}
* if we create a multipath mapped device as a result
* of uev_add_path
*/
- condlog(0, "%s: devmap already registered",
- dev->kernel);
- FREE(alias);
+ condlog(0, "%s: devmap already registered", dev);
return 0;
}
/*
* now we can register the map
*/
- if (map_present && (mpp = add_map_without_path(vecs, minor, alias))) {
+ if (map_present && (mpp = add_map_without_path(vecs, alias))) {
sync_map_state(mpp);
- condlog(2, "%s: devmap %s added", alias, dev->kernel);
+ condlog(2, "%s: devmap %s registered", alias, dev);
return 0;
}
- refwwid = get_refwwid(dev->kernel, DEV_DEVMAP, vecs->pathvec);
+ refwwid = get_refwwid(dev, DEV_DEVMAP, vecs->pathvec);
if (refwwid) {
r = coalesce_paths(vecs, NULL, refwwid, 0);
}
if (!r)
- condlog(2, "%s: devmap %s added", alias, dev->kernel);
+ condlog(2, "%s: devmap %s added", alias, dev);
else
- condlog(0, "%s: uev_add_map %s failed", alias, dev->kernel);
+ condlog(0, "%s: uev_add_map %s failed", alias, dev);
FREE(refwwid);
- FREE(alias);
return r;
}
static int
-uev_remove_map (struct sysfs_device * dev, struct vectors * vecs)
+uev_remove_map (struct uevent * uev, struct vectors * vecs)
{
- condlog(2, "%s: remove map (uevent)", dev->kernel);
- return ev_remove_map(dev->kernel, vecs);
+ char *alias;
+ int minor, rc;
+
+ condlog(2, "%s: remove map (uevent)", uev->kernel);
+ alias = uevent_get_dm_name(uev);
+ if (!alias) {
+ condlog(3, "%s: No DM_NAME in uevent, ignoring", uev->kernel);
+ return 0;
+ }
+ minor = uevent_get_minor(uev);
+ rc = ev_remove_map(uev->kernel, alias, minor, vecs);
+ FREE(alias);
+ return rc;
}
int
-ev_remove_map (char * devname, struct vectors * vecs)
+ev_remove_map (char * devname, char * alias, int minor, struct vectors * vecs)
{
struct multipath * mpp;
- mpp = find_mp_by_str(vecs->mpvec, devname);
+ mpp = find_mp_by_minor(vecs->mpvec, minor);
if (!mpp) {
condlog(2, "%s: devmap not registered, can't remove",
devname);
return 0;
}
- flush_map(mpp, vecs);
-
- return 0;
+ if (strcmp(mpp->alias, alias)) {
+ condlog(2, "%s: minor number mismatch (map %d, event %d)",
+ mpp->alias, mpp->dmi->minor, minor);
+ return 0;
+ }
+ return flush_map(mpp, vecs);
}
static int
-uev_umount_map (struct sysfs_device * dev, struct vectors * vecs)
+uev_umount_map (struct uevent * uev, struct vectors * vecs)
{
struct multipath * mpp;
- condlog(2, "%s: umount map (uevent)", dev->kernel);
+ condlog(2, "%s: umount map (uevent)", uev->kernel);
- mpp = find_mp_by_str(vecs->mpvec, dev->kernel);
+ mpp = find_mp_by_str(vecs->mpvec, uev->kernel);
if (!mpp)
return 0;
return 0;
}
+
static int
-uev_add_path (struct sysfs_device * dev, struct vectors * vecs)
+uev_add_path (struct uevent *uev, struct vectors * vecs)
{
+ struct sysfs_device * dev;
+
+ dev = sysfs_device_get(uev->devpath);
+ if (!dev) {
+ condlog(2, "%s: not found in sysfs", uev->devpath);
+ return 1;
+ }
condlog(2, "%s: add path (uevent)", dev->kernel);
return (ev_add_path(dev->kernel, vecs) != 1)? 0 : 1;
}
-
/*
* returns:
* 0: added
}
static int
-uev_remove_path (struct sysfs_device * dev, struct vectors * vecs)
+uev_remove_path (struct uevent *uev, struct vectors * vecs)
{
+ struct sysfs_device * dev;
int retval;
- condlog(2, "%s: remove path (uevent)", dev->kernel);
- retval = ev_remove_path(dev->kernel, vecs);
+ dev = sysfs_device_get(uev->devpath);
+ if (!dev) {
+ condlog(2, "%s: not found in sysfs", uev->devpath);
+ return 1;
+ }
+ condlog(2, "%s: remove path (uevent)", uev->kernel);
+ retval = ev_remove_path(uev->kernel, vecs);
+
if (!retval)
sysfs_device_put(dev);
uev_trigger (struct uevent * uev, void * trigger_data)
{
int r = 0;
- struct sysfs_device *sysdev;
struct vectors * vecs;
vecs = (struct vectors *)trigger_data;
if (uev_discard(uev->devpath))
return 0;
- sysdev = sysfs_device_get(uev->devpath);
- if(!sysdev)
- return 0;
-
lock(vecs->lock);
/*
* Add events are ignored here as the tables
* are not fully initialised then.
*/
- if (!strncmp(sysdev->kernel, "dm-", 3)) {
+ if (!strncmp(uev->kernel, "dm-", 3)) {
if (!strncmp(uev->action, "change", 6)) {
- r = uev_add_map(sysdev, vecs);
+ r = uev_add_map(uev, vecs);
goto out;
}
if (!strncmp(uev->action, "remove", 6)) {
- r = uev_remove_map(sysdev, vecs);
+ r = uev_remove_map(uev, vecs);
goto out;
}
if (!strncmp(uev->action, "umount", 6)) {
- r = uev_umount_map(sysdev, vecs);
+ r = uev_umount_map(uev, vecs);
goto out;
}
goto out;
* path add/remove event
*/
if (filter_devnode(conf->blist_devnode, conf->elist_devnode,
- sysdev->kernel) > 0)
+ uev->kernel) > 0)
goto out;
if (!strncmp(uev->action, "add", 3)) {
- r = uev_add_path(sysdev, vecs);
+ r = uev_add_path(uev, vecs);
goto out;
}
if (!strncmp(uev->action, "remove", 6)) {
- r = uev_remove_path(sysdev, vecs);
+ r = uev_remove_path(uev, vecs);
goto out;
}
FREE(vecs);
vecs = NULL;
+ cleanup_checkers();
+ cleanup_prio();
+
condlog(2, "--------shut down-------");
if (logsink)