Гость
Целевая тема:
Создать новую тему:
Автор:
Форумы / C++ [игнор отключен] [закрыт для гостей] / Демон под Linux с возможностью восстановления работы / 3 сообщений из 3, страница 1 из 1
17.07.2013, 20:24
    #38334755
Alex_leshii_
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Демон под Linux с возможностью восстановления работы
Пишу демона под Centos на С++ с контролем работы дочерних процессов.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
120.
121.
122.
123.
124.
125.
126.
127.
128.
129.
130.
131.
132.
133.
134.
135.
136.
137.
138.
139.
140.
141.
142.
143.
144.
145.
146.
147.
148.
149.
150.
151.
152.
153.
154.
155.
156.
157.
158.
159.
160.
161.
162.
163.
164.
165.
166.
167.
168.
169.
170.
171.
172.
173.
174.
175.
176.
177.
178.
179.
180.
181.
182.
183.
184.
185.
186.
187.
188.
189.
190.
191.
192.
193.
194.
195.
196.
197.
198.
199.
200.
201.
202.
203.
204.
205.
206.
207.
208.
209.
210.
211.
212.
213.
214.
215.
216.
217.
218.
219.
220.
221.
222.
223.
224.
225.
226.
227.
228.
229.
230.
231.
232.
233.
234.
235.
236.
237.
238.
239.
240.
241.
242.
243.
244.
245.
246.
247.
248.
249.
250.
251.
252.
253.
254.
255.
256.
257.
258.
259.
260.
261.
262.
263.
#define CHILD_NEED_WORK                 1
#define CHILD_NEED_TERMINATE    2

int ReloadConfig()
{
    ....
    return 0;
}

void DestroyWorkThread()
{...}

int InitWorkThread()
{
     ...
    return 0;
}

int LoadConfig(char* FileName)
{
     ...
    return 0;
}

void SetPidFile(char* Filename)
{
    FILE* f;
    f = fopen(Filename, "w+");
    if (f)
    {
        fprintf(f, "%u\n", getpid());
        fclose(f);
    }
}

int SetFdLimit(int MaxFd)
{
    struct rlimit lim;
    int          status;

    lim.rlim_cur = MaxFd;
    lim.rlim_max = MaxFd;

    status = setrlimit(RLIMIT_NOFILE, &lim);

    return status;
}

//Процесс мониторинга
int MonitorProc()
{
    int      pid;
    int      status;
    int      need_start = 1;
    sigset_t sigset;
    siginfo_t siginfo;
    
    parent_pid = getpid();

    sigemptyset(&sigset);

    sigaddset(&sigset, SIGQUIT);

    sigaddset(&sigset, SIGINT);

    sigaddset(&sigset, SIGTERM);

    sigaddset(&sigset, SIGCHLD);

    sigaddset(&sigset, SIGUSR1);

    sigprocmask(SIG_BLOCK, &sigset, NULL);

    SetPidFile(PID_FILE);
                                                         
    for (;;)
    {
        if (need_start)
        {
            pid = fork();
        }

        need_start = 1;

        if (pid == -1)
        {
            
        }
        else if (!pid) 
        {
            status = WorkProc();

            exit(status);
        }
        else
        {
			//Ожидание сигналов
            sigwaitinfo(&sigset, &siginfo);

            if (siginfo.si_signo == SIGCHLD)
            {
                wait(&status);
                                                                                         
               status = WEXITSTATUS(status);
                                                                                                    
                 if (status == CHILD_NEED_TERMINATE)
                 {
                     Write("[MONITOR] Child stopped");
                     break;
                 }
                 else if (status == CHILD_NEED_WORK)
                 {
                     Write("[MONITOR] Child restart");
                 }
             }
             else if (siginfo.si_signo == SIGUSR1)
             {
                 kill(pid, SIGUSR1); 
                 need_start = 0;
             }
             else if (siginfo.si_signo == 0) 
             {
                need_start = 0;
                continue;
             }
             else
             {
                 Write("[MONITOR] Signal ", strsignal(siginfo.si_signo));
                 kill(pid, SIGTERM);
                 status = 0;
                 break;
             }
         }
     }

     Write("[MONITOR] Stop");
        
     unlink(PID_FILE);

     return status;
}

