4

There is a headless machine, with Debian as its OS:

$ cat /etc/issue
Debian GNU/Linux 11 \n \l

$ uname -a
Linux mymachine 6.1.99 #33 SMP Tue Jan 21 11:32:39 CST 2025 aarch64 GNU/Linux

What I wish to achieve is to mount an SD card automatically onto /media/[SD_CARD_LABEL] upon insertion.

Again, this is a headless machine:

  • does not have monitor
  • does not have keyboard
  • does not have GUI
  • does have a few buttons on GPIO

For this task I wish to use (if there are no better alternatives) udisks2 and udiskie.

Udiskie's polkit rule:

$ cat /etc/polkit-1/rules.d/50-udiskie.rules 
polkit.addRule(function(action, subject) {
  var YES = polkit.Result.YES;
  var permission = {
    // required for udisks1:
    "org.freedesktop.udisks.filesystem-mount": YES,
    "org.freedesktop.udisks.luks-unlock": YES,
    "org.freedesktop.udisks.drive-eject": YES,
    "org.freedesktop.udisks.drive-detach": YES,
    // required for udisks2:
    "org.freedesktop.udisks2.filesystem-mount": YES,
    "org.freedesktop.udisks2.encrypted-unlock": YES,
    "org.freedesktop.udisks2.eject-media": YES,
    "org.freedesktop.udisks2.power-off-drive": YES,
    // required for udisks2 if using udiskie from another seat (e.g. systemd):
    "org.freedesktop.udisks2.filesystem-mount-other-seat": YES,
    "org.freedesktop.udisks2.filesystem-unmount-others": YES,
    "org.freedesktop.udisks2.encrypted-unlock-other-seat": YES,
    "org.freedesktop.udisks2.encrypted-unlock-system": YES,
    "org.freedesktop.udisks2.eject-media-other-seat": YES,
    "org.freedesktop.udisks2.power-off-drive-other-seat": YES
  };
  if (subject.isInGroup("plugdev")) {
    return permission[action.id];
  }
});

I wish testuser user to be set as owner and group for the mount. Therefore I have to make sure testuser is in group plugdev:

groups testuser
testuser : testuser plugdev

This is the config of udiskie:

$ cat /etc/systemd/system/udiskie.service 
[Unit]
Description=udiskie mounts drives when plugged in

[Service]
#User=testuser
#Group=testuser
ExecStart=/usr/bin/udiskie -a -N -T -F

[Install]
WantedBy=default.target

I also added an udev rule to mount the SD into /media/, instead of default /media/user/:

$ cat /etc/udev/rules.d/82-udisks2-sd.rules 
# This file contains udev rules for udisks 2.x

# ------------------------------------------------------------------------
# rules for external SD

KERNEL=="mmcblk0p*", ENV{UDISKS_FILESYSTEM_SHARED}="1"

So now, when I insert an SD card and watching the journal log of udiskie:

Nov 18 09:10:51 mymachine udiskie[1461]: mounted /org/freedesktop/UDisks2/block_devices/mmcblk0p1 on /media/sdcard

That's great however it's mounted as root:

$ ls -all /media/
total 144
drwxr-xr-x 1 pi   pi     4096 Nov 18 09:11 .
drwxr-xr-x 1 root root   4096 Aug  4  2017 ..
drwxr-xr-x 4 root root   4096 Nov  7 19:03 sdcard

I tried removing the comments from the systemd script:

[Service]
User=testuser
Group=testuser
ExecStart=/usr/bin/udiskie -a -N -T -F

However in this case I get:

Nov 18 09:12:42 mymachine udiskie[1596]: failed to mount /org/freedesktop/UDisks2/block_devices/mmcblk0p1: GDBus.Error:org.freedesktop.UDisks2.Error.NotAuthorizedCanObtain: Not authorized to perform operation

I also tried to move udiskie systemd config from system to user, but then I got error immediately after start:

