]> git.proxmox.com Git - pve-ha-manager.git/blobdiff - src/watchdog-mux.c
bump version to 3.0-2
[pve-ha-manager.git] / src / watchdog-mux.c
index 16eef641c63da268f00cbf8f617cc26b39dfb0e5..818ae004ddd0880a3d125f540c81afff76a78581 100644 (file)
 #define WD_SOCK_PATH "/run/watchdog-mux.sock"
 #define WD_ACTIVE_MARKER "/run/watchdog-mux.active"
 
-#define LISTEN_BACKLOG 32 /* set same value in watchdog-mux.socket */
+#define LISTEN_BACKLOG 32
 
 #define MAX_EVENTS 10
 
 #define WATCHDOG_DEV "/dev/watchdog"
 
+#define JOURNALCTL_BIN "/bin/journalctl"
+
 int watchdog_fd = -1;
 int watchdog_timeout = 10;
 int client_watchdog_timeout = 60;
-int update_watchdog = 1; 
+int update_watchdog = 1;
 
 typedef struct {
     int fd;
@@ -80,11 +82,11 @@ active_client_count(void)
             count++;
         }
     }
-    
+
     return count;
 }
 
-static void 
+static void
 watchdog_close(void)
 {
     if (watchdog_fd != -1) {
@@ -98,8 +100,22 @@ watchdog_close(void)
 
     watchdog_fd = -1;
 }
-int 
+
+static void
+sync_journal_unsafe(void)
+{
+
+    pid_t child = fork();
+
+    // do not care about fork error or collecting the childs exit status,
+    // we are resetting soon anyway and just want to sync out the journal
+    if (child == 0) {
+       execl(JOURNALCTL_BIN, JOURNALCTL_BIN, "--sync", NULL);
+       exit(-1);
+    }
+}
+
+int
 main(void)
 {
     struct sockaddr_un my_addr, peer_addr;
@@ -111,7 +127,7 @@ main(void)
 
     if (stat(WD_ACTIVE_MARKER, &fs) == 0) {
         fprintf(stderr, "watchdog active - unable to restart watchdog-mux\n");
-        exit(EXIT_FAILURE);       
+        exit(EXIT_FAILURE);
     }
 
     /* if you want to debug, set options in /lib/modprobe.d/aliases.conf
@@ -125,7 +141,9 @@ main(void)
                 perror("assemble modprobe command failed");
                 exit(EXIT_FAILURE);
             }
+            fprintf(stderr, "Loading watchdog module '%s'\n", wd_module);
             system(cmd);
+            free(cmd);
         } else {
             system("modprobe -q softdog"); // load softdog by default
         }
@@ -135,7 +153,7 @@ main(void)
          perror("watchdog open");
          exit(EXIT_FAILURE);
     }
-       
+
     if (ioctl(watchdog_fd, WDIOC_SETTIMEOUT, &watchdog_timeout) == -1) {
         perror("watchdog set timeout");
         watchdog_close();
@@ -167,7 +185,7 @@ main(void)
     strncpy(my_addr.sun_path, WD_SOCK_PATH, sizeof(my_addr.sun_path) - 1);
 
     if (bind(listen_sock, (struct sockaddr *) &my_addr,
-            sizeof(struct sockaddr_un)) == -1) {
+             sizeof(struct sockaddr_un)) == -1) {
       perror("socket bind");
       exit(EXIT_FAILURE);
     }
@@ -195,9 +213,9 @@ main(void)
     sigaddset(&mask, SIGINT);
     sigaddset(&mask, SIGTERM);
     sigaddset(&mask, SIGHUP);
-    
+
     sigprocmask(SIG_BLOCK, &mask, NULL);
-   
+
     if ((sigfd = signalfd(-1, &mask, SFD_NONBLOCK)) < 0) {
         perror("unable to open signalfd");
         goto err;
@@ -209,13 +227,13 @@ main(void)
         perror("epoll_ctl add sigfd");
         goto err;
     }
-  
+
     for (;;) {
         nfds = epoll_wait(epollfd, events, MAX_EVENTS, 1000);
         if (nfds == -1) {
             if (errno == EINTR)
                 continue;
-            
+
             perror("epoll_pwait");
             goto err;
         }
@@ -230,7 +248,7 @@ main(void)
                     if (client_list[i].fd != 0 && client_list[i].time != 0 &&
                         ((ctime - client_list[i].time) > client_watchdog_timeout)) {
                         update_watchdog = 0;
-                        fprintf(stderr, "client watchdog expired - disable watchdog updates\n"); 
+                        fprintf(stderr, "client watchdog expired - disable watchdog updates\n");
                     }
                 }
             }
@@ -240,15 +258,15 @@ main(void)
                     perror("watchdog update failed");
                 }
             }
-            
+
             continue;
         }
 
         if (!update_watchdog)
             break;
-            
+
         int terminate = 0;
-        
+
         int n;
         for (n = 0; n < nfds; ++n) {
             wd_client_t *wd_client = events[n].data.ptr;
@@ -268,14 +286,14 @@ main(void)
                     fprintf(stderr, "unable to alloc wd_client structure\n");
                     goto err; // fixme;
                 }
-                
+
                 mkdir(WD_ACTIVE_MARKER, 0600);
-                
+
                 ev.events = EPOLLIN;
                 ev.data.ptr = new_client;
                 if (epoll_ctl(epollfd, EPOLL_CTL_ADD, conn_sock, &ev) == -1) {
                     perror("epoll_ctl: add conn_sock");
-                    goto err; // fixme                   
+                    goto err; // fixme
                 }
             } else if (wd_client->fd == sigfd) {
 
@@ -292,15 +310,15 @@ main(void)
                         fprintf(stderr, "got terminate request\n");
                     }
                 }
-                
+
             } else {
                 char buf[4096];
                 int cfd = wd_client->fd;
-                
+
                 ssize_t bytes = read(cfd, buf, sizeof(buf));
                 if (bytes == -1) {
                     perror("read");
-                    goto err; // fixme                   
+                    goto err; // fixme
                 } else if (bytes > 0) {
                     int i;
                     for (i = 0; i < bytes; i++) {
@@ -316,20 +334,21 @@ main(void)
                         //printf("GOT %016x event\n", events[n].events);
                         if (epoll_ctl(epollfd, EPOLL_CTL_DEL, cfd, NULL) == -1) {
                             perror("epoll_ctl: del conn_sock");
-                            goto err; // fixme                   
+                            goto err; // fixme
                         }
                         if (close(cfd) == -1) {
                             perror("close conn_sock");
-                            goto err; // fixme                   
+                            goto err; // fixme
                         }
 
                         if (!wd_client->magic_close) {
                             fprintf(stderr, "client did not stop watchdog - disable watchdog updates\n");
+                            sync_journal_unsafe();
                             update_watchdog = 0;
                         } else {
                             free_client(wd_client);
                         }
-                        
+
                         if (!active_client_count()) {
                             rmdir(WD_ACTIVE_MARKER);
                         }
@@ -344,6 +363,7 @@ main(void)
     int active_count = active_client_count();
     if (active_count > 0) {
         fprintf(stderr, "exit watchdog-mux with active connections\n");
+        sync_journal_unsafe();
     } else {
         fprintf(stderr, "clean exit\n");
         watchdog_close();