linux udev支持tf卡自動(dòng)掛載與卸載

當(dāng)udev提示如下報(bào)錯(cuò)時(shí),內(nèi)核配置中選中INOTIFY_USER即可。

udevd[992]: inotify_init failed: Function not implemented


udev規(guī)則文件示例(tf卡插拔自動(dòng)掛載與卸載):

/etc/udev/rules.d/10-tf.rules

#KERNEL=="mmcblk[0-9]p[0-9]", RUN+="/etc/udev/hotplug-tf.sh %k $env{ACTION}"

ACTION=="add", KERNEL=="mmc0:*", RUN+="/etc/udev/hotplug-tf.sh %k $env{ACTION}"

ACTION=="remove", KERNEL=="mmc0:*", RUN+="/etc/udev/hotplug-tf.sh %k $env{ACTION}"

/etc/udev/udev.conf

udev_root="/dev/"

udev_rules="/etc/udev/rules.d/"

udev_log="err"?


要執(zhí)行的shell腳本中記得開頭要加入一行 #!/bin/sh,否則udev會(huì)報(bào)format err.

/etc/udev/hotplug-tf.sh

#!/bin/sh

echo "==============hotplug tf $(date)=============" #>> /run/udev.log

echo "[$#] $0, $1 ,$2" #>> /run/udev.log

if [ "$#" != "2" ];then

? echo " !! param err."? #>> /run/udev.log

? exit 1

fi

if [ "$2" == "remove" ];then

? echo " <==umount"? #>> /run/udev.log

? umount /mnt/extsd

fi

if [ "$2" == "add" ];then

? echo " ==>mount"? #>> /run/udev.log

? mkdir /mnt/extsd

? mount -t vfat /dev/mmcblk0p1 /mnt/extsd

fi

exit 0


udev規(guī)則匹配表:

鍵? ? ? ? ? ? ? ? 含義

----------------------------------------

ACTION? ? ? ? ? ? ? 事件 (uevent) 的行為,例如:add( 添加設(shè)備 )、remove( 刪除設(shè)備 ).

KERNEL? ? ? ? ? ? ? 在內(nèi)核里看到的設(shè)備名字,比如sd*表示任意SCSI磁盤設(shè)備

