LINUX的UDEV(守护进程)

udev是一个在用户空间运行的设备管理工具,作为守护进程动态管理/dev目录下的设备文件。它监听内核uevent,根据硬件状态更新设备文件。守护进程具有生命周期长、与终端无关等特点。udev规则文件用于配置设备管理,如自动挂载U盘。了解udev的配置和规则对于系统管理员至关重要。
摘要由CSDN通过智能技术生成
简介
udev 是一个设备管理工具, udev 守护进程 的形式运行,通过侦听内核发出来的 uevent 来管 理/dev 目录下的设备文件。 udev 在用户空间运行,而不在内核空间 运行。它能够根据系统中的硬
件设备的状态动态更新设备文件,包括设备文件的创建,删除等。设备文件通常放在 /dev 目录
下。使用 udev 后,在 /dev 目录下就只包含系统中真正存在的设备。
1.守护进程:
Linux Daemon (守护进程)是运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行
某种任务或等待处理某些发生的事件。它不需要用户输入就能运行而且提供某种服务,不是对整个
系统就是对某个用户程序提供服务。 Linux 系统的大多数服务器就是通过守护进程实现的。常见的
守护进程包括系统日志进程 syslogd web 服务器 httpd 、邮件服务器 sendmail 和数据库服务器
mysqld 等。守护进程的名称通常以 d 结尾
UDEV 守护进程,它能够根据系统中的硬件设备的状态动态更新设备文件,包括设备文件的创建,删除等。
2.基本特点
(1)生存周期长 [ 非必须 ] ,一般操作系统启动的时候就启动,关闭的时候关闭。
(2)守护进程和终端无关联,也就是他们没有控制终端,所以当控制终端退出,也不会导致守护进程退出
(3)守护进程是在后台运行,不会占着终端,终端可以执行其他命令
(4)一个守护进程的父进程是 init 进程,因为它真正的父进程在 fork 出子进程后就先于子进程 exit 退出
了,所以它是一个由 init 继承的孤儿进程
3.守护进程开发借助daemon()函数完成
#include <unistd.h>
int daemon(int nochdir, int noclose);
/*
    函数参数:
    nochdir:为0时表示将当前目录更改至“/”
    noclose:为0时表示将标准输入、标准输出、标准错误重定向至“/dev/null”
    返回值:
    成功则返回0,失败返回-1
*/

代码实现daemon(),编译生成a.out

#include <unistd.h>
#include <signal.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <sys/stat.h>
#include <time.h>
#include <stdio.h>
//    C 库函数 char *asctime(const struct tm *timeptr) 返回一个指向字符串的指针,它代表了结    构 struct timeptr 的日期和时间。
//    C 库函数 struct tm *localtime(const time_t *timer) 使用 timer 的值来填充 tm 结构。
        timer 的值被分解为 tm 结构,并用本地时区表示。
/*
struct tm {
    int tm_sec; 秒,范围从 0 到 59
    int tm_min; 分,范围从 0 到 59
    int tm_hour; 小时,范围从 0 到 23
    int tm_mday; 一月中的第几天,范围从 1 到 31
    int tm_mon; 月份,范围从 0 到 11
    int tm_year; 自 1900 起的年数
    int tm_wday; 一周中的第几天,范围从 0 到 6
    int tm_yday; 一年中的第几天,范围从 0 到 365
    int tm_isdst; 夏令时
};
*/
static bool flag = true;
void handler(int sig)
{
    printf("I got a signal %d\nI'm quitting.\n", sig);
    flag = false;
}
int main()
{
    time_t t;
    int fd;
    //创建守护进程
    if(-1 == daemon(0, 0))
    {
        printf("daemon error\n");
        exit(1);
    }
    //设置信号处理函数
    struct sigaction act;
    act.sa_handler = handler;//信号处理函数
    sigemptyset(&act.sa_mask);//将参数set信号集初始化并清空。
    act.sa_flags = 0;
    if(sigaction(SIGQUIT, &act, NULL))
    {
        printf("sigaction error.\n");
        exit(0);
    }
    //进程工作内容
    while(flag)
    {
        fd = open("/home/orangepi/daemon.log", O_WRONLY | O_CREAT | O_APPEND,0666);
        if(fd == -1)
        {
            printf("open error\n");
        }
        t = time(NULL);
        char *buf = asctime(localtime(&t));
        write(fd, buf, strlen(buf));
        close(fd);
        sleep(10);
    }
    return 0;
}

若实现开机自启动

sudo vi /etc/rc.local               //进入文件后写入绝对路径和程序名   
例如: /home/orangepi/code/a.out
4.守护进程和后台进程区别
         守护进程和终端不挂钩,后台进程可以往终端输出东西;
         关闭终端,守护进程依旧运行
5.UDEV配置文件
        规则文件是 udev 里最重要的部分,默认是存放在 /etc/udev/rule.d/ 下。所有的规则文件必须以 ".rules" 为后缀名。以sudo vi  xxx.rules 进入文件(可自己创建) 保存,给配置文件设置下权限
         sudo  chmod a+rx  / etc  / udev  / rules.d  / 50 -android.rules
 Restart
         sudo  / etc  / init.d  / udev restart
 最后再重启下adb服务,就可以了(没配置环境变量的请进入Android SDK tools目录执行sudo ./adb  kill-server ./adb devices)
         sudo adb kill-server
          sudo adb devices
         sudo reboot(重启) 

 下面是一个简单的规则:

        KERNEL=="sda", NAME="my_root_disk", MODE="0660"

