在Debian上自动安装USB记忆棒


10

我在可插拔计算机(仅SSH,无GUI)上运行Debian Squeeze,而我想做的就是获取它,以便在插入USB记忆棒时会自动挂载它。

我要做的是安装autofs,只要知道设备所在的位置,就可以根据我的收集进行自动安装/dev

问题在于USB记忆棒并不总是使用相同的设备名称。有时是/dev/sdc1,有时/dev/sdd1是等等。

我认为要纠正这一点,我需要udev确保USB记忆棒始终使用相同的名称。

我得到以下信息udevadm

Udevadm info starts with the device specified by the devpath and then
walks up the chain of parent devices. It prints for every device
found, all possible attributes in the udev rules key format.
A rule to match, can be composed by the attributes of the device
and the attributes from one single parent device.

  looking at device '/block/sdd/sdd1':
    KERNEL=="sdd1"
    SUBSYSTEM=="block"
    DRIVER==""
    ATTR{partition}=="1"
    ATTR{start}=="63"
    ATTR{size}=="129339"
    ATTR{ro}=="0"
    ATTR{alignment_offset}=="0"
    ATTR{discard_alignment}=="0"
    ATTR{stat}=="      31      244      275      190        0        0        0        0        0      190      190"
    ATTR{inflight}=="       0        0"

  looking at parent device '/devices/platform/orion-ehci.0/usb1/1-1/1-1.2/1-1.2:1.0/host8/target8:0:0/8:0:0:0/block/sdd':
    KERNELS=="sdd"
    SUBSYSTEMS=="block"
    DRIVERS==""
    ATTRS{range}=="16"
    ATTRS{ext_range}=="256"
    ATTRS{removable}=="1"
    ATTRS{ro}=="0"
    ATTRS{size}=="129439"
    ATTRS{alignment_offset}=="0"
    ATTRS{discard_alignment}=="0"
    ATTRS{capability}=="51"
    ATTRS{stat}=="      56      727      783      520        0        0        0        0        0      520      520"
    ATTRS{inflight}=="       0        0"
    ATTRS{events}=="media_change"
    ATTRS{events_async}==""
    ATTRS{events_poll_msecs}=="-1"

  looking at parent device '/devices/platform/orion-ehci.0/usb1/1-1/1-1.2/1-1.2:1.0/host8/target8:0:0/8:0:0:0':
    KERNELS=="8:0:0:0"
    SUBSYSTEMS=="scsi"
    DRIVERS=="sd"
    ATTRS{device_blocked}=="0"
    ATTRS{type}=="0"
    ATTRS{scsi_level}=="3"
    ATTRS{vendor}=="        "
    ATTRS{model}=="Flash Disk      "
    ATTRS{rev}=="2.00"
    ATTRS{state}=="running"
    ATTRS{timeout}=="30"
    ATTRS{iocounterbits}=="32"
    ATTRS{iorequest_cnt}=="0x90"
    ATTRS{iodone_cnt}=="0x90"
    ATTRS{ioerr_cnt}=="0x0"
    ATTRS{modalias}=="scsi:t-0x00"
    ATTRS{evt_media_change}=="0"
    ATTRS{queue_depth}=="1"
    ATTRS{queue_type}=="none"
    ATTRS{max_sectors}=="240"

  looking at parent device '/devices/platform/orion-ehci.0/usb1/1-1/1-1.2/1-1.2:1.0/host8/target8:0:0':
    KERNELS=="target8:0:0"
    SUBSYSTEMS=="scsi"
    DRIVERS==""

  looking at parent device '/devices/platform/orion-ehci.0/usb1/1-1/1-1.2/1-1.2:1.0/host8':
    KERNELS=="host8"
    SUBSYSTEMS=="scsi"
    DRIVERS==""

  looking at parent device '/devices/platform/orion-ehci.0/usb1/1-1/1-1.2/1-1.2:1.0':
    KERNELS=="1-1.2:1.0"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb-storage"
    ATTRS{bInterfaceNumber}=="00"
    ATTRS{bAlternateSetting}==" 0"
    ATTRS{bNumEndpoints}=="02"
    ATTRS{bInterfaceClass}=="08"
    ATTRS{bInterfaceSubClass}=="06"
    ATTRS{bInterfaceProtocol}=="50"
    ATTRS{modalias}=="usb:v1976p6025d0100dc00dsc00dp00ic08isc06ip50"
    ATTRS{supports_autosuspend}=="1"

  looking at parent device '/devices/platform/orion-ehci.0/usb1/1-1/1-1.2':
    KERNELS=="1-1.2"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{configuration}==""
    ATTRS{bNumInterfaces}==" 1"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bmAttributes}=="80"
    ATTRS{bMaxPower}=="100mA"
    ATTRS{urbnum}=="383"
    ATTRS{idVendor}=="1976"
    ATTRS{idProduct}=="6025"
    ATTRS{bcdDevice}=="0100"
    ATTRS{bDeviceClass}=="00"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{bDeviceProtocol}=="00"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{bMaxPacketSize0}=="64"
    ATTRS{speed}=="12"
    ATTRS{busnum}=="1"
    ATTRS{devnum}=="11"
    ATTRS{devpath}=="1.2"
    ATTRS{version}==" 1.10"
    ATTRS{maxchild}=="0"
    ATTRS{quirks}=="0x0"
    ATTRS{avoid_reset_quirk}=="0"
    ATTRS{authorized}=="1"

  looking at parent device '/devices/platform/orion-ehci.0/usb1/1-1':
    KERNELS=="1-1"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{configuration}==""
    ATTRS{bNumInterfaces}==" 1"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bmAttributes}=="e0"
    ATTRS{bMaxPower}=="100mA"
    ATTRS{urbnum}=="197"
    ATTRS{idVendor}=="1a40"
    ATTRS{idProduct}=="0101"
    ATTRS{bcdDevice}=="0111"
    ATTRS{bDeviceClass}=="09"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{bDeviceProtocol}=="01"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{bMaxPacketSize0}=="64"
    ATTRS{speed}=="480"
    ATTRS{busnum}=="1"
    ATTRS{devnum}=="2"
    ATTRS{devpath}=="1"
    ATTRS{version}==" 2.00"
    ATTRS{maxchild}=="4"
    ATTRS{quirks}=="0x0"
    ATTRS{avoid_reset_quirk}=="0"
    ATTRS{authorized}=="1"
    ATTRS{product}=="USB 2.0 Hub"

  looking at parent device '/devices/platform/orion-ehci.0/usb1':
    KERNELS=="usb1"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{configuration}==""
    ATTRS{bNumInterfaces}==" 1"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bmAttributes}=="e0"
    ATTRS{bMaxPower}=="  0mA"
    ATTRS{urbnum}=="24"
    ATTRS{idVendor}=="1d6b"
    ATTRS{idProduct}=="0002"
    ATTRS{bcdDevice}=="0206"
    ATTRS{bDeviceClass}=="09"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{bDeviceProtocol}=="01"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{bMaxPacketSize0}=="64"
    ATTRS{speed}=="480"
    ATTRS{busnum}=="1"
    ATTRS{devnum}=="1"
    ATTRS{devpath}=="0"
    ATTRS{version}==" 2.00"
    ATTRS{maxchild}=="1"
    ATTRS{quirks}=="0x0"
    ATTRS{avoid_reset_quirk}=="0"
    ATTRS{authorized}=="1"
    ATTRS{manufacturer}=="Linux 2.6.38.8 ehci_hcd"
    ATTRS{product}=="Marvell Orion EHCI"
    ATTRS{serial}=="orion-ehci.0"
    ATTRS{authorized_default}=="1"

  looking at parent device '/devices/platform/orion-ehci.0':
    KERNELS=="orion-ehci.0"
    SUBSYSTEMS=="platform"
    DRIVERS=="orion-ehci"
    ATTRS{modalias}=="platform:orion-ehci"

  looking at parent device '/devices/platform':
    KERNELS=="platform"
    SUBSYSTEMS==""
    DRIVERS==""

