[multipathd] remove sysfs devices from cache
authorHannes Reinecke <hare@suse.de>
Wed, 25 Jul 2007 19:10:40 +0000 (21:10 +0200)
committerChristophe Varoqui <christophe.varoqui@free.fr>
Wed, 25 Jul 2007 19:10:40 +0000 (21:10 +0200)
Whenever a device is really removed from any multipath map we should
also remove it from the cache. Otherwise we'll induce a memory leak.

libmultipath/sysfs.c
libmultipath/sysfs.h
multipathd/main.c

index d8c65b2..b9621ac 100644 (file)
@@ -342,6 +342,25 @@ struct sysfs_device *sysfs_device_get_parent_with_subsystem(struct sysfs_device
        return NULL;
 }
 
+void sysfs_device_put(struct sysfs_device *dev)
+{
+       struct sysfs_dev *sysdev_loop;
+
+       list_for_each_entry(sysdev_loop, &sysfs_dev_list, node) {
+               if (&sysdev_loop->dev == dev) {
+                       dbg("removed dev '%s' from cache",
+                           sysdev_loop->dev.devpath);
+                       list_del(&sysdev_loop->node);
+                       free(sysdev_loop);
+                       return;
+               }
+       }
+       dbg("dev '%s' not found in cache",
+           sysdev_loop->dev.devpath);
+
+       return;
+}
+
 char *sysfs_attr_get_value(const char *devpath, const char *attr_name)
 {
        char path_full[PATH_SIZE];
index 6d83489..e7fa3e7 100644 (file)
@@ -18,6 +18,7 @@ void sysfs_device_set_values(struct sysfs_device *dev, const char *devpath,
 struct sysfs_device *sysfs_device_get(const char *devpath);
 struct sysfs_device *sysfs_device_get_parent(struct sysfs_device *dev);
 struct sysfs_device *sysfs_device_get_parent_with_subsystem(struct sysfs_device *dev, const char *subsystem);
+void sysfs_device_put(struct sysfs_device *dev);
 char *sysfs_attr_get_value(const char *devpath, const char *attr_name);
 int sysfs_resolve_link(char *path, size_t size);
 
index b1620b5..da5fd8f 100644 (file)
@@ -442,8 +442,14 @@ out:
 static int
 uev_remove_path (struct sysfs_device * dev, struct vectors * vecs)
 {
+       int retval;
+
        condlog(2, "%s: remove path (uevent)", dev->kernel);
-       return ev_remove_path(dev->kernel, vecs);
+       retval = ev_remove_path(dev->kernel, vecs);
+       if (!retval)
+               sysfs_device_put(dev);
+
+       return retval;
 }
 
 int