轻松的优盘备份
如果你曾经丢失(或担心会丢失)USB 优盘,请举手。你花了数小时徒劳地在家中搜索,然后当你打开洗衣机门时,你突然意识到也许你把这批衣物放进去时没有彻底检查你的口袋。
幸运的是,你备份了所有数据,对吧?你定期挂载驱动器并将数据复制到备份目录,不是吗?
这听起来对我来说也很像苦差事,我进入计算机行业是为了避免枯燥的工作。自然,花一些时间研究出完美的轻松优盘备份方法会更有趣。
我说的轻松是什么意思?一个系统,你可以走到你的 Linux 机器前,插入驱动器,等待“备份完成”的声音,拔下插头然后走开?也许是一个保持备份有序的系统(例如,最近的七个副本)?哦,它还应该处理加密的优盘。而且,如果你需要恢复,它应该同时进行整卷替换和逐文件恢复。
没问题。这个系统的关键是使用 udev 规则和一个简单的 shell 脚本。这些工具已经存在于你的系统中。在本例中,我使用 CentOS 4.3 系统,尽管任何带有 2.6 内核的 Linux 发行版都应该可以工作。
udev 是 Linux 的现代设备管理器,取代了 2.4 内核的 devfs。udev 处理所有设备映射,包括设备的热插拔。它最酷的功能之一是它允许你编写自己的事件规则。本文将向你展示如何制作一个规则,该规则在你将 USB 优盘插入系统时自动触发。
这些规则存储在 /etc/udev/rules.d 中(如果你使用的是不同的 Linux 发行版,请检查 /etc/udev/udev.conf 中的 udev_rules= 行,该行应指向规则目录)。你可以将任何你想要的 udev 规则作为文本文件放在此目录中,udev 会立即拾取它们以供使用,而无需重新启动。
要编写 udev 事件规则,你首先需要一种唯一的方式来识别 USB 设备。大多数优盘都有序列号,但并非全部都有。幸运的是,即使对于没有序列号的优盘,你也可以为它们制作 udev 规则。
我使用两个优盘作为示例:一个使用 TrueCrypt 加密的 JetFlash JF110 和一个 Corsair Flash Voyager。JetFlash 有一个序列号;Corsair 没有。
插入你的优盘,然后cat /proc/scsi/usb-storage/*。你应该找到一个类似于此的条目
Host scsi5: usb-storage Vendor: Unknown Product: USB Mass Storage Device Serial Number: 85a5b1f2c96492 Protocol: Transparent SCSI Transport: Bulk Quirks:
如果你有序列号,请跳到本文的“编写规则”部分。如果你看到序列号为“None”,你仍然可以使用 udevinfo 识别设备。按照以下步骤操作
1) 查看 dmesg 的输出。典型的输出如下
usb-storage: waiting for device to settle before scanning Vendor: Corsair Model: Flash Voyager Rev: 1.00 Type: Direct-Access ANSI SCSI SCSI device sde: 2031616 512-byte hdwr sectors (1040 MB) [...] sde: assuming drive cache: write through sde: sde1 Attached scsi removable disk sde at scsi12, channel 0, id 0, lun 0 Attached scsi generic sg4 at scsi12, channel 0, id 0, lun 0, type 0
这告诉你 /dev/sde 是分配的设备。
2) 现在,运行
udevinfo -a -p $(udevinfo -q path -n /dev/sde)
现在,使用序列号或供应商/型号组合,你可以编写规则。该规则在 /dev 树中为设备创建一个符号链接,例如 /dev/corsair_drive,然后调用脚本 /usr/local/bin/backup-thumb.sh,我稍后会介绍它。
成为 root 用户(su -),并在 /etc/udev/rules.d 中创建一个名为 95.backup.rules 的文本文件。你可以使用 95 以外的数字,但请记住,udev 按字母数字顺序处理规则,最好最后处理本地规则。
如果你有序列号,请在文件中输入如下规则(全部在一行中),然后保存它
BUS="usb", SYSFS{serial}="85a5b1f2c96492", SYMLINK="jet_drive", RUN+="/usr/local/bin/backup-thumb.sh jet_drive "
如果你使用供应商/型号识别,你的规则将如下所示
BUS="scsi", SYSFS{vendor}=="Corsair ", SYSFS{model}=="Flash Voyager ", SYMLINK="corsair_drive", RUN+="/usr/local/bin/backup-thumb.sh corsair_drive"
请注意,你可以根据需要将尽可能多的 SYSFS{} 条目串在一起,以唯一地识别驱动器。你的规则现在在你每次插入优盘时都会触发。
注意:如果你的设备有其他规则,udev 会按顺序从上到下执行规则。
backup-thumb.sh 是备份你的优盘的引擎。我们的规则调用它,将设备名称 (SYMLINK) 作为其唯一参数给出。所有其他内容都在 CONFIG 部分配置。备份脚本如清单 1 所示。
清单 1. 备份脚本
#!/bin/bash # Thumbdrive backup script from <citetitle>Linux Journal</citetitle> # ############################################## # CONFIG section # where you want the backups to be kept BACKUP_DIR=/backups/thumb # how many old backups to keep GENERATIONS=7 # backup only once a day # set to 0 if you want a backup run every time # you insert your thumbdrive BACKUP_ONCE_DAY=1 # completion sound to play when backup is done SOUND=/usr/share/sounds/KDE_Beep_ClockChime.wav # END CONFIG # ############################################## # main program # wait for device to settle sleep 10 # make sure no one will be able to copy our backups umask 077 # check the directory DEVICE=$1 if [ ! -d ${BACKUP_DIR} ] ; then mkdir -p ${BACKUP_DIR} fi # only backup once per day if [ ${BACKUP_ONCE_DAY} -gt 0 ] ; then DIDTODAY=${BACKUP_DIR}/${DEVICE}.did_today find ${BACKUP_DIR} -name ${DEVICE}.did_today -a -mtime +1 -delete if [ -f ${DIDTODAY} ] ; then exit else touch ${DIDTODAY} fi fi # rotate backups cd ${BACKUP_DIR} let GENERATIONS=${GENERATIONS}-1 while [ ${GENERATIONS} -ge 0 ] ; do let NEWFILE=${GENERATIONS}+1 if [ -f ${DEVICE}.backup.${GENERATIONS} ] ; then mv -f ${DEVICE}.backup.${GENERATIONS} ${DEVICE}.backup.${NEWFILE} fi let GENERATIONS=${GENERATIONS}-1 done # do the backup dd if=/dev/${DEVICE} of=${BACKUP_DIR}/${DEVICE}.backup.0 > /dev/null 2>&1 # notify that we're done aplay ${SOUND} > /dev/null 2>&1
将此脚本放在 /usr/local/bin/backup-thumb.sh 中,并记住chmod +x它。接下来,编辑 CONFIG 部分——参数如下
BACKUP_DIR:你希望备份去的地方。
GENERATIONS:要保留多少天的备份。备份将编号为 0(最近)到你输入的限制(最旧)。请记住,你需要有足够的存储空间来存储这么多备份。如果你要备份一个 1GB 的优盘并将 GENERATIONS 设置为 7,则备份将占用 7GB 的空间。
BACKUP_ONCE_DAY:如果你一天多次插拔你的优盘,你可能不希望每次都备份它。backup-thumb.sh 使用标记文件,以便它每天只备份一次。如果你想更改此设置,以便在你每次插入优盘时都运行备份,请将 BACKUP_ONCE_DAY 设置为 0。
SOUND:在本例中,我选择了 KDE 发行版的声音,但任何 WAV 文件都可以工作。你可以轻松修改脚本以使用 madplay 而不是 aplay,并使用 MP3 文件作为完成声音。
backup-thumb.sh 在启动时休眠十秒钟,因为它必须等待内核完成扫描优盘。如果你插入优盘并输入dmesg,你会看到一条“waiting for device to settle”消息,此时会发生这种情况。即使对于较旧的机器,内核扫描的十秒钟也应该足够了。
接下来,backup-thumb.sh 严格设置权限,以便只有 root 用户才能读取备份。否则,一些不怀好意的人可能会将你的备份复制到另一台机器并在那里挂载它。
该脚本对你的优盘执行简单的 dd(逐位复制)到备份文件。无论设备是否加密,这都有效。完成后,它会播放一个你会在计算机扬声器上听到的声音。在 USB 2.0 端口上,备份 1GB 的优盘大约需要一分钟。
如果你丢失了你的优盘并想将你的备份恢复到它的替代品,只需像这样将备份映像 dd 到新的优盘即可
dd if=corsair_drive.backup.0 of=/dev/corsair_drive
或者,如果你只想从备份中获取一些文件,请执行以下操作
mkdir /mnt/thumb mount -o loop corsair_drive.backup.0 /mnt/thumb
你现在可以从 /mnt/thumb 复制文件。
如果你使用 TrueCrypt 加密你的优盘,你可以以大致相同的方式挂载备份映像
truecrypt corsair_drive.backup.0 /mnt/thumb/
这已经是我们能做到的最轻松的优盘备份了。如果你懒得插入你的驱动器并在它发出哔哔声时回来...好吧,远离自助洗衣店!
本文仅触及了你可以使用 udev 规则执行的操作的表面。任何类型的热插拔事件都可以触发一个规则,该规则几乎可以执行任何操作。例如,你可以编写规则来自动挂载设备、从数码相机复制图片或设置网络链接。udev 的规则语言提供了极大的灵活性,包括类似 printf 的通配符和设置权限的能力。
编写你自己的 udev 规则的最佳概述是 Daniel Drake 的“Writing udev Rules”,可以在 www.reactivated.net/writing_udev_rules.html 找到。
Andrew Fabbro 已成为 Oracle DBA;但是,他仍然在家中拥有 root 权限,他欢迎你将评论发送至 andrew@fabbro.org。