commit fdb3286

default  ·  2024-01-10 18:37:40 +0000 UTC
parent df266ec
New command-line option 'state'.
2 files changed,  +100, -6
M main.c
+75, -6
  1@@ -22,13 +22,13 @@
  2 
  3 #include <sys/resource.h> // for getrlimit()
  4 
  5+#include <sys/mman.h>
  6+
  7 #ifdef USE_POLL_FOR_SLEEP
  8 #include <poll.h>
  9 #endif
 10 
 11-/** server stat **/
 12-
 13-srv_state s_state = {0};
 14+/** server state **/
 15 srv_state *p_state = NULL;
 16 
 17 
 18@@ -622,6 +622,74 @@ void term_handler(int s)
 19 }
 20 
 21 
 22+srv_state *srv_state_op(xs_str **fname, int op)
 23+/* opens or deletes the shared memory object */
 24+{
 25+    int fd;
 26+    srv_state *ss = NULL;
 27+
 28+    if (*fname == NULL)
 29+        *fname = xs_fmt("/%s_snac_state", xs_dict_get(srv_config, "host"));
 30+
 31+    switch (op) {
 32+    case 0: /* open for writing */
 33+        if ((fd = shm_open(*fname, O_CREAT | O_RDWR, 0666)) != -1) {
 34+            ftruncate(fd, sizeof(*ss));
 35+
 36+            if ((ss = mmap(0, sizeof(*ss), PROT_READ | PROT_WRITE,
 37+                 MAP_SHARED, fd, 0)) == MAP_FAILED)
 38+                ss = NULL;
 39+
 40+            close(fd);
 41+        }
 42+
 43+        if (ss == NULL) {
 44+            /* shared memory error: just create a plain structure */
 45+            srv_log(xs_fmt("warning: shm object error (%s)", strerror(errno)));
 46+            ss = malloc(sizeof(*ss));
 47+        }
 48+
 49+        /* init structure */
 50+        *ss = (srv_state){0};
 51+        ss->s_size = sizeof(*ss);
 52+
 53+        break;
 54+
 55+    case 1: /* open for reading */
 56+        if ((fd = shm_open(*fname, O_RDONLY, 0666)) != -1) {
 57+            if ((ss = mmap(0, sizeof(*ss), PROT_READ, MAP_SHARED, fd, 0)) == MAP_FAILED)
 58+                ss = NULL;
 59+
 60+            close(fd);
 61+        }
 62+
 63+        if (ss == NULL) {
 64+            /* shared memory error */
 65+            srv_log(xs_fmt("error: shm object error (%s) server not running?", strerror(errno)));
 66+        }
 67+        else
 68+        if (ss->s_size != sizeof(*ss)) {
 69+            srv_log(xs_fmt("error: struct size mismatch (%d != %d)",
 70+                ss->s_size, sizeof(*ss)));
 71+
 72+            munmap(ss, sizeof(*ss));
 73+
 74+            ss = NULL;
 75+        }
 76+
 77+        break;
 78+
 79+    case 2: /* unlink */
 80+        if (*fname)
 81+            shm_unlink(*fname);
 82+
 83+        break;
 84+    }
 85+
 86+    return ss;
 87+}
 88+
 89+
 90 void httpd(void)
 91 /* starts the server */
 92 {
 93@@ -631,12 +699,11 @@ void httpd(void)
 94     pthread_t threads[MAX_THREADS] = {0};
 95     int n;
 96     xs *sem_name = NULL;
 97+    xs *shm_name = NULL;
 98     sem_t anon_job_sem;
 99 
100     /* setup the server stat structure */
101-    {
102-        p_state = &s_state;
103-    }
104+    p_state = srv_state_op(&shm_name, 0);
105 
106     p_state->srv_start_time = time(NULL);
107 
108@@ -736,6 +803,8 @@ void httpd(void)
109     sem_close(job_sem);
110     sem_unlink(sem_name);
111 
112+    srv_state_op(&shm_name, 2);
113+
114     xs *uptime = xs_str_time_diff(time(NULL) - p_state->srv_start_time);
115 
116     srv_log(xs_fmt("httpd%s stop %s:%s (run time: %s)",
M main.c
+25, -0
 1@@ -4,6 +4,7 @@
 2 #include "xs.h"
 3 #include "xs_io.h"
 4 #include "xs_json.h"
 5+#include "xs_time.h"
 6 
 7 #include "snac.h"
 8 
 9@@ -22,6 +23,7 @@ int usage(void)
10     printf("deluser {basedir} {uid}             Deletes a user\n");
11     printf("httpd {basedir}                     Starts the HTTPD daemon\n");
12     printf("purge {basedir}                     Purges old data\n");
13+    printf("state {basedir}                     Prints server state\n");
14     printf("webfinger {basedir} {actor}         Queries about an actor (@user@host or actor url)\n");
15     printf("queue {basedir} {uid}               Processes a user queue\n");
16     printf("follow {basedir} {uid} {actor}      Follows an actor\n");
17@@ -138,6 +140,29 @@ int main(int argc, char *argv[])
18         return 0;
19     }
20 
21+    if (strcmp(cmd, "state") == 0) { /** **/
22+        xs *shm_name = NULL;
23+        srv_state *p_state = srv_state_op(&shm_name, 1);
24+
25+        if (p_state == NULL)
26+            return 1;
27+
28+        srv_state ss = *p_state;
29+        int n;
30+
31+        printf("server: %s (%s)\n", xs_dict_get(srv_config, "host"), USER_AGENT);
32+        xs *uptime = xs_str_time_diff(time(NULL) - ss.srv_start_time);
33+        printf("uptime: %s\n", uptime);
34+        printf("job fifo size (cur): %d\n", ss.job_fifo_size);
35+        printf("job fifo size (peak): %d\n", ss.peak_job_fifo_size);
36+        char *th_states[] = { "stopped", "waiting", "input", "output" };
37+
38+        for (n = 0; n < ss.n_threads; n++)
39+            printf("thread #%d state: %s\n", n, th_states[ss.th_state[n]]);
40+
41+        return 0;
42+    }
43+
44     if ((user = GET_ARGV()) == NULL)
45         return usage();
46