diff options
author | Rafał Miłecki <rafal@milecki.pl> | 2018-12-12 15:24:35 +0100 |
---|---|---|
committer | Rafał Miłecki <rafal@milecki.pl> | 2018-12-28 23:10:32 +0100 |
commit | af93f4b8dc32cf1320dfe8f4b93bb3a12606fc33 (patch) | |
tree | 71e08b2d2bbd9072763902bf68ad05fc1c90139e | |
parent | 3bb3352a5f6c1cffd8a487b92eb762c857df75ed (diff) | |
download | fstools-af93f4b8dc32cf1320dfe8f4b93bb3a12606fc33.tar.gz |
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>
-rw-r--r-- | block.c | 31 | ||||
-rw-r--r-- | blockd.c | 4 |
2 files changed, 26 insertions, 9 deletions
@@ -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; @@ -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 |