From b201464a18c990ea6df0f2878e532618d4936c53 Mon Sep 17 00:00:00 2001 From: Jeremy Kerr Date: Tue, 1 Oct 2013 10:42:04 +0800 Subject: [PATCH] discover: Allow for already-mounted devices When we start the discover server, we may find that devices are already mounted. In this case, mount_device will fail, and we'll abort the parse. This change uses /proc/self/mounts to check if new devices are already mounted, and uses the existing mount point. Signed-off-by: Jeremy Kerr --- discover/device-handler.c | 89 +++++++++++++++++++++++++++++++++++---- discover/device-handler.h | 4 +- test/parser/utils.c | 1 + 3 files changed, 85 insertions(+), 9 deletions(-) diff --git a/discover/device-handler.c b/discover/device-handler.c index 251c517..cd9c413 100644 --- a/discover/device-handler.c +++ b/discover/device-handler.c @@ -1,9 +1,11 @@ #include #include +#include #include #include #include +#include #include #include @@ -677,6 +679,58 @@ void device_handler_cancel_default(struct device_handler *handler) } #ifndef PETITBOOT_TEST +static bool check_existing_mount(struct discover_device *dev) +{ + struct stat devstat, mntstat; + struct mntent *mnt; + FILE *fp; + int rc; + + rc = stat(dev->device_path, &devstat); + if (rc) { + pb_debug("%s: stat failed: %s\n", __func__, strerror(errno)); + return false; + } + + if (!S_ISBLK(devstat.st_mode)) { + pb_debug("%s: %s isn't a block device?\n", __func__, + dev->device_path); + return false; + } + + fp = fopen("/proc/self/mounts", "r"); + + for (;;) { + mnt = getmntent(fp); + if (!mnt) + break; + + if (!mnt->mnt_fsname || mnt->mnt_fsname[0] != '/') + continue; + + rc = stat(mnt->mnt_fsname, &mntstat); + if (rc) + continue; + + if (!S_ISBLK(mntstat.st_mode)) + continue; + + if (mntstat.st_rdev == devstat.st_rdev) { + pb_debug("%s: %s is already mounted at %s\n" + __func__, dev->device_path, + mnt->mnt_dir); + dev->mount_path = talloc_strdup(dev, mnt->mnt_dir); + dev->mounted = true; + dev->unmount = false; + break; + } + } + + fclose(fp); + + return mnt != NULL; +} + static int mount_device(struct discover_device *dev) { int rc; @@ -684,29 +738,44 @@ static int mount_device(struct discover_device *dev) if (!dev->device_path) return -1; - if (!dev->mount_path) - dev->mount_path = join_paths(dev, mount_base(), - dev->device_path); + if (dev->mounted) + return 0; + + if (check_existing_mount(dev)) + return 0; + + dev->mount_path = join_paths(dev, mount_base(), + dev->device_path); - if (pb_mkdir_recursive(dev->mount_path)) + if (pb_mkdir_recursive(dev->mount_path)) { pb_log("couldn't create mount directory %s: %s\n", dev->mount_path, strerror(errno)); + goto err_free; + } rc = process_run_simple(dev, pb_system_apps.mount, dev->device_path, dev->mount_path, "-o", "ro", NULL); - - if (!rc) + if (!rc) { + dev->mounted = true; + dev->unmount = true; return 0; + } /* Retry mount without ro option. */ rc = process_run_simple(dev, pb_system_apps.mount, dev->device_path, dev->mount_path, NULL); - if (!rc) + if (!rc) { + dev->mounted = true; + dev->unmount = true; return 0; + } pb_rmdir_recursive(mount_base(), dev->mount_path); +err_free: + talloc_free(dev->mount_path); + dev->mount_path = NULL; return -1; } @@ -714,7 +783,7 @@ static int umount_device(struct discover_device *dev) { int status; - if (!dev->mount_path) + if (!dev->mounted || !dev->unmount) return 0; status = process_run_simple(dev, pb_system_apps.umount, @@ -723,6 +792,10 @@ static int umount_device(struct discover_device *dev) if (!WIFEXITED(status) || WEXITSTATUS(status) != 0) return -1; + dev->mounted = false; + talloc_free(dev->mount_path); + dev->mount_path = NULL; + pb_rmdir_recursive(mount_base(), dev->mount_path); return 0; diff --git a/discover/device-handler.h b/discover/device-handler.h index 854be48..9d477db 100644 --- a/discover/device-handler.h +++ b/discover/device-handler.h @@ -33,8 +33,10 @@ struct discover_device { const char *uuid; const char *label; - const char *mount_path; + char *mount_path; const char *device_path; + bool mounted; + bool unmount; bool notified; diff --git a/test/parser/utils.c b/test/parser/utils.c index f693982..7af4df7 100644 --- a/test/parser/utils.c +++ b/test/parser/utils.c @@ -61,6 +61,7 @@ struct discover_device *test_create_device(struct parser_test *test, dev->device->id = talloc_strdup(dev, name); dev->device_path = talloc_asprintf(dev, "/dev/%s", name); dev->mount_path = talloc_asprintf(dev, "/test/mount/%s", name); + dev->mounted = true; return dev; } -- 2.39.2