multipath: libudev cleanup and bugfixes
authorBenjamin Marzinski <bmarzins@redhat.com>
Tue, 5 Jun 2012 23:04:36 +0000 (18:04 -0500)
committerChristophe Varoqui <christophe.varoqui@opensvc.com>
Wed, 6 Jun 2012 18:09:01 +0000 (20:09 +0200)
get_refwwid wasn't working anymore, since it wasn't setting the path's udevice.
Also, cli_add_path was dereferencing a NULL pointer (pp). Finally, there were
a number of places where udev devices weren't getting dereferenced when they
should have been, causing memory leaks.  This patch cleans these up.

Signed-off-by: Benjamin Marzinski <bmarzins@redhat.com>
libmultipath/configure.c
libmultipath/discovery.c
libmultipath/uevent.c
multipathd/cli_handlers.c
multipathd/main.c

index 001c1f0bd1da46117e50b3ca579286434b8ca950..46910f38a9763a9bef88af6705ea9bc738f9228a 100644 (file)
@@ -13,6 +13,7 @@
 #include <sys/file.h>
 #include <errno.h>
 #include <libdevmapper.h>
+#include <libudev.h>
 
 #include "checkers.h"
 #include "vector.h"
@@ -680,18 +681,17 @@ get_refwwid (char * dev, enum devtypes dev_type, vector pathvec)
 
                pp = find_path_by_dev(pathvec, buff);
                if (!pp) {
-                       pp = alloc_path();
+                       struct udev_device *udevice = udev_device_new_from_subsystem_sysname(conf->udev, "block", buff);
 
-                       if (!pp)
+                       if (!udevice) {
+                               condlog(2, "%s: can't get udev device", buff);
                                return NULL;
-
-                       strncpy(pp->dev, buff, FILE_NAME_SIZE);
-
-                       if (pathinfo(pp, conf->hwtable, DI_SYSFS | DI_WWID))
-                               return NULL;
-
-                       if (store_path(pathvec, pp)) {
-                               free_path(pp);
+                       }
+                       pp = store_pathinfo(pathvec, conf->hwtable, udevice,
+                                           DI_SYSFS | DI_WWID);
+                       udev_device_unref(udevice);
+                       if (!pp) {
+                               condlog(0, "%s can't store path info", buff);
                                return NULL;
                        }
                }
@@ -703,21 +703,17 @@ get_refwwid (char * dev, enum devtypes dev_type, vector pathvec)
                strchop(dev);
                pp = find_path_by_devt(pathvec, dev);
                if (!pp) {
-                       if (devt2devname(buff, FILE_NAME_SIZE, dev))
-                               return NULL;
+                       struct udev_device *udevice = udev_device_new_from_devnum(conf->udev, 'b', parse_devt(dev));
 
-                       pp = alloc_path();
-
-                       if (!pp)
-                               return NULL;
-
-                       strncpy(pp->dev, buff, FILE_NAME_SIZE);
-
-                       if (pathinfo(pp, conf->hwtable, DI_SYSFS | DI_WWID))
+                       if (!udevice) {
+                               condlog(2, "%s: can't get udev device", dev);
                                return NULL;
-
-                       if (store_path(pathvec, pp)) {
-                               free_path(pp);
+                       }
+                       pp = store_pathinfo(pathvec, conf->hwtable, udevice,
+                                           DI_SYSFS | DI_WWID);
+                       udev_device_unref(udevice);
+                       if (!pp) {
+                               condlog(0, "%s can't store path info", buff);
                                return NULL;
                        }
                }
index c4087215046c32bdbb022c878bf3baea691a4b85..25c7cdaede9d6a90843fea2d1cf910667188edbd 100644 (file)
@@ -216,11 +216,11 @@ sysfs_get_tgt_nodename (struct path *pp, char * node)
                const char *value;
 
                value = udev_device_get_sysattr_value(tgtdev, "node_name");
+               udev_device_unref(tgtdev);
                if (value) {
                        strncpy(node, value, NODE_NAME_SIZE);
                        return 0;
                }
-               udev_device_unref(tgtdev);
        }
 
        /* Check for iSCSI */
@@ -235,15 +235,15 @@ sysfs_get_tgt_nodename (struct path *pp, char * node)
        }
        if (parent) {
                tgtdev = udev_device_new_from_subsystem_sysname(conf->udev, "iscsi_session", targetid);
-               if (node) {
+               if (tgtdev) {
                        const char *value;
 
                        value = udev_device_get_sysattr_value(tgtdev, "targetname");
+                       udev_device_unref(tgtdev);
                        if (value) {
                                strncpy(node, value, NODE_NAME_SIZE);
                                return 0;
                        }
-                       udev_device_unref(tgtdev);
                }
        }
        return 1;
@@ -289,7 +289,7 @@ sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp)
                                                 value, 11) < 0)
                                condlog(0, "%s failed to set dev_loss_tmo",
                                        mpp->alias);
-                       return;
+                       goto out;
                }
        }
        if (mpp->fast_io_fail){
@@ -305,6 +305,8 @@ sysfs_set_rport_tmo(struct multipath *mpp, struct path *pp)
                                mpp->alias);
                }
        }
+out:
+       udev_device_unref(rport_dev);
 }
 
 int
index 52b8aaf0f7b453ce592877a48d719ffd449bee4f..0b7eb7a48539499506284964476db1ff35564ff1 100644 (file)
@@ -443,6 +443,7 @@ int uevent_listen(void)
 
                uev = alloc_uevent();
                if (!uev) {
+                       udev_device_unref(dev);
                        condlog(1, "lost uevent, oom");
                        continue;
                }
index 39b89bfb9709d90f10e7532e1b0d3b50ba8b2f33..544cbfbafeed02a09662052363d4723bca605206 100644 (file)
@@ -430,15 +430,17 @@ cli_add_path (void * v, char ** reply, int * len, void * data)
        } else {
                struct udev_device *udevice;
 
-               udevice = udev_device_new_from_devnum(conf->udev, 'b',
-                                                     parse_devt(pp->dev_t));
+               udevice = udev_device_new_from_subsystem_sysname(conf->udev,
+                                                                "block",
+                                                                param);
                pp = store_pathinfo(vecs->pathvec, conf->hwtable,
                                    udevice, DI_ALL);
+               udev_device_unref(udevice);
                if (!pp) {
                        condlog(0, "%s: failed to store path info", param);
-                       udev_device_unref(udevice);
                        return 1;
                }
+               pp->checkint = conf->checkint;
        }
        r = ev_add_path(pp, vecs);
        if (r == 2)
index 5dea9959a4b2929252427e588094cdc981bf8c0e..61d3f9ce998e02e1d2898e60a6a1671876337aa9 100644 (file)
@@ -391,17 +391,13 @@ uev_add_path (struct uevent *uev, struct vectors * vecs)
                if (pp->mpp)
                        return 0;
        } else {
-               struct udev_device *udevice;
-
                /*
                 * get path vital state
                 */
-               udevice = udev_device_ref(uev->udev);
                if (!(pp = store_pathinfo(vecs->pathvec, conf->hwtable,
-                                         udevice, DI_ALL))) {
+                                         uev->udev, DI_ALL))) {
                        condlog(0, "%s: failed to store path info",
                                uev->kernel);
-                       udev_device_unref(udevice);
                        return 1;
                }
                pp->checkint = conf->checkint;