我一直在尝试编写udev规则来强制USB记忆棒取这个名字,/dev/usbstick但是到目前为止我还没有成功。

有人可以帮我解决我需要在规则文件中指定的规则,以使该USB记忆棒始终获得相同的名称吗?

-或者,有没有更简单的方法可以自动挂载我完全丢失的USB记忆棒?

更新

好,所以我取得了一些进展。我添加了以下规则:

SUBSYSTEMS=="scsi", ATTRS{model}=="Flash Disk ", DRIVERS=="sd", NAME="usbstick-%k" RUN+="mkdir /mnt/usbstick-%k; mount /dev/usbstick-%k /mnt/usbstick-%k"

我知道在处理添加/删除方面仍然需要做一些工作,但这只是目前的基本测试。

这样做的效果是,我现在管理获得三个新的设备节点/dev,即/dev/usbstick-sdc/dev/usbstick-sdc1usbstick-sg2

但是,我发现该RUN部分中的代码仅执行一次,仅创建一个目录mnt/usbstick-sdc。我还发现该目录始终为空,因此显然还是有问题!(尽管我正在进步)。


/dev/sdc1应该是那一秒sdd1吗?您可以blkid用来唯一地标识驱动器(实际上是分区;如果重新格式化,它将改变)。
凯文

正确,只是解决了。我要发生的是,当插入USB记忆棒时,它会挂载到某个目录中。我很确定我应该使用udev规则为每个分区创建设备节点,但是我不确定要为哪个级别的udevadm输出制定规则!
jon