$ systemctl --user status udiskie
● udiskie.service - udiskie mounts drives when plugged in
     Loaded: loaded (/etc/xdg/systemd/user/udiskie.service; enabled; vendor preset: enabled)
     Active: failed (Result: exit-code) since Tue 2025-11-18 08:53:43 CET; 51s ago
    Process: 1009 ExecStart=/usr/bin/udiskie -a -N -T -F (code=exited, status=216/GROUP)
   Main PID: 1009 (code=exited, status=216/GROUP)
        CPU: 0

Nov 18 08:53:43 mymachine systemd[1009]: udiskie.service: Failed at step GROUP spawning /usr/bin/udiskie: Operation not permitted

I do not want post-mount shell scripts. I wish to solve this by systemd, udev, polkit-1, and other configs.

3 Answers 3

4

Do you want the user to own the block device(s) in /dev or the mounted filesystem, or both?

They're two very different things.

  • Owning the block devs would allow the user to read and write the raw devices including partitioning and/or formatting them. Typically, non-root users do not have or need this, but it can be useful in some specialised circumstances.

    If needed, it can be done in the udev .rules file you created, /etc/udev/rules.d/82-udisks2-sd.rules by setting the OWNER, GROUP, and/or MODE for the device nodes. See man udev.

  • Owning the mounted filesystem would allow the user to read, write, create, delete, etc files and directories in that fs.

    How to do this varies depending on the filesystem:

    • With FAT or NTFS, you can set the owner, group, and perms in /etc/fstab. See man mount and search for the mount options specific to FAT and NTFS filesystems, as well as generic mount options.

      Note that ALL files and directories on that fs will have the specified ownership and perms because these filesystems do not implement unix-style ownership & permissions.

    • With Linux native filesystems, i.e. those that use unix file ownership and permissions (e.g. ext4, xfs, and many more), just mount the fs and then use chown and optionally chgrp and chmod to set the owner, group, and perms for the top-level directory in that filesystem.

      For example, if it's mounted as /media:

      chown username /media
      chgrp groupname /media
      chmod 755 /media
      

      This only needs to be done once per filesystem, and will persist across un-mounts and re-mounts...but it's worth noting that the ownership & perms are only set on that one specific filesystem on that one specific SD card. If you unmount the SD card and replace it with a different one and mount the filesystem on it, it will NOT have those permissions until & unless you set them.

      The perms above are only an example, there are many combinations. See man chmod. e.g. use 775 if you want the fs to be group-writable. If you want the fs to not be world-accessible, use 750 or 770. Use the setgid bit, e.g. 2755/2750/2775/2770/etc or chmod g+s, if you want all files and dirs created under /media to be created with the same group.

      BTW, because the fs supports unix ownership and permissions, files and directories beneath the top-level can have their own individual owner, group, and/or perms if required, and they can be changed at any time exactly the same as any other mounted linux-native filesystem. root (uid 0) can change the owner, group, and perms of any file or directory. Non-root users can change the group and perms of their own files and dirs, but can't change the owner.


One last thing, just in case you don't know: it's not safe to remove an SD card (or any other mounted filesystem) from a Linux system without properly un-mounting it.

Linux aggressively caches writes to mounted filesystems and you can corrupt the filesystem and the files on it if the SD card is just yanked from the system (same as the risk for an unscheduled power outage, system crash, or system reset).

You could mount it with the sync option but that will tank write performance and possibly reduce the lifespan of flash media.

