Browse Source

block(d): improve hotplug.d "mount" events for the autofs

So far - when using autofs - "add" and "remove" action events were
triggered on every (un)mount. It wasn't very helpful when using autofs
due to its nature.

The point of blockd & autofs is to have block devices mounted on an
access request. Its users should not care / know if it's currently
mounted or not. Mounting should be handled transparently.

To make that work it requires informing listeners whenever device:
1) Becomes *ready* for mounting (by triggering "add" action)
2) Becomes *unavailable* (by triggering "remove" action)

The current mounting state is something that autofs & blockd should
handle internally and should not notify listeners about.

This is implemented by:
1) block generating events for non-autofs cases only (when (un)mounting)
2) blockd informing block when autofs resource becomes (un)available

Signed-off-by: Rafał Miłecki <rafal@milecki.pl>
Rafał Miłecki 5 years ago
parent
commit
af93f4b8dc
2 changed files with 26 additions and 9 deletions
  1. 22 9
      block.c
  2. 4 0
      blockd.c

+ 22 - 9
block.c

@@ -1113,12 +1113,13 @@ static int mount_device(struct probe_info *pr, int type)
 
 	handle_swapfiles(true);
 
-	hotplug_call_mount("add", device);
+	if (type != TYPE_AUTOFS)
+		hotplug_call_mount("add", device);
 
 	return 0;
 }
 
-static int umount_device(char *path)
+static int umount_device(char *path, int type)
 {
 	char *mp;
 	int err;
@@ -1127,7 +1128,8 @@ static int umount_device(char *path)
 	if (!mp)
 		return -1;
 
-	hotplug_call_mount("remove", basename(path));
+	if (type != TYPE_AUTOFS)
+		hotplug_call_mount("remove", basename(path));
 
 	err = umount2(mp, MNT_DETACH);
 	if (err) {
@@ -1154,7 +1156,7 @@ static int mount_action(char *action, char *device, int type)
 		if (type == TYPE_HOTPLUG)
 			blockd_notify(device, NULL, NULL);
 
-		umount_device(path);
+		umount_device(path, type);
 
 		return 0;
 	} else if (strcmp(action, "add")) {
@@ -1177,6 +1179,8 @@ static int main_hotplug(int argc, char **argv)
 
 static int main_autofs(int argc, char **argv)
 {
+	int err = 0;
+
 	if (argc < 3)
 		return -1;
 
@@ -1199,13 +1203,22 @@ static int main_autofs(int argc, char **argv)
 
 			blockd_notify(pr->dev, m, pr);
 		}
-		return 0;
+	} else if (!strcmp(argv[2], "available")) {
+		err = hotplug_call_mount("add", argv[3]);
+	} else if (!strcmp(argv[2], "unavailable")) {
+		err = hotplug_call_mount("remove", argv[3]);
+	} else {
+		if (argc < 4)
+			return -EINVAL;
+
+		err = mount_action(argv[2], argv[3], TYPE_AUTOFS);
 	}
 
-	if (argc < 4)
-		return -EINVAL;
+	if (err) {
+		ULOG_ERR("autofs: \"%s\" action has failed: %d\n", argv[2], err);
+	}
 
-	return mount_action(argv[2], argv[3], TYPE_AUTOFS);
+	return err;
 }
 
 static int find_block_mtd(char *name, char *part, int plen)
@@ -1612,7 +1625,7 @@ static int main_umount(int argc, char **argv)
 		if (m && m->extroot)
 			continue;
 
-		umount_device(pr->dev);
+		umount_device(pr->dev, TYPE_DEV);
 	}
 
 	return 0;

+ 4 - 0
blockd.c

@@ -116,6 +116,8 @@ device_free(struct device *device)
 	if (!device->autofs)
 		return;
 
+	block("autofs", "unavailable", device->name);
+
 	if (device->target)
 		unlink(device->target);
 
@@ -137,6 +139,8 @@ device_add(struct device *device)
 	snprintf(path, sizeof(path), "/tmp/run/blockd/%s", device->name);
 	if (symlink(path, device->target))
 		ULOG_ERR("failed to symlink %s->%s\n", device->target, path);
+	else
+		block("autofs", "available", device->name);
 }
 
 static int