//Дочерний процесс
int WorkProc()
{
    struct sigaction sigact;
    sigset_t         sigset;
    int             signo;
    int             status;

    sigact.sa_flags = SA_SIGINFO;

    sigact.sa_sigaction = signal_error_for_backtrace;

    sigemptyset(&sigact.sa_mask);

    
    sigaction(SIGFPE, &sigact, 0);
    sigaction(SIGILL, &sigact, 0);
    sigaction(SIGSEGV, &sigact, 0);
    sigaction(SIGBUS, &sigact, 0);

    sigemptyset(&sigset);
    
    sigaddset(&sigset, SIGQUIT);
    
    sigaddset(&sigset, SIGINT);
    
    sigaddset(&sigset, SIGTERM);
    
    sigaddset(&sigset, SIGUSR1);
    sigprocmask(SIG_BLOCK, &sigset, NULL);

    SetFdLimit(FD_LIMIT);
    
    
    status = InitWorkThread();
    
    
    if (!status)
    {
        for (;;)
        {
            sigwait(&sigset, &signo);
        
            if (signo == SIGUSR1)
            {
                status = ReloadConfig();
                if (status)
                {
                    Write("[DAEMON] Reload config failed");
                }
                else
                {
                    Write("[DAEMON] Reload config OK");
                }
            }
            else
            {
                break;
            }
        }
        
        DestroyWorkThread();
    }
    else
    {
        Write("[DAEMON] Create work thread failed");
    }

    Write("[DAEMON] Stopped");
    
    
    return CHILD_NEED_TERMINATE;
}


int main(int argc , char *argv[])
{
     
    if (argc != 2)
    {
        printf("Usage: ./test_daemoun.conf failed!\n");
        return -1;
    }

    status = LoadConfig(argv[1]);
    if (status) 
    {
        printf("Error: Load config failed\n");
        return -1;
    }
    
    if (CheckForAnotherInstance())
    {
	printf("Daemon is already running!\n");
	return 1;
    }
    
    pid = fork();
    if (pid == -1)
    {
        printf("Error: Start Daemon failed (%s)\n", strerror(errno));
        return -1;
    }
    else if (!pid)
    {
        umask(0);
        setsid();
                
        close(STDIN_FILENO);
        close(STDOUT_FILENO);
        close(STDERR_FILENO);
		//Запуск процесса мониторинга
        status = MonitorProc();
        return status;
    }
    else
    {
        return 0;
    }
    return 0;
}



Имеется монитор - основной процесс, и дочерний процесс, в котором выполняются основная обработка. Проблема состоит в том, что при завершении дочернего процесса сигнал SIGCHLD о его завершении родительский процесс не получает.
При этом после отправки из консоли kill -s SIGTERM родительский процесс отлавливает этот сигнал. А самое странное, что при подключении к родительскому процессу с помощью strace все работает как надо - сигнал приходит в родительский процесс.
Читал про функцию waitpid - для отлавливания этого типа сигналов - но хотелось бы более универсального решения.
Подскажите, пожалуйста, что я делаю не так.
...
Рейтинг: 0 / 0
17.07.2013, 21:45
    #38334828
Anatoly Moskovsky
Участник
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Демон под Linux с возможностью восстановления работы
Alex_leshii_,

Так а что ж вы хотели, когда у вас этот сигнал в коде явно блокируется:
Код: plaintext
1.
2.
3.
    sigaddset(&sigset, SIGCHLD);
    ...
    sigprocmask(SIG_BLOCK, &sigset, NULL);
...
Рейтинг: 0 / 0
18.07.2013, 08:47
    #38335039
Alex_leshii_
Гость
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Демон под Linux с возможностью восстановления работы
Anatoly Moskovsky,

Судя по докам, блокировка сигналов должна вызываться перед функцией fork. А затем разблокировка происходит при вызове sigwaitinfo.
...
Рейтинг: 0 / 0
Форумы / C++ [игнор отключен] [закрыт для гостей] / Демон под Linux с возможностью восстановления работы / 3 сообщений из 3, страница 1 из 1
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]