Categories
Linux

use mount in udev rule with systemd-udevd

If you write your own scripts called by udevd, for example after plugin a specific USB stick, you maybe want to mount a partition, which could fail. I got often return code 32 from mount, which means “mount failure” but without any additional error message.

This happens, because systemd-udevd is started in its own namespace for mounting. So the filesystem of udevd differs from the main system. You should be aware, that running udevd in an own namespace increases security. But if you want to disable this to run your scripts, do the following steps.

First verify the current MountFlags settings of udevd service. It should be “slave”.

systemctl show systemd-udevd | grep -F MountFlags

Now edit the udevd service

systemctl edit systemd-udevd

and set MountFlags to shared:

[Service]
MountFlags=shared

At last you just have to reload systemd settings and restart the udevd daemon:

systemctl daemon-reload
systemctl restart systemd-udevd

You then also can verify that udevd didn’t use the namespace anymore and list all current mount namespaces in use:

lsns -t mnt
Categories
Linux

run custom script on USB connect in Linux

You can run custom scripts after you have connected a USB device to a Linux system. So you can then perform custom actions also only if a specific device was plugged in.

In modern Linux systems the udevd daemon is used to handle the devices. You can define rules for specific actions the udev should do.

First you have to gather some informations about your target device. You can use the command udevadm monitor to monitor udev events. Some useful commands are also:

CommandUsage
udevadm monitor -pview all events with full properties
udevadm monitor -p -s blockview all events with full properties of block subsystem related events

If your device is already connected, you can also query the attributes of an existing device using (for example disk /dev/sdb): udevadm info -a -n /dev/sdb

Here you should extract some unique attributes of your device.

To run your custom script or command you have to create such a rules file, for example /etc/udev/rules.d/10-myusbstick.rules, defining the match rules for your extracted attributes and the wanted action.

SUBSYSTEM=="block", ACTION=="add", ENV{DEVTYPE}=="partition", ATTRS{idProduct}=="441a", ATTRS{idVendor}=="0815", ATTRS{serial}=="123697755110", ENV{UDISKS_AUTO}="0", ENV{UDISKS_IGNORE}="1", RUN += "/usr/local/sbin/customscript.sh"

You should check that for every event the attributes are matching, the script will be started. So if your rule is too wide, you will call your script multiple times. You can use udevadm monitor to monitor the events and you also can use a simple debug script to get a feeling about the handling:

#!/bin/bash
echo "got event in pid: $$" >> /tmp/udevdebug.log
env >> /tmp/udevdebug-$$.log

The script will add an entry to the file /tmp/udevdebug.log with the own PID and will output the full environment, which contains all relevant variables from udevd, to an logfile.

Categories
Linux

disable automount for specific USB devices in Linux

I had the problem that I don’t want to automount a specific USB device in Linux. I could switch whole automount off, but this was not what I wanted.

To achieve this, you can define a specific udev rule. Udev is the widely used daemon for handling devices of Linux kernels in user space.

First you need to know how to identify your device. So plug your USB stick in and view the device specific parameters. The following example assumes, that your USB stick is added as /dev/sdb.

sudo udevadm info -a -n /dev/sdb

You will see everything which is related to this USB device, so also USB hub, etc. So be careful to choose the correct attributes for further filtering.

Now you have to add a udev rule for your device. You should create a new rules file, for example in /etc/udev/rules.d/10-myspecialdevice.rules with the following content:

ATTRS{idProduct}=="449a", ATTRS{idVendor}=="0815", ATTRS{serial}=="foobar", ENV{UDISKS_AUTO}="0"

The first 3 ATTRS parts are your extracted attributes from the previous command. The last sets an environment variable UDISKS_AUTO which handles the automount behavior of Gnome. There are more variables, for example UDISKS_IGNORE=1 for hiding the device in Nautilus. The following overview can be found in the man pages via man udisks:

UDISKS_SYSTEM
If set, this overrides the value of the HintSystem property.

UDISKS_IGNORE
If set, this overrides the value of the HintIgnore property.

UDISKS_AUTO
If set, this overrides the value of the HintAuto property.

UDISKS_CAN_POWER_OFF
If set, this overrides the value of the CanPowerOff property.

UDISKS_NAME
The name to use for the device when presenting it in an user interface. This corresponds to the HintName property.

UDISKS_ICON_NAME
The icon to use for the device when presenting it in an user interface. If set, the name must adhere to the freedesktop.org icon theme specification[4]. This corresponds to the HintIconName property.

UDISKS_SYMBOLIC_ICON_NAME
The icon to use for the device when presenting it in an user interface using a symbolic icon. If set, the name must adhere to the freedesktop.org icon theme specification[4]. This corresponds to the HintSymbolicIconName property.

UDISKS_FILESYSTEM_SHARED
If set to 1, the filesystem on the device will be mounted in a shared directory (e.g. /media/VolumeName) instead of a private directory (e.g. /run/media/$USER/VolumeName) when the Filesystem.Mount() method is handled.

ID_SEAT
The physical seat the device is attached to. If unset or set to the empty string, “seat0” (the first seat) is assumed.

After you created your file you have to reload your rules:

sudo udevadm control --reload