This article was reproduced from: http://blog.csdn.net/skyflying2012/article/details/9364555
I. About UDEV
U is user Space,dev is the device, through its name, we can simply understand that it is a user-state-related drive device management mechanism. Udev is a file system for the 2.6 kernel. Provides a solution for dynamic device node management and naming based on user space. Used to replace the backward DEVFS
Udev is independent of the hardware platform, belongs to the process of user space, is a background program, it is disconnected from the drive layer, and built on the operating system, as long as the configuration file to make it effective, no need to restart the operating system, it needs SYSFS support, when the underlying device Plug and unplug, The underlying driver sends events via NetLink (uevent) to the Udev daemon, and Udev listens for these events and makes the corresponding device node creation, naming, permission control, etc. on the upper level.
It has the following advantages:
1. Dynamic management: When the device is added/removed, the Udev daemon hears the uevent from the kernel to add or remove the device files under/dev, so udev only generates the device files for the connected devices, not the/dev/ Generating a large amount of empty equipment files. In the event of hot swapping, information about the change of the device is output to the kernel's/sys (SYSFS file System), and Udev uses SYSFS information to manage the corresponding device node.
2. Custom naming rules: Through the Rules file, Udev defines the kernel device names for all devices under/dev/, such as/DEV/SDA,/DEV/HDA,/DEV/FD (these are the device names defined by the driver layer) and so on. Since Udev is running in user space, Linux users can define their own rules files, producing highly identifiable device files, such as/dev/boot_disk,/dev/root_disk,/dev/color_printer, etc.
3. Set the permissions and owner/group of the device. Also in the rules file, you can define your own device-related permissions and owners/groups
Work Flow:
Two. Uevent's interaction
As mentioned earlier, Udev must have SYSFS support, SYSFS is a memory-based file system that organizes the devices and buses connected to the system into a hierarchical file that can be accessed by user space, exporting the kernel data structures to user space, and their properties. It is built on the basis of kernel object kobject.
In the kernel space, when the system boot load drive or device hot plug, the driver itself needs to do the corresponding hardware detection work, after detecting the device, will load the corresponding device driver, create add kernel object under Sysfs, call to Kobject_add () To complete the added registration of the kernel object, and then call Kobject_uevent () to notify the system that the object has been added. The Kobject_uevent () function is the key function of uevent, which sends the object's corresponding information, attributes, etc. to the upper user space through the netlink socket.
int Device_add (struct device *dev)
{
struct device *parent = NULL;
struct Class_interface *class_intf;
int error =-einval;
dev = get_device (dev);
if (!dev)
Goto done;
.......
/* First, register with generic layer. */
Error = Kobject_add (&dev->kobj, Dev->kobj.parent, "%s", Dev_name (Dev));
if (Error)
Goto Error;
.......
Kobject_uevent (&dev->kobj, Kobj_add);
Bus_attach_device (Dev);
if (parent)
Klist_add_tail (&dev->knode_parent, &parent->klist_children);
.......
Attrerror:
Kobject_uevent (&dev->kobj, Kobj_remove);
Kobject_del (&dev->kobj);
Error:
Cleanup_device_parent (Dev);
if (parent)
Put_device (parent);
Goto done;
}
The above code snippet for our common add registration device when the call to the interface, Device_add () function, delete some irrelevant code, it can be seen that the first call to Kobject_add () to create the kernel object to add, and then call Kobject_uevent () To inform the system of uevent changes, the action here is kobj_add, the relative should have
Enum Kobject_action {
Kobj_add,
Kobj_remove,
Kobj_change,
Kobj_move,
Kobj_online,
Kobj_offline,
Kobj_max
};
In Kobject_uevent () is used in Linux more classic kernel space and user space of a communication mechanism netlink socket, this is not the focus of udev, I do not do too much explanation, in short, I believe it can let the kernel space and user space to communicate on the line. The Udev will also have a corresponding socket to accept the underlying message. The following is a simple uevent message listener written in reference to the Udev source code:
#define UEVENT_BUFFER_SIZE 2048
static int init_hotplug_sock (void)
{
struct SOCKADDR_NL SNL;
const int buffersize = 16 * 1024 * 1024;
int retval;
memset (&SNL, 0x00, sizeof (struct sockaddr_nl));
snl.nl_family = Af_netlink;
Snl.nl_pid = Getpid ();
snl.nl_groups = 1;
int hotplug_sock = socket (Pf_netlink, SOCK_DGRAM, netlink_kobject_uevent);
if (Hotplug_sock = =-1) {
printf ("Error getting socket:%s", Strerror (errno));
return-1;
}
/* Set receive buffersize */
SetSockOpt (Hotplug_sock, Sol_socket, So_rcvbufforce, &buffersize, sizeof (buffersize));
retval = Bind (Hotplug_sock, (struct sockaddr *) &snl, sizeof (struct sockaddr_nl));
if (retval < 0) {
printf ("Bind failed:%s", Strerror (errno));
Close (Hotplug_sock);
Hotplug_sock =-1;
return-1;
}
return hotplug_sock;
}
int main (int argc, char* argv[])
{
int hotplug_sock = Init_hotplug_sock ();
while (1)
{
printf ("Sunqidong debug\n");
Char buf[uevent_buffer_size*2] = {0};
Recv (Hotplug_sock, &buf, sizeof (BUF), 0);
printf ("%s\n", buf);
}
return 0;
}
This is also a background service program, the execution of the loop to accept the underlying message, when a USB flash drive Plug and unplug, will produce the following log:
[Email protected] test]#./hotplug
[Email protected]/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1
[Email protected]/class/usb_endpoint/usbdev1.5_ep00
[Email protected]/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.0
[Email Protected]/class/scsi_host/host6
[Email protected]/class/usb_endpoint/usbdev1.5_ep81
[Email PROTECTED]/CLASS/USB_ENDPOINT/USBDEV1.5_EP02
[Email protected]/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.0/host6/target6:0:0/6:0:0:0
[Email protected]/class/scsi_disk/6:0:0:0
[Email Protected]/block/sdb
[Email PROTECTED]/BLOCK/SDB/SDB1
[Email PROTECTED]/BLOCK/SDB/SDB2
[Email PROTECTED]/BLOCK/SDB/SDB5
[Email PROTECTED]/BLOCK/SDB/SDB6
[Email protected]/block/sdb/sdb7
[Email PROTECTED]/BLOCK/SDB/SDB8
[Email protected]/class/scsi_device/6:0:0:0
[Email PROTECTED]/CLASS/SCSI_GENERIC/SG2
[Email protected]/class/bsg/6:0:0:0
[Email protected]/class/usb_endpoint/usbdev1.5_ep81
[Email PROTECTED]/CLASS/USB_ENDPOINT/USBDEV1.5_EP02
[Email protected]/class/bsg/6:0:0:0
[Email PROTECTED]/CLASS/SCSI_GENERIC/SG2
[Email protected]/class/scsi_device/6:0:0:0
[Email protected]/class/scsi_disk/6:0:0:0
[Email PROTECTED]/BLOCK/SDB/SDB8
[Email protected]/block/sdb/sdb7
[Email PROTECTED]/BLOCK/SDB/SDB6
[Email PROTECTED]/BLOCK/SDB/SDB5
[Email PROTECTED]/BLOCK/SDB/SDB2
[Email PROTECTED]/BLOCK/SDB/SDB1
[Email Protected]/block/sdb
[Email protected]/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.0/host6/target6:0:0/6:0:0:0
[Email Protected]/class/scsi_host/host6
[Email protected]/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1/1-1:1.0
[Email protected]/class/usb_endpoint/usbdev1.5_ep00
[Email protected]/devices/pci0000:00/0000:00:11.0/0000:02:03.0/usb1/1-1
Three. Udev's rules file rule file is the most important part of Udev, which is stored under/etc/udev/rules.d/by default. All rule files must be suffixed with ". Rules". Here is a simple rule file example that illustrates
kernel== "Sdb8", name= "Mydisk", mode= "0660"
Kernel is the matching key, and name and mode are the assignment keys. "=" This is the judgment statement, "=" is an assignment statement, this rule means that if there is a device with the kernel device name SDB8 (I moved a partition within the hard disk), then the condition takes effect, perform the following assignment: Under/dev/, a device file named Mydisk is generated, and set the permissions of the device file to 0660.
With this simple rule, you should have a basic understanding of the rules file. Each rule file is divided into one or more matching and assignment sections. The matching section is represented by matching keywords, and the corresponding assignment parts are represented by assigned words.
1. Common Match Keywords: action (for matching behavior add/remove), KERNEL (device name defined in the kernel), bus (used to match bus type), SYSFS (used to match information obtained from SYSFS, such as Lable,vendor, USB serial number, etc.), SUBSYSTEM (matching subsystem name), etc.
2. Common Assignment Keywords:
Name (device file name created), SYMLINK (symbol creation link name), owner (set device owner), group (set device groups), IMPORT (call external program), MODE (permission bit)
Four Application of auto-mount USB storage device on XX project
In the XX project, we need to automatically mount USB storage device, and to support a number of common file systems, such as FAT32,NTFS,EXFAT, including FAT32 and other Fat series, Linux has long been supported, NTFS and EXFAT the current kernel itself is not supported, We have kernel module files for these two file systems Tntfs,ko and Texfat.ko, which will allow our kernel to recognize these two file systems for manual loading of these two types of storage devices. However, if you want to support automatic loading there are problems, you need to modify the corresponding rules file.
At the time of loading, different formats of the file system, loaded parameters are not the same, such as exFAT for
Mount-t Texfat/dev/sda/mnt/udisk
While NTFS is
Mount-t Tntfs/dev/sda/mnt/udisk
And for different formats, there are other Mount option parameters, so different formats need to be treated differently.
Inside the rule file is the Blkid-o udev command to get the file system information, determine which format the disk is, and then perform different mount commands.
The following is the file system format information that Blkid-o Udev reads
id_fs_uuid=2ee054b8e054884b
id_fs_uuid_enc=2ee054b8e054884b
Id_fs_label=disk3
Id_fs_label_enc=disk3
Id_fs_type=ntfs
Id_fs_label=disk4
Id_fs_label_enc=disk4
Id_fs_uuid=b8cf-ff22
Id_fs_uuid_enc=b8cf-ff22
Id_fs_type=vfat
Id_fs_uuid=3606-1b2c
Id_fs_uuid_enc=3606-1b2c
Id_fs_type=exfat
Id_fs_label=disk5
Id_fs_label_enc=disk5
You can see several of the above assignment items, which are read in the rules file. Make the corresponding judgment, realize the difference of the different file system to treat the mount
This is part of the rule file
kernel!= "sd[a-z][0-9]", goto= "Media_by_label_auto_mount_end"
# Import FS infos
import{program}= "/sbin/blkid-o udev-p%N"
Env{id_fs_label}!= "", env{dir_name}= "%e{id_fs_label}"
env{id_fs_label}== "", env{dir_name}= "Usb-%k"
#vfat, Fat
action== "Add", env{id_fs_type}== "Vfat|fat", run+= "/bin/mkdir-p/mnt/udisk/%e{dir_name}", env{mount_options}= "$env { mount_options},gid=100,umask=000 ", run+="/bin/mount-o $env {Mount_options},iocharset=utf8/dev/%k/mnt/udisk/%e{dir _name} "
#ntfs
action== "Add", env{id_fs_type}== "NTFS", run+= "/bin/mkdir-p/mnt/udisk/%e{dir_name}", env{mount_options}= "$env { mount_options},gid=100,umask=000 ", run+="/bin/mount-t tntfs-o $env {mount_options},iostreaming/dev/%k/mnt/udisk/%e {Dir_name} "
#exfat
action== "Add", env{id_fs_type}== "exFAT", run+= "/bin/mkdir-p/mnt/udisk/%e{dir_name}", run+= "/bin/mount-t texfat-o RW /dev/%k/mnt/udisk/%e{dir_name} "
About Blkid, in our current file system, Blkid is not supported exFAT format, through the command to view the disk information, the EXFAT format of the disk can not be found. So before doing automatic mount of time can not realize hanging exFAT, later found on the Internet a util-linux-ng2.18 source package, which contains blkid source code. Modify the compilation, compile a new Blkid file, make it run on our system, be able to recognize the exFAT file
Introduction to Linux under Udev "Go"