From f7d46a8048af1189af2ff3bf97024ef2f9f93d23 Mon Sep 17 00:00:00 2001
From: obarun <eric@obarun.org>
Date: Sat, 15 Oct 2022 20:53:11 +1100
Subject: [PATCH] revamp of the unsupervise process

---
 src/lib66/svc/deps-lib/deps      |  5 +-
 src/lib66/svc/svc_init_pipe.c    | 63 ----------------------
 src/lib66/svc/svc_scandir_ok.c   | 50 ++++++++++++++++++
 src/lib66/svc/svc_scandir_send.c | 46 ++++++++++++++++
 src/lib66/svc/svc_send.c         | 23 ++++----
 src/lib66/svc/svc_unsupervise.c  | 90 ++++++++++----------------------
 6 files changed, 134 insertions(+), 143 deletions(-)
 delete mode 100644 src/lib66/svc/svc_init_pipe.c
 create mode 100644 src/lib66/svc/svc_scandir_ok.c
 create mode 100644 src/lib66/svc/svc_scandir_send.c

diff --git a/src/lib66/svc/deps-lib/deps b/src/lib66/svc/deps-lib/deps
index 52e32bea..2621aa49 100644
--- a/src/lib66/svc/deps-lib/deps
+++ b/src/lib66/svc/deps-lib/deps
@@ -1,7 +1,6 @@
-svc_init.o
-svc_init_pipe.o
+svc_scandir_ok.o
+svc_scandir_send.o
 svc_send.o
-svc_switch_to.o
 svc_unsupervise.o
 -ls6
 -loblibs
diff --git a/src/lib66/svc/svc_init_pipe.c b/src/lib66/svc/svc_init_pipe.c
deleted file mode 100644
index 6747fc37..00000000
--- a/src/lib66/svc/svc_init_pipe.c
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * svc_init_pipe.c
- *
- * Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org>
- *
- * All rights reserved.
- *
- * This file is part of Obarun. It is subject to the license terms in
- * the LICENSE file found in the top-level directory of this
- * distribution.
- * This file may not be copied, modified, propagated, or distributed
- * except according to the terms contained in the LICENSE file./
- */
-
-#include <66/svc.h>
-
-#include <string.h>
-
-#include <oblibs/log.h>
-
-#include <skalibs/genalloc.h>
-#include <skalibs/stralloc.h>
-#include <skalibs/tai.h>
-
-#include <s6/ftrigr.h>
-#include <s6/ftrigw.h>
-#include <s6/supervise.h>
-
-#include <66/utils.h>
-#include <66/resolve.h>
-
-
-int svc_init_pipe(ftrigr_t *fifo,genalloc *gasv,tain *deadline)
-{
-    log_flow() ;
-
-    size_t i = 0 ;
-    ss_resolve_sig_t *svc ;
-
-    if (!ftrigr_startf_g(fifo, deadline))
-        log_warnusys_return(LOG_EXIT_ZERO,"initiate fifo") ;
-
-    for (; i < genalloc_len(ss_resolve_sig_t,gasv) ; i++)
-    {
-        svc = &genalloc_s(ss_resolve_sig_t,gasv)[i] ;
-        char *svok = svc->res.sa.s + svc->res.runat ;
-        size_t scanlen = strlen(svok) ;
-        char svfifo[scanlen + 6 + 1] ;
-        memcpy(svfifo, svok,scanlen) ;
-        memcpy(svfifo + scanlen, "/event",6) ;
-        svfifo[scanlen + 6] = 0 ;
-
-        log_trace("clean up fifo: ", svfifo) ;
-        if (!ftrigw_clean (svok))
-            log_warnusys_return(LOG_EXIT_ZERO,"clean up fifo: ", svfifo) ;
-
-        log_trace("subcribe to fifo: ",svfifo) ;
-        svc->ids = ftrigr_subscribe_g(fifo, svfifo, "[DuUdOxs]", FTRIGR_REPEAT, deadline) ;
-        if (!svc->ids)
-            log_warnusys_return(LOG_EXIT_ZERO,"subcribe to fifo: ",svfifo) ;
-    }
-    return 1 ;
-}
diff --git a/src/lib66/svc/svc_scandir_ok.c b/src/lib66/svc/svc_scandir_ok.c
new file mode 100644
index 00000000..dd05d5a8
--- /dev/null
+++ b/src/lib66/svc/svc_scandir_ok.c
@@ -0,0 +1,50 @@
+/*
+ * svc_scandir_ok.c
+ *
+ * Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org>
+ *
+ * All rights reserved.
+ *
+ * This file is part of Obarun. It is subject to the license terms in
+ * the LICENSE file found in the top-level directory of this
+ * distribution.
+ * This file may not be copied, modified, propagated, or distributed
+ * except according to the terms contained in the LICENSE file./
+ */
+
+#include <string.h>
+#include <errno.h>
+
+#include <oblibs/log.h>
+#include <oblibs/string.h>
+
+#include <skalibs/djbunix.h>
+
+#include <66/svc.h>
+
+#include <s6/supervise.h>
+
+/** this following function come from Laurent Bercot
+ * author of s6 library all rights reserved on this author
+ * It was just modified a little bit to be able to scan
+ * a scandir directory instead of a service directory */
+int svc_scandir_ok (char const *dir)
+{
+    log_flow() ;
+
+    size_t dirlen = strlen(dir) ;
+    int fd ;
+    char fn[dirlen + 1 + strlen(S6_SVSCAN_CTLDIR) + 9] ;
+
+    auto_strings(fn, dir, "/", S6_SVSCAN_CTLDIR, "/control") ;
+
+    fd = open_write(fn) ;
+    if (fd < 0)
+    {
+        if ((errno == ENXIO) || (errno == ENOENT)) return 0 ;
+        else return -1 ;
+    }
+    fd_close(fd) ;
+
+    return 1 ;
+}
diff --git a/src/lib66/svc/svc_scandir_send.c b/src/lib66/svc/svc_scandir_send.c
new file mode 100644
index 00000000..0710141e
--- /dev/null
+++ b/src/lib66/svc/svc_scandir_send.c
@@ -0,0 +1,46 @@
+/*
+ * svc_scandir_send.c
+ *
+ * Copyright (c) 2018-2021 Eric Vidal <eric@obarun.org>
+ *
+ * All rights reserved.
+ *
+ * This file is part of Obarun. It is subject to the license terms in
+ * the LICENSE file found in the top-level directory of this
+ * distribution.
+ * This file may not be copied, modified, propagated, or distributed
+ * except according to the terms contained in the LICENSE file./
+ */
+
+#include <string.h>
+
+#include <oblibs/log.h>
+
+#include <66/svc.h>
+
+#include <s6/supervise.h>
+
+int svc_scandir_send(char const *scandir,char const *signal)
+{
+    log_flow() ;
+
+    size_t idlen = strlen(signal) ;
+    char data[idlen + 1] ;
+    size_t datalen = 0 ;
+
+    for (; datalen < idlen ; datalen++)
+        data[datalen] = signal[datalen] ;
+
+    log_trace("send signal: ", signal, " to scandir: ", scandir) ;
+    switch (s6_svc_writectl(scandir, S6_SVSCAN_CTLDIR, data, datalen))
+    {
+        case -1: log_warnusys("control: ", scandir) ;
+                return 0 ;
+        case -2: log_warnsys("something is wrong with the ", scandir, "/" S6_SVSCAN_CTLDIR " directory. errno reported") ;
+                return 0 ;
+        case 0: log_warnu("control: ", scandir, ": supervisor not listening") ;
+                return 0 ;
+    }
+
+    return 1 ;
+}
diff --git a/src/lib66/svc/svc_send.c b/src/lib66/svc/svc_send.c
index c6e6f2e6..d9b64cce 100644
--- a/src/lib66/svc/svc_send.c
+++ b/src/lib66/svc/svc_send.c
@@ -12,35 +12,30 @@
  * except according to the terms contained in the LICENSE file./
  */
 
