[systemd-devel] [correct PATCH v2] dev-root.device is not active, results in an umount spree

Lennart Poettering lennart at poettering.net
Mon May 18 13:57:34 PDT 2015


On Mon, 18.05.15 16:08, Martin Pitt (martin.pitt at ubuntu.com) wrote:

> Change device_found_node() to also create a .device unit if a device is not
> known by udev; this is the case for "tentative" devices picked up by mountinfo
> (DEVICE_FOUND_MOUNT).  With that we can record the "found" attribute on the
> unit.

Ah, I see now. This makes sense!

>  static int device_setup_unit(Manager *m, struct udev_device *dev, const char *path, bool main) {
>          _cleanup_free_ char *e = NULL;
> -        const char *sysfs;
> +        const char *sysfs = NULL;
>          Unit *u = NULL;
>          bool delete;
>          int r;
>  
>          assert(m);
> -        assert(dev);
>          assert(path);
>  
> -        sysfs = udev_device_get_syspath(dev);
> -        if (!sysfs)
> -                return 0;
> -
>          r = unit_name_from_path(path, ".device", &e);
>          if (r < 0)
>                  return log_error_errno(r, "Failed to generate unit name from device path: %m");
>  
>          u = manager_get_unit(m, e);
>  
> +        if (dev) {
> +                sysfs = udev_device_get_syspath(dev);
> +                if (!sysfs)
> +                        return 0;
> +        }

Why move this down? In order to keep the patch small and easy to grok,
can this stay up where it was, but simply be enclosed in the "if (dev) {}" check?

>  
> -                if (stat(node, &st) < 0) {
> -                        if (errno == ENOENT)
> +                if (stat(node, &st) >= 0) {
> +                        if (!S_ISBLK(st.st_mode) && !S_ISCHR(st.st_mode))
>                                  return 0;
>  
> -                        return log_error_errno(errno, "Failed to stat device node file %s: %m", node);
> -                }
> -
> -                if (!S_ISBLK(st.st_mode) && !S_ISCHR(st.st_mode))
> -                        return 0;
> +                        dev = udev_device_new_from_devnum(m->udev, S_ISBLK(st.st_mode) ? 'b' : 'c', st.st_rdev);
> +                        if (!dev && errno != ENOENT)
> +                                return log_oom();

Hmm, why are all these errors supposed to be OOM?
udev_device_new_from_devnum sets errno correctly, hence we should just
print what it really is set to with log_error_errno(), unless of
course it is ENOENT.

> -                dev = udev_device_new_from_devnum(m->udev, S_ISBLK(st.st_mode) ? 'b' : 'c', st.st_rdev);
> -                if (!dev) {
> -                        if (errno == ENOENT)
> -                                return 0;
> -
> -                        return log_oom();
> +                } else {
> +                        if (errno != ENOENT)
> +                                return log_error_errno(errno, "Failed to stat device node file %s: %m", node);

The if "else {" and "if (errn..." lines could be merged into one 
"else if (errno != ...", no?

> From c18dbd432ecd16c57123b5fc04313d625e8a8e88 Mon Sep 17 00:00:00 2001
> From: Martin Pitt <martin.pitt at ubuntu.com>
> Date: Sun, 17 May 2015 15:17:58 +0200
> Subject: [PATCH 2/3] device: never transition from "tentative" to "dead"
> 
> Only set a device to state "dead" if it was previously plugged through udev. We
> must never transition from "tentative" to "dead", as there is no way to be sure
> that this is actually true.
> 
> This fixes systemd unmounting everything from a tentative device as soon as
> mountinfo changes.

Not following on this patch: what's the rationale here? your patch
basically means we would never ever clean up "tentative" devices, if
they once were referenced in mountinfo or /proc/swaps, but no longer
are.

Can you elaborate on what this patch is supposed to achieve? How could
it be problematic to deactivate device units that are neither
announced anywhere in /proc nor in udev?

Lennart

-- 
Lennart Poettering, Red Hat


More information about the systemd-devel mailing list