Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

systemd-udevd.service not responding to PrivateMounts or MountFlags #11982

Closed
archenemies opened this Issue Mar 13, 2019 · 25 comments

Comments

3 participants
@archenemies
Copy link

archenemies commented Mar 13, 2019

systemd version the issue has been seen with

244

Used distribution

Arch Linux

Expected behaviour you didn't see

See Udev rule to mount disk does not work

Many users want to add udev rules to automatically mount removable devices when attached.

However, Udev by default runs in a separate mount namespace.

The workaround should be documented somewhere easy to find.

In the above SE post, some users reported that creating an override file for the Udev service, with

[Service]
MountFlags=shared

was successful. However, this does not work for me, and another SE user reported the same.

I also tried editing the full Unit file:

#  SPDX-License-Identifier: LGPL-2.1+
#
#  This file is part of systemd.
#
#  systemd is free software; you can redistribute it and/or modify it
#  under the terms of the GNU Lesser General Public License as published by
#  the Free Software Foundation; either version 2.1 of the License, or
#  (at your option) any later version.

[Unit]
Description=udev Kernel Device Manager
Documentation=man:systemd-udevd.service(8) man:udev(7)
DefaultDependencies=no
After=systemd-sysusers.service systemd-hwdb-update.service
Before=sysinit.target
ConditionPathIsReadWrite=/sys

[Service]
Type=notify
OOMScoreAdjust=-1000
Sockets=systemd-udevd-control.socket systemd-udevd-kernel.socket
Restart=always
RestartSec=0
ExecStart=/usr/lib/systemd/systemd-udevd
KillMode=mixed
WatchdogSec=3min
TasksMax=infinity
####
# edit 13 Mar 2019
PrivateMounts=no
MountFlags=shared
####
MemoryDenyWriteExecute=yes
RestrictRealtime=yes
RestrictAddressFamilies=AF_UNIX AF_NETLINK AF_INET AF_INET6
SystemCallFilter=@system-service @module @raw-io
SystemCallErrorNumber=EPERM
SystemCallArchitectures=native
LockPersonality=yes
IPAddressDeny=any

I tried sudo systemctl daemon-reload, sudo systemctl restart systemd-udevd.service, and also rebooting my system. However Udev still runs in a separate namespace:

# readlink /proc/222/ns/mnt
mnt:[4026532273]
# readlink /proc/1/ns/mnt
mnt:[4026531840]

This is related to #1741 - I am trying to find a better solution for dealing with removable drives, which doesn't use /etc/fstab.

I couldn't find information in systemd.exec or systemd.unit. I will try a different solution but I think someone should comment on the above SE post, since it is the second result on Google for "udev automatically mount removable drive"; the first result is a blog post which also describes a non-working solution. Of interest is also how to debug the non-working situation, e.g. what is the path a user should take to figure out why the supplied PrivateMounts and MountFlags directives are not having an effect.

Thank you!

@yuwata

This comment has been minimized.

Copy link
Member

yuwata commented Mar 13, 2019

However, this does not work for me, and another SE user reported the same.

I guess the workaround is now work again with 37ed15d.

@archenemies

This comment has been minimized.

Copy link
Author

archenemies commented Mar 13, 2019

I've still been playing with this and I found that commenting out everything after TasksMax=infinity also makes systemd-udevd have the same namespace... so that's what I'm doing for now I guess

@yuwata

This comment has been minimized.

Copy link
Member

yuwata commented Mar 13, 2019

You mean 37ed15d does not work??

BTW, Could you tell the correct version of systemd? v244 is not released yet...

@poettering

This comment has been minimized.

Copy link
Member

poettering commented Mar 13, 2019

Many users want to add udev rules to automatically mount removable devices when attached.

btw, pull in a .mount unit via SYSTEMD_WANTS from a device for this purpose, or even better use the systemd-mount utility. mounting directly from udev rules is problematic, and shouldn't be done.

@archenemies

This comment has been minimized.

Copy link
Author

archenemies commented Mar 13, 2019

version 241 sorry!

Now using https://github.com/Ferk/udev-media-automount which works

@poettering

This comment has been minimized.

Copy link
Member

poettering commented Mar 13, 2019

@archenemies really, consider using the "systemd-mount" tool instead. it#s the solution you really want, as it does autofs and fsck and everything else...

@archenemies

This comment has been minimized.

Copy link
Author

