[systemd-devel] [PATCH v3] device: Fix overzealous unmounting of tentative device mounts

Umut Tezduyar Lindskog umut at tezduyar.com
Tue May 19 06:43:07 PDT 2015


On Tue, May 19, 2015 at 1:56 PM, Lennart Poettering
<lennart at poettering.net> wrote:
> On Tue, 19.05.15 10:23, Martin Pitt (martin.pitt at ubuntu.com) wrote:
>
>> Hello all,
>>
>> I have a better fix now.
>>
>> > So the problem is that this tentative → dead transition only works if
>> > a device is referenced once, but causes overzealous unmounts if there
>> > are more references.
>
> Ah, indeed, that makes sense!
>
>> > We need a reference count, or check if the device is bound by other
>> > device still. Come to think of it now, we actually already have that:
>> >
>> >   Id=dev-foo.device
>> >   BoundBy=tmp-boot.mount tmp-etc.mount
>> >
>> > But my patch doesn't take that into account yet.
>>
>> This one does now. I left a fairly comprehensive commit log as this
>> isn't that easy to explain/understand. If it's too verbose for you I
>> can also trim it back a bit.
>
> I have now committed a different fix now, that keeps counting of the
> mount points in mount.c, instead of "reaching over" from device.c.
>
> I only gave this light testing, would be cool if you could check if
> this fixes things for you.
>
> http://cgit.freedesktop.org/systemd/systemd/commit/?id=fcd8b266edf0df2b85079fcf7b099cd4028740e6
>
> This commit will now collect two sets of devices while going through
> /proc/self/mountinfo: the devices of lines that are no longer there,
> and the devices of lines that are there. Only for devices in the
> former set that are not in the latter we will now propagate an event
> to device.c.
>
> Does this make sense?
>
>> +        /* If we found a tentative device via mountinfo which is still
>> +         * referenced by other mounts than the one that just got unmounted, we
>> +         * must leave it FOUND_MOUNT/tentative; otherwise we'd trigger
>> +         * unmounting of all other bound mounts. */
>> +        if (d->found == DEVICE_FOUND_MOUNT && n == 0) {
>> +                Iterator i;
>> +                Unit *bound;
>> +
>> +                SET_FOREACH(bound, UNIT(d)->dependencies[UNIT_BOUND_BY], i) {
>> +                        if (bound->type == UNIT_MOUNT &&
>> +                            MOUNT(bound)->state != MOUNT_DEAD && MOUNT(bound)->state != MOUNT_FAILED) {
>> +                                log_unit_debug(UNIT(d), "Still bound by %s (%s), keeping state.",
>> +                                               bound->id, mount_state_to_string(MOUNT(bound)->state));
>> +                                return;
>> +                        }
>> +                }
>> +                log_unit_debug(UNIT(d), "Not referenced by any mounts any more, changing to dead.");
>> +        }
>> +
>>          previous = d->found;
>>          d->found = n;
>
> Lennart

Didn't work for me. Removed device doesn't go in to either cases, so
it never makes it to the "around" set but it makes it to "gone" set.

if (!mount->is_mounted)
{

}
else if (mount->just_mounted || mount->just_changed)
{

}

Umut

>
> --
> Lennart Poettering, Red Hat
> _______________________________________________
> systemd-devel mailing list
> systemd-devel at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/systemd-devel


More information about the systemd-devel mailing list