- Ubuntu Server 11.10 için not: Bu komut, kullanılmayan
vol_id
komut nedeniyle Ubuntu Server 11.10'da başarısız olur . vol_id
tarafından yerini aldı blkid
. Komut dosyasını düzeltmek için komut dosyasında "vol_id" yerine "blkid -o udev" yazın udev-auto-mount.sh
.
Bir süredir bu konuda kafamı çarpıyordum ve sanırım çalışan bir çözüm buldum. Bu, Debian tabanlı bir sistemde geliştirilmiş ve test edilmiştir, bu nedenle Ubuntu üzerinde çalışmalıdır. Diğer varsayımlara da uyarlanabilmesi için yaptığı varsayımlara dikkat çekeceğim.
- USB sürücülerini otomatik olarak eklentiye bağlar ve Firewire'a uyum sağlamak için fazla zaman harcamamalıdır.
- UDEV kullanır, bu yüzden HAL / DeviceKit / GNOME-Anything ile karışmaz.
/media/LABEL
Cihazı otomatik olarak bağlamak için bir dizin oluşturur .
- Bununla birlikte, diğer otomatik sayaçlarla etkileşime girebilir ; Bunun için test edemiyorum. Gnome-VFS etkinken her ikisinin de bağlamayı deneyebileceğini düşünüyorum ... Gnome-VFS bağlantıyı kuramazsa, bir masaüstü simgesi yapılandırmayabilir. Gnome'dan sökme işlemi mümkün olmalı, ancak gerekli
gksudo
veya benzeri olabilir .
Bunu sistem önyüklemesinde test etmedim, ancak işe yaramadığını görebilmemin tek nedeni, sistem takılmaya hazır olmadan önce USB sürücüsünü takmaya çalışırsa. Bu durumda, büyük olasılıkla mount komut dosyasına bir ek ince ayar yapmanız gerekir. ( Herhangi bir tavsiye olup olmadığını görmek için ServerFault ile kontrol ediyorum , ancak bu konuda çok fazla ilgi duymadım .)
Bunun üzerine, o zaman.
UDEV referansları:
Arkaplan (UDEV? Whuzzat?)
UDEV, çekirdeğin hotplug sistemidir. /dev/disk/by-label/<LABEL>
Hem önyükleme sırasında hem de sistem çalışırken eklenen cihazlar için uygun cihazları ve cihaz işaretlerini (örn. ) Otomatik olarak yapılandırır .
D-Bus ve HAL, Masaüstü Ortamları gibi dinleyicilere donanım olayları göndermek için kullanılır. Dolayısıyla, GNOME'da oturum açıp bir CD veya bir USB sürücüye taktığınızda, bu olay şu zinciri izler:
kernel -> udev -> dbus -> hal -> gnome-vfs/nautilus (mount)
Presto, sürücünüz monte edilir. Ancak başsız bir sistemde, otomatik sıralamadan faydalanmak için giriş yapmak zorunda değiliz.
Udev Kuralları
UDEV bize kurallar yazmamıza ve aygıtları yerleştirme programlarını çalıştırmamıza izin verdiğinden, bu ideal bir seçimdir. Debian / Ubuntu'nun mevcut kurallarından faydalanacağız, /dev/disk/by-label/<LABEL>
bize bağ kuracaklar ve cihazı bizim için monte edecek başka bir kural ekleyelim.
UDEV'in kuralları /etc/udev/rules.d
(ve Karmik'te) tutulur ve /lib/udev/rules.d
sayısal sırada işlenir. Numara ile başlamayan herhangi bir dosya, numaralandırılmış dosyalardan sonra işlenir. Sistemimde, HAL kuralları adı verilen bir dosyada 90-hal.rules
, bu yüzden de kurallarını koydum, böylece 89-local.rules
HAL'e ulaşmadan önce işlenmelerini sağladım. Öncelikle, bu kuralların bundan sonra olmasına dikkat etmeniz gerekir 60-persistent-storage.rules
. local.rules
yeterince iyi olabilir.
Bunu yeni kurallar dosyasına ekleyin:
# /etc/udev/rules.d/local.rules
# /etc/udev/rules.d/89-local.rules
# ADD rule: if we have a valid ID_FS_LABEL_ENC, and it's USB, mkdir and mount
ENV{ID_FS_LABEL_ENC}=="?*", ACTION=="add", SUBSYSTEMS=="usb", \
RUN+="/usr/local/sbin/udev-automounter.sh %k"
Bundan sonra boşluk olmadığından emin olun \
, sadece newline
( \n
).
Değişim SUBSYSTEMS=="usb"
için SUBSYSTEMS=="usb|ieee1394"
Firewire desteği için.
Aygıtın her zaman belirli bir kullanıcıya ait olmasını istiyorsanız, bir OWNER="username"
fıkra ekleyin . Sadece belirli bir kullanıcının sahip olduğu dosyalara ihtiyacınız varsa, bunun yerine mount komut dosyasını düzenleyin.
Kural Okuma
Bu, cihazın çalışacak programlar listesine çalıştırılacak bir program ekler. USB bölüm aygıtlarını tanımlar <LABEL>
, ardından bu bilgiyi montajı yapan bir komut dosyasına iletir. Özellikle, bu kural eşleşiyor:
ENV{ID_FS_LABEL_ENC}=="?*"
- önceki bir sistem kuralı tarafından ayarlanan bir ortam değişkeni. Dosya sistemi olmayanlar için mevcut değil, bu yüzden araştırıyoruz. Aslında ID_FS_LABEL
bağlama noktası için kullanmak istiyoruz , ancak UDEV'yi benim için kaçmaya ikna etmedim, bu yüzden mount komut dosyasının bunu yapmasına izin vereceğiz.
Bu ve diğer ortam değişkenleri udev tarafından vol_id
komut kullanılarak ( kullanımdan kaldırılmış ) elde edilir . Bir bölümdeki güzel hızlı ayrıntıları görmek için kullanışlı bir araçtır:
$ sudo vol_id /dev/sdc1
ID_FS_TYPE=ext2
ID_FS_UUID=a40d282a-4a24-4593-a0ab-6f2600f920dd
ID_FS_LABEL=Travel Dawgs
ID_FS_LABEL_ENC=Travel\x20Dawgs
ID_FS_LABEL_SAFE=Travel_Dawgs
ACTION=="add"
- sadece maç add
etkinlikleri ...
SUBSYSTEMS=="usb"
- sadece USB veri yolu üzerindeki cihazlarla eşleşin. Burada kullanıyoruz, SUBSYSTEMS
çünkü bu cihazımızın ebeveynleriyle eşleşiyor; İlgilendiğimiz cihaz aslında SUBSYSTEM == "scsi" olacak. Bir ana USB cihazıyla eşleştirmek, programımızı dahili sürücülere eklemekten kaçınır.
RUN+="..."
- eşleşme değil, eylem: bu programı çalıştırılacak programlar listesine ekleyin. Programın argümanlarında, %k
cihaz adına genişletilir (örn sdc1
. Değil /dev/sdc1
) ve $env{FOO}
FOO ortam değişkeninin içeriğini alır.
Kural Testi
İlk referans bağlantısı (yukarıdaki) mükemmel bir UDEV dersidir, ancak biraz güncel değildir. Kurallarınızı sınamak için çalıştırdığı programlar ( udevtest
özellikle de), hepsini yakala udevadm
yardımcı program tarafından değiştirildi .
Kuralı ekledikten sonra cihazınızı takın. Birkaç saniye verin, ardından hangi cihaza atandığını görmek için kontrol edin:
$ ls -l /dev/disk/by-label/*
lrwxrwxrwx 1 root root 10 2009-10-25 07:27 label_Foo -> ../../sda1
lrwxrwxrwx 1 root root 10 2009-10-25 07:27 label_Bar -> ../../sdb1
lrwxrwxrwx 1 root root 10 2009-10-25 07:27 label_Baz -> ../../sdc1
Çıkarılabilir sürücünüz içeriyorsa label_Baz
, aygıtta bulunur sdc1
. Bunu çalıştırın ve çıktının sonuna doğru bakın:
$ sudo udevadm test /sys/block/sdc/sdc1
parse_file: reading (...) (many lines about files it reads)
import_uevent_var: import into environment: (...) (many lines about env variables)
(...) (many lines tracing rule matches & programs run)
update_link: found 1 devices with name 'disk/by-label/LABEL_BAZ'
update_link: found '/block/sdc/sdc1' for 'disk/by-label/LABEL_BAZ'
update_link: compare (our own) priority of '/block/sdc/sdc1' 0 >= 0
update_link: 'disk/by-label/LABEL_BAZ' with target 'sdc1' has the highest priority 0, create it
udevtest: run: '/usr/local/sbin/udev-automounter.sh sdc1 LABEL_BAZ'
udevtest: run: 'socket:/org/freedesktop/hal/udev_event'
udevtest: run: 'socket:@/org/kernel/udev/monitor'
RUN+=
Son birkaç satırdaki kuralımızın kod adını arayın (bu örnekte alttan 3.). Bu cihaz için kullanılacak argümanları görebilirsiniz. Argümanların sağlam olduğunu kontrol etmek için şimdi bu komutu çalıştırabilirsiniz; Komut satırınızda çalışıyorsa, bir cihaz takıldığında otomatik olarak çalışması gerekir.
UDEV olaylarını gerçek zamanlı olarak da izleyebilirsiniz: run sudo udevadm monitor
( man udevadm
anahtarlarla ilgili detaylar için bakınız). Ardından, yeni bir cihaz takın ve olayların yan yana geldiğini izleyin. (Gerçekten düşük seviyeli ayrıntılara girmediğiniz sürece büyük olasılıkla overkill ...)
Kuralların Yeniden Yüklenmesi
Kuralın doğru bir şekilde okunduğunu doğruladıktan sonra, yeni kuralın yürürlüğe girmesi için UDEV'ye kurallarını yeniden yüklemesini söylemeniz gerekir. Bu yöntemlerden herhangi birini kullanın (ilk işe yaramazsa, ikincisi gerekir ... ama ilkini deneyin):
Senaryo! Aslında, 2 Script ...
İşte ilk senaryo. Çalıştırdığımız programın hızlı bir şekilde tamamlanması gerektiğinden, bu sadece arka plandaki ikinci yazıyı döndürür. Bunu içine koy /usr/local/sbin/udev-automounter.sh
:
#!/bin/sh
#
# USAGE: usb-automounter.sh DEVICE
# DEVICE is the actual device node at /dev/DEVICE
/usr/local/sbin/udev-auto-mount.sh ${1} &
İşte ikinci senaryo. Bu biraz daha fazla giriş kontrolü yapar. Bunu içine koy /usr/local/sbin/udev-auto-mount.sh
. Aşağıdaki montaj seçeneklerini değiştirmek isteyebilirsiniz. Bu senaryo şimdi LABEL bölümünü kendi başına bulmayı ele alıyor; UDEV sadece CİHAZ adını gönderir.
Sürücüleri önyükleme sırasında takmakta bir sorun varsasleep 60
, komut dosyası sürücüyü monte etmeyi denemeden önce sisteme sonuna kadar gelmesi için uzun süre bu komut dosyasında uzun süre kullanabilirsiniz.
Nasıl kontrol edileceğine ( ps
bir web sunucusunun çalışıp çalışmadığını görmek için çalıştırın) yorumlarda bir öneride bulundum , ancak bunu sisteminiz için ince ayar yapmak isteyeceksiniz. Kullanmakta olduğunuz herhangi bir ağ sunucusunun bu amaç için yeterli olacağını düşünüyorum - nfsd, smbd, apache, vb. Tabii ki, hizmetin çalışmadığı durumda elbette mount komut dosyasının başarısız olması riskidir; belirli bir dosyanın varlığı daha iyi bir çözüm olacaktır.
#!/bin/sh
#
# USAGE: udev-auto-mount.sh DEVICE
# DEVICE is the actual device node at /dev/DEVICE
#
# This script takes a device name, looks up the partition label and
# type, creates /media/LABEL and mounts the partition. Mount options
# are hard-coded below.
DEVICE=$1
# check input
if [ -z "$DEVICE" ]; then
exit 1
fi
# test that this device isn't already mounted
device_is_mounted=`grep ${DEVICE} /etc/mtab`
if [ -n "$device_is_mounted" ]; then
echo "error: seems /dev/${DEVICE} is already mounted"
exit 1
fi
# If there's a problem at boot-time, this is where we'd put
# some test to check that we're booting, and then run
# sleep 60
# so the system is ready for the mount below.
#
# An example to experiment with:
# Assume the system is "booted enough" if the HTTPD server is running.
# If it isn't, sleep for half a minute before checking again.
#
# The risk: if the server fails for some reason, this mount script
# will just keep waiting for it to show up. A better solution would
# be to check for some file that exists after the boot process is complete.
#
# HTTPD_UP=`ps -ax | grep httpd | grep -v grep`
# while [ -z "$HTTPD_UP" ]; do
# sleep 30
# HTTPD_UP=`ps -ax | grep httpd | grep -v grep`
# done
# pull in useful variables from vol_id, quote everything Just In Case
eval `/sbin/vol_id /dev/${DEVICE} | sed 's/^/export /; s/=/="/; s/$/"/'`
if [ -z "$ID_FS_LABEL" ] || [ -z "$ID_FS_TYPE" ]; then
echo "error: ID_FS_LABEL is empty! did vol_id break? tried /dev/${DEVICE}"
exit 1
fi
# test mountpoint - it shouldn't exist
if [ ! -e "/media/${ID_FS_LABEL}" ]; then
# make the mountpoint
mkdir "/media/${ID_FS_LABEL}"
# mount the device
#
# If expecting thumbdrives, you probably want
# mount -t auto -o sync,noatime [...]
#
# If drive is VFAT/NFTS, this mounts the filesystem such that all files
# are owned by a std user instead of by root. Change to your user's UID
# (listed in /etc/passwd). You may also want "gid=1000" and/or "umask=022", eg:
# mount -t auto -o uid=1000,gid=1000 [...]
#
#
case "$ID_FS_TYPE" in
vfat) mount -t vfat -o sync,noatime,uid=1000 /dev/${DEVICE} "/media/${ID_FS_LABEL}"
;;
# I like the locale setting for ntfs
ntfs) mount -t auto -o sync,noatime,uid=1000,locale=en_US.UTF-8 /dev/${DEVICE} "/media/${ID_FS_LABEL}"
;;
# ext2/3/4 don't like uid option
ext*) mount -t auto -o sync,noatime /dev/${DEVICE} "/media/${ID_FS_LABEL}"
;;
esac
# all done here, return successful
exit 0
fi
exit 1
Süper Bonus Temizleme Script!
Bir komut dosyası daha. Tüm bunlar cihazın bağlantısını kesmek ve bağlama noktası dizinlerini kaldırmaktır. Bunu yapmak için ayrıcalıkları olduğunu varsayar, bu nedenle çalıştırmanız gerekir sudo
. Bu komut dosyası şimdi komut satırında tam bağlama noktasını alır, örneğin:
$ /usr/local/sbin/udev-unmounter.sh "/media/My Random Disk"
Bunu içine koy /usr/local/sbin/udev-unmounter.sh
:
#!/bin/sh
#
# USAGE: udev-unmounter.sh MOUNTPT
# MOUNTPT is a mountpoint we want to unmount and delete.
MOUNTPT="$1"
if [ -z "$MOUNTPT" ]; then
exit 1
fi
# test mountpoint - it should exist
if [ -e "${MOUNTPT}" ]; then
# very naive; just run and pray
umount -l "${MOUNTPT}" && rmdir "${MOUNTPT}" && exit 0
echo "error: ${MOUNTPT} failed to unmount."
exit 1
fi
echo "error: ${MOUNTPT} does not exist"
exit 1