archenemies commented Mar 13, 2019

You mean as an alternative to calling 'mount' from a udev rule?

The solution I want

  1. automatically mounts devices by label in /media. keep it simple

  2. doesn't use X (except maybe for notification) or depend on user being logged in -> no udiskie

  3. isn't long and complicated to configure -> no udiisk2

  4. allows me to set mount options from a script, e.g.

    case $TYPE in
        vfat|exfat)
        mopts="$mopts,flush,gid=100,umask=022"
    

So some kind of script is going to be called. I guess udev rules could call the script directly, and then the script could call systemd-mount which doesn't produce any long-running processes, is that the idea? Whereas @Ferk's solution uses a Systemd unit which is an unnecessary additional component? Please let me know if I'm misunderstanding you, I'd like to have a grasp of what you're recommending.

@archenemies

This comment has been minimized.

Copy link
Author

archenemies commented Mar 13, 2019

I put a list here of various articles that came up when I was researching this: Ferk/udev-media-automount#1

@poettering

This comment has been minimized.

Copy link
Member

poettering commented Mar 13, 2019

coming back to the original issue this is about: if you comment MountFlags= and PrivateMounts= in the unit file, and issue daemon-reload and restart udevd then it should live in the same namespace as the host. Are you saying that's not the case?

@archenemies

This comment has been minimized.

Copy link
Author

archenemies commented Mar 13, 2019

  1. No... by "same namespace" I meant "same namespace as everything else". #11982 (comment)

  2. Please clarify what you're trying to say about usage of systemd-mount (by the way, there are no examples in the manual page)

@poettering

This comment has been minimized.

Copy link
Member

poettering commented Mar 13, 2019

hmm, that this is supposed to be dependent on TaskMax sounds very strange. Are you sure you properly issued both "systemctl daemon-reload" and "systemctl restart systemd-udevd" after making the changes?

@poettering

This comment has been minimized.

Copy link
Member

poettering commented Mar 13, 2019

"systemd-mount" allows you to do everything you need, have a look at the man page. It tells PID 1 to do the mount/automount stuff, and hence doesn't have any probs with namespacing. invoke it from a udev rule and all should be good.

@archenemies

This comment has been minimized.

Copy link
Author

archenemies commented Mar 13, 2019

Wow this issue is really getting cluttered with miscommunication. I'm sorry I should be keeping things simpler. I should have just stuck to asking "You mean [use systemd-mount] as an alternative to calling 'mount' from a udev rule?" which I think you just answered with "yes".