KERNEL 是匹配键, NAME MODE 是赋值键。这条规则的意思是:如果有一个设备的内核名称为 sda,则该条件生效,执行后面的赋值:在 /dev 下产生一个名为 my_root_disk 的设备文件,并把设备 文件的权限设为 0660
查看设备一下信息,我这里是usb接安卓手机
udevadm info --attribute-walk --name=/dev/ 设备名字
udevadm info --attribute-walk --name=/dev/bus/usb/001/005
SUBSYSTEM=="usb", ATTRS{idVendor}=="12d1", ATTRS{idProduct}=="107e", MODE="0666"

 查看关键字匹配信息

 looking at device '/devices/platform/soc/5200000.ehci1-controller/usb1/1-1':
    KERNEL=="1-1"
    SUBSYSTEM=="usb"
    DRIVER=="usb"
    ATTR{authorized}=="1"
    ATTR{avoid_reset_quirk}=="0"
    ATTR{bConfigurationValue}=="1"
    ATTR{bDeviceClass}=="00"
    ATTR{bDeviceProtocol}=="00"
    ATTR{bDeviceSubClass}=="00"
    ATTR{bMaxPacketSize0}=="64"
    ATTR{bMaxPower}=="500mA"
    ATTR{bNumConfigurations}=="1"
    ATTR{bNumInterfaces}==" 4"
    ATTR{bcdDevice}=="0299"
    ATTR{bmAttributes}=="c0"
    ATTR{busnum}=="1"
    ATTR{configuration}=="hisuite_mtp_mass_storage_adb_hdb"
    ATTR{devnum}=="5"
    ATTR{devpath}=="1"
    ATTR{idProduct}=="107e"
    ATTR{idVendor}=="12d1"
    ATTR{ltm_capable}=="no"
    ATTR{manufacturer}=="HUAWEI"
    ATTR{maxchild}=="0"
    ATTR{product}=="LLD-AL00"
    ATTR{quirks}=="0x0"
    ATTR{removable}=="unknown"
    ATTR{serial}=="MKJNW18302010625"
    ATTR{speed}=="480"
    ATTR{urbnum}=="28"
    ATTR{version}==" 2.00"

  looking at parent device '/devices/platform/soc/5200000.ehci1-controller/usb1':
    KERNELS=="usb1"
    SUBSYSTEMS=="usb"
    DRIVERS=="usb"
    ATTRS{authorized}=="1"
    ATTRS{authorized_default}=="1"
    ATTRS{avoid_reset_quirk}=="0"
    ATTRS{bConfigurationValue}=="1"
    ATTRS{bDeviceClass}=="09"
    ATTRS{bDeviceProtocol}=="00"
    ATTRS{bDeviceSubClass}=="00"
    ATTRS{bMaxPacketSize0}=="64"
    ATTRS{bMaxPower}=="0mA"
    ATTRS{bNumConfigurations}=="1"
    ATTRS{bNumInterfaces}==" 1"
    ATTRS{bcdDevice}=="0409"
    ATTRS{bmAttributes}=="e0"
    ATTRS{busnum}=="1"
    ATTRS{configuration}==""
    ATTRS{devnum}=="1"
    ATTRS{devpath}=="0"
    ATTRS{idProduct}=="0002"
    ATTRS{idVendor}=="1d6b"
    ATTRS{interface_authorized_default}=="1"
    ATTRS{ltm_capable}=="no"
    ATTRS{manufacturer}=="Linux 4.9.170-sun50iw9 ehci_hcd"
    ATTRS{maxchild}=="1"
    ATTRS{product}=="SW USB2.0 'Enhanced' Host Controller (EHCI) Driver"
    ATTRS{quirks}=="0x0"
    ATTRS{removable}=="unknown"
    ATTRS{serial}=="sunxi-ehci"
    ATTRS{speed}=="480"
    ATTRS{urbnum}=="78"
    ATTRS{version}==" 2.00"

  looking at parent device '/devices/platform/soc/5200000.ehci1-controller':
    KERNELS=="5200000.ehci1-controller"
    SUBSYSTEMS=="platform"
    DRIVERS=="sunxi-ehci"
    ATTRS{companion}==""
    ATTRS{driver_override}=="(null)"
    ATTRS{ehci_enable}=="ehci:1, probe:1"
    ATTRS{phy_range}=="rate:0x1a8"
    ATTRS{phy_threshold}=="threshold:0x0"
    ATTRS{uframe_periodic_max}=="100"

  looking at parent device '/devices/platform/soc':
    KERNELS=="soc"
    SUBSYSTEMS=="platform"
    DRIVERS==""
    ATTRS{driver_override}=="(null)"

  looking at parent device '/devices/platform':
    KERNELS=="platform"
    SUBSYSTEMS==""
    DRIVERS==""
6.udev 规则的匹配键
ACTION:事件(uevent)的行为,例如:add(添加设备)、remove(删除设备);
KERNEL:内核设备名称,例如:sda,cdrom;
DEVPATH:设备的 devpath 路径;
SUBSYSTEM:设备的子系统名称,例如:sda 的系统为 block;
BUS:设备在 devpath 里的总线名称,例如:usb;
DRIVER:设备在 devpath 的设备驱动名称,例如:ide-cdrom;
ID:设备在 devpath 里的识别号;
SYSFS{filename}:设备的 devpath 路径下,设备的属性文件 "filename" 里的内容;
ENV{key}:环境变量。在一条规则中,可以设定最多五条环境变量的 匹配键;
PROGRAM:调用外部命令;
RESULT:外部命令 PROGRAM 的返回结果。

自动挂载U

ACTION=="add", SUBSYSTEMS=="usb", SUBSYSTEM=="block", RUN{program}+="/bin/mkdir
/media/%k" ,RUN{program}+="/usr/bin/systemd-mount --no-block --collect $devnode
/media/%k"

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值