]> git.proxmox.com Git - pve-cluster.git/commitdiff
pmxcfs: only exit parent when successfully started
authorDominik Csapak <d.csapak@proxmox.com>
Wed, 2 May 2018 08:59:53 +0000 (10:59 +0200)
committerWolfgang Bumiller <w.bumiller@proxmox.com>
Wed, 2 May 2018 12:33:49 +0000 (14:33 +0200)
since systemd depends that parent exits only
when the service is actually started, we need to wait for the
child to get to the point where it starts the fuse loop
and signal the parent to now exit and write the pid file

without this, we had an issue, where the
ExecStartPost hook (which runs pvecm updatecerts) did not run reliably,
but which is necessary to setup the nodes/ dir in /etc/pve
and generating the ssl certificates

this could also affect every service which has an
After=pve-cluster

Signed-off-by: Dominik Csapak <d.csapak@proxmox.com>
(cherry picked from commit 3db2f0de7d7f314d16af8fff080de07d3447b169)
Signed-off-by: Thomas Lamprecht <t.lamprecht@proxmox.com>
data/src/pmxcfs.c

index 6047ad05aa13604dd66153dd65a836f2256d4f1a..de6163ab991872951c58944190179adc70be2b92 100644 (file)
@@ -775,6 +775,7 @@ int main(int argc, char *argv[])
 {
        int ret = -1;
        int lockfd = -1;
+       int pipefd[2];
 
        gboolean foreground = FALSE;
        gboolean force_local_mode = FALSE;
@@ -954,17 +955,39 @@ int main(int argc, char *argv[])
        fuse_set_signal_handlers(fuse_get_session(fuse));
 
        if (!foreground) {
+               if (pipe(pipefd) == -1) {
+                       cfs_critical("pipe error: %s", strerror(errno));
+                       goto err;
+               }
+
                pid_t cpid = fork();
 
                if (cpid == -1) {
                        cfs_critical("failed to daemonize program - %s", strerror (errno));
                        goto err;
                } else if (cpid) {
+                       int readbytes, errno_tmp;
+                       char readbuffer;
+                       close(pipefd[1]);
+                       readbytes = read(pipefd[0], &readbuffer, sizeof(readbuffer));
+                       errno_tmp = errno;
+                       close(pipefd[0]);
+                       if (readbytes == -1) {
+                               cfs_critical("read error: %s", strerror(errno_tmp));
+                               kill(cpid, SIGKILL);
+                               goto err;
+                       } else if (readbytes != 1 || readbuffer != '1') {
+                               cfs_critical("child failed to send '1'");
+                               kill(cpid, SIGKILL);
+                               goto err;
+                       }
+                       /* child finished starting up */
                        write_pidfile(cpid);
                        qb_log_fini();
                        _exit (0);
                } else {
                        int nullfd;
+                       close(pipefd[0]);
 
                        chroot("/");
 
@@ -1022,6 +1045,12 @@ int main(int argc, char *argv[])
 
        unlink(RESTART_FLAG_FILE);
 
+       if (!foreground) {
+               /* finished starting up, signaling parent */
+               write(pipefd[1], "1", 1);
+               close(pipefd[1]);
+       }
+
        ret = fuse_loop_mt(fuse);
 
        open(RESTART_FLAG_FILE, O_CREAT|O_NOCTTY|O_NONBLOCK);