On Sat, Apr 14, 2018 at 12:00:13AM +0200, Martin Wilck wrote:
> For "find_multipaths smart", check if a path is already in use
> before setting DM_MULTIPATH_DEVICE_PATH to 1 or 2 (and thus,
> SYSTEMD_READY=0). If we don't do this, a device which has already been
> mounted (e.g. during initrd processing) may be unmounted by systemd, causing
> havoc to the boot process.
> 

Reviewed-by: Benjamin Marzinsk <bmarz...@redhat.com>
> Signed-off-by: Martin Wilck <mwi...@suse.com>
> ---
>  multipath/main.c | 39 ++++++++++++++++++++++++++++++++++++++-
>  1 file changed, 38 insertions(+), 1 deletion(-)
> 
> diff --git a/multipath/main.c b/multipath/main.c
> index 573d94f9..c69e996e 100644
> --- a/multipath/main.c
> +++ b/multipath/main.c
> @@ -675,6 +675,9 @@ configure (struct config *conf, enum mpath_cmds cmd,
>  
>  
>       if (cmd == CMD_VALID_PATH) {
> +             struct path *pp;
> +             int fd;
> +
>               /* This only happens if find_multipaths and
>                * ignore_wwids is set, and the path is not in WWIDs
>                * file, not currently multipathed, and has
> @@ -682,11 +685,45 @@ configure (struct config *conf, enum mpath_cmds cmd,
>                * If there is currently a multipath device matching
>                * the refwwid, or there is more than one path matching
>                * the refwwid, then the path is valid */
> -             if (VECTOR_SIZE(curmp) != 0 || VECTOR_SIZE(pathvec) > 1)
> +             if (VECTOR_SIZE(curmp) != 0) {
> +                     r = 0;
> +                     goto print_valid;
> +             } else if (VECTOR_SIZE(pathvec) > 1)
>                       r = 0;
>               else
>                       /* Use r=2 as an indication for "maybe" */
>                       r = 2;
> +
> +             /*
> +              * If opening the path with O_EXCL fails, the path
> +              * is in use (e.g. mounted during initramfs processing).
> +              * We know that it's not used by dm-multipath.
> +              * We may not set SYSTEMD_READY=0 on such devices, it
> +              * might cause systemd to umount the device.
> +              * Use O_RDONLY, because udevd would trigger another
> +              * uevent for close-after-write.
> +              *
> +              * The O_EXCL check is potentially dangerous, because it may
> +              * race with other tasks trying to access the device. Therefore
> +              * this code is only executed if the path hasn't been released
> +              * to systemd earlier (see above).
> +              *
> +              * get_refwwid() above stores the path we examine in slot 0.
> +              */
> +             pp = VECTOR_SLOT(pathvec, 0);
> +             fd = open(udev_device_get_devnode(pp->udev),
> +                       O_RDONLY|O_EXCL);
> +             if (fd >= 0)
> +                     close(fd);
> +             else {
> +                     condlog(3, "%s: path %s is in use: %s",
> +                             __func__, pp->dev,
> +                             strerror(errno));
> +                     /*
> +                      * Check if we raced with multipathd
> +                      */
> +                     r = !sysfs_is_multipathed(VECTOR_SLOT(pathvec, 0));
> +             }
>               goto print_valid;
>       }
>  
> -- 
> 2.16.1

--
dm-devel mailing list
dm-devel@redhat.com
https://www.redhat.com/mailman/listinfo/dm-devel

Reply via email to