O comando - mount do Linux retorna zero / 0, mas não funciona

5

Parece estranho, eu tenho um shell script que é acionado pelas regras do udev , para montar o dispositivo USB conectado à árvore de arquivos do sistema. O script é executado quando um dispositivo USB é anexado ao sistema, portanto as regras parecem estar bem. Eu monituro como o script progride pelo syslog, e também corre bem, e até mesmo o comando mount retorna zero, e diz:

 root[1023]: mount: /dev/sda1 mounted on /media/partitionlabel.

Mas no final o dispositivo não está montado, ele não está listado em / etc / mtab - / proc / mounts - findmnt - mount . e se eu executar umount no dispositivo, ele também diz, o dispositivo não está montado.

No entanto, se eu executar o script manualmente como raiz do terminal, ele funcionará perfeito e o dispositivo será montado, mas não quando for executado por udev .

Adicionei 8 segundos para o início do script, para ter certeza de que não é um problema de tempo e também removi o número do nome do arquivo de regras para garantir que o udevd colocaria as novas regras na parte inferior da fila de regras, e o script seria executado depois de outras regras do sistema, mas sem sucesso.

O syslog:

(logo após o dispositivo anexado)

kernel: usb 1-1.2: new high-speed USB device number 12 using dwc_otg
kernel: usb 1-1.2: New USB device found, idVendor=058f, idProduct=6387
kernel: usb 1-1.2: New USB device strings: Mfr=1, Product=2, SerialNumber=3
kernel: usb 1-1.2: Product: Mass Storage
kernel: usb 1-1.2: Manufacturer: Generic
kernel: usb 1-1.2: SerialNumber: 24DCF568
kernel: usb-storage 1-1.2:1.0: USB Mass Storage device detected
kernel: scsi host6: usb-storage 1-1.2:1.0
kernel: scsi 6:0:0:0: Direct-Access     Generic  Flash Disk       8.07 PQ: 0 ANSI: 4
kernel: sd 6:0:0:0: [sda] 1968128 512-byte logical blocks: (1.00 GB/961 MiB)
kernel: sd 6:0:0:0: [sda] Write Protect is off
kernel: sd 6:0:0:0: [sda] Mode Sense: 23 00 00 00
kernel: sd 6:0:0:0: [sda] Write cache: disabled, read cache: enabled, doesn't support DPO or FUA
kernel:  sda: sda1
kernel: sda: p1 size 1968126 extends beyond EOD, enabling native capacity
kernel:  sda: sda1
kernel: sda: p1 size 1968126 extends beyond EOD, truncated
kernel: sd 6:0:0:0: [sda] Attached SCSI removable disk
root[1004]: /usr/local/sbin/udev-auto-mount.sh - status: started to automount sda1
root[1019]: /usr/local/sbin/udev-auto-mount.sh - status: Device Label is partitionlabel and Filesystem is vfat.
root[1021]: /usr/local/sbin/udev-auto-mount.sh - status: mounting the device sda1 by filesystem vfat to /media/partitionlabel.
root[1023]: mount: /dev/sda1 mounted on /media/partitionlabel.
root[1024]: /usr/local/sbin/udev-auto-mount.sh status: mount command proceed for vfat, retval is 0
root[1025]: /usr/local/sbin/udev-auto-mount.sh - status: succeed!

Configs:

/etc/udev/rules.d/local-rules:

A regra definida em udev é:

# /etc/udev/rules.d/local-rules
ENV{ID_BUS}=="usb",     ACTION=="add",  ENV{DEVTYPE}=="partition",      \
          RUN+="/usr/local/sbin/udev-automounter.sh %k $ENV{ID_FS_LABEL_ENC}"

udev-auto-mount.sh