Also by commenting "everything after TasksMax=infinity" I mean I commented everything on the following lines. So that line itself was still uncommented. But commenting just "MountFlags=" and "PrivateMounts=" also achieves this as I just checked. (as for why that is, I don't understand)

@poettering

This comment has been minimized.

Copy link
Member

poettering commented Mar 13, 2019

ah, ok, then everything's good. Everything works as it should. And 37ed15d makes work that your first change also works.

I guess we can close this hence.

@poettering poettering closed this Mar 13, 2019

@archenemies

This comment has been minimized.

Copy link
Author

archenemies commented Mar 14, 2019

I think I'll just stick with Ferk's solution, based on a simple Systemd service, which works fine. If I take a udev-rule/script combination which is able to 'mount' successfully (but where the mount disappears after a few seconds because Systemd kills the process) and then I replace the 'mount' command with 'systemd-mount', then what happens is it takes a very long time and seems to time out. The log file says I should check the journal, which has an entry like:

Mar 13 19:30:26 mycomputer systemd[1]: Dependency failed for /media/kt-local.
-- Subject: A start job for unit media-kt\x2dlocal.mount has failed
-- Defined-By: systemd
-- Support: https://lists.freedesktop.org/mailman/listinfo/systemd-devel
-- 
-- A start job for unit media-kt\x2dlocal.mount has finished with a failure.
-- 
-- The job identifier is 44235 and the job result is dependency.

Strangely if I run sudo udevadm trigger /dev/sdd -c add then the same script now causes the device to be mounted, sometimes after one try, sometimes after two. But Ferk's solution seems more transparent and reliable. It works when I actually plug the device in.

If your intention is for people to be automounting USB devices in /media using systemd-mount, then I think it would help to create a short tutorial showing how, and also showing how to debug the various problems that will inevitably arise. Also it would be good to provide support on the forums where people are talking about this common use of udev, particularly on the Stack Exchange network. Examples are much more helpful than long technical references.

@yuwata

This comment has been minimized.

Copy link
Member

yuwata commented Mar 14, 2019

Interesting.

@yuwata

This comment has been minimized.

Copy link
Member

yuwata commented Mar 14, 2019

At the initial run, the corresponding device is not ready, and systemd does not have corresponding .device unit.
So, maybe, we need to add --fork or extend --no-block option to systemd-mount and wait for the device initialization. @poettering WDYT?

@yuwata

This comment has been minimized.

Copy link
Member

yuwata commented Mar 14, 2019

Hmm, .mount unit has implicit dependencies BindTo= and After= with the backing .device unit... So, it is not necessary to wait for the device initialization.

@yuwata

This comment has been minimized.

Copy link
Member

yuwata commented Mar 14, 2019

Oh, I got that --no-block option is necessary.

ACTION=="remove", GOTO="hoge_end"

SUBSYSTEM!="block", GOTO="hoge_end"
ENV{DEVTYPE}!="partition", GOTO="hoge_end"
ENV{ID_FS_UUID}=="", GOTO="hoge_end"

SUBSYSTEMS=="usb", RUN{program}+="/usr/bin/systemd-mount --no-block $devnode /media/$env{ID_FS_UUID}"

LABEL="hoge_end"

Then I got

$ df -h /media/*
/dev/sdb1       583M  583M     0 100% /media/2018-04-25-03-09-37-00
/dev/sdb2       9.1M  8.7M  472K  95% /media/16EE-78E4
/dev/sdb3        20M   11M  8.4M  57% /media/35075928-c55a-36ef-9254-1f9b655f0e20
@poettering

This comment has been minimized.

Copy link
Member

poettering commented Mar 14, 2019

Yes, the command you want to run is something like this:

RUN{program}+="/usr/bin/systemd-mount --no-block --automount=yes --collect $devnode"
@poettering

This comment has been minimized.

Copy link
Member

poettering commented Mar 14, 2019

I posted #11998 to provide an example for the right udev line in the docs. ptal.

@archenemies

This comment has been minimized.

Copy link
Author

archenemies commented Mar 14, 2019

Thank you. The commit has:

ACTION=="add", SUBSYSTEMS=="usb", SUBSYSTEM=="block", ENV{ID_FS_USAGE}=="filesystem", RUN{program}+="/usr/bin/systemd-mount --no-block --automount=yes --collect $devnode"

One thing I don't understand is where the device gets mounted, i.e. how do I specify that it should be mounted in /media/? What is $devnode, is that the same as $DEVNAME or "%k"? What was reponsibe for the behavior I was seeing where the filesystem doesn't get mounted at all? Anyway I tried this and nothing seemed to happen. I think a little more detail is warranted, also showing an example output. But I think @yuwata is willing to run examples so maybe I should leave it to you two at this point, anyway those are my comments after taking a look.

keszybz added a commit that referenced this issue Mar 14, 2019

@poettering

This comment has been minimized.

Copy link
Member

poettering commented Mar 14, 2019

One thing I don't understand is where the device gets mounted, i.e. how do I specify that it should be mounted in /media/?

See man page:

https://www.freedesktop.org/software/systemd/man/systemd-mount.html#Description

By default the mount point is below /run/media/system/ and a name derived from the fs label. you can tweak that however, by setting the SYSTEMD_MOUNT_WHERE udev prop (or specifiying a second arg to the systemd-mount cmdline)

What is $devnode, is that the same as $DEVNAME or "%k"?

It contains the device node path (i.e. /dev/xyz). The other two contain the kernel internal name, i.e. not a path.

@poettering

This comment has been minimized.

Copy link
Member

poettering commented Mar 14, 2019

I posted #11999 now that explains the /run/media/system/ thing

@archenemies

This comment has been minimized.

Copy link
Author

archenemies commented Mar 14, 2019

OK that's good.

Well, anyway, strange that it didn't work for me. Maybe others will have better luck.

keszybz added a commit that referenced this issue Mar 15, 2019

wat-ze-hex added a commit to wat-ze-hex/systemd that referenced this issue Mar 18, 2019

wat-ze-hex added a commit to wat-ze-hex/systemd that referenced this issue Mar 18, 2019

keszybz added a commit to systemd/systemd-stable that referenced this issue Mar 29, 2019

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.