summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafał Miłecki <rafal@milecki.pl>2018-12-12 15:24:35 +0100
committerRafał Miłecki <rafal@milecki.pl>2018-12-28 23:10:32 +0100
commitaf93f4b8dc32cf1320dfe8f4b93bb3a12606fc33 (patch)
tree71e08b2d2bbd9072763902bf68ad05fc1c90139e
parent3bb3352a5f6c1cffd8a487b92eb762c857df75ed (diff)
downloadfstools-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.c31
-rw-r--r--blockd.c4
2 files changed, 26 insertions, 9 deletions
diff --git a/block.c b/block.c
index f7fdc27..cfc8727 100644
--- a/block.c
+++ b/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;
diff --git a/blockd.c b/blockd.c
index a00a5b3..88fe168 100644
--- a/blockd.c
+++ b/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