O script inicia com outro script que é definido na regra do udev. É tão simples que cria o diretório ponto de montagem e monta o dispositivo usb no ponto de montagem usando seu tipo de sistema de arquivos e algumas opções regulares. Eu adicionei a opção "-v" ao comando mount para ser mais detalhado e também redirecionei todas as saídas para o syslog, para que eu possa ver como ele é executado, mas não diz muito.

#!/bin/sh
## /usr/local/sbin/udec-auto-mount.sh
##

logger -s "$0 - status: started to automount ${1}"
DEVICE=$1
sleep 8 

#...
#...
# Checking inputs, getting filesystem type (ID_FS_TYPE), partition label
# (ID_FS_LABEL) and ...

mkdir "/media/${ID_FS_LABEL}"


logger -s "$0 - status: mounting the device ${DEVICE} by filesystem ${ID_FS_TYPE} to /media/${ID_FS_LABEL}."
case $ID_FS_TYPE in
    vfat)   mount -v -t vfat -o sync,noatime,nosuid,nodev /dev/${DEVICE} "/media/${ID_FS_LABEL}" 2>&1 | logger
        let retVal=$?
        logger -s "$0 status: mount command proceed for vfat, retval is ${retVal}"
        ;;

    *)  mount -v -t auto -o sync,noatime /dev/${DEVICE} "/media/${ID_FS_LABEL}"
        ;;
esac
if [ ${retVal} -eq 0 ]; then
    logger -s "$0 - status: succeed!"
    exit 0
else
    logger -s "$0 Error: unable to mount the device ${DEVICE}, retval is ${retVal}"
    rmdir "/media/${ID_FS_LABEL}"
fi

exit 0

Talvez ajude:

Às vezes, depois que o script não consegue montar o dispositivo USB, quando eu desanexar o dispositivo, aparece algum erro no syslog como:

kernel: usb 1-1.2: USB disconnect, device number 11
systemd-udevd[143]: error: /dev/sda: No such file or directory
systemd-udevd[977]: inotify_add_watch(7, /dev/sda, 10) failed: No such file or directory

Editar:

Esta é a versão "mount":

$ mount -V:
mount from util-linux 2.27.1 (libmount 2.27.0: assert, debug)
    
por 2i3r 21.05.2015 / 21:08

2 respostas

0

Finalmente encontrei a resposta aqui .

Na verdade, o problema veio de systemd-udevd , que obteve o% original udev . O systemd-udevd cria seu próprio espelho do sistema de arquivos raiz, quando a regra 'udev' monta o dispositivo, é montada e é acessível de:

/proc/{PID of systemd-udevd service}/root/{path to mount point}

mas não é visível no sistema de arquivos raiz principal / .

O wiki de

archlinux ( aqui ) sugere:

Warning: To mount removable drives, do not call mount from udev rules. In case of FUSE filesystems, you will get Transport endpoint not connected errors. Instead, you could use udisks that handles automount correctly or to make mount work inside udev rules, copy /usr/lib/systemd/system/systemd-udevd.service to /etc/systemd/system/systemd-udevd.service and replace MountFlags=slave to MountFlags=shared.[3] Keep in mind though that udev is not intended to invoke long-running processes.

Solução:

Copiei /usr/lib/systemd/system/systemd-udevd.service para o diretório /etc/systemd/sytem/ e substituí MountFlags=slave por MountFlags=shared . então reiniciei o sistema, e agora tudo funciona bem.

    
por 21.04.2017 / 17:04
1

A sequência

mount ... | logger
rc=$?

não está funcionando como esperado: o valor de retorno de um canal é o valor de retorno do último elemento nesse canal.

$> false | true; echo $?
0

Se você usar o bash, tente PIPESTATUS :

$> false | true; echo $? ${PIPESTATUS[0]}
0 1
$> true | false; echo $? {PIPESTATUS[0]}
1 0

PIPESTATUS é uma variável de matriz. Detalhes na página man do bash. Outros shells podem ter algo parecido com PIPESTATUS

    
por 04.09.2015 / 22:03