adds unix domain socket for server control ops srvctrl

Tue, 24 Jan 2017 22:48:14 +0100

author
Olaf Wintermann <olaf.wintermann@gmail.com>
date
Tue, 24 Jan 2017 22:48:14 +0100
branch
srvctrl
changeset 156
724e107983e9
parent 155
36cd2e280386
child 158
77f4f0079428

adds unix domain socket for server control ops

src/server/daemon/main.c file | annotate | diff | comparison | revisions
src/server/daemon/webserver.c file | annotate | diff | comparison | revisions
src/server/daemon/webserver.h file | annotate | diff | comparison | revisions
--- a/src/server/daemon/main.c	Tue Jan 24 17:36:28 2017 +0100
+++ b/src/server/daemon/main.c	Tue Jan 24 22:48:14 2017 +0100
@@ -39,6 +39,8 @@
 #include "../util/plist.h"
 #include "../util/date.h"
 
+#include "../../ucx/string.h"
+
 #include "webserver.h"
 #include "log.h"
 #include "httprequest.h"
@@ -99,6 +101,29 @@
     return NULL;
 }
 
+void handle_srvctrl() {
+    int srvctrl = webserver_srvctrl_fd();
+    listen(srvctrl, 8);
+    
+    for(;;) {
+        int admin_client = accept(srvctrl, NULL, 0);
+        if(admin_client < 0) {
+            log_ereport(
+                    LOG_FAILURE,
+                    "srvctrl: accept failed: %s",
+                    strerror(errno));
+            continue;
+        }
+        
+        // TODO: read commands
+        webserver_shutdown();
+        
+        close(admin_client);
+        
+        break;
+    }
+}
+
 int main(int argc, char **argv) {
     //test();
     
@@ -164,17 +189,20 @@
     int status;
     status = webserver_init();
     if(status != 0) {
-        log_ereport(LOG_FAILURE, "Cannot initialize server.");
+        log_ereport(LOG_FAILURE, "cannot initialize server.");
         return EXIT_FAILURE;
     }
 
     status = webserver_run();
     if(status != 0) {
-        log_ereport(LOG_FAILURE, "Cannot run server.");
+        log_ereport(LOG_FAILURE, "cannot run server.");
         return EXIT_FAILURE;
     }
-     
+    
+    handle_srvctrl();
+    
     /* TODO: join threads (or not?) */
+/*
     while(1) {
         if(is_daemon) {
             fflush(stdout);
@@ -185,6 +213,7 @@
             break;
         }
     }
+*/
 
     return EXIT_SUCCESS;
 }
--- a/src/server/daemon/webserver.c	Tue Jan 24 17:36:28 2017 +0100
+++ b/src/server/daemon/webserver.c	Tue Jan 24 22:48:14 2017 +0100
@@ -48,6 +48,8 @@
 #include "../util/io.h"
 #include "../util/util.h"
 
+#include "../../ucx/utils.h"
+
 #include "../safs/common.h"
 
 #include "func.h"
@@ -62,6 +64,8 @@
 
 static RestartCallback *atrestart;
 
+static int srvctrl;
+
 int webserver_init() { 
     // init NSPR
     systhread_init("webserver");
@@ -91,20 +95,6 @@
     // init caches
     auth_cache_init();
     
-    // create tmp dir and pid file
-    char *mkdir_cmd = NULL;
-    asprintf(&mkdir_cmd, "mkdir -p %s", cfg->tmp.ptr);
-    system(mkdir_cmd);
-    free(mkdir_cmd);
-
-    char *pid_file_path = NULL;
-    asprintf(&pid_file_path, "%s/pid", cfg->tmp.ptr);
-    FILE *pidfile = fopen(pid_file_path, "w"); // TODO: check error
-    pid_t pid = getpid();
-    fprintf(pidfile, "%d", pid);
-    fclose(pidfile);
-    free(pid_file_path);
-    
     // init SAFs
     common_saf_init();
     
@@ -168,6 +158,92 @@
                     "server must be started as root to change uid");
     }
     
