about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2023-02-08 04:09:30 +0000
committerLaurent Bercot <ska@appnovation.com>2023-02-08 04:09:30 +0000
commit370e78d9230d18b260df395e6d437c241b02c93c (patch)
tree3216eb9efa542404ff8067c7589077583b7df292 /src
parentc6b70ab00c94d26f0df6a96fde3ffe7324254a23 (diff)
downloads6-370e78d9230d18b260df395e6d437c241b02c93c.tar.gz
s6-370e78d9230d18b260df395e6d437c241b02c93c.tar.xz
s6-370e78d9230d18b260df395e6d437c241b02c93c.zip
Add s6_servicedir_instances_recreate_offline functions
This will be used for more transparent instance management
in s6-rc.

Signed-off-by: Laurent Bercot <ska@appnovation.com>
Diffstat (limited to 'src')
-rw-r--r--src/include/s6/servicedir.h5
-rw-r--r--src/libs6/deps-lib/s62
-rw-r--r--src/libs6/s6_servicedir_instances_recreate_offline.c10
-rw-r--r--src/libs6/s6_servicedir_instances_recreate_offline_tmp.c73
4 files changed, 90 insertions, 0 deletions
diff --git a/src/include/s6/servicedir.h b/src/include/s6/servicedir.h
index b575370..c0b69c3 100644
--- a/src/include/s6/servicedir.h
+++ b/src/include/s6/servicedir.h
@@ -5,6 +5,8 @@
 
 #include <stdint.h>
 
+#include <skalibs/stralloc.h>
+
 #define S6_SERVICEDIR_FILE_MAXLEN 16
 
 #define S6_FILETYPE_NORMAL 0
@@ -26,4 +28,7 @@ struct s6_servicedir_desc_s
 
 extern s6_servicedir_desc const *const s6_servicedir_file_list ;
 
+extern int s6_servicedir_instances_recreate_offline (char const *, char const *) ;
+extern int s6_servicedir_instances_recreate_offline_tmp (char const *, char const *, stralloc *) ;
+
 #endif
diff --git a/src/libs6/deps-lib/s6 b/src/libs6/deps-lib/s6
index 732e071..9924d83 100644
--- a/src/libs6/deps-lib/s6
+++ b/src/libs6/deps-lib/s6
@@ -33,6 +33,8 @@ s6_dtally_read.o
 s6_dtally_write.o
 s6_instance_chdirservice.o
 s6_servicedir_file_list.o
+s6_servicedir_instances_recreate_offline.o
+s6_servicedir_instances_recreate_offline_tmp.o
 s6_svc_ok.o
 s6_svc_write.o
 s6_svc_writectl.o
diff --git a/src/libs6/s6_servicedir_instances_recreate_offline.c b/src/libs6/s6_servicedir_instances_recreate_offline.c
new file mode 100644
index 0000000..f461a1d
--- /dev/null
+++ b/src/libs6/s6_servicedir_instances_recreate_offline.c
@@ -0,0 +1,10 @@
+/* ISC license. */
+
+#include <skalibs/skamisc.h>
+
+#include <s6/servicedir.h>
+
+int s6_servicedir_instances_recreate_offline (char const *old, char const *new)
+{
+  return s6_servicedir_instances_recreate_offline_tmp(old, new, &satmp) ;
+}
diff --git a/src/libs6/s6_servicedir_instances_recreate_offline_tmp.c b/src/libs6/s6_servicedir_instances_recreate_offline_tmp.c
new file mode 100644
index 0000000..b6a7ddb
--- /dev/null
+++ b/src/libs6/s6_servicedir_instances_recreate_offline_tmp.c
@@ -0,0 +1,73 @@
+/* ISC license. */
+
+#include <errno.h>
+#include <string.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include <skalibs/stralloc.h>
+#include <skalibs/djbunix.h>
+
+#include <s6/servicedir.h>
+
+int s6_servicedir_instances_recreate_offline_tmp (char const *old, char const *new, stralloc *sa)
+{
+  int n ;
+  mode_t m ;
+  size_t maxlen = 0 ;
+  size_t sabase = sa->len ;
+  size_t oldlen = strlen(old) ;
+  size_t newlen = strlen(new) ;
+  char templatedir[oldlen + 11] ;
+  memcpy(templatedir, old, oldlen) ;
+  memcpy(templatedir + oldlen, "/instances", 11) ;
+  n = sals(templatedir, sa, &maxlen) ;
+  if (n == -1) return errno == ENOENT ? 0 : -1 ;
+
+  {
+    size_t pos = sabase ;
+    char olddir[oldlen + 16 + maxlen] ;
+    char newsd[newlen + 11 + maxlen] ;
+    char newdir[newlen + 17 + maxlen] ;
+    char lnk[14 + maxlen] ;
+    memcpy(olddir, templatedir, oldlen + 10) ;
+    olddir[oldlen + 10] = '/' ;
+    memcpy(templatedir + oldlen + 1, "template", 9) ;
+    memcpy(newsd, new, newlen) ;
+    memcpy(newsd + newlen, "/instance", 10) ;
+    memcpy(newdir, newsd, newlen + 9) ;
+    newdir[newlen + 9] = 's' ; newdir[newlen + 10] = 0 ;
+    memcpy(lnk, "../instances/", 13) ;
+    m = umask(0) ;
+    if (mkdir(newsd, 0755) == -1 && errno != EEXIST) goto merr ;
+    if (mkdir(newdir, 0755) == -1 && errno != EEXIST) goto merr ;
+    umask(m) ;
+    newsd[newlen+9] = '/' ;
+    newdir[newlen+10] = '/' ;
+    while (pos < sa->len)
+    {
+      size_t len = strlen(sa->s + pos) ;
+      memcpy(olddir + oldlen + 10, sa->s + pos, len) ;
+      memcpy(olddir + oldlen + 10 + len, "/down", 6) ;
+      memcpy(newsd + newlen + 10, sa->s + pos, len + 1) ;
+      memcpy(newdir + newlen + 11, sa->s + pos, len + 1) ;
+      memcpy(lnk + 13, sa->s + pos, len + 1) ;
+      if (!hiercopy_tmp(templatedir, newdir, sa)) goto err ;
+      if (symlink(lnk, newsd) == -1 && errno != EEXIST) goto err ;
+      if (access(olddir, F_OK) == 0)
+      {
+        memcpy(newdir + newlen + 11 + len, "/down", 6) ;
+        if (!openwritenclose_unsafe(newdir, "", 0)) goto err ;
+      }
+      else if (errno != ENOENT) goto err ;
+      pos += len + 1 ;
+    }
+  }
+  return n ;
+
+ merr:
+  umask(m) ;
+ err:
+  sa->len = sabase ;
+  return -1 ;
+}