天天看點

linux根據磁盤的屬性挂載root

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