1 00:00:06,488 --> 00:00:08,490 - An important task of the kernel 2 00:00:08,490 --> 00:00:09,323 is to make sure that 3 00:00:09,323 --> 00:00:11,160 you can use your hardware. 4 00:00:11,160 --> 00:00:13,263 So how exactly does that work? 5 00:00:14,250 --> 00:00:16,290 Well, the kernel itself is small 6 00:00:16,290 --> 00:00:19,440 and it contains essential drivers only 7 00:00:19,440 --> 00:00:22,440 and additional drivers are provided dynamically. 8 00:00:22,440 --> 00:00:25,350 And there's many ways in which that happens. 9 00:00:25,350 --> 00:00:27,510 To start it, there is InitramFS 10 00:00:27,510 --> 00:00:29,760 the initial RAM file system, 11 00:00:29,760 --> 00:00:31,353 which is loaded while booting. 12 00:00:32,190 --> 00:00:34,170 Also there is systemd-udevd 13 00:00:34,170 --> 00:00:35,850 which takes care of loading drivers 14 00:00:35,850 --> 00:00:37,593 automatically and on demand. 15 00:00:38,460 --> 00:00:39,630 To access devices, 16 00:00:39,630 --> 00:00:43,020 device files in the /dev directory are used. 17 00:00:43,020 --> 00:00:46,140 The kernel doesn't know about device file names. 18 00:00:46,140 --> 00:00:48,420 It uses the device fellow major and minor 19 00:00:48,420 --> 00:00:50,730 to address the devices. 20 00:00:50,730 --> 00:00:51,603 Let me show you. 21 00:00:54,060 --> 00:00:59,060 So if I use ls - l on /dev/sda* 22 00:00:59,784 --> 00:01:02,460 /dev/sda* is obviously your hard drive. 23 00:01:02,460 --> 00:01:04,440 Then what I want you to be aware of 24 00:01:04,440 --> 00:01:06,930 is this 8,0 , this 8, 0. 25 00:01:06,930 --> 00:01:09,240 That's your major and your minor. 26 00:01:09,240 --> 00:01:10,380 And that is what the kernel 27 00:01:10,380 --> 00:01:12,033 really all knows about. 28 00:01:12,900 --> 00:01:16,500 Now in /proc there is this file 29 00:01:16,500 --> 00:01:19,560 with the name /proc/devices 30 00:01:19,560 --> 00:01:20,730 and in /proc/devices 31 00:01:20,730 --> 00:01:21,990 we have the block devices 32 00:01:21,990 --> 00:01:22,823 and what do we see? 33 00:01:22,823 --> 00:01:25,230 Block device 8 is sd. 34 00:01:25,230 --> 00:01:26,370 What does that mean? 35 00:01:26,370 --> 00:01:27,270 Well that means that 36 00:01:27,270 --> 00:01:31,620 if the block device major "8" is addressed 37 00:01:31,620 --> 00:01:34,050 then the kernel is going to contact the sd, 38 00:01:34,050 --> 00:01:36,420 which is SCSI disk module 39 00:01:36,420 --> 00:01:38,250 and that is how these major minors 40 00:01:38,250 --> 00:01:39,986 allow the kernel to allocate 41 00:01:39,986 --> 00:01:42,423 the right, the right modules. 42 00:01:44,940 --> 00:01:45,930 You can also see that 43 00:01:45,930 --> 00:01:46,763 in a different way 44 00:01:46,763 --> 00:01:48,933 using lsblk, for instance. 45 00:01:50,100 --> 00:01:51,630 I like this overview because 46 00:01:51,630 --> 00:01:54,557 in lsblk you see not only the major and the minor 47 00:01:54,557 --> 00:01:57,510 but on the left hand the device name 48 00:01:57,510 --> 00:01:58,620 and on the right hand, 49 00:01:58,620 --> 00:01:59,820 if the device is mounted, 50 00:01:59,820 --> 00:02:01,590 you can even see the mount point. 51 00:02:01,590 --> 00:02:04,410 And that's how major and minor are are used. 52 00:02:04,410 --> 00:02:07,083 Now let's talk about hardware initialization a bit. 53 00:02:10,050 --> 00:02:13,710 So to access hardware, the Linux kernel uses drivers 54 00:02:13,710 --> 00:02:16,470 and these drivers are the kernel modules. 55 00:02:16,470 --> 00:02:18,930 Drivers can be provided through the InitramFS 56 00:02:18,930 --> 00:02:22,590 or loaded dynamically through systemd-udevd. 57 00:02:22,590 --> 00:02:24,810 And device valves in /dev provide 58 00:02:24,810 --> 00:02:27,450 user interface to the devices. 59 00:02:27,450 --> 00:02:30,300 Device files are mostly auto-generated 60 00:02:30,300 --> 00:02:31,890 and the device files correspond 61 00:02:31,890 --> 00:02:33,240 to the device nodes 62 00:02:33,240 --> 00:02:34,950 which are a major and a minor number 63 00:02:34,950 --> 00:02:38,130 that the kernel uses to identify devices. 64 00:02:38,130 --> 00:02:39,840 You can even create them yourselves 65 00:02:39,840 --> 00:02:42,000 using the mknod command. 66 00:02:42,000 --> 00:02:44,220 That's something that was useful in the past. 67 00:02:44,220 --> 00:02:47,790 Nowadays they should never be necessary anymore. 68 00:02:47,790 --> 00:02:50,280 Also involved in hardware management 69 00:02:50,280 --> 00:02:52,470 is a sysfs file system. 70 00:02:52,470 --> 00:02:54,930 So /sys is used to provide information 71 00:02:54,930 --> 00:02:57,540 about devices and their attributes. 72 00:02:57,540 --> 00:02:59,640 And /sys/devices is dedicated 73 00:02:59,640 --> 00:03:01,113 to device information. 74 00:03:02,370 --> 00:03:05,880 An easy interface to query device information 75 00:03:05,880 --> 00:03:08,250 from /sys is udevadm. 76 00:03:08,250 --> 00:03:09,330 Use, for instance, 77 00:03:09,330 --> 00:03:14,070 udevadm info --query=all --name=/dev/sda 78 00:03:14,070 --> 00:03:16,020 and you will find all the information stored 79 00:03:16,020 --> 00:03:19,713 in the sysfs file system about a /dev/sda device. 80 00:03:21,480 --> 00:03:22,920 Now before I'm going to show you 81 00:03:22,920 --> 00:03:26,313 I want you to understand systemd-udevd a bit. 82 00:03:27,420 --> 00:03:29,910 The Linux kernel initiates device loading 83 00:03:29,910 --> 00:03:31,127 and next sends out uevents 84 00:03:31,127 --> 00:03:34,080 to the udevd user space daemon. 85 00:03:34,080 --> 00:03:36,600 Well, the systemd-udevd user space daemon 86 00:03:36,600 --> 00:03:37,860 is what we should say 87 00:03:37,860 --> 00:03:40,890 because udevd is the old name of the process. 88 00:03:40,890 --> 00:03:43,320 Nowadays it's integrated in systemd 89 00:03:43,320 --> 00:03:46,673 and the name of the process really is systemd-udevd. 90 00:03:46,673 --> 00:03:49,650 systemd-uddevd catches the event 91 00:03:49,650 --> 00:03:51,060 and decides how to handle it 92 00:03:51,060 --> 00:03:52,200 based on attributes 93 00:03:52,200 --> 00:03:54,870 that it has received in the event. 94 00:03:54,870 --> 00:03:56,610 And it next reads its rules 95 00:03:56,610 --> 00:03:59,040 and acts based on these rules. 96 00:03:59,040 --> 00:04:02,400 It has default rules in /usr/lib/udev/rules.d 97 00:04:02,400 --> 00:04:04,260 and custom rules can be stored 98 00:04:04,260 --> 00:04:06,570 in /etc/udev/rules.d. 99 00:04:06,570 --> 00:04:09,060 Now let me demonstrate how to use udev rules. 100 00:04:09,060 --> 00:04:10,560 You can find the steps in this demo 101 00:04:10,560 --> 00:04:12,540 on the slide, just for your convenience. 102 00:04:12,540 --> 00:04:13,373 Let me show you. 103 00:04:15,870 --> 00:04:19,350 So to start with, I need udevamd monitor 104 00:04:19,350 --> 00:04:21,300 which is showing all the udev events 105 00:04:21,300 --> 00:04:22,680 that are going to happen. 106 00:04:22,680 --> 00:04:25,203 And now I'm plugging in the USB thumb drive. 107 00:04:28,260 --> 00:04:29,940 So as you can see 108 00:04:29,940 --> 00:04:33,117 the USB thumb drive is now initialized 109 00:04:33,117 --> 00:04:35,250 and udevadm monitor is showing 110 00:04:35,250 --> 00:04:37,050 exactly what is happening. 111 00:04:37,050 --> 00:04:39,270 So it's a step-by-step procedure 112 00:04:39,270 --> 00:04:40,830 where we can see that the kernel 113 00:04:40,830 --> 00:04:42,260 has detected an event 114 00:04:42,260 --> 00:04:45,030 and then has pass the event through udev 115 00:04:45,030 --> 00:04:47,820 and based on that, the kernel can continue 116 00:04:47,820 --> 00:04:50,580 and down the road, everything is loaded 117 00:04:50,580 --> 00:04:52,710 that is, that is required. 118 00:04:52,710 --> 00:04:55,290 So here for instance you can see SCSI disc 119 00:04:55,290 --> 00:04:57,390 that is involved SCSI generic, 120 00:04:57,390 --> 00:04:59,160 that's about block devices. 121 00:04:59,160 --> 00:05:03,210 Then we can see that the sdb block device is created 122 00:05:03,210 --> 00:05:06,300 and all of these are file names, 123 00:05:06,300 --> 00:05:11,300 file names that are relative to the /sys file system. 124 00:05:11,400 --> 00:05:13,117 Now the big question is, 125 00:05:13,117 --> 00:05:15,150 "What exactly is going on 126 00:05:15,150 --> 00:05:17,940 when stuff like this is happening?" 127 00:05:17,940 --> 00:05:21,150 Well, that is determined by the udev rules. 128 00:05:21,150 --> 00:05:23,488 So let's have a look at 129 00:05:23,488 --> 00:05:25,480 /lib/udev/rules.d 130 00:05:26,768 --> 00:05:29,760 /lib/udev/rules.d 131 00:05:29,760 --> 00:05:31,740 where we have multiple rules. 132 00:05:31,740 --> 00:05:34,890 We don't wanna see all 122. 133 00:05:34,890 --> 00:05:38,407 So let me just go for 60. 134 00:05:38,407 --> 00:05:40,570 And in 60 we have the persistent 135 00:05:42,054 --> 00:05:44,340 storage.rules 136 00:05:44,340 --> 00:05:48,570 and there we can see how such a rule is composed. 137 00:05:48,570 --> 00:05:51,764 So it's, it's quite complex. 138 00:05:51,764 --> 00:05:54,300 Here we see if the kernel detects 139 00:05:54,300 --> 00:05:55,650 one of these loop devices, 140 00:05:55,650 --> 00:05:57,780 then it's going to take action. 141 00:05:57,780 --> 00:05:58,860 Now I don't want to go 142 00:05:58,860 --> 00:06:01,860 through all of the lines in this example file. 143 00:06:01,860 --> 00:06:03,843 I want to create our own. 144 00:06:05,070 --> 00:06:06,720 Now how are we going to do that? 145 00:06:06,720 --> 00:06:09,450 Well, we need to work 146 00:06:09,450 --> 00:06:13,140 with the device that was just added. 147 00:06:13,140 --> 00:06:14,400 So which device is that? 148 00:06:14,400 --> 00:06:16,950 Well ls -l in /dev/disk 149 00:06:16,950 --> 00:06:19,560 is showing the different device names. 150 00:06:19,560 --> 00:06:22,410 lsblk is showing the different device names 151 00:06:22,410 --> 00:06:23,880 from a different perspective. 152 00:06:23,880 --> 00:06:25,833 And what we need is sdb. 153 00:06:27,150 --> 00:06:28,140 In a udev rule 154 00:06:28,140 --> 00:06:31,170 you are going to use device attributes 155 00:06:31,170 --> 00:06:33,150 and to find these device attributes, 156 00:06:33,150 --> 00:06:38,150 udevadm info --query=all --name=dev/sdb 157 00:06:38,290 --> 00:06:43,290 udevadm info --query=all --name=dev/sdb 158 00:06:43,710 --> 00:06:45,720 It's showing all the information 159 00:06:45,720 --> 00:06:48,000 on this USB thumb drive. 160 00:06:48,000 --> 00:06:49,860 Now this is device-specific 161 00:06:49,860 --> 00:06:53,460 and you can use this device-specific information 162 00:06:53,460 --> 00:06:55,263 in the udev rules. 163 00:06:56,190 --> 00:06:57,780 There's another way to display 164 00:06:57,780 --> 00:06:59,340 more or less the same 165 00:06:59,340 --> 00:07:00,510 information 166 00:07:00,510 --> 00:07:01,343 and 167 00:07:01,343 --> 00:07:02,176 that is 168 00:07:02,176 --> 00:07:03,009 - -attribute-walk. 169 00:07:03,009 --> 00:07:05,013 - -attribute-walk. 170 00:07:08,400 --> 00:07:10,230 That is giving detailed information 171 00:07:10,230 --> 00:07:11,670 about everything that was found 172 00:07:11,670 --> 00:07:13,170 on this USB thumb drive. 173 00:07:13,170 --> 00:07:14,784 And this information is the information 174 00:07:14,784 --> 00:07:16,440 that you can use 175 00:07:16,440 --> 00:07:17,700 in your 176 00:07:17,700 --> 00:07:19,110 udev rules. 177 00:07:19,110 --> 00:07:20,700 So that is what I wanna do now. 178 00:07:20,700 --> 00:07:22,563 I want to create a custom rule. 179 00:07:23,610 --> 00:07:24,660 So to make it easier 180 00:07:24,660 --> 00:07:26,640 to create a custom rule, 181 00:07:26,640 --> 00:07:28,770 I'm providing it as an example file 182 00:07:28,770 --> 00:07:30,780 in the course get repository. 183 00:07:30,780 --> 00:07:34,080 The name of the file's 50-custom.rules 184 00:07:34,080 --> 00:07:36,510 And in this custom rule we define an action. 185 00:07:36,510 --> 00:07:39,240 So the action is "add" on the subsystem "block" 186 00:07:39,240 --> 00:07:42,180 and the driver involved is USB-storage 187 00:07:42,180 --> 00:07:43,980 And if that is going to happen, 188 00:07:43,980 --> 00:07:45,000 then we are going to 189 00:07:45,000 --> 00:07:46,410 create a symbolic link. 190 00:07:46,410 --> 00:07:47,910 This symbolic link is created 191 00:07:47,910 --> 00:07:49,920 in the /dev directory. 192 00:07:49,920 --> 00:07:52,460 So it creates /dev/usb/ 193 00:07:53,310 --> 00:07:54,420 We will see. 194 00:07:54,420 --> 00:07:57,240 And this is the power of udev. 195 00:07:57,240 --> 00:08:00,480 It allows you to run any arbitrary command 196 00:08:00,480 --> 00:08:03,238 and in this case the arbitrary command is 197 00:08:03,238 --> 00:08:08,010 /usr/bin/logger CUSTOMUDEV Added %k 198 00:08:08,010 --> 00:08:10,923 which is printing the message to udev. 199 00:08:11,880 --> 00:08:13,680 Now to have this work, 200 00:08:13,680 --> 00:08:15,810 I need to make sure that we copy the custom rule 201 00:08:15,810 --> 00:08:17,493 to the appropriate location. 202 00:08:18,990 --> 00:08:21,840 And here we are going to respect the convention 203 00:08:21,840 --> 00:08:25,619 that custom stuff is in the /etc directory. 204 00:08:25,619 --> 00:08:28,530 /usr/lib is for the default stuff, 205 00:08:28,530 --> 00:08:31,680 custom files are in the /etc directory, 206 00:08:31,680 --> 00:08:34,210 in this case in /etc/udev/rules.d 207 00:08:35,220 --> 00:08:37,530 So, there we go. 208 00:08:37,530 --> 00:08:39,000 Just to make sure it's picked up, 209 00:08:39,000 --> 00:08:40,800 systemctl restart 210 00:08:40,800 --> 00:08:41,880 systemd-udevd 211 00:08:41,880 --> 00:08:43,300 systemd-udevd 212 00:08:44,580 --> 00:08:46,465 and now I'm going to 213 00:08:46,465 --> 00:08:49,680 disconnect the USB thumb drive 214 00:08:49,680 --> 00:08:51,813 and I'm going to reconnect it. 215 00:08:54,090 --> 00:08:55,590 So how can we verify? 216 00:08:55,590 --> 00:08:58,833 Well journalctl | grep CUSTOMUDEV. 217 00:09:02,280 --> 00:09:03,662 And there we can see, yay, 218 00:09:03,662 --> 00:09:06,060 CUSTOMUDEV Added sdb. 219 00:09:06,060 --> 00:09:06,990 That's a command 220 00:09:06,990 --> 00:09:08,400 that we have defined 221 00:09:08,400 --> 00:09:10,020 in the custom rule file. 222 00:09:10,020 --> 00:09:11,220 And that is how you can create 223 00:09:11,220 --> 00:09:12,633 your own udev rules.