DEVPATH? ? ? ? ? ? ? 內(nèi)核設(shè)備錄進(jìn),比如/devices/*

SUBSYSTEM? ? ? ? ? ? 子系統(tǒng)名字,例如:sda 的子系統(tǒng)為 block.

BUS? ? ? ? ? ? ? ? ? 總線的名字,比如IDE,USB

DRIVER? ? ? ? ? ? ? 設(shè)備驅(qū)動(dòng)的名字,比如ide-cdrom

ID? ? ? ? ? ? ? ? ? 獨(dú)立于內(nèi)核名字的設(shè)備名字

SYSFS{ value}? ? ? ? sysfs屬性值,他可以表示任意

ENV{ key}? ? ? ? ? ? 環(huán)境變量,可以表示任意

PROGRAM? ? ? ? ? ? ? 可執(zhí)行的外部程序,如果程序返回0值,該鍵則認(rèn)為為真(true)

RESULT? ? ? ? ? ? ? 上一個(gè)PROGRAM調(diào)用返回的標(biāo)準(zhǔn)輸出.

NAME? ? ? ? ? ? ? ? 根據(jù)這個(gè)規(guī)則創(chuàng)建的設(shè)備文件的文件名.

(注意:僅僅第一行的NAME描述是有效的,后面的均忽略.如果你想使用使用兩個(gè)以上的名字來(lái)訪問一個(gè)設(shè)備的話,可以考慮SYMLINK鍵.)

SYMLINK? ? ? ? ? ? ? 為 /dev/下的設(shè)備文件產(chǎn)生符號(hào)鏈接.由于 udev 只能為某個(gè)設(shè)備產(chǎn)生一個(gè)設(shè)備文件,

(所以為了不覆蓋系統(tǒng)默認(rèn)的 udev 規(guī)則所產(chǎn)生的文件,推薦使用符號(hào)鏈接.)

OWNER? ? ? ? ? ? ? ? 設(shè)備文件的屬組

GROUP? ? ? ? ? ? ? ? 設(shè)備文件所在的組.

MODE? ? ? ? ? ? ? ? 設(shè)備文件的權(quán)限,采用8進(jìn)制

RUN? ? ? ? ? ? ? ? ? 為設(shè)備而執(zhí)行的程序列表

LABEL? ? ? ? ? ? ? ? 在配置文件里為內(nèi)部控制而采用的名字標(biāo)簽(下下面的GOTO服務(wù))

GOTO? ? ? ? ? ? ? ? 跳到匹配的規(guī)則(通過(guò)LABEL來(lái)標(biāo)識(shí)),有點(diǎn)類似程序語(yǔ)言中的GOTO

IMPORT{ type}? ? ? ? 導(dǎo)入一個(gè)文件或者一個(gè)程序執(zhí)行后而生成的規(guī)則集到當(dāng)前文件

WAIT_FOR_SYSFS? ? ? 等待一個(gè)特定的設(shè)備文件的創(chuàng)建.主要是用作時(shí)序和依賴問題.

PTIONS? ? ? ? ? ? ? 特定的選項(xiàng):

last_rule? ? ? ? ? ? 對(duì)這類設(shè)備終端規(guī)則執(zhí)行;

ignore_device? ? ? ? 忽略當(dāng)前規(guī)則;

ignore_remove? ? ? ? 忽略接下來(lái)的并移走請(qǐng)求.

all_partitions? ? ? 為所有的磁盤分區(qū)創(chuàng)建設(shè)備文件.


udev一些特殊的值和替換值:

在鍵值對(duì)中的鍵和操作符都介紹完了,最后是值 (value).Linux 用戶可以隨意地定制 udev 規(guī)則文件的值.

例如:my_root_disk, my_printer.同時(shí)也可以引用下面的替換操作符:

----------------------------------------

$kernel,? ? ? %k:? ? ? 設(shè)備的內(nèi)核設(shè)備名稱,例如:sda、cdrom.

$number,? ? ? %n:? ? ? 設(shè)備的內(nèi)核號(hào)碼,例如:sda3 的內(nèi)核號(hào)碼是 3.

$devpath,? ? ? %p:? ? ? 設(shè)備的 devpath路徑.

$id,? ? ? ? ? %b:? ? ? 設(shè)備在 devpath里的 ID 號(hào).

$sysfs{file},? %s{file}: 設(shè)備的 sysfs里 file 的內(nèi)容.其實(shí)就是設(shè)備的屬性值.

$env{key},? ? %E{key}:? 一個(gè)環(huán)境變量的值.

$major,? ? ? ? %M:? ? ? ? 設(shè)備的 major 號(hào).

$minor,? ? ? %m:? ? ? ? 設(shè)備的 minor 號(hào).

$result,? ? ? %c:? ? ? ? PROGRAM 返回的結(jié)果

$parent,? ? ? %P:? ? ? ? 父設(shè)備的設(shè)備文件名.

$root,? ? ? ? %r:? ? ? ? udev_root的值,默認(rèn)是 /dev/.

$tempnode,? ? %N:? ? ? ? 臨時(shí)設(shè)備名.

%%:? ? ? ? ? 符號(hào) % 本身.

$$:? ? ? ? ? 符號(hào) $ 本身.

————————————————

原文鏈接:https://blog.csdn.net/xiaoliu5396/article/details/46531893

以下源碼用來(lái)讀取net link消息

#include <stdio.h>

#include <stdlib.h>

#include <string.h>

#include <errno.h>

#include <sys/types.h>

#include <asm/types.h>

//該頭文件需要放在netlink.h前面防止編譯出現(xiàn)__kernel_sa_family未定義

#include <sys/socket.h>?

#include <linux/netlink.h>

void MonitorNetlinkUevent()

{

? ? int sockfd;

? ? struct sockaddr_nl sa;

? ? int len;

? ? char buf[4096];

? ? struct iovec iov;

? ? struct msghdr msg;

? ? int i;

? ? memset(&sa,0,sizeof(sa));

? ? sa.nl_family=AF_NETLINK;

? ? sa.nl_groups=NETLINK_KOBJECT_UEVENT;

? ? sa.nl_pid = 0;//getpid(); both is ok

? ? memset(&msg,0,sizeof(msg));

? ? iov.iov_base=(void *)buf;

? ? iov.iov_len=sizeof(buf);

? ? msg.msg_name=(void *)&sa;

? ? msg.msg_namelen=sizeof(sa);

? ? msg.msg_iov=&iov;

? ? msg.msg_iovlen=1;

? ? sockfd=socket(AF_NETLINK,SOCK_RAW,NETLINK_KOBJECT_UEVENT);

? ? if(sockfd==-1)

? ? ? ? printf("socket creating failed:%s\n",strerror(errno));

? ? if(bind(sockfd,(struct sockaddr *)&sa,sizeof(sa))==-1)

? ? ? ? printf("bind error:%s\n",strerror(errno));

? ? while(1){

? ? len=recvmsg(sockfd,&msg,0);

? ? if(len<0)

? ? ? ? printf("receive error\n");

? ? else if(len<32||len>sizeof(buf))

? ? ? ? printf("invalid message");

? ? for(i=0;i<len;i++)

? ? ? ? if(*(buf+i)=='\0')

? ? ? ? ? ? buf[i]='\n';

? ? printf("received %d bytes\n%s\n",len,buf);

? ? }

}

int main(int argc,char **argv)

{

? ? MonitorNetlinkUevent();

? ? return 0;

}

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容