您的规则看起来太复杂了。尝试制作一个只有一个ACTION==,一个KERNEL==和一个的简单对象ATTRS{something}==(这是完全可行的-这就是我所使用的)。另外,请考虑运行单个脚本,而不是中的命令链RUN+=
rozcietrzewiacz 2011年

感谢您的建议,但问题仍然存在:我应将规则定位到设备树的哪个级别?这一切似乎非常令人困惑,而且在线上确实没有太多信息可以解释这一点。到目前为止,我非常感谢您花时间向我解释一下,我觉得我已经快到了,但只是错过了要定位的级别。
jon

我现在尝试了一个非常基本的规则:KERNEL=="sd??", NAME="%k", RUN+="mkdir /mnt/usbstick-%k; mount /dev/usbstick-%k /mnt/usbstick-%k"-但是,当然,这也不起作用。在花了整整一天时间试图解决如何插入可自我安装的USB记忆棒之后,我现在变得越来越沮丧。事情真的应该这么困难吗?udevadm test /sys/block/sdd当然- 的输出几乎是不可读的,因此我无法知道我要去哪里。有人可以为此指出正确的方向吗?
jon

Answers:


13

认为应该有一种更简单的方法来解决这种常见问题,并且确实存在。这是我在wheezy / sid服务器上尝试的方法:

sudo apt-get install usbmount

插入USB记忆棒,完成!现在可以通过访问我的棍子/media/usb

顺便说一句,usbmount没有手册页,请改为阅读/usr/share/doc/usbmount/README.gz。似乎usbmount默认情况下会使用sync选项挂载您的棍子。对于您的棍子,将其异步安装并运行syncumount在拔出它之前可能要好得多。那是可配置的。


另请参见pumount
Alex

请注意,usbmount自从debian jessie以来,不再支持NTFS:bugs.debian.org/774149
malat 2015年

在Debian Jessie上运行它,usbmount似乎从未安装过它。软件包页面说它现在不需要维护,我正在运行systemd。我想知道这个软件包是否不再适用于systemd更改?
Travis Griggs

确实,在杰西(Jessie)上对我不起作用,请参见我的回答(this:ddumont.wordpress.com/2015/09/27/…确实起作用)
保罗

2

请注意,您不能仅仅拥有一个设备节点来代表任何可能的笔式驱动器。如果您插入其中两个怎么办?或Pendrive具有多个分区时?