8
  • I wish the user to own the mounted filesystem only (user needs to be able to delete files). "will persist across un-mounts and re-mounts": I have several SD cards, and I wish all to be fully managable by user (i.e. delete contents). They are all mounted onto /media/LABEL. Lables are different. In case I change ownership once, will it be preserved between SD ejections and reboots? Commented Nov 18 at 14:41
  • Yes, once you change the owner, group, and/or perms on a mounted filesystem, it will persist. Those details are stored with the top-level directory of that fs, same as they are on any other directory. Next time you mount that fs, they'll be the same as they were when you unmounted it. So, yes, you can just spend an hour or so mounting the fs on each sd card and setting the ownership & perms and then unmounting it and moving on to the next one, and then forget about it, it's done. You'll only have to do it again for any new sd cards you might buy in future. Commented Nov 18 at 16:22
  • Strange: udiskie mounts this SD card: /dev/mmcblk0p1 on /media/6564-3031 type vfat (rw,nosuid,nodev,relatime,fmask=0022,dmask=0022,codepage=936,iocharset=utf8,shortname=mixed,showexec,utf8,flush,errors=remount-ro,uhelper=udisks2). Ownership is root:root. I can't change anything to different owner: sudo chown -R testuser:testuser 6564-3031: "chown: changing ownership of '654-3031': Operation not permitted" Commented Nov 18 at 17:07
  • But if I mount it manually by sudo mount -o rw,user,uid=1000,gid=1000,umask=007,exec /dev/mmcblk0p1 /media/sd, it will get the correct user ownership. Commented Nov 18 at 17:18
  • 1
    The issue here is that SD cards typically use a filesystem which has no concept of file ownership. So the mount options uid/gid are instructing the system as to which user it should treat as owning the contents. That seems to be the correct thing for your situation. Commented Nov 18 at 17:21
2

If the label is fixed, create an /etc/fstab entry for /dev/mmcblk0p1. The resulting auto-generated media-FOO.mount can be linked into dev-mmcblk0p1.device.wants/ to have the appearance of the device trigger the mount, or dev-mmcblk0p1.device.d/override.conf can have a Wants= added for the mount.

If the label is dynamic, have the udev rule invoke systemd-mount from RUN+="".


Polkit requires the process to be either directly running within a systemd-logind session, or to be indirectly associated with a "graphical" systemd-logind session (i.e. owned by an UID which has at least one logind session for which the 'display' parameter is set); the latter case is to handle graphical apps which were launched through systemd --user as e.g. GNOME does.

Processes running as system services don't fall into the former category unless you configure PAMName= just right in the systemd .service (make it call some PAM stack which invokes pam_systemd). The system being headless rules out the latter.

It might be possible to get polkit to accept the udiskie process if you set PAMName= to the name of a PAM stack that usually creates a systemd-logind session (i.e. has pam_systemd in its 'session' group). You could try e.g. login which is used for interactive tty logins, but it might be doing too many unwanted things; or you could try writing your own /etc/pam.d/myservicestuff.

I'm not entirely sure whether there is also a requirement for the user's session to have registered a "polkit agent." Normally the agent's job is to display polkit password prompts, but I think it might be that the check for the agent's presence (for that user or session) might happen before polkit knows that a password isn't required.

1
  • Label (SD-card's name) is dynamic. But device name mmcblk0p1 is always the same. All I want is to get it mounted to /media/[SDLABEL] automatically but with my preferred user as owner. Can I add some config to fstab to use the label for mount-path? Commented Nov 18 at 9:02
1

Main problem was with polkit.

Debian's current LTS version is 11 (Bullseye).

In this version, PolicyKit is locked to version 0.105.

However, the JavaScript syntax is introduced only in newer versions of PolicyKit (>= 0.106).

One can verify the policykit's version:

pkaction --version

So my problem was that this polkit rule was skipped entirely:

/etc/polkit-1/rules.d/50-udiskie.rules

In version 0.105, we still have to use "pkla" files:

cat /etc/polkit-1/localauthority/50-local.d/50-udiskie.pkla 
[udiskie mount for plugdev group]
Identity=unix-group:plugdev
Action=org.freedesktop.udisks2.filesystem-mount;org.freedesktop.udisks2.encrypted-unlock;org.freedesktop.udisks2.eject-media;org.freedesktop.udisks2.power-off-drive;org.freedesktop.udisks2.filesystem-mount-system;org.freedesktop.udisks2.filesystem-mount-other-seat;org.freedesktop.udisks2.encrypted-unlock-other-seat;org.freedesktop.udisks2.eject-media-other-seat;org.freedesktop.udisks2.power-off-drive-other-seat
ResultAny=yes
ResultInactive=yes
ResultActive=yes

While this might be too open for the most users, it functions perfectly for my needs.

Now SD cards are mounting with the user's ownership defined in systemd's service file under "[Service]" section.

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.