Re: [systemd-devel] sd_watchdog_enabled: how to use when forking process?

2018-01-22 Thread Lennart Poettering
On Fr, 19.01.18 17:41, Simon McVittie (s...@collabora.com) wrote:

> On Fri, 19 Jan 2018 at 17:22:51 +, philip is hungry wrote:
> > however if i run the forkme function (to put process in the background) it
> > behaves as follows:
> > 
> > Jan 18 15:06:25 thinkpad waitonly[11228]: Return from forkme = 11228
> > Jan 18 15:06:25 thinkpad waitonly[11228]: Return from lockme = 0
> > Jan 18 15:06:25 thinkpad waitonly[11228]: PID to compare with watchdog_pid:
> > 11228
> 
> systemd tells your service which process it expects to be sending
> keepalives ($WATCHDOG_PID), and only accepts keepalives from that
> process.

This is not fully correct. We accept keepalives from every process
that NotifyAccess= whitelists... If not specified it will only allow
them from the service's main process, which is the same as the one
indicated in $WATCHDOG_PID, but this is not true for the general
case...

But yeah, in general Simon is right: don't fork if you don#t have
to. And if you do: use NotifyAccess= and make sure that WATCHDOG_PID
matches what you expect then.

(the reason why $WATCHDOG_PID exists is to cancel the usual
inheritance effect of env vars: if we would not set it, and you have
an app that would generically ping $NOTIFY_SOCKET if $WATCHDOG_USEC is
set, then this app called from some arbitrary child process of the
daemon might feel requested to ping PID 1 even though it was only
daemon itself that was supposed to do that...)

Lennart

-- 
Lennart Poettering, Red Hat
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] sd_watchdog_enabled: how to use when forking process?