通常,用于创建自定义名称的设备节点的是SYMLINK+=。使用grep查看规则中的用法:grep SYMLINK /etc/udev/rules.d/*。与所有udev触发的命令一样,您可以使用中描述的一些有意义的变量man udev。您可能会意识到实际上并不需要为设备指定自定义名称,因为您可以将其名称输入脚本(通过%k变量)。

至于自动安装解决方案,请看一下UAM,我已经在回答这个问题中做了一些描述。


我了解这些限制。碰巧的是,我只需要支持一次随时连接到该特定系统的单个USB记忆棒。但是,我需要在USB记忆棒上支持多个分区(如果可以将这些分区从安装点安装到子文件夹中,那就太好了)。鉴于这些要求,您对潜在解决方案有何建议?由于项目的性质,如果可能的话,我需要避免使用其他第三方软件。
jon

然后看一下我刚刚进行的编辑(中间部分)。这样够了吗?
rozcietrzewiacz 2011年

另请注意,UAM并不是真正的程序-它是udev带有附带脚本的一堆不错的规则。您可以查看规则,并轻松地将其适应您的需求。
rozcietrzewiacz

谢谢你的建议。另一件事:您认为您可以查看我的输出udevadm并告诉我该设备实际上是我应该根据规则定位的设备吗?我在网上看到的各种示例似乎都包含较短的树,并且每个示例似乎都针对不同级别的设备,而没有说明应该针对哪个设备以及为什么。
jon

刚刚在上面添加了更新,有什么想法吗?谢谢!
jon

2

这是我最近的操作方式,现在我对这种方法感到非常满意。这适用于Ubuntu 12.04 + Gentoo,但我想任何发行版都可以安装udev和autofs。

先决条件:您必须已安装udev + autofs。

第1步)

创建以下“ /etc/udev/rules.d/90-usbsd-auto.rules”文件(当然,您可以使用任何以“ .rules”结尾的名称)。:

# Add symlink /dev/usbdisks/<label> to /dev/sd[a-z][1-9] 
# for automounter support

ACTION=="add", KERNEL=="sd*", ENV{DEVTYPE}=="partition", \
    ENV{ID_BUS}=="usb", \
    SYMLINK+="usbdisks/%k", MODE:="0660", \
    RUN+="/bin/rm /media/usb/%k", \
    RUN+="/bin/ln -sf /media/autousb/%k /media/usb/%k"

# Some FileSystems emit a "change" event when they are unmounted.
# UDEV seems to delete the device symlink in this case :-(
# So we need to re-create it here
ACTION=="change", KERNEL=="sd*", ENV{DEVTYPE}=="partition", \
    ENV{ID_BUS}=="usb", \
    SYMLINK+="usbdisks/%k", MODE:="0660"


# When device is removed, also remove /media/usb/<...>
ACTION=="remove", KERNEL=="sd*", ENV{DEVTYPE}=="partition", \
    ENV{ID_BUS}=="usb", \
    RUN+="/bin/rm /media/usb/%k"

这是做什么的:它创建两个符号链接,一个符号链接用于“ / dev / usbdisks / <...>”下的USB存储设备分区。

第二个符号链接将从“ / media / usb / <...>”链接到“ / media / autousb / <...>”,以实现自动安装程序支持(请参阅步骤2)。

为了确保udev读取这些规则,请使用

sudo udevadm control --reload-rules

注意:同一USB棒的名称相同:可能但可能很危险:例如,您可以使用“ $ env {ID_FS_LABEL_ENC}”,而不是上述UDEV规则中的“%k”。这将使用卷标创建/ media / usb / <...>,但是如果您插入两个USB记忆棒并且都使用相同的卷标会发生什么情况...

使用此udev规则文件,所有内容均已设置为自动挂载USB存储设备分区。请注意,虽然现在不会自动安装设备(有意)。一旦与

第2步)

设置autofs以自动挂载/ media / autousb / <...>:我在“ /etc/auto.master”文件中添加了以下行(对于Ubuntu 12.04):

/media/autousb /etc/auto.usb --timeout=60

这意味着60秒不活动后,AutoFS将卸载设备。您可能要根据自己的口味少用或多用。

对于Gentoo,您必须修改“ /etc/autofs/auto.master”,因此使用起来很有意义

/media/autousb /etc/autofs/auto.usb --timeout=60

现在,我创建了具有以下内容的“ auto.usb”:

#!/bin/bash

key=${1}
fstype=$(/sbin/blkid -o value -s TYPE /dev/usbdisks/${key})
if [ "${fstype}" = "vfat" ] ; then
  echo "-fstype=vfat,sync,uid=0,gid=plugdev,umask=007 :/dev/usbdisks/${key}"
  exit 0
fi
if [ "${fstype}" = "ntfs" ] ; then
  echo "-fstype=fuse.ntfs-3g,sync,uid=0,gid=plugdev,umask=007 :/dev/usbdisks/${key}"
  exit 0
fi
if [ "${fstype}" = "ext4" ] ; then
  echo "-fstype=ext4,sync,nocheck :/dev/usbdisks/${key}"
  exit 0
fi

exit 1

该auto.usb需要是可执行的,因此autofs将此用作(bash)脚本。所以举个例子

sudo chmod 0755 /etc/auto.usb

这是做什么的:该脚本将告诉AutoFS(/ usr / sbin / automount)如何挂载USB存储设备分区。

该脚本将首先使用“ / sbin / blkid”来查找分区上的文件系统类型。

然后,脚本将根据设备分区提供正确的安装选项。

注意:我提供了“ vfat”(可能是USB记忆棒最常见),“ ntfs”和“ ext4”文件系统的示例代码。当然,扩展它以支持更多文件系统是很容易的。

第三步

可选...要“弹出” ==卸载USB存储棒(或USB存储棒上的分区),请在/ sbin / usbeject下创建一个脚本:

#!/bin/bash
# make sure everything is written to USB disk(s)
sync
# sending SIUGSR1 to automount will unmount the media
killall -s SIGUSR1 /usr/sbin/automount

使用此脚本,您可以使用“ sudo usbeject”来卸载所有已安装的USB设备分区(通过告诉automount卸载它们)。

当然,您可以简单地确保该分区没有在任何地方使用。60秒超时后,自动挂载程序将卸载该分区...

真正的窍门是使用从“ / media / usb”到“ / media / autousb”的符号链接:

  • “ / media / usb”符号链接将由udev创建,为用户提供了一个简单的概览,其中列出了哪些USB存储设备分区
  • 如果您通过/ media / usb使用分区,则AutoFS将根据需要自动挂载该分区
  • 使用脚本化的“ auto.usb”文件,您可以支持任何类型的文件系统,此外,您还可以支持任何种类的命名方案。
  • 即使这些分区使用不同的文件系统类型,此方法也支持具有多个分区的USB记忆棒。

我可以告诉您autofs提示如何破坏我的/ home / frank目录吗?谢谢。
弗兰克,

1

很抱歉回答我自己的问题,非常感谢rozcietrzewiacz做出的贡献,但经过数小时的在线阅读,我终于设法使用以下规则取得了一些重大进展:

SUBSYSTEMS=="scsi", KERNEL=="sd[a-h]1", SYMLINK+="removable", RUN+="/bin/mount /dev/removable /path/to/mount"

这将挂载任何SCSI设备的第一个分区。我想下一个问题将是如何挂载多个分区,但这又是另一天的问题。


1
这不是一个好规则。这也将匹配硬盘驱动器的分区。有一个removable您应该测试的属性,而block不是scsi
rozcietrzewiacz

1

我发现最好的答案实际上已被弃用,因为它没有得到维护,也无法在杰西身上使用(请参见malat的评论)

对我(在Jessie上)而言,此博客中的解决方案就像一个魅力。

归功于“ ddumont”,但在此处发布了他的博客/答案的概述,以应对将来可能发生的链接腐烂。

将以下行添加到 /etc/fstab

/dev/sr0 /media/bluray auto defaults,nofail,x-systemd.automount 0 2

您可以使用nano来做到这一点:

sudo nano /etc/fstab

说明:

/dev/sr0是设备文件。您还可以使用udev在/ dev / disk / by-id中设置的符号链接之一。您将必须根据设备文件进行更改(sudo fdisk -l以列出设备)

/media/bluray是安装点。您可以选择另一个安装点

nofail 在光盘驱动器中没有光盘引导时需要使用它来避免失败报告

x-systemd.automount 是将systemd配置为自动装入插入的光盘的选项

不要指定noauto:这将阻止systemd自动装入光盘,这将使目的无效。

测试

journalctl -x -f在终端中运行命令以检查systemd发生了什么

使用重新加载systemd配置sudo systemctl daemon-reload

将光盘放入光驱

然后,journalctl应该显示如下内容:

Sept. 27 16:07:01 frodo systemd[1]: Mounted /media/bluray.

进一步

要成功安装NTFS驱动器,我必须安装ntfs-3g(旧的ntfsprogs)

sudo apt-get install ntfs-3g

我不必安装hfsprogs即可使OSX格式的USB正常工作,但您应该自己进行检查。


它不会通过USB-HDD自动安装在我的Debian jessie上。
buhtz

@buhtz,但是手动安装是否有效?上面的步骤实际上仅对启动时系统中的驱动器有效,而不能在系统运行时“动态”插入和移除USB。
Paul
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.