Calling a sd_notify(0, "WATCHDOG=1") in a service

11,475

Solution 1

sd_notify(0,"WATCHDOG=1") is a API for notifying systemd that your process is working fine.

As Type=notify has been used, sd_notify(0,"WATCHDOG=1") should be called in your application not in service and this must be called at regular interval(before 30 sec as WatchdogSec=30s is mentioned in your service file) so that systemd get notified else,

systemd will think of this as failed service and hence systemd will kill your service and restart it.

Solution 2

I had to install systemd lib:

sudo apt-get install libsystemd-dev

And compile the program passing it to linker:

gcc testWatchDogProcess.c -o testWatchDogProcess -lsystemd

I´ve made some changes in @rameshrgtvl code to make it run directly without any warning or errors.

#include <systemd/sd-daemon.h>
#include <fcntl.h>
#include <time.h>
/* This should be sent once you are done with your initialization */
/* Until you call this systemd will keep your service as activating status */
/* Once you called, systemd will change the status of ur service to active */

#define true  1

int main ()
{
        sd_notify (0, "READY=1");

        /* Way to get the WatchdogSec value from service file */
        char * env;
        int interval=0;
        int isRun = true;
        env = getenv("WATCHDOG_USEC");
        if (env)
        {
                interval = atoi(env)/(2*1000000);
        }
        /* Ping systsemd once you are done with Init */
        sd_notify (0, "WATCHDOG=1");

        /* Now go for periodic notification */
        while(isRun == true)
        {
                sleep(interval);
            /* Way to ping systemd */
                sd_notify (0, "WATCHDOG=1");
        }
        return 0;
}

Solution 3

Sample Service File

[Unit]
Description=Test watchdog Demo process
DefaultDependencies=false
Requires=basic.target

[Service]
Type=notify
WatchdogSec=10s
ExecStart=/usr/bin/TestWatchDogProcess
StartLimitInterval=5min
StartLimitBurst=5
StartLimitAction=reboot
Restart=always

Sample Code For testWatchDogProcess.c:

#include "systemd/sd-daemon.h"
#include <fcntl.h>
#include <time.h>

/* This should be sent once you are done with your initialization */
/* Until you call this systemd will keep your service as activating status */
/* Once you called, systemd will change the status of ur service to active */

sd_notify (0, "READY=1");

/* Way to get the WatchdogSec value from service file */
env = getenv("WATCHDOG_USEC");
if(env != NULL)
int interval = atoi(env)/(2*1000000);

/* Ping systsemd once you are done with Init */
sd_notify (0, "WATCHDOG=1");

/* Now go for periodic notification */
while(isRun == true)
{
    sleep(interval);
    /* Way to ping systemd */
    sd_notify (0, "WATCHDOG=1");
}

    return 0;

}

Note: Based on your systemd version please take care to include proper header and library during compilation.

Share:
11,475
pnv
Author by

pnv

Hi there, I am a polyglot guy that has strong experience in Python/Golang/Docker/Swarms on the backend side, and hands-on experience on javascript/react/HTML/CSS on the frontend side of the tech stack. I am well versed in building things from scratch and have a bias towards Golang/Python when it comes to building stuff from the ground up. However, I am willing to learn new languages and frameworks as and when necessary.

Updated on July 27, 2022

Comments

  • pnv
    pnv over 1 year

    I have a sys d service. I want to implement a watch dog for that. It's something like,

    [Unit]
    Description=Watchdog example service
    
    [Service]
    Type=notify
    Environment=NOTIFY_SOCKET=/run/%p.sock
    ExecStartPre=-/usr/bin/docker kill %p
    ExecStartPre=-/usr/bin/docker rm %p
    ExecStart=/usr/libexec/sdnotify-proxy /run/%p.sock /usr/bin/docker run \
        --env=NOTIFY_SOCKET=/run/%p.sock \
        --name %p pranav93/test_watchdogged python hello.py
    ExecStop=/usr/bin/docker stop %p
    
    Restart=on-success
    WatchdogSec=30s
    RestartSec=30s
    
    
    [Install]
    WantedBy=multi-user.target
    

    According to docs I've to call sd_notify("watchdog=1") every half of the interval specified (In this case it's 15s). But I've no idea how to call that function in a service. Help would be highly appreciated.

  • fabatera
    fabatera almost 8 years
    Now I see that was you sharing the code, @rameshrgtvl . Thanks!