orangepi – hot swap udev mechanism for linux (daemon process)

1. Introduction to udev

1 Introduction:

udev is a device management tool. udev runs as a daemon process, and manages device files in the /dev directory by listening to uevents sent by the kernel.

udev runs in user space, not kernel space. It can dynamically update device files according to the status of hardware devices in the system, including file creation, deletion, etc. Device files are usually placed in the /dev directory. After using udev, only the devices that actually exist in the system are included in the /dev directory.

The application space will call library functions→library functions provided by the system, and the system will intervene in the kernel when calling.

For example, read → call syst_read → call the kernel in the file implemented by yourself to read the contents of the register (hardware).

2. In the last class, the mobile phone was inserted into udev to use

It is because the meizu-android.rules rule program for Meizu mobile phone insertion is created under /etc/udev/rules.d/

orangepi@orangepizero2:/etc/udev/rules.d$ cat meizu-android.rules
SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_device", MODE="0666"
SUBSYSTEM=="usb_device", SYSFS{idVendor}=="2A45", MODE="0666"

Otherwise, udev has no way to insert the node that provides access to the usb mobile phone

3. Realize hot-swapping of U disk, udev automatic mounting

When a new device is inserted, the first thing to know about this event is the Linux kernel. The kernel will notify the application layer of this event. If the application layer ignores this event. When it is necessary to open and read the hardware (everything in linux is a file, and the newly connected hardware is also a file), if there is no access right to the newly connected device, then the upper layer instructions cannot manage the device.

udev captures the event notification of the hardware device, tells the application layer and the operating system layer that a new device is inserted, manages the device, and creates a file. Write permission 0666, readable and writable. Allows application layer access.

2. Daemon process: linux Daemon

1 Introduction:

It is a special process that runs in the background. It is independent of the controlling terminal and periodically performs some task or waits for some event to occur. It runs without user input and provides a service, either to the system as a whole or to a user program.

Most servers in the Linux system are implemented through daemon processes. Common daemon processes include the system log process syslogd, the web server httpd, the mail server sendmail, and the database server mysqld. Daemon process names usually end in d. Instruction ps -elf: can view the process (with square brackets is the kernel daemon process)

ps -elf |grep a.out: (view the a.out daemon and the process)

ps -elf |grep a.out|grep -v grep (check a.out process, ignore the process itself)

udev is a daemon process, which can dynamically update device files according to the status of hardware devices in the system, including the creation and deletion of device files.

2. Features;

①The life cycle is long. Generally, the operating system starts when it starts and shuts down when it is closed. (manually to set)

②The daemon process is not associated with the terminal, that is, they do not have a control terminal, so when the control terminal exits, it will not cause the daemon process to exit.

③The daemon process runs in the background and does not occupy the terminal, and the terminal can execute other commands.

④The parent process of a daemon process is the init process, because its real parent process exits before the Forbidden City exit after fork, so it is an orphan process inherited by init

The Linux operating system itself has many daemon processes running silently, maintaining the daily activities of the system, about 30-50

orangepi@orangepizero2:/etc/udev/rules.d$ ps -efj
UID PID PPID PGID SID C STIME TTY TIME CMD
root 1 0 1 1 0 04:04 ? 00:00:07 /sbin/init
root 2 0 0 0 0 04:04 ? 00:00:00 [kthreadd]
root 4 2 0 0 0 04:04 ? 00:00:00 [kworker/0:0H]
root 6 2 0 0 0 04:04 ? 00:00:03 [ksoftirqd/0]
root 7 2 0 0 0 04:04 ? 00:00:34 [rcu_preempt]
root 8 2 0 0 0 04:04 ? 00:00:05 [rcu_sched]
root 9 2 0 0 0 04:04 ? 00:00:00 [rcu_bh]
root 10 2 0 0 0 04:04 ? 00:00:00 [migration/0]
root 11 2 0 0 0 04:04 ? 00:00:00 [lru-add-drain]
root 12 2 0 0 0 04:04 ? 00:00:00 [cpuhp/0]
root 13 2 0 0 0 04:04 ? 00:00:00 [cpuhp/1]
root 14 2 0 0 0 04:04 ? 00:00:00 [migration/1]
root 15 2 0 0 0 04:04 ? 00:00:02 [ksoftirqd/1]
root 17 2 0 0 0 04:04 ? 00:00:00 [kworker/1:0H]
root 18 2 0 0 0 04:04 ? 00:00:00 [cpuhp/2]
root 19 2 0 0 0 04:04 ? 00:00:00 [migration/2]
root 20 2 0 0 0 04:04 ? 00:00:02 [ksoftirqd/2]
root 22 2 0 0 0 04:04 ? 00:00:00 [kworker/2:0H]
root 23 2 0 0 0 04:04 ? 00:00:00 [cpuhp/3]
root 24 2 0 0 0 04:04 ? 00:00:00 [migration/3]
root 25 2 0 0 0 04:04 ? 00:00:02 [ksoftirqd/3]

