2023年9月16日 星期六

Linux Kernel(11.2)- mdev.conf


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




沒有留言:

張貼留言

熱門文章