2018-01-22 Thread Jérémy Rosen
Alternatively, NotifyAccess= in [Service allows other processes to ping 
the watchdog, but Simon is right...


forking is not needed for systemd.

On 19/01/2018 18:41, Simon McVittie wrote:

On Fri, 19 Jan 2018 at 17:22:51 +, philip is hungry wrote:

however if i run the forkme function (to put process in the background) it
behaves as follows:

Jan 18 15:06:25 thinkpad waitonly[11228]: Return from forkme = 11228
Jan 18 15:06:25 thinkpad waitonly[11228]: Return from lockme = 0
Jan 18 15:06:25 thinkpad waitonly[11228]: PID to compare with watchdog_pid:
11228

systemd tells your service which process it expects to be sending
keepalives ($WATCHDOG_PID), and only accepts keepalives from that
process. The forked child process has some other process ID, so
sd_watchdog_enabled() returns false for it.

If you want to use the watchdog, don't fork and go to the background: it's
unnecessary for systemd services. To notify systemd that your process
is ready to receive requests (which was done via the double-fork trick
in init-script-based init systems), a daemon that natively supports
systemd features can use sd_notify() and Type=notify.

If you want your service to continue to support non-systemd init systems,
you might want to add a --no-fork command-line option and make the systemd
unit's ExecStart use that option. For example, that's how it works for
dbus-daemon, which needs to continue to default to forking for
compatibility with what it does on non-Linux OSs or non-systemd init.
Or, if your service will only ever run under systemd, you can make it
not fork/background itself at all.

 smcv
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/systemd-devel


--
SMILE 

20 rue des Jardins
92600 Asnières-sur-Seine


*Jérémy ROSEN*
Architecte technique
Responsable de l'expertise Smile-ECS

email jeremy.ro...@smile.fr 
phone +33141402967
url http://www.smile.eu

Twitter  Facebook 
 LinkedIn 
 Github 




Découvrez l’univers Smile, rendez-vous sur smile.eu 



eco Pour la planète, n'imprimez ce mail que si c'est nécessaire
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/systemd-devel


Re: [systemd-devel] sd_watchdog_enabled: how to use when forking process?

2018-01-19 Thread Simon McVittie
On Fri, 19 Jan 2018 at 17:22:51 +, philip is hungry wrote:
> however if i run the forkme function (to put process in the background) it
> behaves as follows:
> 
> Jan 18 15:06:25 thinkpad waitonly[11228]: Return from forkme = 11228
> Jan 18 15:06:25 thinkpad waitonly[11228]: Return from lockme = 0
> Jan 18 15:06:25 thinkpad waitonly[11228]: PID to compare with watchdog_pid:
> 11228

systemd tells your service which process it expects to be sending
keepalives ($WATCHDOG_PID), and only accepts keepalives from that
process. The forked child process has some other process ID, so
sd_watchdog_enabled() returns false for it.

If you want to use the watchdog, don't fork and go to the background: it's
unnecessary for systemd services. To notify systemd that your process
is ready to receive requests (which was done via the double-fork trick
in init-script-based init systems), a daemon that natively supports
systemd features can use sd_notify() and Type=notify.

If you want your service to continue to support non-systemd init systems,
you might want to add a --no-fork command-line option and make the systemd
unit's ExecStart use that option. For example, that's how it works for
dbus-daemon, which needs to continue to default to forking for
compatibility with what it does on non-Linux OSs or non-systemd init.
Or, if your service will only ever run under systemd, you can make it
not fork/background itself at all.

smcv
___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/systemd-devel


[systemd-devel] sd_watchdog_enabled: how to use when forking process?

2018-01-19 Thread philip is hungry
I am trying to use "sd_watchdog_enabled".  If I run my service without forking, 
the sd_watchdog_enabled function works as expected:

Jan 18 15:05:29 thinkpad systemd[1]: Starting WaitonlyServer...
Jan 18 15:05:30 thinkpad waitonly[11172]: PID before fork  = 11172
Jan 18 15:05:30 thinkpad waitonly[11172]: Return from lockme = 0
Jan 18 15:05:30 thinkpad waitonly[11172]: PID to compare with watchdog_pid: 
11172
Jan 18 15:05:30 thinkpad waitonly[11172]: Return from watchdog = 1

however if i run the forkme function (to put process in the background) it 
behaves as follows:

Jan 18 15:06:25 thinkpad waitonly[11228]: Return from forkme = 11228
Jan 18 15:06:25 thinkpad waitonly[11228]: Return from lockme = 0
Jan 18 15:06:25 thinkpad waitonly[11228]: PID to compare with watchdog_pid: 
11228
Jan 18 15:06:25 thinkpad waitonly[11228]: systemd watchdog not enabled - not 
sending watchdog keepalives!
Jan 18 15:06:25 thinkpad waitonly[11228]: systemd watchdog pid = -1905553534
Jan 18 15:06:25 thinkpad waitonly[11228]: Return from watchdog = 0

where am I going wrong? any help with this is greatly appreciated.

thanks!

main.c ---

pid_t pid;
int watchdogInfo = 0;
int ret;

int main() {

  setlogmask (LOG_UPTO (LOG_INFO));
  openlog (NULL, LOG_CONS | LOG_PID | LOG_NDELAY, LOG_LOCAL1);

  pid = getpid();
  syslog (LOG_NOTICE, "PID before fork  = %d", pid);
  ret = forkme();
  syslog (LOG_NOTICE, "Return from forkme = %d", ret);

  ret = lockme();
  syslog (LOG_NOTICE, "Return from lockme = %d", ret);

  pid = getpid();
  syslog (LOG_NOTICE, "PID after fork  = %d", pid);

  watchdogInfo = systemd_get_watchdog_time();
  syslog (LOG_NOTICE, "Return from watchdog = %d", watchdogInfo);

  for (;;) { // Run forever
    sleep(10);
    syslog (LOG_NOTICE, "Service Running...");
}
}

forkme.c ---

pid_t pid;
int forkme(void) {
  if ((pid = fork()) < 0)
    exit(1);
  else if(pid != 0) /* parent */
    exit(0);
  setsid();
}

lockme.c ---

#define LOCKFILE "/var/run/waitonly.pid"
#define LOCKMODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH)

int lockme(void)
{
  int fd;
  char buf[16];
  fd = open(LOCKFILE, O_RDWR|O_CREAT, LOCKMODE);
  if (fd < 0) {
    syslog(LOG_ERR, "can’t open %s: %s", LOCKFILE, strerror(errno));
    exit(1);
  }
  ftruncate(fd, 0);
  sprintf(buf, "%ld", (long)getpid());
  write(fd, buf, strlen(buf)+1);
  return(0);
}

systemd.c ---

//  return watchdog - 0 means that watchdog is not enabled
int systemd_get_watchdog_time(void)
{
uint64_t usec;
char *watchdog = NULL;
char *watchdog_pid = NULL;
int ret;

ret = sd_watchdog_enabled(0, );

if (ret == 0) {
  syslog (LOG_NOTICE, "systemd watchdog not enabled - not sending watchdog 
keepalives!");
  watchdog_pid = getenv("WATCHDOG_PID");
  syslog (LOG_NOTICE, "systemd watchdog pid = %d", watchdog_pid);
}
if (ret < 0) {
  syslog (LOG_NOTICE, "systemd watchdog returned error %d - not sending 
watchdog keepalives", ret);
}
}
waitonly.service 
---
[Unit]Description=WaitonlyServer 
After=syslog.target networking.service
OnFailure=heartbeat-failed@%n.service

[Service]
Nice=-5
Type=forking
NotifyAccess=all
StartLimitInterval=3m
StartLimitBurst=3
TimeoutSec=1m
WatchdogSec=60s
PIDFile=/var/run/waitonly.pid
RestartSec=5
Restart=on-abnormal
LimitNOFILE=1024
ExecStart=/usr/bin/waitonly
ExecStop=/usr/bin/kill $MAINPID
ExecReload=/usr/bin/kill -HUP $MAINPID


[Install]
WantedBy=multi-user.target___
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/systemd-devel