linux的2.6核心有了sysfs,可以通過這個檔案系統得到系統裝置的一些屬性,作為使用sysfs的一個例子,我們可以修改initrd的init腳本,使得它可以根據磁盤的屬性而不是bootloader中kernel的root參數來尋找并挂載root,傳統中都是根據root=/dev/sdXy(hdXy)來挂載根的,寫下這個sdXy或者hdXy需要使用者對linux的磁盤命名很了解,一旦hda變成了hdb1(很容易發生,比如跳線或者換了主機闆或者磁盤插錯了槽),很多人就不知所措了,我們更需要一種人性化的方式,比如root=seagate/usb等等來尋找并挂載root,有了sysfs,這些都可以在initrd的init腳本中做到。以下是基本的sh1腳本(或者寫成一個腳本函數也行):
sh1:
mount -t sysfs sys /sys
for DISK in `ls /sys/block/|grep $pref`; do #pref為磁盤字首,比如hd為ide磁盤,sd為scsi磁盤
disk=`cat /sys/block/$DISK/device/model`
if [ -n "$disk" ]; then
if [ "${disk:0:12}" = "$type" ]; then #type為磁盤類型,比如cf卡,dom等
maj=`cat /sys/block/sda/dev|awk -F : '{print $1}'`
min=$((`cat /sys/block/sda/dev|awk -F : '{print $2}'`+1)) #預設是第一個分區,當然可以在此加以判斷尋找任意分區。
mknod /dev2/device1 b $maj $min #尋找到了裝置号,建立裝置
mount -t ext3 /dev2/device1 /mnt #挂載剛建立的裝置,後面我們直接chroot到/mnt,然後exec(sbin/init)即可
if [ "$?" -eq 0 ]; then #成功
flag="found" #設定标志
rm -f /mnt/dev/root #删除建立的裝置
mknod /mnt/dev/root b $maj $min #建立根檔案系統中的裝置,用于mount時的顯式(/etc/fstab中寫/dev/root)
break #跳出循環
else
echo "not found" #測試
fi
else
echo BianFen #測試“扁粉菜”
fi
fi
done
可以在initrd的init腳本中實作一個基于優先級的挂載序列,類似bios中設定啟動順序的那樣,比如可以設定usb,dom卡,cf卡,sata磁盤為挂載為根的順序,在init腳本中首先通過sh1尋找usb裝置,如果找到直接将之挂為root,如果找不到則繼續調用sh1尋找dom,依次類推。這樣的話,即使事先不知道磁盤是hd的還是sd的,又不知道是hda1還是hdb1的情況下,隻要我們隻知道磁盤的一些特性(在sh1這個例子中我們使用model特性,也可以周遊device目錄比對任意屬性,當然sh1的代碼需要更複雜一些,這裡僅僅給出思想)。
為何要修改initrd,因為很多場景都需要一份grub配置檔案在多台不同機器上都能用,而這些機器的磁盤引線可能不同,比如有的機器上磁盤在hda1,而另外一些機器上就成了hdb1,這樣就需要修改grub配置中kernel的root參數了,或者通過硬體跳線來解決,為了不做這些煩人的動作,索性搞一個自适應的initrd,而我們所做的僅僅是知道一些磁盤的内秉屬性即可,比如一塊西部資料的磁盤作為hda和hdb時都是這個牌子,不會變的,不會因機器主機闆的變化而變化。
本文轉自 dog250 51CTO部落格,原文連結:http://blog.51cto.com/dog250/1271085