Создание демона в среде Linux

Конспект в доработке

    Процессы демонов

    Процесс демона является процессом фоновой службы, переодически выполняет задачи и ожидает какие либо события.
    Как правило демоны запускаются во время загрузки системы.
    Чтобы вывести список процессов где есть демоны, необходимо выполнить следующую команду:

    ps -ajx

    Демоны не привязаны к терминалу, TPGID = -1, UID = 0, родительский процесс PPID = 1 (init)
    -j - показать информацию о задании, где TPGID - идентификатор группы процессов переднего плана не связанная с терминалом, TTY - терминал управления, PGID - идентификатор группы процессов, SID - идентификатор сеанса.
    -x - показать процессы без управления терминалом

    toly@X250:~$ ps -ajx | head -n 1 ; ps -ajx | grep cron PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 1 748 748 748 ? -1 Ss 0 0:01 /usr/sbin/cron -f 22231 2395 2390 22231 pts/2 2390 S+ 1000 0:00 grep --color=auto cron

    После входа в систему создается процесс лидер, для лидера и для его дочерних процессов PID = SID
    Терминал через который входит пользователь становится управляющим для сеанса.
    Процесс лидера сеанса - контроль процесса
    1 сеанс 1 терминал
    TPGID идентификатор группы процессов, определяет, входит ли процесс в группу процессов связанных с терминалом. Если процесс не связан не с одним терминалом, его значение = -1.
    В группе приоритетных процессов(переднего плана) TPGID = PGID, в группе фоновых процессов TPGID != PGID
    Чтобы убедиться в этом, запустить две инструкция сначала в фоновом режиме, затем на переднем плане:

    ping 127.0.1.1 | grep icmp > temp & ping 127.0.1.1 | grep icmp

    Сравним:

    toly@X250:~$ ps -ajx | head -n 1; ps -ajx | grep -e ping -e icmp -e 4857 PPID PID PGID SID TTY TPGID STAT UID TIME COMMAND 22231 4342 4342 22231 pts/2 4857 S 1000 0:00 ping 127.0.1.1 22231 4857 4857 22231 pts/2 4857 S+ 1000 0:00 ping 127.0.1.1 6097 22231 22231 22231 pts/2 4857 Ss 1000 0:01 bash

    Видно что у всех одинаковый SID(один сеанс, одна оболочка) и там где запущен фоновый режим, значение PID отличается от TGPID.
    Видно, что bash является лидером сессии и TTY = 22231(PID bash)
    Создание процесса демона fork()
    Смена рабочей директории демона chdir()
    Очистить маску создания файла демоном umask(0)

    В языке C:
    #include pid_t setsid(void) создает новый сеанс и процесс, отбрасывается родительский. Здесь инфа
    Если при вызове процесс уже является лидером, тогда функция возвращает ошибку.
    При выполнении этой функции создается процесс лидер и его группа процессов, родительский процесс отбрасывается и становится потерянным.
    Если процесс был привязан к родительскому терминалу, то терминал также отбрасывается.
    В Linux найденный потерянный процесс будет автоматически принят процессом init, причем не обязательно init, в некоторых дистрибутивах, это может быть пользовательский процесс.

    Процесс создания демона

    Создать дочерний процесс
    Создать новый сеанс в дочернем процессе
    Как раз таки здесь используется системная функция sedsid()
    Идентификатор группы процессов является обязательным атрибутом процесса, снятие этого идентификатора с руководителя группы процессов не повлияет на идентификатор группы процесса.
    С начала запуска сеанса все процессы принадлежат одному сеансу.
    Вызов sedsid нужен для того чтобы освободить процесс от контроля предыдущего сеанса, удалить процесс из контроля исходной группы процессов, дать процессу выйти из под контроля управляющего терминала.
    Пока функция не задействована, предыдущий процесс, группа процессов и управляющий терминал не изменились, поэтому они не являются независимыми и могут контролироваться другими процессами.
    Изменить текущий каталог на корневой каталог
    Для этого есть функция chdir()
    Сбросить маску разрешения файла
    Дочерний процесс созданный fork() наследует родительскую маску прав доступа. Для сброса маски используется функция umask()
    Закрыть дескриптор файла
    Добавить журнал логов
    openlog() это функция, которая используется для открытия ссылки на syslog
    syslog() функция для формата и приоритета вывода сообщений в журнал
    closelog() закрывает ссылку на syslog
    syslog служба управления журналами linux

    Реализация демона
    #include<stdio.h> #include<fcntl.h> #include<syslog.h> #include<sys/types.h> #include<unistd.h> #include<sys/wait.h> #include<stdlib.h> #include<string.h> int main() { int i, fdes; char *buffer = "My name is Demon\n"; pid_t pid; //pid_t тип данных для id процесса pid = fork(); //Выполнение первого шага if(pid < 0) { printf("Error\n"); exit(1); } else if(pid > 0) { exit(0); //родительский процесс завершается } //Открыть ссылку на системный журнал openlog("syslog-demon", LOG_PID, LOG_DAEMON); if((setsid()) < 0) { syslog(LOG_ERR, "%s\n", "setsid()"); //Выполнение второго шага exit(1); } if((chdir("/")) < 0) { syslog(LOG_ERR, "%s\n", "chdir"); //Выполнение третьего шага exit(1); } umask (0); //Выполнение четвертого шага for(i = 0; i <getdtablesize(); i ++) //Выполнение пятого шага { close(i); } //Конец создания демона //Задание демона while(1) { if((fdes = open("/tmp/demon.log", O_CREAT|O_WRONLY|O_APPEND, 0600)) < 0) { syslog(LOG_ERR, "%s\n", "open"); exit(1); } write(fdes, buffer, strlen(buffer) + 1); close(fdes); sleep(5); } closelog(); exit(0); }

    Результат выполнения

    $ ps -ajx | grep demon1 1219 7000 7000 7000 ? -1 Ss 1000 0:00 ./demon1 1219 7971 7971 7971 ? -1 Ss 1000 0:00 ./demon1 5565 7976 7975 5565 pts/0 7975 S+ 1000 0:00 grep --color=auto demon1
    Запуск демона

    Для запуска демона необходим сценарий инициализации


    Источники
    Последнее изменение: 07.10.2024 20:15


    Здесь пока нет комментариев
    Добавлять комментарии могут только авторизованные пользователи

    Авторизоваться
    Я буду рекламой
    Я тоже буду рекламой
    И я
    ВВЕРХ