управление демоном
От: Force_Majeure Россия  
Дата: 03.09.05 05:35
Оценка:
Написал простейшего демона, разделив процесс через fork() и setsid(). Родитель завершается, в потомке бесконечный while(1). Подскажите, как теперь сделать управление процессом потомка через команды? Например как обычные демоны, пишешь service iptables stop и iptables завершается. Как сделать такое для моего демона? Видимо я что-то недопонимаю с обработкой сигналов, разъясните, плz.
Re: управление демоном
От: Kubyshev Andrey  
Дата: 03.09.05 07:59
Оценка:
Если ты профессионал (или хочешь им стать) он не понимаешь важных вещей то надо немедленно прочитать книжку. Благо есть на русском очень хорошая. Стевенс "unix: взаимодействие процессов"
Re: управление демоном
От: fefelov Россия  
Дата: 03.09.05 08:18
Оценка:
Здравствуйте, Force_Majeure, Вы писали:

F_M>Написал простейшего демона, разделив процесс через fork() и setsid(). Родитель завершается, в потомке бесконечный while(1). Подскажите, как теперь сделать управление процессом потомка через команды? Например как обычные демоны, пишешь service iptables stop и iptables завершается. Как сделать такое для моего демона? Видимо я что-то недопонимаю с обработкой сигналов, разъясните, плz.


Команда service stop SRV просто вызывает скрипт /etc/init.d/SRV с параметром stop. А уж этот скрипт выполняет соответствующее действие (которое зависит от самого сервиса), например, "киляет" процесс по его PID, выполняя что-то вроде kill `pgrep SRV`. Посмотрите тексты скриптов из каталога /etc/init.d/.
Re[2]: управление демоном
От: Force_Majeure Россия  
Дата: 04.09.05 03:06
Оценка:
Здравствуйте, fefelov, Вы писали:

F>Здравствуйте, Force_Majeure, Вы писали:


F_M>>Написал простейшего демона, разделив процесс через fork() и setsid(). Родитель завершается, в потомке бесконечный while(1). Подскажите, как теперь сделать управление процессом потомка через команды? Например как обычные демоны, пишешь service iptables stop и iptables завершается. Как сделать такое для моего демона? Видимо я что-то недопонимаю с обработкой сигналов, разъясните, плz.


F>Команда service stop SRV просто вызывает скрипт /etc/init.d/SRV с параметром stop. А уж этот скрипт выполняет соответствующее действие (которое зависит от самого сервиса), например, "киляет" процесс по его PID, выполняя что-то вроде kill `pgrep SRV`. Посмотрите тексты скриптов из каталога /etc/init.d/.


т.е. получается, что "общаться" с демоном можно только передавая ему сигналы, а внутри него переопределяя обработчики этих сигналов? Есть-ли какой-то дипазон сигналов, предназначенный для пользовательских нужд или для этого нужно использовать системные?
Re[3]: управление демоном
От: fefelov Россия  
Дата: 04.09.05 04:38
Оценка: 2 (1)
Здравствуйте, Force_Majeure, Вы писали:

F_M>т.е. получается, что "общаться" с демоном можно только передавая ему сигналы, а внутри него переопределяя обработчики этих сигналов? Есть-ли какой-то дипазон сигналов, предназначенный для пользовательских нужд или для этого нужно использовать системные?


Не только. Посмотрите, например, здесь:

8. Средства межпроцессного взаимодействия

Рассматриваются средства локального межпроцессного взаимодействия — каналы, сигналы, очереди сообщений, семафоры, разделяемые сегменты памяти.

Re[4]: управление демоном
От: aka50 Россия  
Дата: 04.09.05 07:08
Оценка: 9 (3) +2
Здравствуйте, fefelov, Вы писали:

F>Не только. Посмотрите, например, здесь:

F>

F>8. Средства межпроцессного взаимодействия

F>Рассматриваются средства локального межпроцессного взаимодействия — каналы, сигналы, очереди сообщений, семафоры, разделяемые сегменты памяти.


У всех этих ipc (очереди сообщений, семафоры, разделяемые сегменты памяти) есть плохие моменты:
— они не удаляются после аварийного завершения процесса (или если процесс "забыл" из удалить). Приходится их потом чистить ipсrm.
— они конечны (нужно подкручивать sysctl или /proc чтоб на все хватало)

По этому если ничего специального не надо, лучше обойтись двумя вещами:
1. Сигнал — это просто пнуть процесс. Просто и дешего .
2. unix socket — это уже полноценный канал управления.
Re[5]: управление демоном
От: Force_Majeure Россия  
Дата: 04.09.05 10:46
Оценка:
Здравствуйте, aka50, Вы писали:

A>Здравствуйте, fefelov, Вы писали:


F>>Не только. Посмотрите, например, здесь:

F>>

F>>8. Средства межпроцессного взаимодействия

F>>Рассматриваются средства локального межпроцессного взаимодействия — каналы, сигналы, очереди сообщений, семафоры, разделяемые сегменты памяти.


A>У всех этих ipc (очереди сообщений, семафоры, разделяемые сегменты памяти) есть плохие моменты:

A>- они не удаляются после аварийного завершения процесса (или если процесс "забыл" из удалить). Приходится их потом чистить ipсrm.
A>- они конечны (нужно подкручивать sysctl или /proc чтоб на все хватало)

A>По этому если ничего специального не надо, лучше обойтись двумя вещами:

A>1. Сигнал — это просто пнуть процесс. Просто и дешего .
A>2. unix socket — это уже полноценный канал управления.

Похоже действительно оптимальный путь — создать сокет и через него командами управлять демоном.
Re[6]: управление демоном
От: aka50 Россия  
Дата: 05.09.05 10:09
Оценка:
Здравствуйте, Force_Majeure, Вы писали:

F_M>Здравствуйте, aka50, Вы писали:


A>>2. unix socket — это уже полноценный канал управления.


F_M>Похоже действительно оптимальный путь — создать сокет и через него командами управлять демоном.

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

#define SIGSOCK_WRFD 0
#define SIGSOCK_RDFD 1
int g_sigsock[2]; // это можно при старте сосздать как socketpair(AF_UNIX ...)

//где-то в main()
{
     socketpair(AF_UNIX, SOCK_DGRAM, 0, g_sigsock); // можно и SOCK_STREAM, но если буфер переполнится
                                                    // можно в send() заблокироваться. А он там не большой (вроде 
                                                    // 32к в FreeBSD... точно уже не помню)
}

sig_handler(int sig)
{
    case SIGHUP:
       send(g_sigsock[SIGSOCK_RDFD], "H", 1, 0);
       break;
    ....
}

// где-то в коде через select или просто в блокирующем режимe
// в другой нити

{
    char sigchar[1];
    int rc = recv(g_sigsock[1], sigchar, 1, 0);
    if (rc // ошибка можно завершаться ;) )
...
    switch (sigchar[0])
    {
        case 'H':
          // тут пинаем другие потоки или еще что-то делаем чтобы обработать HUP
    }

}

Помимо разных бонусов это еще позволяет сериализовать поступающие сигналы и не получить
какойнибудь UB.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.