[CRIU] [PATCH] service: rotate log by SIGHUP
Vladimir Davydov
vdavydov at parallels.com
Tue Feb 11 00:37:19 PST 2014
On 02/11/2014 12:17 PM, Ruslan Kuprieiev wrote:
> On 11.02.2014 12:11, Vladimir Davydov wrote:
>> On 02/11/2014 11:49 AM, Ruslan Kuprieiev wrote:
>>> On 11.02.2014 11:28, Vladimir Davydov wrote:
>>>> On 02/11/2014 11:11 AM, Ruslan Kuprieiev wrote:
>>>>> Because we wan't service to work non-stop.
>>>>> And, as far as I know, by just using logrotate we will need to
>>>>> restart
>>>>> service.
>>>> Not necessarily, you can specify what should be done after rotate
>>>> (`postrotate'), e.g. send a signal to your service so that it could
>>>> reopen the logfile. However, I guess that `copytruncate' would be
>>>> enough
>>>> in your case.
>>> But what if service will write something between the moment when
>>> logrotate will copy log and the moment when it will send signal to
>>> service?
>> Oh, if your logs are so valuable that loosing a message or two once a
>> day/week/month is a disaster, then logrotate is, of course, not an
>> option for you, sorry.
> =)
>> However, from what I see you have the same race in your implementation:
>> what if somebody prints to log while you're renaming it (after
>> log_fini(), but before log_init())? Errors will go to stderr, which
>> should be closed for a daemon?
>
> In theory, no one, except service daemon, can write to that log.(In
> theory, because we are not shutting down log for children, but it
> needs to be done soon).
Oh, if it's single-threaded and have no children sharing the log fd,
then your approach is safe.
I just want to say that I've never seen a daemon implementing its own
logrotate instead of using existing one, just to eliminate any
possibility of loosing a message. Even those daemons that need to run
non-stop (e.g. libvirtd) prefer to use logrotate with `copytruncate'...
> And as it rotate log in signal handler, service can't write to log,
> while signal handler is working.
>
>>>>> On 11.02.2014 10:59, Vladimir Davydov wrote:
>>>>>> Sorry for butting in, but why don't you use logrotate(8)?
>>>>>>
>>>>>> On 02/11/2014 10:41 AM, Ruslan Kuprieiev wrote:
>>>>>>> Many existing daemons rotate logs by SIGHUP, so lets do the same
>>>>>>> with our service.
>>>>>>>
>>>>>>> Signed-off-by: Ruslan Kuprieiev <kupruser at gmail.com>
>>>>>>> ---
>>>>>>> cr-service.c | 30 ++++++++++++++++++++++++++----
>>>>>>> 1 file changed, 26 insertions(+), 4 deletions(-)
>>>>>>>
>>>>>>> diff --git a/cr-service.c b/cr-service.c
>>>>>>> index 26dd3e2..49454e7 100644
>>>>>>> --- a/cr-service.c
>>>>>>> +++ b/cr-service.c
>>>>>>> @@ -489,12 +489,21 @@ static void reap_worker(int signo)
>>>>>>> }
>>>>>>> }
>>>>>>> -static int setup_sigchld_handler()
>>>>>>> +static void rotate_log(int signo)
>>>>>>> +{
>>>>>>> + pr_info("Rotating log.\n");
>>>>>>> +
>>>>>>> + if (log_rotate())
>>>>>>> + exit(1);
>>>>>>> +}
>>>>>>> +
>>>>>>> +static int setup_signal_handlers()
>>>>>>> {
>>>>>>> struct sigaction action;
>>>>>>> sigemptyset(&action.sa_mask);
>>>>>>> sigaddset(&action.sa_mask, SIGCHLD);
>>>>>>> + sigaddset(&action.sa_mask, SIGHUP);
>>>>>>> action.sa_handler = reap_worker;
>>>>>>> action.sa_flags = SA_RESTART;
>>>>>>> @@ -503,15 +512,23 @@ static int setup_sigchld_handler()
>>>>>>> return -1;
>>>>>>> }
>>>>>>> + action.sa_handler = rotate_log;
>>>>>>> +
>>>>>>> + if (sigaction(SIGHUP, &action, NULL)) {
>>>>>>> + pr_perror("Can't setup SIGUSR1 handler");
>>>>>>> + return -1;
>>>>>>> + }
>>>>>>> +
>>>>>>> return 0;
>>>>>>> }
>>>>>>> -static int restore_sigchld_handler()
>>>>>>> +static int restore_signal_handlers()
>>>>>>> {
>>>>>>> struct sigaction action;
>>>>>>> sigemptyset(&action.sa_mask);
>>>>>>> sigaddset(&action.sa_mask, SIGCHLD);
>>>>>>> + sigaddset(&action.sa_mask, SIGHUP);
>>>>>>> action.sa_handler = SIG_DFL;
>>>>>>> action.sa_flags = SA_RESTART;
>>>>>>> @@ -520,6 +537,11 @@ static int restore_sigchld_handler()
>>>>>>> return -1;
>>>>>>> }
>>>>>>> + if (sigaction(SIGHUP, &action, NULL)) {
>>>>>>> + pr_perror("Can't restore SIGHUP handler");
>>>>>>> + return -1;
>>>>>>> + }
>>>>>>> +
>>>>>>> return 0;
>>>>>>> }
>>>>>>> @@ -596,7 +618,7 @@ int cr_service(bool daemon_mode)
>>>>>>> }
>>>>>>> }
>>>>>>> - if (setup_sigchld_handler())
>>>>>>> + if (setup_signal_handlers())
>>>>>>> goto err;
>>>>>>> while (1) {
>>>>>>> @@ -615,7 +637,7 @@ int cr_service(bool daemon_mode)
>>>>>>> if (child_pid == 0) {
>>>>>>> int ret;
>>>>>>> - if (restore_sigchld_handler())
>>>>>>> + if (restore_signal_handlers())
>>>>>>> exit(1);
>>>>>>> close(server_fd);
>
More information about the CRIU
mailing list