+    // create tmp dir and pid file
+    char *mkdir_cmd = NULL;
+    asprintf(&mkdir_cmd, "mkdir -p %s", cfg->tmp.ptr);
+    system(mkdir_cmd);
+    free(mkdir_cmd);
+
+    char *pid_file_path = NULL;
+    asprintf(&pid_file_path, "%s/pid", cfg->tmp.ptr);
+    FILE *pidfile = fopen(pid_file_path, "w"); // TODO: check error
+    pid_t pid = getpid();
+    fprintf(pidfile, "%d", pid);
+    fclose(pidfile);
+    free(pid_file_path);
+    
+    // create unix domain socket for server control
+    sstr_t tmp_priv = ucx_sprintf("%s/private", cfg->tmp.ptr);
+    // TODO: remove existing private dir
+    if(mkdir(tmp_priv.ptr, S_IRWXU)) {
+        if(errno == EEXIST) {
+            if(chmod(tmp_priv.ptr, S_IRWXU)) {
+                log_ereport(
+                        LOG_CATASTROPHE,
+                        "cannot change permissions of tmp dir %s:",
+                        tmp_priv.ptr,
+                        strerror(errno));
+                return 0;
+            }
+        } else {
+            log_ereport(
+                    LOG_CATASTROPHE,
+                    "cannot create tmp dir %s:",
+                    tmp_priv.ptr,
+                    strerror(errno));
+            return -1;
+        }
+    }
+    
+    
+    // create srvctrl unix domain socket
+    // this socket is used for stop, reconfigure and other operations
+    sstr_t uds_path = ucx_sprintf("%s/private/srvctrl.sock", cfg->tmp.ptr);
+    struct sockaddr_un addr;
+    if(uds_path.length > sizeof(addr.sun_path)-1) {
+        log_ereport(
+                LOG_CATASTROPHE,
+                "path '%s' too long for unix domain socket",
+                uds_path.ptr);
+        return -1;
+    }
+    
+    // make sure there is no old srvctrl socket file
+    // otherweise bind would fail
+    if(unlink(uds_path.ptr)) {
+        if(errno != ENOENT) {
+            log_ereport(
+                    LOG_CATASTROPHE,
+                    "cannot unlink old srvctrl socket '%s': %s",
+                    uds_path.ptr,
+                    strerror(errno));
+            return -1;
+        }
+    }
+
+    ZERO(&addr, sizeof(addr));
+    addr.sun_family = AF_UNIX;
+    memcpy(addr.sun_path, uds_path.ptr, uds_path.length);
+    
+    srvctrl = socket(AF_UNIX, SOCK_STREAM, 0);
+    if(srvctrl == -1) {
+        log_ereport(
+                LOG_CATASTROPHE,
+                "Cannot create server control socket: %s",
+                strerror(errno));
+        return -1;
+    }
+    if(bind(srvctrl, (struct sockaddr*)&addr, sizeof(addr))) {
+        log_ereport(
+                LOG_CATASTROPHE,
+                "srvctrl socket bind failed: %s",
+                strerror(errno));
+        return -1;
+    }
+    
+    free(uds_path.ptr);
+    
+    
     //endpwent(); // TODO: close or not?
     //free(pwbuf); // TODO: ?
     
@@ -198,6 +274,10 @@
     }
 }
 
+int webserver_srvctrl_fd() {
+    return srvctrl;
+}
+
 void webserver_atrestart(void (*fn)(void *), void *data) {
     RestartCallback *cb = malloc(sizeof(RestartCallback));
     cb->func = fn;
--- a/src/server/daemon/webserver.h	Tue Jan 24 17:36:28 2017 +0100
+++ b/src/server/daemon/webserver.h	Tue Jan 24 22:48:14 2017 +0100
@@ -46,6 +46,8 @@
 int webserver_run();
 void webserver_shutdown();
 
+int webserver_srvctrl_fd();
+
 void webserver_atrestart(void (*fn)(void *), void *data);
 
 int ws_init_ssl();

mercurial