A regra do Udev para dispositivos de mídia automount parou de funcionar depois que o systemd foi atualizado para a versão 239

1

Por algum tempo, eu tinha uma regra do udev funcional para montar dispositivos de mídia automaticamente.

/etc/udev/rules.d/61-mount_media_by_label.rules

#
# To propagate udev's mountpoint to the user space, MountFlags must have a value "shared" in the /usr/lib/systemd/system/systemd-udevd.service.
#

# Ignore devices that aren't storage block-devices and block-devices that are already listed in /etc/fstab.
KERNEL!="sd[a-z][1-9]*", GOTO="mount_media_by_label_end"
PROGRAM="/bin/grep -e '^UUID=%E{ID_FS_UUID}' /etc/fstab", RESULT!="", GOTO="mount_media_by_label_end"

# Decide the name for device's mountpoint directory, based on device's label.
ENV{ID_FS_LABEL}!="", ENV{mountpoint}="%E{ID_FS_LABEL}"
ENV{ID_FS_LABEL}=="", ENV{mountpoint}="usb-%k"

# If device is being plugged in, set options for mount command.
ACTION=="add", ENV{mount_options}="relatime"
ACTION=="add", ENV{ID_FS_TYPE}=="vfat|ntfs", ENV{mount_options}="%E{mount_options},utf8,gid=100,umask=002"

# If device is being plugged in, create mountpoint directory in /media and mount device node to it.
ACTION=="add", RUN+="/bin/mkdir -p /media/%E{mountpoint}", RUN+="/bin/mount -o %E{mount_options} /dev/%k /media/%E{mountpoint}"

# If device is being plugged out, unmount it and delete its mountpoint directory.
ACTION=="remove", ENV{mountpoint}!="", RUN+="/bin/umount -l /media/%E{mountpoint}", RUN+="/bin/rmdir /media/%E{mountpoint}"

# Label for early exit.
LABEL="mount_media_by_label_end"

Para fazer esta regra funcionar, eu só tive que alterar o valor da opção MountFlags para shared em
/usr/lib/systemd/system/systemd-udevd.service
Depois que eu atualizei o systemd para a versão 239 , esse arquivo parece diferente. Eu notei duas alterações que podem ser problemáticas:

  1. A opção MountFlags não está especificada nas configurações padrão.
  2. Existe uma nova opção PrivateMounts definida como yes .

Da documentação do systemd , percebi que agora só preciso definir PrivateMounts=no e propagação do ponto de montagem alcançariam o espaço do usuário.

No entanto, este não é o caso.
Eu tentei

  1. Alterando PrivateMounts=no
  2. Alterando PrivateMounts=no e adicionando MountFlags=shared

mas não funciona.

Qual é a maneira correta de montar dispositivos de mídia a partir das regras do udev em systemd v239 e posterior?

    
por Iskustvo 26.08.2018 / 22:20

1 resposta

1

Esta abordagem pode ser sub-ótima. Por exemplo, se você suportar a montagem de NTFS gravável usando ntfs-3g , o processo ntfs-3g será eliminado sempre que você reiniciar o udev.

Observe que a moderna doutrina de segurança sugere que os desktops devem começar a usar o FUSE para montar todos sistemas de arquivos removíveis. link

Seria preferível se você pudesse descobrir como iniciar (e parar?) uma unidade separada do sistema ... e escrevê-la como a abordagem preferencial, em qualquer documento peculiar que continue sugerindo que os usuários do Arch usem esse padrão: ). O uso de uma unidade systemd separada evitará as restrições aplicadas ao serviço do udev.

Por exemplo, inicie um comando em uma unidade de escopo do systemd usando systemd-run --no-block --scope -- my mount command here .

Infelizmente, se você quiser que a unidade que contém ntfs-3g tenha um nome identificável , não é imediatamente óbvio qual é a maneira 100% correta. Se uma unidade antiga com esse nome ainda for rastreada como "ativa", mas o processo tiver acabado de sair, simplesmente solicitar que o serviço seja iniciado não fará nada. Você poderia ignorar o problema, gerar um sufixo aleatório para o nome ou tentar excluir essa sequência de eventos ... mas talvez haja uma maneira melhor.

Eu não testei isso com o FUSE, mas acho que a maneira de fazer isso seria o comando systemd-mount .

Uma resposta de superusuário sugere que usar systemd-mount em um dispositivo enquanto a regra do udev ainda está em execução, pode não funcionar corretamente. Isso exigiria soluções alternativas bastante barrocas. ( RUN+="/path/to/my/script %k" que executa systemd-run --no-block --scope --unit=mount-$1 sh -c "systemctl start /dev/$1; systemd-mount ..." ).

Acho que a maneira de fazer isso seria algo como

ENV{SYSTEMD_WANTS}=my-mounter@%k.service

# /etc/systemd/system/[email protected]
[Service]
Type=oneshot
ExecStart=systemd-mount %I

#!/bin/sh
# /usr/local/lib/my-mounter
# You can make this as complicated as you want.
# (Although curiously systemd-mount also reads SYSTEMD_MOUNT_WHERE and
# SYSTEMD_MOUNT_OPTIONS properties if you set them on the udev device.)
# You could also read udev properties yourself using 
# eval "$(udevadm info --query=property --export)"

DEVNAME="$1"
systemd-mount "/dev/$DEVNAME"

Os padrões para systemd-mount fazem com que o sistema de arquivos seja desmontado automaticamente na remoção, mas eles não limpam o diretório do ponto de montagem criado automaticamente (!).

Havia duas alterações separadas na v239 - duas diretivas separadas que você deve reverter para obter o comportamento antigo.

  1. %código%. Substitua isto por PrivateMounts=yes .
  2. PrivateMounts=no

    O uso desta diretiva é novo na v239. Portanto, a maneira mais simples de recuperar o comportamento anterior é removê-lo completamente.

por 27.08.2018 / 11:39