[PATCH] Remove devices from sysfs cache

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



Hi Christophe,

whenever a device is finally removed from a multipath map we should also remove it from the sysfs cache. Otherwise we'll hogging up memory with multipathd. And we might rely on wrong information as the device in the sysfs cache might in fact be a different device if the system decided to assign the same number to a different device or if some values have changed.

Please apply.

Cheers,

Hannes
-- 
Dr. Hannes Reinecke		      zSeries & Storage
hare@xxxxxxx			      +49 911 74053 688
SUSE LINUX Products GmbH, Maxfeldstr. 5, 90409 Nürnberg
GF: Markus Rex, HRB 16746 (AG Nürnberg)
multipathd: remove sysfs devices from cache

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.

Signed-off-by: Hannes Reinecke <hare@xxxxxxx>

diff --git a/libmultipath/sysfs.c b/libmultipath/sysfs.c
index d8c65b2..b9621ac 100644
--- a/libmultipath/sysfs.c
+++ b/libmultipath/sysfs.c
@@ -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];
diff --git a/libmultipath/sysfs.h b/libmultipath/sysfs.h
index 6d83489..e7fa3e7 100644
--- a/libmultipath/sysfs.h
+++ b/libmultipath/sysfs.h
@@ -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);
 
diff --git a/multipathd/main.c b/multipathd/main.c
index b1620b5..da5fd8f 100644
--- a/multipathd/main.c
+++ b/multipathd/main.c
@@ -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
--
dm-devel mailing list
dm-devel@xxxxxxxxxx
https://www.redhat.com/mailman/listinfo/dm-devel

[Index of Archives]     [DM Crypt]     [Fedora Desktop]     [ATA RAID]     [Fedora Marketing]     [Fedora Packaging]     [Fedora SELinux]     [Yosemite Discussion]     [KDE Users]     [Fedora Docs]

  Powered by Linux