busybox實作了mdev來處理動態更新/dev, 這篇文章主要是mdev.txt心得記錄.
以下幾個範例是在init script做init的範例,
Here's a typical code snippet from the init script: [0] mount -t proc proc /proc [1] mount -t sysfs sysfs /sys [2] echo /sbin/mdev > /proc/sys/kernel/hotplug [3] mdev -s Alternatively, without procfs the above becomes: [1] mount -t sysfs sysfs /sys [2] sysctl -w kernel.hotplug=/sbin/mdev [3] mdev -s基本上不論如何都要先mount /sys才能開始做, mdev -s, 因為mdev主要就是靠讀取/sys/dev底下的資訊來建立相關的device node. 基本上kernel config要開CONFIG_UEVENT_HELPER才會有/proc/sys/kernel/hotplug (kernel.hotplug), 不過沒開就是在系統裝置異動時, 得自己手動執行mdev -s. 最後就是執行mdev -s建立相關的device node.
接著說明一下/etc/mdev.conf
The file has the format: [-][envmatch]<device regex> <uid>:<gid> <permissions> [envmatch]@<maj[,min1[-min2]]> <uid>:<gid> <permissions> $envvar=<regex> <uid>:<gid> <permissions> You can rename/move device nodes by using the next optional field. <device regex> <uid>:<gid> <permissions> [=path] For example: hd[a-z][0-9]* 0:3 660 Mdev has an optional config file for controlling ownership/permissions of device nodes if your system needs something more than the default root/root 660 permissions.
基本上mdev是採first match, 如果第一個rule比對成功, 就會套用該rule, 不然就往下一個去, 但是如果遇到"-"不論有沒有match, 都會往下一個去match去執行. 另外, 參數沒有給齊會用"0:0 600"當預設值.
下面的範例就是用"-"跟沒有"-"作範例, 可以看到"-"rule match, 也會繼續往下比
/ # cat /etc/mdev.conf -tty0 1:1 0660 @/x.sh 就算tty0 match這個rule, 也會繼續執行下一個 tty0 1:1 0660 @/y.sh tty1 1:1 0660 @/x.sh 如果tty1 match這個rule, 就會結束, 下一個就不會被執行了 tty1 1:1 0660 @/y.sh / # cat /x.sh #!/bin/sh -x # Redirect standard output to /dev/console exec 1>/dev/kmsg echo "start $0" env # Your script commands go here echo "end $0" / # cat /y.sh #!/bin/sh -x # Redirect standard output to /dev/console exec 1>/dev/kmsg echo "start $0" env # Your script commands go here echo "end $0" / # mdev -s + exec + echo 'start /x.sh' start /x.sh + env USER=root ACTION=add SHLVL=3 HOME=/ OLDPWD=/dev MDEV=tty0 第一次呼叫 TERM=vt102 SUBSYSTEM=tty PATH=/sbin:/usr/sbin:/bin:/usr/bin SHELL=/bin/sh PWD=/dev + echo 'end /x.sh' end /x.sh + exec + echo 'start /y.sh' start /y.sh + env USER=root ACTION=add SHLVL=3 HOME=/ OLDPWD=/dev MDEV=tty0 第二次呼叫 TERM=vt102 SUBSYSTEM=tty PATH=/sbin:/usr/sbin:/bin:/usr/bin SHELL=/bin/sh PWD=/dev + echo 'end /y.sh' end /y.sh + exec + echo 'start /x.sh' start /x.sh + env USER=root ACTION=add SHLVL=3 HOME=/ OLDPWD=/dev MDEV=tty1 一次呼叫 TERM=vt102 SUBSYSTEM=tty PATH=/sbin:/usr/sbin:/bin:/usr/bin SHELL=/bin/sh PWD=/dev + echo 'end /x.sh' end /x.sh
下一個範例是rename或者放到/dev底下的子目錄, 語法是<device regex> <uid>:<gid> <permissions> [=path], 而如果要產在在某個子目錄下, 就在後面多加"/".
/ # rm /dev/tty* 刪除所有tty檔案後重新透過mdev -s建立 / # ls /dev/ 確認tty檔案都被砍掉 console mmcblk0p2 ptyp5 urandom cpu_dma_latency mtd0 ptyp6 usbmon0 dri mtd0ro ptyp7 vcs fb0 mtd1 ptyp8 vcs1 full mtd1ro ptyp9 vcs2 gpiochip0 mtdblock0 ptypa vcsa gpiochip1 mtdblock1 ptypb vcsa1 gpiochip2 null ptypc vcsa2 gpiochip3 ptmx ptypd vcsu hwrng pts ptype vcsu1 input ptyp0 ptypf vcsu2 kmsg ptyp1 random zero mem ptyp2 rtc0 mmcblk0 ptyp3 snd mmcblk0p1 ptyp4 ubi_ctrl / # cat /etc/mdev.conf tty0 1:1 0660 =ttyBrook0 會把tty0 rename 成 ttyBrook0 tty.* 1:1 0660 =ttyBrook/ 把其他tty都建立在/dev/ttyBrook目錄下 / # mdev -s / # ls /dev/ console mmcblk0p2 ptyp5 ttyBrook0 cpu_dma_latency mtd0 ptyp6 ubi_ctrl dri mtd0ro ptyp7 urandom fb0 mtd1 ptyp8 usbmon0 full mtd1ro ptyp9 vcs gpiochip0 mtdblock0 ptypa vcs1 gpiochip1 mtdblock1 ptypb vcs2 gpiochip2 null ptypc vcsa gpiochip3 ptmx ptypd vcsa1 hwrng pts ptype vcsa2 input ptyp0 ptypf vcsu kmsg ptyp1 random vcsu1 mem ptyp2 rtc0 vcsu2 mmcblk0 ptyp3 snd zero mmcblk0p1 ptyp4 ttyBrook / # ls /dev/ttyBrook除了tty0其餘tty都在這子目錄下 tty tty19 tty29 tty39 tty49 tty59 ttyAMA2 ttyp9 tty1 tty2 tty3 tty4 tty5 tty6 ttyAMA3 ttypa tty10 tty20 tty30 tty40 tty50 tty60 ttyp0 ttypb tty11 tty21 tty31 tty41 tty51 tty61 ttyp1 ttypc tty12 tty22 tty32 tty42 tty52 tty62 ttyp2 ttypd tty13 tty23 tty33 tty43 tty53 tty63 ttyp3 ttype tty14 tty24 tty34 tty44 tty54 tty7 ttyp4 ttypf tty15 tty25 tty35 tty45 tty55 tty8 ttyp5 tty16 tty26 tty36 tty46 tty56 tty9 ttyp6 tty17 tty27 tty37 tty47 tty57 ttyAMA0 ttyp7 tty18 tty28 tty38 tty48 tty58 ttyAMA1 ttyp8
這個範例,是在最後一個欄位加上"!", 代表不創建該node, 語法是<device regex> <uid>:<gid> <permissions> [!] [@|$|*<command>], 下面只會建立tty0, 其餘的tty都不會被建立
/ # cat /etc/mdev.conf tty0 1:1 0660 =ttyBrook0 會把tty0 rename 成ttyBrook0 tty1 1:1 0660 ! @/x.sh 雖然不會建立tty1, 但是會去執行/x.sh tty.* 1:1 0660 ! 其餘的tty都不建立了 / # cat /x.sh #!/bin/sh -x # Redirect standard output to /dev/console exec 1>/dev/kmsg echo "start $0" env # Your script commands go here echo "end $0" / # rm -rf /dev/tty* / # ls /dev/ console mmcblk0p2 ptyp5 urandom cpu_dma_latency mtd0 ptyp6 usbmon0 dri mtd0ro ptyp7 vcs fb0 mtd1 ptyp8 vcs1 full mtd1ro ptyp9 vcs2 gpiochip0 mtdblock0 ptypa vcsa gpiochip1 mtdblock1 ptypb vcsa1 gpiochip2 null ptypc vcsa2 gpiochip3 ptmx ptypd vcsu hwrng pts ptype vcsu1 input ptyp0 ptypf vcsu2 kmsg ptyp1 random zero mem ptyp2 rtc0 mmcblk0 ptyp3 snd mmcblk0p1 ptyp4 ubi_ctrl / # mdev -s + exec + echo 'start /x.sh' start /x.sh + env USER=root ACTION=add SHLVL=3 HOME=/ OLDPWD=/dev MDEV=tty1 雖然不會建立tty1, 但是會去執行/x.sh TERM=vt102 SUBSYSTEM=tty PATH=/sbin:/usr/sbin:/bin:/usr/bin SHELL=/bin/sh PWD=/dev + echo 'end /x.sh' end /x.sh / # ls /dev/ console mmcblk0p2 ptyp5 ubi_ctrl cpu_dma_latency mtd0 ptyp6 urandom dri mtd0ro ptyp7 usbmon0 fb0 mtd1 ptyp8 vcs full mtd1ro ptyp9 vcs1 gpiochip0 mtdblock0 ptypa vcs2 gpiochip1 mtdblock1 ptypb vcsa gpiochip2 null ptypc vcsa1 gpiochip3 ptmx ptypd vcsa2 hwrng pts ptype vcsu input ptyp0 ptypf vcsu1 kmsg ptyp1 random vcsu2 mem ptyp2 rtc0 zero mmcblk0 ptyp3 snd mmcblk0p1 ptyp4 ttyBrook0只有ttyBrook0
這個範例是說明指令被執行的時機,'@'建立node之後執行, '$'移除node前執行, '*'等同'@'+'$', 這個我就想透過CONFIG_UEVENT_HELPER來demo比較有感覺
The special characters have the meaning: @ Run after creating the device. $ Run before removing the device. * Run both after creating and before removing the device. / # sysctl -a| grep hotplug 確認hotplug有被設定 kernel.hotplug = /sbin/mdev / # cat /etc/mdev.conf mmc.* 1:1 0660 @/x.sh 設定create node之後執行 / # cat /x.sh #!/bin/sh -x # Redirect standard output to /dev/console exec 1>/dev/kmsg echo "start $0" sleep 1 env ls /dev/mmcblk* # Your script commands go here echo "end $0" / # ls /dev/mmcblk* /dev/mmcblk0 / # echo -e 'n\np\n1\n\n\nw' | fdisk /dev/mmcblk0 建立一個新分區 The number of cylinders for this disk is set to 32768. There is nothing wrong with that, but this is larger than 1024, and could in certain setups cause problems with: 1) software that runs at boot time (e.g., old versions of LILO) 2) booting and partitioning software from other OSs (e.g., DOS FDISK, OS/2 FDISK) Command (m for help): Partition type p primary partition (1-4) e extended Partition number (1-4): First sector (16-2097151, default 16): Using default value 16 Last sector or +size{,K,M,G,T} (16-2097151, default 2097151): Using default value 2097151 Command (m for help): The partition table has been altered. Calling ioctl() to re-read partition table mmcblk0: p1 / # start /x.sh該scrip會在node建立後被執行 DEVNAME=mmcblk0p1 ACTION=add SHLVL=2 HOME=/ SEQNUM=762 MAJOR=179 MDEV=mmcblk0p1 DEVPATH=/devices/platform/bus@40000000/bus@40000000:motherboard-bus@40000000/bus@40000000:motherboard-bus@40000000:iofpga@7,00000000/10005000.mmci/mmc_host/mmc0/mmc0:4567/block/mmcblk0/mmcblk0p1 SUBSYSTEM=block PATH=/sbin:/bin:/usr/sbin:/usr/bin DISKSEQ=3 MINOR=1 PARTN=1 PWD=/dev DEVTYPE=partition /dev/mmcblk0 /dev/mmcblk0p1 end /x.sh / # echo -e 'd\nw' | fdisk /dev/mmcblk0 刪除分區, 因為mdev只有設定新增node之後執行, 所以移除分區不會執行/x.sh The number of cylinders for this disk is set to 32768. There is nothing wrong with that, but this is larger than 1024, and could in certain setups cause problems with: 1) software that runs at boot time (e.g., old versions of LILO) 2) booting and partitioning software from other OSs (e.g., DOS FDISK, OS/2 FDISK) Command (m for help): Selected partition 1 Command (m for help): The partition table has been altered. Calling ioctl() to re-read partition table mmcblk0: / # cat /etc/mdev.conf 修改移除node之後執行 mmc.* 1:1 0660 $/x.sh / # ls /dev/mmcblk* 底下沒有任何新分割區 /dev/mmcblk0 / # echo -e 'n\np\n1\n\n\nw' | fdisk /dev/mmcblk0 建立新分區, 但是mdev被設定移除才會執行/x.sh, 所以此時不會執行/x.sh The number of cylinders for this disk is set to 32768. There is nothing wrong with that, but this is larger than 1024, and could in certain setups cause problems with: 1) software that runs at boot time (e.g., old versions of LILO) 2) booting and partitioning software from other OSs (e.g., DOS FDISK, OS/2 FDISK) Command (m for help): Partition type p primary partition (1-4) e extended Partition number (1-4): First sector (16-2097151, default 16): Using default value 16 Last sector or +size{,K,M,G,T} (16-2097151, default 2097151): Using default value 2097151 Command (m for help): The partition table has been altered. Calling ioctl() to re-read partition table mmcblk0: p1 / # ls /dev/mmcblk* /dev/mmcblk0 /dev/mmcblk0p1 / # echo -e 'd\nw' | fdisk /dev/mmcblk0 移除分區 The number of cylinders for this disk is set to 32768. There is nothing wrong with that, but this is larger than 1024, and could in certain setups cause problems with: 1) software that runs at boot time (e.g., old versions of LILO) 2) booting and partitioning software from other OSs (e.g., DOS FDISK, OS/2 FDISK) Command (m for help): Selected partition 1 Command (m for help): The partition table has been altered. Calling ioctl() to re-read partition table mmcblk0: / # start /x.sh 因為此時的mdev.conf被設定移除node後執行/x.sh, 所以這裡會執行/x.sh DEVNAME=mmcblk0p1 ACTION=remove SHLVL=2 HOME=/ SEQNUM=767 MAJOR=179 MDEV=mmcblk0p1 DEVPATH=/devices/platform/bus@40000000/bus@40000000:motherboard-bus@40000000/bus@40000000:motherboard-bus@40000000:iofpga@7,00000000/10005000.mmci/mmc_host/mmc0/mmc0:4567/block/mmcblk0/mmcblk0p1 SUBSYSTEM=block PATH=/sbin:/bin:/usr/sbin:/usr/bin DISKSEQ=3 MINOR=1 PARTN=1 PWD=/dev DEVTYPE=partition /dev/mmcblk0 /dev/mmcblk0p1 end /x.sh
- busybox docs/mdev.txt
- http://kernel.org/doc/pending/hotplug.txt
- https://www.cnblogs.com/sky-heaven/p/5688092.html