-#include <66/svc.h>
-
-#include <stddef.h>
-
 #include <oblibs/log.h>
 
-#include <skalibs/genalloc.h>
-
+#include <66/svc.h>
 #include <66/resolve.h>
 #include <66/ssexec.h>
 
-int svc_send(ssexec_t *info, resolve_service_t *sv, unsigned int len, char const *sig)
+int svc_send(char const *const *list, unsigned int nservice, char **sig, unsigned int siglen, ssexec_t *info)
 {
     log_flow() ;
 
-    unsigned int pos = 0 ;
-    int nargc = 3 + len ;
+    int nargc = 2 + nservice + siglen ;
     char const *newargv[nargc] ;
     unsigned int m = 0 ;
 
-    newargv[m++] = "svc_send" ;
-    newargv[m++] = sig ;
+    newargv[m++] = "66-svctl" ;
+    for (; *sig ; sig++)
+        newargv[m++] = *sig ;
 
-    for (; pos < len ; pos++)
-        newargv[m++] = sv[pos].sa.s + sv[pos].name ;
+    for (; *list ; list++)
+        newargv[m++] = *list ;
 
     newargv[m++] = 0 ;
 
-    if (ssexec_svctl(nargc, newargv, (char const *const *) environ, info))
+    if (ssexec_svctl(nargc, newargv, info))
         return 0 ;
 
     return 1 ;
diff --git a/src/lib66/svc/svc_unsupervise.c b/src/lib66/svc/svc_unsupervise.c
index 0751823c..2a45dccc 100644
--- a/src/lib66/svc/svc_unsupervise.c
+++ b/src/lib66/svc/svc_unsupervise.c
@@ -12,91 +12,55 @@
  * except according to the terms contained in the LICENSE file./
  */
 
-#include <66/svc.h>
-
-#include <string.h>
-
 #include <oblibs/log.h>
 
 #include <skalibs/genalloc.h>
-#include <skalibs/stralloc.h>
-#include <skalibs/djbunix.h>
 
-#include <66/utils.h>
-#include <66/resolve.h>
-#include <66/ssexec.h>
 #include <66/state.h>
+#include <66/sanitize.h>
+#include <66/graph.h>
+#include <66/svc.h>
 
-int svc_unsupervise(ssexec_t *info, resolve_service_t *sv, unsigned int len)
+static void sanitize_it(resolve_service_t *res)
+{
+    sanitize_fdholder(res, STATE_FLAGS_FALSE) ;
+    sanitize_scandir(res, STATE_FLAGS_TOUNSUPERVISE) ;
+    sanitize_livestate(res, STATE_FLAGS_TOUNSUPERVISE) ;
+}
+
+/** this function considers that the service is already down */
+void svc_unsupervise(unsigned int *alist, unsigned int alen, graph_t *g, resolve_service_t *ares, unsigned int areslen)
 {
     log_flow() ;
 
     unsigned int pos = 0 ;
-    ss_state_t sta = STATE_ZERO ;
-    resolve_service_t_ref pres = 0 ;
 
-    if (!svc_send(info, sv, len, "-d"))
-        log_warnu_return(LOG_EXIT_ZERO, "stop services") ;
+    if (!alen)
+        return ;
 
-    for (; pos < len ; pos++) {
+    for (; pos < alen ; pos++) {
 
-        char const *string = sv[pos].sa.s ;
-        int r = access(string, F_OK) ;
-        if (!r) {
-            log_trace("delete service directory: ",string + sv[pos].runat) ;
-            if (rm_rf(string + sv[pos].runat) < 0)
-                log_warnu_return(LOG_EXIT_ZERO, "delete: ", string + sv[pos].runat) ;
-        }
-    }
-
-    for (pos = 0 ; pos < len ; pos++) {
-
-        pres = &sv[pos] ;
-        char const *string = pres->sa.s ;
-        char const *name = string + pres->name  ;
-        char const *state = string + pres->state ;
-        size_t treenamelen = strlen(string + pres->treename) ;
-        char res_s[info->base.len + SS_SYSTEM + 1 + treenamelen + SS_SVDIRS_LEN + 1] ;
-
-        // remove the resolve/state file if the service is disabled
-        if (!pres->disen) {
+        char *name = g->data.s + genalloc_s(graph_hash_t,&g->hash)[alist[pos]].vertex ;
 
-            auto_strings(res_s, info->base.s, SS_SYSTEM, "/", string + pres->treename, SS_SVDIRS) ;
+        int aresid = service_resolve_array_search(ares, areslen, name) ;
+        if (aresid < 0)
+            log_dieu(LOG_EXIT_SYS,"find ares id -- please make a bug reports") ;
 
-            log_trace("Delete resolve file of: ", name) ;
-            resolve_rmfile(res_s, name) ;
+        sanitize_it(&ares[aresid]) ;
 
-            int r = access(state, F_OK) ;
-            if (!r) {
-                log_trace("Delete state file of: ", name) ;
-                state_rmfile(state, name) ;
-            }
+        if (ares[aresid].logger.name) {
+            resolve_service_t res = RESOLVE_SERVICE_ZERO ;
+            resolve_wrapper_t_ref wres = resolve_set_struct(DATA_SERVICE, &res) ;
 
-        } else if (!access(state, F_OK)) {
+            if (!resolve_read_g(wres, ares[aresid].sa.s + ares[aresid].path.home, ares[aresid].sa.s + ares[aresid].logger.name))
+                log_dieusys(LOG_EXIT_SYS, "read resolve file of: ", ares[aresid].sa.s + ares[aresid].logger.name) ;
 
-            /**
-             * The svc_unsupervise can be called with service which was
-             * never initialized. In this case the live state directory
-             * doesn't exist and we don't want to create a fresh one.
-             * So check first if the state directory exist before
-             * passing through here
-             * */
-
-            state_setflag(&sta, SS_FLAGS_RELOAD, SS_FLAGS_FALSE) ;
-            state_setflag(&sta, SS_FLAGS_INIT, SS_FLAGS_TRUE) ;
-    //      state_setflag(&sta, SS_FLAGS_UNSUPERVISE, SS_FLAGS_FALSE) ;
-            state_setflag(&sta, SS_FLAGS_STATE, SS_FLAGS_FALSE) ;
-            state_setflag(&sta, SS_FLAGS_PID, SS_FLAGS_FALSE) ;
-
-            log_trace("Write state file of: ", name) ;
-            if (!state_write(&sta, state, name))
-                log_warnu_return(LOG_EXIT_ZERO, "write state file of: ", name) ;
+            sanitize_it(&res) ;
 
+            resolve_free(wres) ;
         }
 
         log_info("Unsupervised successfully: ", name) ;
     }
-
-    return 1 ;
 }
 
-- 
GitLab