ppid=0: The kernel process starts with the system startup, and its life cycle runs through the entire system

cmd with []: called the kernel daemon process. Those without [] are normal daemons (user set daemons)

The ancestor init: the system daemon process, responsible for starting specific system services at each operating level; the ppid of many processes is init, and is also responsible for adopting orphan processes.

3. The development method of the daemon process

1. Method 1:

Use the daemon function

#include <unistd.h>

int daemon(int nochdir, int noclose);


/* function parameters
nochdir: When it is 0, it means change the current directory to "/"
noclose: When it is 0, it means that the standard input, standard output, and standard error are redirected to "/dev/null"
Return value: return 0 on success, return -1 on failure
*/

Code demonstration: run the code and create a daemon process

#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>
#include <stdbool.h>
//C library function char *asctime(const struct tm *timeptr) returns a pointer to a string, which represents the date and time of the structure struct timeptr.
//The C library function struct tm *localtime(const time_t *timer) fills the tm structure with the value of timer. The value of timer is broken into a tm structure and represented in the local time zone.
/*
   struct tm {
   int tm_sec; seconds, range from 0 to 59
   int tm_min; minute, range from 0 to 59
   int tm_hour; hour, range from 0 to 23
   int tm_mday; day of the month, range from 1 to 31
   int tm_mon; month, range from 0 to 11
   int tm_year; year since 1900
   int tm_wday; day of the week, ranges from 0 to 6
   int tm_yday; day of the year, ranges from 0 to 365
   int tm_isdst; daylight saving time
   };
   */
static bool flag = true;
void handler(int sig)
{
        printf("I got a signal %d\\
I'm quitting.\\
", sig);
        flag = false;
}
int main()
{
        time_t t;
        int fd;
        //Create daemon process
        if(-1 == daemon(0, 0))
        {
                printf("daemon error\\
");
                exit(1);
        }
        //Set signal handler function
        struct sigaction act;
        act.sa_handler = handler;
        sigemptyset( &act.sa_mask);
        act.sa_flags = 0;
        if(sigaction(SIGQUIT, & act, NULL))
        {
                printf("sigaction error.\\
");
                exit(0);
        }
        //Process work content
        while(flag)
        {
                fd = open("/home/orangepi/daemon.log", O_WRONLY | O_CREAT | O_APPEND,0644);
                if(fd == -1)
                {
                        printf("open error\\
");
                }
                t = time(0);
                char *buf = asctime(localtime( &t));
                write(fd, buf, strlen(buf));
                close(fd);
                sleep(10);
        }
        return 0;
}

Compile the code: gcc timedaemon.c

Run the code: ./a.out

You can see that the /home/orangepi/daemon.log path generates a daemon.log file, and the time information is stored in it.

Command: ps -ef|grep a.out: View the running status of the a.out process & amp;pid number

Command: kill -3 pid: kill the a.out process

2. Self-starting at boot;

Command: sudo vi /etc/rc.local: Open the file storing the daemon process (absolute path plus startup name)

Paste the file path of the daemon into this file: ls /home/orangepi/cbak/tdaemon (add -o when compiling to generate a tdaemon executable file)

It can prevent the program from crashing and exiting unexpectedly, and can restart itself

3. Method 2

Use fork to create sub-process implementation, Baidu blog post implementation