From 87b8fcabeecf2a9cff2ca596da54d6c1cf17d89f Mon Sep 17 00:00:00 2001
From: Laurent Bercot
Date: Sun, 14 Jun 2026 04:37:32 +0000
Subject: Prepare for 0.7.0.0; lots of changes!
- s6-rc-bundle deleted. Changing bundles without recompiling is not
supported anymore. (It works, but it incentivizes poor workflows; it is
better to handle stuff at the source level and recompile when in doubt,
that's what s6-frontend does.)
- new db format, need to recompile and use s6-rc-format-upgrade on new live db
- support for the reload-signal file in service directories
- new reload scripts for oneshots (which is why the db format has changed)
- new "s6-rc reload" command, calling s6-svc -l on longruns (which makes use
of reload-signal, HUP by default) and the reload script on oneshots
- the live state now tracks when a service has been explicitly brought up
as opposed to by pulled by dependencies. Nothing uses the feature for now
but now the tech is there for an auto-stop-if-unneeded feature.
---
.gitignore | 1 -
NEWS | 2 +-
doc/faq.html | 7 -
doc/index.html | 5 +-
doc/overview.html | 10 -
doc/s6-rc-bundle.html | 138 -------------
doc/s6-rc-compile.html | 26 +--
doc/s6-rc.html | 3 +-
doc/upgrade.html | 13 +-
package/info | 2 +-
package/modes | 1 -
package/targets.mak | 1 -
src/include/s6-rc/s6rc-db.h | 4 +-
src/libs6rc/s6rc_db_read.c | 2 +-
src/libs6rc/s6rc_servicedir_internal.c | 17 +-
src/s6-rc/s6-rc-bundle.c | 341 ---------------------------------
src/s6-rc/s6-rc-compile.c | 285 ++++++++++++++-------------
src/s6-rc/s6-rc-format-upgrade.c | 77 +++++---
src/s6-rc/s6-rc-init.c | 3 +-
src/s6-rc/s6-rc-oneshot-run.c | 36 ++--
src/s6-rc/s6-rc.c | 230 +++++++++++-----------
21 files changed, 376 insertions(+), 828 deletions(-)
delete mode 100644 doc/s6-rc-bundle.html
delete mode 100644 src/s6-rc/s6-rc-bundle.c
diff --git a/.gitignore b/.gitignore
index 0e74e9e..45ac2ce 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,7 +8,6 @@
/s6-rc-compile
/s6-rc-dryrun
/s6-rc-db
-/s6-rc-bundle
/s6-rc-init
/s6-rc
/s6-rc-update
diff --git a/NEWS b/NEWS
index 9a4a32f..2862d00 100644
--- a/NEWS
+++ b/NEWS
@@ -1,6 +1,6 @@
Changelog for s6-rc.
-In 0.6.2.0
+In 0.7.0.0
----------
- Bugfixes.
diff --git a/doc/faq.html b/doc/faq.html
index 23797f1..59b1d82 100644
--- a/doc/faq.html
+++ b/doc/faq.html
@@ -339,13 +339,6 @@ you don't want up anymore: s6-rc -p change runlevel-2.
Bundles are easy to use, they're flexible, and they're powerful.
They give you the same level of functionality as runlevels would, and more.
-You can even add bundles to compiled service databases - including the
-live one - or remove bundles from them without having to recompile them:
-that's what the s6-rc-bundle utility is
-for.
-
-
-
When in doubt, use bundles.
diff --git a/doc/index.html b/doc/index.html
index 426bdb5..1278c18 100644
--- a/doc/index.html
+++ b/doc/index.html
@@ -69,8 +69,8 @@ requirement if you link against the shared version of the skalibs library.
- The current released version of s6-rc is
-0.6.2.0.
-You can access its checksum here.
+0.7.0.0.
+You can access its checksum here.
- Alternatively, you can checkout a copy of the
s6-rc
git repository:
@@ -106,7 +106,6 @@ the previous versions of s6-rc and the current one.
Online tools: managing your live services
diff --git a/doc/overview.html b/doc/overview.html
index e563256..1dfd4dc 100644
--- a/doc/overview.html
+++ b/doc/overview.html
@@ -219,16 +219,6 @@ provided in the packages, an invocation of
keep the live state up to date.
- Live bundle modifications
-
-
- It is possible to change bundle definitions in a compiled service
-database, including the live one, without recompiling everything by
-calling s6-rc-compile. The
-s6-rc-bundle tool can edit compiled
-databases to add bundles to them, or delete bundles from them.
-
-
Management of source definition directories
diff --git a/doc/s6-rc-bundle.html b/doc/s6-rc-bundle.html
deleted file mode 100644
index fbe8d06..0000000
--- a/doc/s6-rc-bundle.html
+++ /dev/null
@@ -1,138 +0,0 @@
-
-
-
-
-
-
- s6-rc: the s6-rc-bundle program
-
-
-
-
-
-
-
-s6-rc
-Software
-skarnet.org
-
-
- The s6-rc-bundle program
-
-
- s6-rc-bundle is a tool to add or delete bundles from a compiled
-service database without having to recompile it from source.
-
-
-
- It is an offline tool, i.e. you can run it on any
-compiled service database without actually having a live set
-of services managed by s6-rc. However, if you do have a live
-set, you can still run s6-rc-bundle on the current database (and
-it is the default); it won't interfere with your normal service
-operation.
-
-
- Interface
-
-
- s6-rc-bundle help
- s6-rc-bundle [ -f ] [ -l live ] [ -c compiled ] [ -b ] add bundlename contents...
- s6-rc-bundle [ -f ] [ -l live ] [ -c compiled ] [ -b ] delete bundlenames...
- s6-rc-bundle [ -f ] [ -l live ] [ -c compiled ] [ -b ] multiple args...
-
-
-
- - s6-rc-bundle expects to find a compiled service database
-in compiled; by default it uses the service database
-used by the live state in live.
- - Depending on the arguments, it adds a bundle definition to this database, or
-deletes a bundle definition from it, or performs multiple additions/deletions.
-
-
- Options
-
-
- - -c compiled : operate on a
-compiled service database in compiled instead of
-the current live one.
- - -l live : assume the live
-state is in live. This option is ignored if the
--c option has been given. Default is
-/run/s6-rc. The default can be changed at package
-compilation time, by giving the --livedir=live
-option to ./configure.
- - -f : force. s6-rc-bundle will not complain
-when given a nonexisting name to delete (it will do nothing), or
-when given an existing name to add (it will replace the definition).
-By default, s6-rc-bundle will complain and exit when asked to delete a
-nonexistent name or to add an existing name.
- - -b : blocking lock. If the database is currently
-being used by another program, s6-rc-bundle will wait until that
-other program has released its lock on the database, then proceed.
-By default, s6-rc-bundle fails with an error message if the database
-is currently in use.
-
-
- Exit codes
-
-
- - 0: success
- - 1: identifier already exists in service database
- - 3: identifier not found in service database
- - 4: invalid or corrupted service database
- - 5: wrong identifier type for the given command
- - 100: wrong usage
- - 111: system call failed
-
-
- Subcommands
-
- s6-rc-bundle help
-
-
- Prints a help message on stdout.
-
-
- s6-rc-bundle add bundlename contents...
-
-
- Adds a bundle named bundlename to the database, representing
-the services listed in contents. The arguments in contents...
-are resolved before the database is modified by the
-s6-rc-bundle invocation.
-
-
- s6-rc-bundle delete bundlenames...
-
-
- Deletes bundles listed in bundlenames....
-
-
- s6-rc-bundle multiple args...
-
-
- Performs multiple bundle deletions and additions. This subcommand is best
-used in an execline
-script, because it uses
-blocks.
-
-
-
-args... is composed of:
-
-
-
- - One block listing bundle names that will be
-deleted from the database.
- - Zero or more addition definitions, each of them composed of:
-
- - One argument that is the name of the bundle to add
- - One block listing the services contained in the
-new bundle. The names in the block are resolved before any addition
-or deletion is made to the database.
-
-
-
-
-
diff --git a/doc/s6-rc-compile.html b/doc/s6-rc-compile.html
index 07625ac..d207b6c 100644
--- a/doc/s6-rc-compile.html
+++ b/doc/s6-rc-compile.html
@@ -198,30 +198,30 @@ complain and exit 1.
For oneshots
- - Two regular files named up and down, which
-must each contain a single Unix command line. The files will be interpreted by the
+
- Three regular files named up, down, and reload,
+which must each contain a single Unix command line. The up file is
+mandatory, the other two are optional; if they are absent, they are considered
+empty, i.e. nothing happens when the corresponding script is executed and the
+operation is considered a success.
+The files will be interpreted by the
execlineb
lexer at compile time and the results will be stored into the
compiled database in an internal form. up will be run when
-the service is started, and down will be executed when the service
-is stopped. up is mandatory, but down is optional;
-if no down file is provided in the source definition directory,
-then it is treated as the empty script. If a script is empty,
-then s6-rc will consider that the corresponding transition for this service
-does nothing and always succeeds.
+the service is started, down will be executed when the service
+is stopped, and reload will be executed when the service is
+reloaded
- up and down are interpreted by
+ up, down and reload are interpreted by
execlineb, but
that does not mean they have to be entirely written in the
execline language. The
execlineb
lexer is only used because it can compile a Unix command line from a text file
and store the compiled result, whereas a shell would have to be invoked
-everytime the script is run. There are many ways to write up and
-down scripts:
+everytime the script is run. There are many ways to write these scripts:
@@ -239,8 +239,8 @@ while down contains /etc/init.d/service stop, and
Don't think you have to learn all the intricacies of the execline language
-just because the up and down scripts get lexed by it.
-You don't.
+just because the up, down and reloadscripts get
+lexed by it. You don't.
For longruns
diff --git a/doc/s6-rc.html b/doc/s6-rc.html
index bb16113..afd6795 100644
--- a/doc/s6-rc.html
+++ b/doc/s6-rc.html
@@ -252,8 +252,7 @@ given on the command line, which must all be up. For a longrun,
s6-rc reload sends an s6-svc -l
command to the service, which causes it to receive a SIGHUP, or any
overriding signal configured in the reload-signal file.
-For a oneshot, the service's up script is executed, with
-an additional RC_RELOAD environment variable containing 1.
+For a oneshot, the service's reload script is executed.
diff --git a/doc/upgrade.html b/doc/upgrade.html
index 0aac5cf..f61933c 100644
--- a/doc/upgrade.html
+++ b/doc/upgrade.html
@@ -31,7 +31,7 @@ minor and bugfix version changes.
What has changed in s6-rc
- in 0.6.2.0
+ in 0.7.0.0
- skalibs
@@ -39,8 +39,17 @@ dependency bumped to 2.15.0.1.
- execline
dependency bumped to 2.9.9.2.
- s6
-dependency bumped to 2.15.0.1.
+dependency bumped to 2.15.1.0.
- New s6-rc reload command.
+ - The database format has changed! To safely upgrade a running s6-rc installation:
+
+ - Compile your current live database from the same source
+using the latest s6-rc-compile
+ - Run the latest s6-rc-format-upgrade with the
+newly obtained database
+ - Run the latest s6-rc-update with the same database
+ - Your system is now running the latest version of s6-rc; you can delete your old database
+
in 0.6.1.1
diff --git a/package/info b/package/info
index 0b55290..c0cd306 100644
--- a/package/info
+++ b/package/info
@@ -1,4 +1,4 @@
package=s6-rc
-version=0.6.2.0
+version=0.7.0.0
category=admin
package_macro_name=S6RC
diff --git a/package/modes b/package/modes
index 0676950..c76a046 100644
--- a/package/modes
+++ b/package/modes
@@ -1,7 +1,6 @@
s6-rc-compile 0755
s6-rc-db 0755
s6-rc-dryrun 0755
-s6-rc-bundle 0755
s6-rc-init 0755
s6-rc 0755
s6-rc-update 0755
diff --git a/package/targets.mak b/package/targets.mak
index fe89f89..0dd4abf 100644
--- a/package/targets.mak
+++ b/package/targets.mak
@@ -2,7 +2,6 @@ BIN_TARGETS := \
s6-rc-compile \
s6-rc-dryrun \
s6-rc-db \
-s6-rc-bundle \
s6-rc-init \
s6-rc \
s6-rc-update \
diff --git a/src/include/s6-rc/s6rc-db.h b/src/include/s6-rc/s6rc-db.h
index 0f03967..9b156f8 100644
--- a/src/include/s6-rc/s6rc-db.h
+++ b/src/include/s6-rc/s6rc-db.h
@@ -18,8 +18,8 @@
typedef struct s6rc_oneshot_s s6rc_oneshot_t, *s6rc_oneshot_t_ref ;
struct s6rc_oneshot_s
{
- uint32_t argc[2] ;
- uint32_t argv[2] ;
+ uint32_t argc[3] ;
+ uint32_t argv[3] ;
} ;
typedef struct s6rc_longrun_s s6rc_longrun_t, *s6rc_longrun_t_ref ;
diff --git a/src/libs6rc/s6rc_db_read.c b/src/libs6rc/s6rc_db_read.c
index b233cfe..46fb939 100644
--- a/src/libs6rc/s6rc_db_read.c
+++ b/src/libs6rc/s6rc_db_read.c
@@ -72,7 +72,7 @@ static inline int s6rc_db_read_services (buffer *b, s6rc_db_t *db)
else
{
unsigned int j = 0 ;
- for (; j < 2 ; j++)
+ for (; j < 3 ; j++)
{
uint32_t pos, argc ;
if (!s6rc_db_read_uint32(b, &argc)) return -1 ;
diff --git a/src/libs6rc/s6rc_servicedir_internal.c b/src/libs6rc/s6rc_servicedir_internal.c
index e81f378..5c55d28 100644
--- a/src/libs6rc/s6rc_servicedir_internal.c
+++ b/src/libs6rc/s6rc_servicedir_internal.c
@@ -27,7 +27,7 @@ static s6_servicedir_desc const svdir_file_list[] =
{ .name = "down-signal", .type = S6_FILETYPE_NORMAL, .options = 0 },
{ .name = "reload-signal", .type = S6_FILETYPE_NORMAL, .options = 0 },
{ .name = "flag-newpidns", .type = S6_FILETYPE_EMPTY, .options = 0 },
- { .name = "template", .type = S6_FILETYPE_DIR, .options = 0 },
+ { .name = "template", .type = S6_FILETYPE_TEMPLATE, .options = 0 },
{ .name = "data", .type = S6_FILETYPE_DIR, .options = 0 },
{ .name = "env", .type = S6_FILETYPE_DIR, .options = 0 },
{ .name = 0, .options = 0 }
@@ -61,7 +61,7 @@ int s6rc_servicedir_copy_one (char const *src, char const *dst, s6_servicedir_de
break ;
}
case S6_FILETYPE_EMPTY :
- if (access(srcfn, F_OK) < 0)
+ if (access(srcfn, F_OK) == -1)
{
if (errno != ENOENT || p->options & S6_SVFILE_MANDATORY) return 0 ;
}
@@ -81,16 +81,17 @@ int s6rc_servicedir_copy_one (char const *src, char const *dst, s6_servicedir_de
}
break ;
}
+ case S6_FILETYPE_TEMPLATE :
case S6_FILETYPE_DIR :
if (!hiercopy(srcfn, dstfn))
{
- if (errno != ENOENT || p->options & S6_SVFILE_MANDATORY) return 0 ;
- }
- if (!strcmp(p->name, "template"))
- {
- memcpy(dstfn + dstlen + 1, "instance", 9) ;
- if (mkdir(dstfn, 0755) == -1 && errno != EEXIST) return 0 ;
+ if (errno != ENOENT) return 0 ;
+ if (p->options & S6_SVFILE_MANDATORY) return 0 ;
+ break ;
}
+ if (p->type != S6_FILETYPE_TEMPLATE) break ;
+ memcpy(dstfn + dstlen + 1, "instance", 9) ;
+ if (mkdir(dstfn, 0755) == -1 && errno != EEXIST) return 0 ;
break ;
default : return (errno = EDOM, 0) ;
}
diff --git a/src/s6-rc/s6-rc-bundle.c b/src/s6-rc/s6-rc-bundle.c
deleted file mode 100644
index d2b447a..0000000
--- a/src/s6-rc/s6-rc-bundle.c
+++ /dev/null
@@ -1,341 +0,0 @@
-/* ISC license. */
-
-#include
-#include
-#include
-#include
-#include
-
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-#include
-
-#include
-
-#include
-#include
-
-#define USAGE "s6-rc-bundle [ -l live ] [ -c compiled ] [ -b ] command... (use s6-rc-bundle help for more information)"
-#define dieusage() strerr_dieusage(100, USAGE)
-
-static void cleanup (char const *compiled)
-{
- size_t len = strlen(compiled) ;
- char fn[len + sizeof("/resolve.cdb.new")] ;
- memcpy(fn, compiled, len) ;
- memcpy(fn + len, "/resolve.cdb.new", sizeof("/resolve.cdb.new")) ;
- unlink_void(fn) ;
-}
-
-
- /* TODO: switch to renameat when it's more portable */
-
-static inline int renameit (char const *compiled, char const *src, char const *dst)
-{
- size_t clen = strlen(compiled) ;
- size_t srclen = strlen(src) ;
- size_t dstlen = strlen(dst) ;
- char srcfn[clen + srclen + 2] ;
- char dstfn[clen + dstlen + 2] ;
- memcpy(srcfn, compiled, clen) ;
- srcfn[clen] = '/' ;
- memcpy(srcfn + clen + 1, src, srclen + 1) ;
- memcpy(dstfn, compiled, clen) ;
- dstfn[clen] = '/' ;
- memcpy(dstfn + clen + 1, dst, dstlen + 1) ;
- return rename(srcfn, dstfn) ;
-}
-
-static void check (cdb const *cr, s6rc_db_t *db, char const *name, int h, int force, char const *compiled)
-{
- size_t namelen = strlen(name) ;
- cdb_data data ;
- int r = cdb_find(cr, &data, name, namelen) ;
- if (r < 0) strerr_diefu3sys(111, "cdb_find in ", compiled, "/resolve.cdb") ;
- if (!r)
- {
- if (!h && !force)
- strerr_dief4x(3, "identifier ", name, " does not exist in database ", compiled) ;
- return ;
- }
- if (h && !force)
- strerr_dief4x(1, "identifier ", name, " already exists in database ", compiled) ;
- if (data.len == 4)
- {
- uint32_t x ;
- uint32_unpack_big(data.s, &x) ;
- if (x >= db->nshort + db->nlong)
- strerr_dief2x(4, "invalid database in ", compiled) ;
- if (!strcmp(name, db->string + db->services[x].name))
- strerr_dief4x(5, "identifier ", name, " does not represent a bundle for database ", compiled) ;
- }
-}
-
-static void modify_resolve (int fdcompiled, s6rc_db_t *db, char const *const *todel, unsigned int todeln, char const *const *toadd, char const *const *const *toadd_contents, unsigned int toaddn, int force, char const *compiled)
-{
- cdb cr = CDB_ZERO ;
- cdbmaker cw = CDBMAKER_ZERO ;
- uint32_t pos = CDB_TRAVERSE_INIT() ;
- unsigned int i = toaddn ;
- int fdw ;
- unsigned int n = db->nlong + db->nshort ;
- unsigned char bits[bitarray_div8(n)] ;
- if (!cdb_init_at(&cr, fdcompiled, "resolve.cdb"))
- strerr_diefu3sys(111, "cdb_init ", compiled, "/resolve.cdb") ;
- while (i--) check(&cr, db, toadd[i], 1, force, compiled) ;
- i = todeln ;
- while (i--) check(&cr, db, todel[i], 0, force, compiled) ;
- fdw = open_truncatb(fdcompiled, "resolve.cdb.new") ;
- if (fdw < 0) strerr_diefu3sys(111, "open ", compiled, "/resolve.cdb.new") ;
- if (!cdbmake_start(&cw, fdw))
- {
- cleanup(compiled) ;
- strerr_diefu1sys(111, "cdbmake_start") ;
- }
- for (;;)
- {
- cdb_data key, data ;
- int r = cdb_traverse_next(&cr, &key, &data, &pos) ;
- if (r < 0)
- {
- cleanup(compiled) ;
- strerr_dief3x(4, "invalid cdb in ", compiled, "/resolve.cdb") ;
- }
- if (!r) break ;
- for (i = 0 ; i < todeln ; i++) if (key.len == strlen(todel[i]) && !strncmp(todel[i], key.s, key.len)) break ;
- if (i < todeln) continue ;
- for (i = 0 ; i < toaddn ; i++) if (key.len == strlen(toadd[i]) && !strncmp(toadd[i], key.s, key.len)) break ;
- if (i < toaddn) continue ;
- if (!cdbmake_add(&cw, key.s, key.len, data.s, data.len))
- {
- cleanup(compiled) ;
- strerr_diefu1sys(111, "cdb_make_add") ;
- }
- }
- i = toaddn ;
- while (i--)
- {
- char const *const *p = toadd_contents[i] ;
- unsigned int total = 0 ;
- memset(bits, 0, bitarray_div8(n)) ;
- for (; *p ; p++)
- {
- cdb_data data ;
- int r = cdb_find(&cr, &data, *p, strlen(*p)) ;
- if (r < 0) strerr_diefu3x(4, "invalid cdb in ", compiled, "/resolve.cdb") ;
- if (!r) strerr_dief4x(3, "identifier ", *p, " does not exist in database ", compiled) ;
- for (uint32_t j = 0 ; j < data.len ; j += 4)
- {
- uint32_t x ;
- uint32_unpack_big(data.s + j, &x) ;
- if (x >= db->nshort + db->nlong)
- strerr_dief2x(4, "invalid database in ", compiled) ;
- if (!bitarray_testandset(bits, x)) total++ ;
- }
- }
- {
- char pack[total << 2 ? total << 2 : 1] ;
- char *s = pack ;
- uint32_t j = n ;
- while (j--) if (bitarray_peek(bits, j))
- {
- uint32_pack_big(s, j) ;
- s += 4 ;
- }
- if (!cdbmake_add(&cw, toadd[i], strlen(toadd[i]), pack, total << 2))
- {
- cleanup(compiled) ;
- strerr_diefu1sys(111, "cdbmake_add") ;
- }
- }
- }
- cdb_free(&cr) ;
- if (!cdbmake_finish(&cw) || fsync(fdw) < 0)
- {
- cleanup(compiled) ;
- strerr_diefu3sys(111, "write to ", compiled, "/resolve.cdb.new") ;
- }
- close(fdw) ;
- if (renameit(compiled, "resolve.cdb.new", "resolve.cdb") < 0)
- {
- cleanup(compiled) ;
- strerr_diefu2sys(111, "rename resolve.cdb.new to resolve.cdb in ", compiled) ;
- }
-}
-
-static inline void parse_multiple (int argc, char const **argv, unsigned int *todeln, unsigned int *toaddn, char const **toadd, char const *const **toadd_contents)
-{
- unsigned int m = 0 ;
- int argc1 = el_semicolon(argv) ;
- if (argc1 >= argc) strerr_dief1x(100, "unterminated block") ;
- *todeln = argc1 ;
- argv += argc1 + 1 ; argc -= argc1 + 1 ;
- while (argc)
- {
- toadd[m] = *argv++ ;
- if (!--argc) strerr_dief1x(100, "missing bundle contents block") ;
- argc1 = el_semicolon(argv) ;
- if (argc1 >= argc) strerr_dief1x(100, "unterminated block") ;
- argv[argc1] = 0 ;
- toadd_contents[m++] = argv ;
- argv += argc1 + 1 ; argc -= argc1 + 1 ;
- }
- *toaddn = m ;
-}
-
-static inline void print_help (void)
-{
- static char const *help =
-"s6-rc-bundle help\n"
-"s6-rc-bundle add bundlename contents...\n"
-"s6-rc-bundle delete bundlenames...\n"
-"s6-rc-bundle multiple { to-delete } to-add { contents... } ... (execlineb syntax)\n" ;
- if (buffer_putsflush(buffer_1, help) < 0)
- strerr_diefu1sys(111, "write to stdout") ;
-}
-
-static inline unsigned int lookup (char const *const *table, char const *command)
-{
- unsigned int i = 0 ;
- for (; table[i] ; i++) if (!strcmp(command, table[i])) break ;
- return i ;
-}
-
-static inline unsigned int parse_command (char const *command)
-{
- static char const *const command_table[5] =
- {
- "help",
- "add",
- "delete",
- "multiple",
- 0
- } ;
- unsigned int i = lookup(command_table, command) ;
- if (!command_table[i]) dieusage() ;
- return i ;
-}
-
-int main (int argc, char const **argv)
-{
- char const *live = S6RC_LIVEDIR ;
- char const *compiled = 0 ;
- unsigned int what ;
- int force = 0 ;
- int blocking = 0 ;
- PROG = "s6-rc-bundle" ;
- {
- subgetopt l = SUBGETOPT_ZERO ;
- for (;;)
- {
- int opt = subgetopt_r(argc, argv, "fl:c:b", &l) ;
- if (opt == -1) break ;
- switch (opt)
- {
- case 'f' : force = 1 ; break ;
- case 'l' : live = l.arg ; break ;
- case 'c' : compiled = l.arg ; break ;
- case 'b' : blocking = 1 ; break ;
- default : dieusage() ;
- }
- }
- argc -= l.ind ; argv += l.ind ;
- }
-
- if (!argc) dieusage() ;
- what = parse_command(*argv++) ;
- if (!what)
- {
- print_help() ;
- return 0 ;
- }
- if (!--argc) dieusage() ;
- if (what != 2 && argc < 2) dieusage() ;
-
- {
- size_t livelen = strlen(live) ;
- int fdcompiled = -1 ;
- int compiledlock ;
- s6rc_db_t dbblob ;
- char compiledblob[compiled ? strlen(compiled) : livelen + 10] ;
-
- if (!compiled)
- {
- memcpy(compiledblob, live, livelen) ;
- memcpy(compiledblob + livelen, "/compiled", 10) ;
- compiled = compiledblob ;
- }
-
- if (!s6rc_lock(0, 0, 0, compiled, 2, &compiledlock, blocking))
- strerr_diefu2sys(111, "take lock on ", compiled) ;
- fdcompiled = open_readb(compiled) ;
- if (fdcompiled < 0)
- strerr_diefu2sys(111, "open ", compiled) ;
-
-
- /* Read the sizes of the compiled db */
-
- fdcompiled = open_readb(compiled) ;
- if (!s6rc_db_read_sizes(fdcompiled, &dbblob))
- strerr_diefu3sys(111, "read ", compiled, "/n") ;
-
-
- /* Allocate enough stack for the db */
-
- {
- unsigned int n = dbblob.nshort + dbblob.nlong ;
- s6rc_service_t serviceblob[n] ;
- char const *argvblob[dbblob.nargvs] ;
- uint32_t depsblob[dbblob.ndeps << 1] ;
- uint32_t producersblob[dbblob.nproducers] ;
- char stringblob[dbblob.stringlen] ;
- int r ;
-
- dbblob.services = serviceblob ;
- dbblob.argvs = argvblob ;
- dbblob.deps = depsblob ;
- dbblob.producers = producersblob ;
- dbblob.string = stringblob ;
-
-
- /* Read the db from the file */
-
- r = s6rc_db_read(fdcompiled, &dbblob) ;
- if (r < 0) strerr_diefu3sys(111, "read ", compiled, "/db") ;
- if (!r) strerr_dief3x(4, "invalid service database in ", compiled, "/db") ;
-
-
- /* Perform the action */
-
- switch (what)
- {
- case 1 : /* add */
- {
- char const *const *contents = argv + 1 ;
- modify_resolve(fdcompiled, &dbblob, 0, 0, argv, &contents, 1, force, compiled) ;
- break ;
- }
- case 2 : /* delete */
- modify_resolve(fdcompiled, &dbblob, argv, argc, 0, 0, 0, force, compiled) ;
- break ;
- case 3 : /* multiple */
- {
- unsigned int toaddn, todeln ;
- char const *toadd[argc - 1] ;
- char const *const *toadd_contents[argc - 1] ;
- parse_multiple(argc, argv, &todeln, &toaddn, toadd, toadd_contents) ;
- modify_resolve(fdcompiled, &dbblob, argv, todeln, toadd, toadd_contents, toaddn, force, compiled) ;
- break ;
- }
- }
- }
- }
- return 0 ;
-}
diff --git a/src/s6-rc/s6-rc-compile.c b/src/s6-rc/s6-rc-compile.c
index 2947c14..62b9aef 100644
--- a/src/s6-rc/s6-rc-compile.c
+++ b/src/s6-rc/s6-rc-compile.c
@@ -23,7 +23,7 @@
#define USAGE "s6-rc-compile [ -v verbosity ] [ -h fdholder_user ] [ -b ] destdir sources..."
#define dieusage() strerr_dieusage(100, USAGE)
-#define dienomem() strerr_dief1x(111, "out of memory") ;
+#define dienomem() strerr_dief(111, "out of memory") ;
#define S6RC_INTERNALS "s6-rc-compile internals"
@@ -97,8 +97,8 @@ typedef struct oneshot_s oneshot_t, *oneshot_t_ref ;
struct oneshot_s
{
common_t common ;
- unsigned int argvindex[2] ; /* pos in keep */
- unsigned int argc[2] ;
+ unsigned int argvindex[3] ; /* pos in keep */
+ unsigned int argc[3] ;
} ;
typedef struct longrun_s longrun_t, *longrun_t_ref ;
@@ -166,7 +166,7 @@ static int add_name_nocheck (before_t *be, char const *srcdir, char const *name,
{
uint32_t id ;
if (verbosity >= 4)
- strerr_warnt6x("from ", srcdir, ": adding identifier ", name, " of type ", typestr(type)) ;
+ strerr_warnt("from ", srcdir, ": adding identifier ", name, " of type ", typestr(type)) ;
if (avltree_search(&names_map, name, &id))
{
@@ -174,7 +174,7 @@ static int add_name_nocheck (before_t *be, char const *srcdir, char const *name,
if (type == SVTYPE_UNDEFINED)
{
if (verbosity >= 4)
- strerr_warnt4x("identifier ", name, " was already declared with type ", typestr(info->type)) ;
+ strerr_warnt("identifier ", name, " was already declared with type ", typestr(info->type)) ;
switch (info->type)
{
case SVTYPE_ONESHOT :
@@ -186,7 +186,7 @@ static int add_name_nocheck (before_t *be, char const *srcdir, char const *name,
{
info->type = type ;
if (verbosity >= 4)
- strerr_warnt4x("previously encountered identifier ", name, " now has type ", typestr(type)) ;
+ strerr_warnt("previously encountered identifier ", name, " now has type ", typestr(type)) ;
switch (type)
{
case SVTYPE_UNDEFINED : break ;
@@ -205,7 +205,7 @@ static int add_name_nocheck (before_t *be, char const *srcdir, char const *name,
break ;
}
}
- else strerr_dief6x(1, "duplicate service definition: ", name, " defined in ", srcdir, " is already defined and has type ", typestr(info->type)) ;
+ else strerr_dief(1, "duplicate service definition: ", name, " defined in ", srcdir, " is already defined and has type ", typestr(info->type)) ;
*pos = info->pos ;
*kpos = info->kpos ;
return 1 ;
@@ -238,7 +238,7 @@ static int add_name_nocheck (before_t *be, char const *srcdir, char const *name,
static void check_identifier (char const *srcdir, char const *s)
{
if (!strncmp(s, "s6rc-", 5) || !strncmp(s, "s6-rc-", 6))
- strerr_dief5x(1, "in ", srcdir, ": identifier ", s, " starts with reserved prefix") ;
+ strerr_dief(1, "in ", srcdir, ": identifier ", s, " starts with reserved prefix") ;
}
static int add_name (before_t *be, char const *srcdir, char const *name, servicetype_t type, unsigned int *pos, unsigned int *kpos)
@@ -286,7 +286,7 @@ static int add_namelist (before_t *be, int dfd, char const *srcdir, char const *
if (fd < 0)
{
if (errno == ENOENT) return 0 ;
- strerr_diefu6sys(111, "open ", srcdir, "/", name, "/", list) ;
+ strerr_diefusys(111, "open ", srcdir, "/", name, "/", list) ;
}
buffer_init(&b, &buffer_read, fd, buf, 2048) ;
*listindex = genalloc_len(unsigned int, &be->indices) ;
@@ -299,7 +299,7 @@ static int add_namelist (before_t *be, int dfd, char const *srcdir, char const *
size_t i = start ;
if (r < 0)
{
- if (errno != EPIPE) strerr_diefu6sys(111, "read ", srcdir, "/", name, "/", list) ;
+ if (errno != EPIPE) strerr_diefusys(111, "read ", srcdir, "/", name, "/", list) ;
if (!stralloc_0(&satmp)) dienomem() ;
cont = 0 ;
}
@@ -315,7 +315,7 @@ static int add_namelist (before_t *be, int dfd, char const *srcdir, char const *
dienomem() ;
}
else if (verbosity >= 2)
- strerr_warnw8x("in ", srcdir, "/", name, "/", list, ": name listed more than once: ", satmp.s + i) ;
+ strerr_warnw("in ", srcdir, "/", name, "/", list, ": name listed more than once: ", satmp.s + i) ;
}
satmp.len = start ;
}
@@ -331,7 +331,7 @@ static int add_namelistd (before_t *be, int dfd, char const *srcdir, char const
if (!dir)
{
if (errno == ENOENT) return 0 ;
- strerr_diefu6sys(111, "opendir ", srcdir, "/", name, "/", list) ;
+ strerr_diefusys(111, "opendir ", srcdir, "/", name, "/", list) ;
}
*listindex = genalloc_len(unsigned int, &be->indices) ;
for (;;)
@@ -346,7 +346,7 @@ static int add_namelistd (before_t *be, int dfd, char const *srcdir, char const
if (!genalloc_append(unsigned int, &be->indices, &pos)) dienomem() ;
}
dir_close(dir) ;
- if (errno) strerr_diefu4sys(111, "readdir ", srcdir, "/", list) ;
+ if (errno) strerr_diefusys(111, "readdir ", srcdir, "/", list) ;
*n = genalloc_len(unsigned int, &be->indices) - *listindex ;
return 1 ;
}
@@ -356,10 +356,10 @@ static void read_script (before_t *be, int dfd, char const *srcdir, char const *
int r = 0 ;
int fd = open_readatb(dfd, script) ;
*argvindex = keep.len ;
- if (fd < 0)
+ if (fd == -1)
{
if (errno != ENOENT || mandatory)
- strerr_diefu6sys(111, "open ", srcdir, "/", name, "/", script) ;
+ strerr_diefusys(111, "open ", srcdir, "/", name, "/", script) ;
}
else
{
@@ -368,10 +368,10 @@ static void read_script (before_t *be, int dfd, char const *srcdir, char const *
r = el_parse_from_buffer(&keep, &b) ;
switch (r)
{
- case -4 : strerr_dief8x(1, "syntax error in ", srcdir, "/", name, "/", script, ": unmatched ", "}");
- case -3 : strerr_dief8x(1, "syntax error in ", srcdir, "/", name, "/", script, ": unmatched ", "{");
- case -2 : strerr_dief6x(1, "syntax error in ", srcdir, "/", name, "/", script) ;
- case -1 : strerr_diefu6sys(111, "parse ", srcdir, "/", name, "/", script) ;
+ case -4 : strerr_dief(1, "syntax error in ", srcdir, "/", name, "/", script, ": unmatched ", "}");
+ case -3 : strerr_dief(1, "syntax error in ", srcdir, "/", name, "/", script, ": unmatched ", "{");
+ case -2 : strerr_dief(1, "syntax error in ", srcdir, "/", name, "/", script) ;
+ case -1 : strerr_diefusys(111, "parse ", srcdir, "/", name, "/", script) ;
}
close(fd) ;
}
@@ -387,7 +387,7 @@ static uint32_t read_timeout (int dfd, char const *srcdir, char const *name, cha
if (r == -1)
{
if (errno && errno != ENOENT)
- strerr_diefu6sys(111, "read ", srcdir, "/", name, "/", tname) ;
+ strerr_diefusys(111, "read ", srcdir, "/", name, "/", tname) ;
}
else
{
@@ -414,7 +414,7 @@ static uint32_t read_flags (int dfd, char const *srcdir, char const *name)
if (access_at(dfd, files[i], F_OK, 0) < 0)
{
if (errno != ENOENT)
- strerr_diefu6sys(111, "read ", srcdir, "/", name, "/", files[i]) ;
+ strerr_diefusys(111, "read ", srcdir, "/", name, "/", files[i]) ;
}
else flags |= 1 << i ;
}
@@ -439,8 +439,9 @@ static void add_common (before_t *be, int dfd, char const *srcdir, char const *n
static inline void add_oneshot (before_t *be, int dfd, char const *srcdir, char const *name)
{
oneshot_t service ;
- if (verbosity >= 3) strerr_warni3x(name, " has type ", "oneshot") ;
+ if (verbosity >= 3) strerr_warni(name, " has type ", "oneshot") ;
add_common(be, dfd, srcdir, name, &service.common, SVTYPE_ONESHOT) ;
+ read_script(be, dfd, srcdir, name, "reload", &service.argvindex[2], &service.argc[2], 0) ;
read_script(be, dfd, srcdir, name, "up", &service.argvindex[1], &service.argc[1], 1) ;
read_script(be, dfd, srcdir, name, "down", &service.argvindex[0], &service.argc[0], 0) ;
if (!genalloc_append(unsigned int, &be->indices, &be->specialdeps[0])) dienomem() ;
@@ -453,7 +454,7 @@ static inline void add_oneshot (before_t *be, int dfd, char const *srcdir, char
while (i--)
{
fmt[uint_fmt(fmt, *p)] = 0 ;
- strerr_warnt7x("dependency from ", name, " to ", data.s + *p, " (", fmt, ")") ;
+ strerr_warnt("dependency from ", name, " to ", data.s + *p, " (", fmt, ")") ;
p++ ;
}
}
@@ -465,34 +466,34 @@ static inline void add_longrun (before_t *be, int dfd, char const *srcdir, char
longrun_t service = { .srcdir = srcdir, .nproducers = 0, .prodindex = 0, .consumer = 0, .pipelinename = 0 } ;
unsigned int relatedindex, n ;
int fd ;
- if (verbosity >= 3) strerr_warni3x(name, " has type ", "longrun") ;
+ if (verbosity >= 3) strerr_warni(name, " has type ", "longrun") ;
add_common(be, dfd, srcdir, name, &service.common, SVTYPE_LONGRUN) ;
fd = open_readat(dfd, "run") ;
- if (fd < 0)
+ if (fd == -1)
{
if (errno == ENOENT)
- strerr_diefu5x(1, "find a run script in ", srcdir, "/", name, "/run") ;
- else strerr_diefu5sys(111, "open ", srcdir, "/", name, "/run") ;
+ strerr_diefu(1, "find a run script in ", srcdir, "/", name, "/run") ;
+ else strerr_diefusys(111, "open ", srcdir, "/", name, "/run") ;
}
else
{
struct stat st ;
if (fstat(fd, &st) < 0)
- strerr_diefu5sys(111, "stat ", srcdir, "/", name, "/run") ;
+ strerr_diefusys(111, "stat ", srcdir, "/", name, "/run") ;
if (!S_ISREG(st.st_mode))
- strerr_dief4x(1, srcdir, "/", name, "/run is not a regular file") ;
+ strerr_dief(1, srcdir, "/", name, "/run is not a regular file") ;
}
close(fd) ;
fd = 0 ;
if (add_namelist(be, dfd, srcdir, name, "producer-for", &relatedindex, &n))
{
if (n != 1)
- strerr_dief5x(1, srcdir, "/", name, "/producer-for", " should only contain one service name") ;
+ strerr_dief(1, srcdir, "/", name, "/producer-for", " should only contain one service name") ;
service.consumer = genalloc_s(unsigned int, &be->indices)[relatedindex] ;
if (!genalloc_append(unsigned int, &be->indices, &be->specialdeps[1])) dienomem() ;
service.common.ndeps += 2 ;
if (verbosity >= 3)
- strerr_warni3x(name, " is a producer for ", data.s + service.consumer) ;
+ strerr_warni(name, " is a producer for ", data.s + service.consumer) ;
fd = 1 ;
}
if (add_namelist(be, dfd, srcdir, name, "consumer-for", &service.prodindex, &service.nproducers) && service.nproducers)
@@ -508,14 +509,14 @@ static inline void add_longrun (before_t *be, int dfd, char const *srcdir, char
}
if (verbosity >= 3)
for (unsigned int i = 0 ; i < service.nproducers ; i++)
- strerr_warni3x(name, " is a consumer for ", data.s + genalloc_s(unsigned int, &be->indices)[service.prodindex + i]) ;
+ strerr_warni(name, " is a consumer for ", data.s + genalloc_s(unsigned int, &be->indices)[service.prodindex + i]) ;
}
if (fd == 2)
{
if (add_namelist(be, dfd, srcdir, name, "pipeline-name", &relatedindex, &n))
{
if (n != 1)
- strerr_dief5x(1, srcdir, "/", name, "/pipeline-name", " should only contain one name") ;
+ strerr_dief(1, srcdir, "/", name, "/pipeline-name", " should only contain one name") ;
service.pipelinename = genalloc_s(unsigned int, &be->indices)[relatedindex] ;
genalloc_setlen(unsigned int, &be->indices, relatedindex) ;
}
@@ -523,10 +524,10 @@ static inline void add_longrun (before_t *be, int dfd, char const *srcdir, char
else if (access_at(dfd, "pipeline-name", F_OK, 0) < 0)
{
if (errno != ENOENT)
- strerr_diefu5sys(111, "access ", srcdir, "/", name, "/pipeline-name") ;
+ strerr_diefusys(111, "access ", srcdir, "/", name, "/pipeline-name") ;
}
else if (verbosity)
- strerr_warnw4x(srcdir, "/", name, " contains a pipeline-name file despite not being a last consumer; this file will be ignored") ;
+ strerr_warnw(srcdir, "/", name, " contains a pipeline-name file despite not being a last consumer; this file will be ignored") ;
if (!genalloc_append(longrun_t, &be->longruns, &service)) dienomem() ;
}
@@ -534,25 +535,25 @@ static inline void add_bundle (before_t *be, int dfd, char const *srcdir, char c
{
bundle_t bundle ;
unsigned int dummy ;
- if (verbosity >= 3) strerr_warni3x(name, " has type ", "bundle") ;
+ if (verbosity >= 3) strerr_warni(name, " has type ", "bundle") ;
add_name(be, srcdir, name, SVTYPE_BUNDLE, &bundle.name, &dummy) ;
if (!add_namelistd(be, dfd, srcdir, name, "contents.d", &bundle.listindex, &bundle.n)
&& !add_namelist(be, dfd, srcdir, name, "contents", &bundle.listindex, &bundle.n))
- strerr_diefu5sys(111, "open ", srcdir, "/", name, "/contents") ;
+ strerr_diefusys(111, "open ", srcdir, "/", name, "/contents") ;
bundle.annotation_flags = read_flags(dfd, srcdir, name) ;
if (!genalloc_append(bundle_t, &be->bundles, &bundle)) dienomem() ;
}
static inline void add_source (before_t *be, int dfd, char const *srcdir, char const *name)
{
- if (verbosity >= 3) strerr_warni4x("parsing ", srcdir, "/", name) ;
+ if (verbosity >= 3) strerr_warni("parsing ", srcdir, "/", name) ;
switch (type_check(dfd))
{
- case 0 : strerr_dief6x(1, "invalid ", srcdir, "/", name, "/type", ": must be oneshot, longrun, or bundle") ;
+ case 0 : strerr_dief(1, "invalid ", srcdir, "/", name, "/type", ": must be oneshot, longrun, or bundle") ;
case 1 : add_longrun(be, dfd, srcdir, name) ; break ;
case 2 : add_oneshot(be, dfd, srcdir, name) ; break ;
case 3 : add_bundle(be, dfd, srcdir, name) ; break ;
- default : strerr_diefu5sys(111, "read ", srcdir, "/", name, "/type") ;
+ default : strerr_diefusys(111, "read ", srcdir, "/", name, "/type") ;
}
}
@@ -561,7 +562,7 @@ static inline void add_sources (before_t *be, char const *srcdir, stralloc *sa)
unsigned int n = 0 ;
int fdsrc ;
DIR *dir = opendir(srcdir) ;
- if (!dir) strerr_diefu2sys(111, "opendir ", srcdir) ;
+ if (!dir) strerr_diefusys(111, "opendir ", srcdir) ;
if (verbosity >= 2) strerr_warni("adding sources from ", srcdir) ;
fdsrc = dir_fd(dir) ;
for (;;)
@@ -573,15 +574,15 @@ static inline void add_sources (before_t *be, char const *srcdir, stralloc *sa)
if (!d) break ;
if (d->d_name[0] == '.') continue ;
if (strchr(d->d_name, '\n'))
- strerr_dief3x(1, "subdirectory of ", srcdir, " contains a newline character") ;
+ strerr_dief(1, "subdirectory of ", srcdir, " contains a newline character") ;
check_identifier(srcdir, d->d_name) ;
if (stat_at(fdsrc, d->d_name, &st) < 0)
- strerr_diefu4sys(111, "stat ", srcdir, "/", d->d_name) ;
+ strerr_diefusys(111, "stat ", srcdir, "/", d->d_name) ;
if (!S_ISDIR(st.st_mode)) continue ;
n++ ;
if (!stralloc_catb(sa, d->d_name, strlen(d->d_name)+1)) dienomem() ;
}
- if (errno) strerr_diefu2sys(111, "readdir ", srcdir) ;
+ if (errno) strerr_diefusys(111, "readdir ", srcdir) ;
if (n)
{
size_t pos = 0 ;
@@ -595,13 +596,13 @@ static inline void add_sources (before_t *be, char const *srcdir, stralloc *sa)
for (unsigned int i = 0 ; i < n ; i++)
{
int fd = open_readatb(fdsrc, names[i]) ;
- if (fd < 0) strerr_diefu4sys(111, "open ", srcdir, "/", names[i]) ;
+ if (fd < 0) strerr_diefusys(111, "open ", srcdir, "/", names[i]) ;
add_source(be, fd, srcdir, names[i]) ;
close(fd) ;
}
sa->len = 0 ;
}
- else if (verbosity) strerr_warnw3x("source ", srcdir, " is empty") ;
+ else if (verbosity) strerr_warnw("source ", srcdir, " is empty") ;
dir_close(dir) ;
}
@@ -624,16 +625,16 @@ static servicetype_t add_tree_to_bundle_rec (struct pipeline_recinfo_s *recinfo,
}
if (info->type != SVTYPE_LONGRUN) return info->type ;
if (recinfo->bundle.n++ >= recinfo->nlong)
- strerr_dief4x(1, "pipeline ", data.s + recinfo->pipelinename, " is too long: possible loop involving ", name) ;
+ strerr_dief(1, "pipeline ", data.s + recinfo->pipelinename, " is too long: possible loop involving ", name) ;
if (verbosity >= 4)
- strerr_warni4x("adding ", name, " to pipeline ", data.s + recinfo->pipelinename) ;
+ strerr_warni("adding ", name, " to pipeline ", data.s + recinfo->pipelinename) ;
if (!genalloc_append(unsigned int, &recinfo->be->indices, &info->pos)) dienomem() ;
for (unsigned int i = 0 ; i < recinfo->longruns[info->i].nproducers ; i++)
{
char *prodname = data.s + genalloc_s(unsigned int, &recinfo->be->indices)[recinfo->longruns[info->i].prodindex + i] ;
servicetype_t type = add_tree_to_bundle_rec(recinfo, prodname) ;
if (type != SVTYPE_LONGRUN)
- strerr_dief6x(1, "longrun ", name, " declares a producer ", prodname, " of type ", typestr(type)) ;
+ strerr_dief(1, "longrun ", name, " declares a producer ", prodname, " of type ", typestr(type)) ;
}
return SVTYPE_LONGRUN ;
}
@@ -642,7 +643,7 @@ static inline void add_pipeline_bundles (before_t *be)
{
longrun_t const *longruns = genalloc_s(longrun_t, &be->longruns) ;
unsigned int i = genalloc_len(longrun_t, &be->longruns) ;
- if (verbosity >= 2) strerr_warni1x("making bundles for pipelines") ;
+ if (verbosity >= 2) strerr_warni("making bundles for pipelines") ;
while (i--) if (longruns[i].pipelinename)
{
struct pipeline_recinfo_s recinfo =
@@ -654,7 +655,7 @@ static inline void add_pipeline_bundles (before_t *be)
.pipelinename = longruns[i].pipelinename
} ;
if (verbosity >= 3)
- strerr_warni2x("creating bundle for pipeline ", data.s + recinfo.pipelinename) ;
+ strerr_warni("creating bundle for pipeline ", data.s + recinfo.pipelinename) ;
{
uint32_t dummy ;
add_name(be, S6RC_INTERNALS, data.s + recinfo.pipelinename, SVTYPE_BUNDLE, &recinfo.bundle.name, &dummy) ;
@@ -690,7 +691,7 @@ static void resolve_bundle_rec (bundle_recinfo_t *recinfo, unsigned int i)
unsigned int const *listindex = recinfo->indices + me->listindex ;
unsigned int j = 0 ;
if (recinfo->mark[i] & 1)
- strerr_dief4x(1, "cyclic bundle definition: resolution of ", data.s + recinfo->oldb[recinfo->source].name, " encountered a cycle involving ", data.s + me->name) ;
+ strerr_dief(1, "cyclic bundle definition: resolution of ", data.s + recinfo->oldb[recinfo->source].name, " encountered a cycle involving ", data.s + me->name) ;
recinfo->mark[i] |= 1 ;
for (; j < me->n ; j++)
{
@@ -711,7 +712,7 @@ static void resolve_bundle_rec (bundle_recinfo_t *recinfo, unsigned int i)
bitarray_or(recinfo->barray + i * recinfo->nbits, recinfo->barray + i * recinfo->nbits, recinfo->barray + p->i * recinfo->nbits, recinfo->n) ;
break ;
default :
- strerr_dief4x(1, "during resolution of bundle ", data.s + me->name, ": undefined service name ", data.s + p->pos) ;
+ strerr_dief(1, "during resolution of bundle ", data.s + me->name, ": undefined service name ", data.s + p->pos) ;
}
}
recinfo->mark[i] |= 2 ;
@@ -723,7 +724,7 @@ static inline unsigned int resolve_bundles (bundle_t const *oldb, bundle_t *newb
unsigned int total = 0, i = 0 ;
unsigned char mark[nbundles] ;
bundle_recinfo_t recinfo = { .oldb = oldb, .newb = newb, .n = nshort + nlong, .nlong = nlong, .nbits = bitarray_div8(nshort + nlong), .indices = indices, .barray = barray, .mark = mark } ;
- if (verbosity >= 2) strerr_warni1x("resolving bundle names") ;
+ if (verbosity >= 2) strerr_warni("resolving bundle names") ;
memset(barray, 0, recinfo.nbits * nbundles) ;
memset(mark, 0, nbundles) ;
for (; i < nbundles ; i++)
@@ -745,7 +746,7 @@ static inline unsigned int resolve_bundles (bundle_t const *oldb, bundle_t *newb
static inline void flatlist_bundles (bundle_t *bundles, unsigned int nbundles, unsigned int nbits, unsigned char const *barray, uint32_t *bdeps)
{
unsigned int i = 0 ;
- if (verbosity >= 3) strerr_warni1x("converting bundle array") ;
+ if (verbosity >= 3) strerr_warni("converting bundle array") ;
for (; i < nbundles ; i++)
{
unsigned char const *mybits = barray + i * nbits ;
@@ -773,7 +774,7 @@ static void resolve_deps (common_t const *me, unsigned int nlong, unsigned int n
{
char fmt[UINT_FMT] ;
fmt[uint_fmt(fmt, nlong + p->i)] = 0 ;
- strerr_warnt6x(keep.s + me->kname, " depends on oneshot ", data.s + p->pos, " (", fmt, ")") ;
+ strerr_warnt(keep.s + me->kname, " depends on oneshot ", data.s + p->pos, " (", fmt, ")") ;
}
break ;
case SVTYPE_LONGRUN :
@@ -782,7 +783,7 @@ static void resolve_deps (common_t const *me, unsigned int nlong, unsigned int n
{
char fmt[UINT_FMT] ;
fmt[uint_fmt(fmt, p->i)] = 0 ;
- strerr_warnt6x(keep.s + me->kname, " depends on longrun ", data.s + p->pos, " (", fmt, ")") ;
+ strerr_warnt(keep.s + me->kname, " depends on longrun ", data.s + p->pos, " (", fmt, ")") ;
}
break ;
case SVTYPE_BUNDLE :
@@ -791,11 +792,11 @@ static void resolve_deps (common_t const *me, unsigned int nlong, unsigned int n
{
char fmt[UINT_FMT] ;
fmt[uint_fmt(fmt, nlong + p->i)] = 0 ;
- strerr_warnt3x(keep.s + me->kname, " depends on bundle ", data.s + p->pos) ;
+ strerr_warnt(keep.s + me->kname, " depends on bundle ", data.s + p->pos) ;
}
break ;
default :
- strerr_dief4x(1, "during dependency resolution for service ", keep.s + me->kname, ": undefined service name ", data.s + p->pos) ;
+ strerr_dief(1, "during dependency resolution for service ", keep.s + me->kname, ": undefined service name ", data.s + p->pos) ;
}
}
}
@@ -810,7 +811,7 @@ static inline uint32_t resolve_prodcons (s6rc_longrun_t *l, longrun_t const *lon
avltree_search(&names_map, data.s + longruns[n].consumer, &j) ;
p = genalloc_s(nameinfo_t, &nameinfo) + j ;
if (p->type != SVTYPE_LONGRUN)
- strerr_dief6x(1, "longrun service ", keep.s + longruns[n].common.kname, " declares being a producer for a service named ", data.s + p->pos, " of type ", typestr(p->type)) ;
+ strerr_dief(1, "longrun service ", keep.s + longruns[n].common.kname, " declares being a producer for a service named ", data.s + p->pos, " of type ", typestr(p->type)) ;
for (; i < longruns[p->i].nproducers ; i++)
{
uint32_t k ;
@@ -818,11 +819,11 @@ static inline uint32_t resolve_prodcons (s6rc_longrun_t *l, longrun_t const *lon
avltree_search(&names_map, data.s + indices[longruns[p->i].prodindex + i], &k) ;
q = genalloc_s(nameinfo_t, &nameinfo) + k ;
if (q->type != SVTYPE_LONGRUN)
- strerr_dief6x(1, "longrun service ", data.s + p->pos, " declares a consumer ", data.s + q->pos, " of type ", typestr(q->type)) ;
+ strerr_dief(1, "longrun service ", data.s + p->pos, " declares a consumer ", data.s + q->pos, " of type ", typestr(q->type)) ;
if (q->i == n) break ;
}
if (i == longruns[p->i].nproducers)
- strerr_dief5x(1, "longrun service ", keep.s + longruns[n].common.kname, " declares being a producer for a service named ", data.s + p->pos, " that does not declare it back") ;
+ strerr_dief(1, "longrun service ", keep.s + longruns[n].common.kname, " declares being a producer for a service named ", data.s + p->pos, " that does not declare it back") ;
l->consumer = p->i ;
}
else l->consumer = nlong ;
@@ -835,13 +836,13 @@ static inline uint32_t resolve_prodcons (s6rc_longrun_t *l, longrun_t const *lon
avltree_search(&names_map, data.s + indices[longruns[n].prodindex + i], &j) ;
p = genalloc_s(nameinfo_t, &nameinfo) + j ;
if (p->type != SVTYPE_LONGRUN)
- strerr_dief6x(1, "longrun service ", keep.s + longruns[n].common.kname, " declares being the consumer for a service named ", data.s + p->pos, " of type ", typestr(p->type)) ;
+ strerr_dief(1, "longrun service ", keep.s + longruns[n].common.kname, " declares being the consumer for a service named ", data.s + p->pos, " of type ", typestr(p->type)) ;
avltree_search(&names_map, data.s + longruns[p->i].consumer, &k) ;
q = genalloc_s(nameinfo_t, &nameinfo) + k ;
if (q->type != SVTYPE_LONGRUN)
- strerr_dief6x(1, "longrun service ", data.s + p->pos, " declares a producer ", data.s + q->pos, " of type ", typestr(q->type)) ;
+ strerr_dief(1, "longrun service ", data.s + p->pos, " declares a producer ", data.s + q->pos, " of type ", typestr(q->type)) ;
if (q->i != n)
- strerr_dief5x(1, "longrun service ", keep.s + longruns[n].common.kname, " declares being the consumer for a service named ", data.s + p->pos, " that does not declare it back") ;
+ strerr_dief(1, "longrun service ", keep.s + longruns[n].common.kname, " declares being the consumer for a service named ", data.s + p->pos, " that does not declare it back") ;
prodlist[prodindex + i] = p->i ;
}
l->producers = prodindex ;
@@ -852,8 +853,7 @@ static inline uint32_t resolve_prodcons (s6rc_longrun_t *l, longrun_t const *lon
static inline unsigned int ugly_bitarray_vertical_countones (unsigned char const *sarray, unsigned int n, unsigned int i)
{
unsigned int m = 0, j = 0, nbits = bitarray_div8(n) ;
- for (; j < n ; j++)
- if (bitarray_peek(sarray + j * nbits, i)) m++ ;
+ for (; j < n ; j++) if (bitarray_peek(sarray + j * nbits, i)) m++ ;
return m ;
}
@@ -867,7 +867,7 @@ static inline void resolve_services (s6rc_db_t *db, before_t const *be, char con
uint32_t prodindex = 0 ;
uint32_t i = 0 ;
uint32_t total[2] = { 0, 0 } ;
- if (verbosity >= 2) strerr_warni1x("resolving service names") ;
+ if (verbosity >= 2) strerr_warni("resolving service names") ;
memset(sarray, 0, nbits * n) ;
for (; i < db->nlong ; i++)
{
@@ -889,6 +889,8 @@ static inline void resolve_services (s6rc_db_t *db, before_t const *be, char con
db->services[db->nlong + i].x.oneshot.argv[0] = oneshots[i].argvindex[0] ;
db->services[db->nlong + i].x.oneshot.argc[1] = oneshots[i].argc[1] ;
db->services[db->nlong + i].x.oneshot.argv[1] = oneshots[i].argvindex[1] ;
+ db->services[db->nlong + i].x.oneshot.argc[2] = oneshots[i].argc[2] ;
+ db->services[db->nlong + i].x.oneshot.argv[2] = oneshots[i].argvindex[2] ;
resolve_deps(&oneshots[i].common, db->nlong, n, nbits, indices, sarray + (db->nlong + i) * nbits, barray) ;
}
@@ -903,7 +905,7 @@ static inline void resolve_services (s6rc_db_t *db, before_t const *be, char con
}
if (total[0] != total[1])
- strerr_dief1x(101, "database inconsistency: dependencies and reverse dependencies do not match. Please submit a bug-report.") ;
+ strerr_dief(101, "database inconsistency: dependencies and reverse dependencies do not match. Please submit a bug-report.") ;
db->ndeps = total[1] ;
}
@@ -914,7 +916,7 @@ static inline void flatlist_services (s6rc_db_t *db, unsigned char const *sarray
diuint32 problem ;
unsigned int i = 0 ;
int r ;
- if (verbosity >= 3) strerr_warni1x("converting service dependency array") ;
+ if (verbosity >= 3) strerr_warni("converting service dependency array") ;
for (; i < n ; i++)
{
uint32_t *mydeps = db->deps + db->services[i].deps[0] ;
@@ -927,16 +929,16 @@ static inline void flatlist_services (s6rc_db_t *db, unsigned char const *sarray
if (bitarray_peek(sarray + i * nbits, j)) mydeps[k++] = j ;
}
- if (verbosity >= 3) strerr_warni1x("checking database correctness") ;
+ if (verbosity >= 3) strerr_warni("checking database correctness") ;
if (s6rc_db_check_depcycles(db, 1, &problem))
- strerr_dief5x(1, "cyclic service dependency", " reached from ", db->string + db->services[problem.left].name, " and involving ", db->string + db->services[problem.right].name) ;
+ strerr_dief(1, "cyclic service dependency", " reached from ", db->string + db->services[problem.left].name, " and involving ", db->string + db->services[problem.right].name) ;
r = s6rc_db_check_pipelines(db, &problem) ;
if (r)
{
if (r == 1)
- strerr_dief5x(1, "cyclic longrun pipeline", " reached from ", db->string + db->services[problem.left].name, " and involving ", db->string + db->services[problem.right].name) ;
+ strerr_dief(1, "cyclic longrun pipeline", " reached from ", db->string + db->services[problem.left].name, " and involving ", db->string + db->services[problem.right].name) ;
else
- strerr_dief5x(1, "longrun pipeline collision", " reached from ", db->string + db->services[problem.left].name, " and involving ", db->string + db->services[problem.right].name) ;
+ strerr_dief(1, "longrun pipeline collision", " reached from ", db->string + db->services[problem.left].name, " and involving ", db->string + db->services[problem.right].name) ;
}
}
@@ -969,7 +971,7 @@ static void auto_dir (char const *compiled, char const *dir)
if (mkdir(fn, 0755) < 0)
{
cleanup(compiled) ;
- strerr_diefu2sys(111, "mkdir ", fn) ;
+ strerr_diefusys(111, "mkdir ", fn) ;
}
}
@@ -984,7 +986,7 @@ static void auto_file (char const *compiled, char const *file, char const *s, un
if (!openwritenclose_unsafe(fn, s, n))
{
cleanup(compiled) ;
- strerr_diefu2sys(111, "write to ", fn) ;
+ strerr_diefusys(111, "write to ", fn) ;
}
}
@@ -999,7 +1001,7 @@ static void auto_symlink (char const *compiled, char const *name, char const *ta
if (symlink(target, fn) < 0)
{
cleanup(compiled) ;
- strerr_diefu4sys(111, "symlink ", target, " to ", fn) ;
+ strerr_diefusys(111, "symlink ", target, " to ", fn) ;
}
}
@@ -1014,7 +1016,7 @@ static void auto_rights (char const *compiled, char const *file, mode_t mode)
if (chmod(fn, mode) < 0)
{
cleanup(compiled) ;
- strerr_diefu2sys(111, "chmod ", fn) ;
+ strerr_diefusys(111, "chmod ", fn) ;
}
}
@@ -1022,16 +1024,16 @@ static inline void init_compiled (char const *compiled)
{
int compiledlock ;
if (mkdir(compiled, 0755) < 0)
- strerr_diefu2sys(111, "mkdir ", compiled) ;
+ strerr_diefusys(111, "mkdir ", compiled) ;
if (!s6rc_lock(0, 0, 0, compiled, 2, &compiledlock, 0))
- strerr_diefu2sys(111, "take lock on ", compiled) ;
+ strerr_diefusys(111, "take lock on ", compiled) ;
auto_dir(compiled, "servicedirs") ;
}
static inline void write_sizes (char const *compiled, s6rc_db_t const *db)
{
char pack[24] ;
- if (verbosity >= 3) strerr_warni3x("writing ", compiled, "/n") ;
+ if (verbosity >= 3) strerr_warni("writing ", compiled, "/n") ;
uint32_pack_big(pack, (uint32_t)db->nshort) ;
uint32_pack_big(pack + 4, (uint32_t)db->nlong) ;
uint32_pack_big(pack + 8, (uint32_t)db->stringlen) ;
@@ -1078,7 +1080,7 @@ static inline void write_oneshot_runner (char const *compiled, int blocking)
size_t base = satmp.len ;
make_skel(compiled, S6RC_ONESHOT_RUNNER, 3) ;
if (!stralloc_cats(&satmp, "#!"
- EXECLINE_SHEBANGPREFIX "execlineb -P\n"
+ EXECLINE_SHEBANGPREFIX "execlineb -s1\n"
EXECLINE_EXTBINPREFIX "fdmove -c 2 1\n"
EXECLINE_EXTBINPREFIX "fdmove 1 3\n"
S6_EXTBINPREFIX "s6-ipcserver-socketbinder -- s\n"
@@ -1087,7 +1089,11 @@ static inline void write_oneshot_runner (char const *compiled, int blocking)
S6_EXTBINPREFIX "s6-sudod -t 30000 --\n"
S6RC_EXTLIBEXECPREFIX "s6-rc-oneshot-run -l ../.. ")
|| (blocking && !stralloc_cats(&satmp, "-b "))
- || !stralloc_cats(&satmp, "--\n")) dienomem() ;
+ || !stralloc_cats(&satmp, "--\n"))
+ {
+ cleanup(compiled) ;
+ dienomem() ;
+ }
auto_file(compiled, "servicedirs/" S6RC_ONESHOT_RUNNER "/run", satmp.s + base, satmp.len - base) ;
satmp.len = base ;
auto_rights(compiled, "servicedirs/" S6RC_ONESHOT_RUNNER "/run", 0755) ;
@@ -1117,7 +1123,7 @@ static inline void write_fdholder (char const *compiled, s6rc_db_t const *db, ch
if (db->services[j].x.longrun.nproducers)
{
if (!stralloc_cats(&satmp, db->string + db->services[j].name)
- || !stralloc_catb(&satmp, "\n", 1)) dienomem() ;
+ || !stralloc_catb(&satmp, "\n", 1)) goto err ;
nfds += 2 ;
}
if (nfds < 240) nfds = 256 ; else nfds += (nfds >> 4) + 2 ;
@@ -1126,7 +1132,7 @@ static inline void write_fdholder (char const *compiled, s6rc_db_t const *db, ch
satmp.len = base ;
if (!stralloc_cats(&satmp,
- "#!" EXECLINE_SHEBANGPREFIX "execlineb -P\n"
+ "#!" EXECLINE_SHEBANGPREFIX "execlineb -s1\n"
EXECLINE_EXTBINPREFIX "pipeline -dw --\n{\n "
EXECLINE_EXTBINPREFIX "if --\n {\n "
EXECLINE_EXTBINPREFIX "forstdin -x0 -- i\n "
@@ -1135,28 +1141,33 @@ static inline void write_fdholder (char const *compiled, s6rc_db_t const *db, ch
EXECLINE_EXTBINPREFIX "redirfd -r 0 ./data/autofilled\n "
S6_EXTBINPREFIX "s6-ipcclient -l0 -- s\n "
S6RC_EXTLIBEXECPREFIX "s6-rc-fdholder-filler -1 --\n }\n "
- S6_EXTBINPREFIX "s6-svc -t .\n}\n")) dienomem() ;
+ S6_EXTBINPREFIX "s6-svc -t .\n}\n")) goto err ;
if (fdhuser)
{
if (!stralloc_cats(&satmp, S6_EXTBINPREFIX "s6-envuidgid -i -- ")
|| !string_quote(&satmp, fdhuser, strlen(fdhuser))
- || !stralloc_catb(&satmp, "\n", 1)) dienomem() ;
+ || !stralloc_catb(&satmp, "\n", 1)) goto err ;
}
- if (!stralloc_cats(&satmp, S6_EXTBINPREFIX "s6-fdholder-daemon -1 -n ")) dienomem() ;
+ if (!stralloc_cats(&satmp, S6_EXTBINPREFIX "s6-fdholder-daemon -1 -n ")) goto err ;
{
char fmt[UINT_FMT] ;
size_t len = uint_fmt(fmt, nfds) ;
fmt[len++] = ' ' ;
- if (!stralloc_catb(&satmp, fmt, len)) dienomem() ;
+ if (!stralloc_catb(&satmp, fmt, len)) goto err ;
}
if (fdhuser)
{
- if (!stralloc_cats(&satmp, "-U ")) dienomem() ;
+ if (!stralloc_cats(&satmp, "-U ")) goto err ;
}
- if (!stralloc_cats(&satmp, "-i data/rules -- s\n")) dienomem() ;
+ if (!stralloc_cats(&satmp, "-i data/rules -- s\n")) goto err ;
auto_file(compiled, "servicedirs/" S6RC_FDHOLDER "/run", satmp.s + base, satmp.len - base) ;
satmp.len = base ;
auto_rights(compiled, "servicedirs/" S6RC_FDHOLDER "/run", 0755) ;
+ return ;
+
+ err:
+ cleanup(compiled) ;
+ dienomem() ;
}
static inline void write_resolve (char const *compiled, s6rc_db_t const *db, bundle_t const *bundles, unsigned int nbundles, uint32_t const *bdeps)
@@ -1166,19 +1177,19 @@ static inline void write_resolve (char const *compiled, s6rc_db_t const *db, bun
cdbmaker c = CDBMAKER_ZERO ;
unsigned int i = db->nshort + db->nlong ;
char fn[clen + 13] ;
- if (verbosity >= 3) strerr_warni3x("writing ", compiled, "/resolve.cdb") ;
+ if (verbosity >= 3) strerr_warni("writing ", compiled, "/resolve.cdb") ;
memcpy(fn, compiled, clen) ;
memcpy(fn + clen, "/resolve.cdb", 13) ;
fd = open_trunc(fn) ;
if (fd < 0 || ndelay_off(fd) < 0)
{
cleanup(compiled) ;
- strerr_diefu2sys(111, "open_trunc ", fn) ;
+ strerr_diefusys(111, "open_trunc ", fn) ;
}
if (!cdbmake_start(&c, fd))
{
cleanup(compiled) ;
- strerr_diefu2sys(111, "cdbmake_start on ", fn) ;
+ strerr_diefusys(111, "cdbmake_start on ", fn) ;
}
/* atomic services */
@@ -1189,7 +1200,7 @@ static inline void write_resolve (char const *compiled, s6rc_db_t const *db, bun
if (!cdbmake_add(&c, db->string + db->services[i].name, strlen(db->string + db->services[i].name), pack, 4))
{
cleanup(compiled) ;
- strerr_diefu1sys(111, "cdbmake_add") ;
+ strerr_diefusys(111, "cdbmake_add") ;
}
}
@@ -1204,14 +1215,14 @@ static inline void write_resolve (char const *compiled, s6rc_db_t const *db, bun
if (!cdbmake_add(&c, data.s + bundles[i].name, strlen(data.s + bundles[i].name), pack, bundles[i].n << 2))
{
cleanup(compiled) ;
- strerr_diefu1sys(111, "cdbmake_add") ;
+ strerr_diefusys(111, "cdbmake_add") ;
}
}
if (!cdbmake_finish(&c))
{
cleanup(compiled) ;
- strerr_diefu2sys(111, "write to ", fn) ;
+ strerr_diefusys(111, "write to ", fn) ;
}
close(fd) ;
}
@@ -1223,17 +1234,17 @@ static int dircopy (char const *compiled, char const *srcfn, char const *dstfn)
{
if (errno == ENOENT) return 0 ;
cleanup(compiled) ;
- strerr_diefu2sys(111, "stat ", srcfn) ;
+ strerr_diefusys(111, "stat ", srcfn) ;
}
if (!S_ISDIR(st.st_mode))
{
cleanup(compiled) ;
- strerr_dief2x(1, srcfn, " is not a directory") ;
+ strerr_dief(1, srcfn, " is not a directory") ;
}
if (!hiercopy(srcfn, dstfn))
{
cleanup(compiled) ;
- strerr_diefu4sys(111, "recursively copy ", srcfn, " to ", dstfn) ;
+ strerr_diefusys(111, "recursively copy ", srcfn, " to ", dstfn) ;
}
return 1 ;
}
@@ -1241,12 +1252,12 @@ static int dircopy (char const *compiled, char const *srcfn, char const *dstfn)
static void write_exe_wrapper (char const *compiled, char const *fn, s6rc_db_t const *db, unsigned int i, char const *exe)
{
size_t base = satmp.len ;
- if (!stralloc_cats(&satmp, "#!" EXECLINE_SHEBANGPREFIX "execlineb -S0\n")) dienomem() ;
+ if (!stralloc_cats(&satmp, "#!" EXECLINE_SHEBANGPREFIX "execlineb -S0\n")) goto err ;
if (db->services[i].x.longrun.nproducers)
{
if (!stralloc_cats(&satmp, S6_EXTBINPREFIX "s6-fdholder-retrieve ../s6rc-fdholder/s \"pipe:s6rc-r-")
|| !string_quote_nodelim(&satmp, db->string + db->services[i].name, strlen(db->string + db->services[i].name))
- || !stralloc_cats(&satmp, "\"\n")) dienomem() ;
+ || !stralloc_cats(&satmp, "\"\n")) goto err ;
}
if (db->services[i].x.longrun.consumer < db->nlong)
{
@@ -1255,23 +1266,28 @@ static void write_exe_wrapper (char const *compiled, char const *fn, s6rc_db_t c
S6_EXTBINPREFIX "s6-fdholder-retrieve ../s6rc-fdholder/s \"pipe:s6rc-w-")
|| !string_quote_nodelim(&satmp, consumername, strlen(consumername))
|| !stralloc_cats(&satmp, "\"\n"
- EXECLINE_EXTBINPREFIX "fdswap 0 1\n")) dienomem() ;
+ EXECLINE_EXTBINPREFIX "fdswap 0 1\n")) goto err ;
}
if (!stralloc_cats(&satmp, "./")
|| !stralloc_cats(&satmp, exe)
- || !stralloc_cats(&satmp, ".user $@\n")) dienomem() ;
+ || !stralloc_cats(&satmp, ".user $@\n")) goto err ;
auto_file(compiled, fn, satmp.s + base, satmp.len - base) ;
satmp.len = base ;
auto_rights(compiled, fn, 0755) ;
+ return ;
+
+ err:
+ cleanup(compiled) ;
+ dienomem() ;
}
static int copy_uint (char const *compiled, char const *srcfn, char const *dstfn, unsigned int *u)
{
int r = s6rc_read_uint(srcfn, u) ;
- if (r < 0)
+ if (r == -1)
{
cleanup(compiled) ;
- strerr_diefu2sys(111, "read ", srcfn) ;
+ strerr_diefusys(111, "read ", srcfn) ;
}
if (r)
{
@@ -1281,12 +1297,12 @@ static int copy_uint (char const *compiled, char const *srcfn, char const *dstfn
if (!openwritenclose_unsafe(dstfn, fmt, len))
{
cleanup(compiled) ;
- strerr_diefu2sys(111, "write to ", dstfn) ;
+ strerr_diefusys(111, "write to ", dstfn) ;
}
if (chmod(dstfn, 0644) == -1)
{
cleanup(compiled) ;
- strerr_diefu2sys(111, "set permissions on ", dstfn) ;
+ strerr_diefusys(111, "set permissions on ", dstfn) ;
}
return 1 ;
}
@@ -1299,13 +1315,13 @@ static int copy_empty (char const *compiled, char const *srcfn, char const *dstf
{
if (errno == ENOENT) return 0 ;
cleanup(compiled) ;
- strerr_diefu2sys(111, "access ", srcfn) ;
+ strerr_diefusys(111, "access ", srcfn) ;
}
if (!openwritenclose_unsafe(dstfn, "", 0))
{
cleanup(compiled) ;
- strerr_diefu2sys(111, "create ", dstfn) ;
+ strerr_diefusys(111, "create ", dstfn) ;
}
return 1 ;
}
@@ -1314,7 +1330,7 @@ static inline void write_servicedirs (char const *compiled, s6rc_db_t const *db,
{
size_t clen = strlen(compiled) ;
unsigned int i = 2 ;
- if (verbosity >= 3) strerr_warni3x("writing ", compiled, "/servicedirs") ;
+ if (verbosity >= 3) strerr_warni("writing ", compiled, "/servicedirs") ;
for (; i < db->nlong ; i++)
{
size_t srcdirlen = strlen(srcdirs[i]) ;
@@ -1330,7 +1346,7 @@ static inline void write_servicedirs (char const *compiled, s6rc_db_t const *db,
if (mkdir(dstfn, 0755) < 0)
{
cleanup(compiled) ;
- strerr_diefu2sys(111, "mkdir ", dstfn) ;
+ strerr_diefusys(111, "mkdir ", dstfn) ;
}
dstfn[clen + len + 13] = '/' ;
memcpy(srcfn, srcdirs[i], srcdirlen) ;
@@ -1350,7 +1366,7 @@ static inline void write_servicedirs (char const *compiled, s6rc_db_t const *db,
if (!filecopy_unsafe(srcfn, dstfn, 0755))
{
cleanup(compiled) ;
- strerr_diefu4sys(111, "copy ", srcfn, " to ", dstfn) ;
+ strerr_diefusys(111, "copy ", srcfn, " to ", dstfn) ;
}
}
@@ -1364,7 +1380,7 @@ static inline void write_servicedirs (char const *compiled, s6rc_db_t const *db,
if (!filecopy_unsafe(srcfn, dstfn, 0755))
{
cleanup(compiled) ;
- strerr_diefu4sys(111, "copy ", srcfn, " to ", dstfn) ;
+ strerr_diefusys(111, "copy ", srcfn, " to ", dstfn) ;
}
memcpy(srcfn + srcdirlen + len + 2, "notification-fd", 16) ;
@@ -1377,7 +1393,7 @@ static inline void write_servicedirs (char const *compiled, s6rc_db_t const *db,
{
char fmt[UINT_FMT] ;
fmt[uint_fmt(fmt, u)] = 0 ;
- strerr_warnw4x("longrun ", db->string + db->services[i].name, " has a notification-fd of ", fmt) ;
+ strerr_warnw("longrun ", db->string + db->services[i].name, " has a notification-fd of ", fmt) ;
}
}
else fdnotif = u ;
@@ -1393,7 +1409,7 @@ static inline void write_servicedirs (char const *compiled, s6rc_db_t const *db,
{
char fmt[UINT_FMT] ;
fmt[uint_fmt(fmt, u)] = 0 ;
- strerr_warnw4x("longrun ", db->string + db->services[i].name, " has a lock-fd of ", fmt) ;
+ strerr_warnw("longrun ", db->string + db->services[i].name, " has a lock-fd of ", fmt) ;
}
}
else if (fdnotif == u)
@@ -1423,6 +1439,10 @@ static inline void write_servicedirs (char const *compiled, s6rc_db_t const *db,
memcpy(dstfn + clen + 14 + len, "down-signal", 12) ;
filecopy_unsafe(srcfn, dstfn, 0644) ;
+ memcpy(srcfn + srcdirlen + len + 2, "reload-signal", 14) ;
+ memcpy(dstfn + clen + 14 + len, "reload-signal", 14) ;
+ filecopy_unsafe(srcfn, dstfn, 0644) ;
+
memcpy(srcfn + srcdirlen + len + 2, "flag-newpidns", 14) ;
memcpy(dstfn + clen + 14 + len, "flag-newpidns", 14) ;
copy_empty(compiled, srcfn, dstfn) ;
@@ -1435,13 +1455,13 @@ static inline void write_servicedirs (char const *compiled, s6rc_db_t const *db,
if (mkdir(dstfn, 0755) == -1)
{
cleanup(compiled) ;
- strerr_diefu2sys(111, "mkdir ", dstfn) ;
+ strerr_diefusys(111, "mkdir ", dstfn) ;
}
dstfn[clen + 22 + len] = 0 ;
if (mkdir(dstfn, 0755) == -1)
{
cleanup(compiled) ;
- strerr_diefu2sys(111, "mkdir ", dstfn) ;
+ strerr_diefusys(111, "mkdir ", dstfn) ;
}
}
@@ -1457,7 +1477,7 @@ static inline void write_servicedirs (char const *compiled, s6rc_db_t const *db,
static int write_service (buffer *b, s6rc_service_t const *sv, int type)
{
- char pack[49] ;
+ char pack[57] ;
unsigned int m ;
uint32_pack_big(pack, sv->name) ;
uint32_pack_big(pack + 4, sv->flags) ;
@@ -1480,7 +1500,9 @@ static int write_service (buffer *b, s6rc_service_t const *sv, int type)
uint32_pack_big(pack + 36, sv->x.oneshot.argv[0]) ;
uint32_pack_big(pack + 40, sv->x.oneshot.argc[1]) ;
uint32_pack_big(pack + 44, sv->x.oneshot.argv[1]) ;
- m = 48 ;
+ uint32_pack_big(pack + 48, sv->x.oneshot.argc[2]) ;
+ uint32_pack_big(pack + 52, sv->x.oneshot.argv[2]) ;
+ m = 56 ;
}
pack[m++] = '\376' ;
return (buffer_put(b, pack, m) == m) ;
@@ -1495,24 +1517,24 @@ static inline void write_db (char const *compiled, s6rc_db_t const *db)
char dbfn[clen + 4] ;
memcpy(dbfn, compiled, clen) ;
memcpy(dbfn + clen, "/db", 4) ;
- if (verbosity >= 3) strerr_warni2x("writing ", dbfn) ;
+ if (verbosity >= 3) strerr_warni("writing ", dbfn) ;
fd = open_trunc(dbfn) ;
- if (fd < 0)
+ if (fd == -1)
{
cleanup(compiled) ;
- strerr_diefu3sys(111, "open ", dbfn, " for writing") ;
+ strerr_diefusys(111, "open ", dbfn, " for writing") ;
}
- if (ndelay_off(fd) < 0)
+ if (ndelay_off(fd) == -1)
{
cleanup(compiled) ;
- strerr_diefu2sys(111, "ndelay_off ", dbfn) ;
+ strerr_diefusys(111, "ndelay_off ", dbfn) ;
}
buffer_init(&b, &buffer_write, fd, buf, 4096) ;
- if (buffer_put(&b, S6RC_DB_BANNER_START, S6RC_DB_BANNER_START_LEN) < 0)
+ if (buffer_put(&b, S6RC_DB_BANNER_START, S6RC_DB_BANNER_START_LEN) < S6RC_DB_BANNER_START_LEN)
goto err ;
- if (buffer_put(&b, db->string, db->stringlen) < 0) goto err ;
+ if (buffer_put(&b, db->string, db->stringlen) < db->stringlen) goto err ;
{
unsigned int i = db->ndeps << 1 ;
@@ -1540,14 +1562,15 @@ static inline void write_db (char const *compiled, s6rc_db_t const *db)
while (i--) if (!write_service(&b, sv++, 0)) goto err ;
}
- if (buffer_putflush(&b, S6RC_DB_BANNER_END, S6RC_DB_BANNER_END_LEN) < 0)
+ if (buffer_putflush(&b, S6RC_DB_BANNER_END, S6RC_DB_BANNER_END_LEN) < S6RC_DB_BANNER_END_LEN)
goto err ;
close(fd) ;
return ;
+
err:
cleanup(compiled) ;
- strerr_diefu2sys(111, "write to ", dbfn) ;
+ strerr_diefusys(111, "write to ", dbfn) ;
}
static inline void write_compiled (
@@ -1560,7 +1583,7 @@ static inline void write_compiled (
char const *fdhuser,
int blocking)
{
- if (verbosity >= 2) strerr_warni2x("writing compiled information to ", compiled) ;
+ if (verbosity >= 2) strerr_warni("writing compiled information to ", compiled) ;
init_compiled(compiled) ;
write_sizes(compiled, db) ;
write_resolve(compiled, db, bundles, nbundles, bdeps) ;
@@ -1595,7 +1618,7 @@ int main (int argc, char const *const *argv)
if (wgola[GOLA_VERBOSITY])
{
if (!uint0_scan(wgola[GOLA_VERBOSITY], &verbosity))
- strerr_dief1x(100, "verbosity must be an unsigned integer") ;
+ strerr_dief(100, "verbosity must be an unsigned integer") ;
}
compiled = *argv++ ;
diff --git a/src/s6-rc/s6-rc-format-upgrade.c b/src/s6-rc/s6-rc-format-upgrade.c
index e7e29b5..eeb3c18 100644
--- a/src/s6-rc/s6-rc-format-upgrade.c
+++ b/src/s6-rc/s6-rc-format-upgrade.c
@@ -1,10 +1,12 @@
/* ISC license. */
#include
+#include
#include
+#include
#include
-#include
+#include
#include
#include
@@ -14,6 +16,19 @@
#define USAGE "s6-rc-format-upgrade [ -v verbosity ] [ -t timeout ] [ -l live ] [ -b ] newdb"
#define dieusage() strerr_dieusage(100, USAGE)
+enum golb_e
+{
+ GOLB_BLOCK = 0x01,
+} ;
+
+enum gola_e
+{
+ GOLA_VERBOSITY,
+ GOLA_LIVEDIR,
+ GOLA_TIMEOUT,
+ GOLA_N
+} ;
+
static unsigned int verbosity = 1 ;
@@ -26,47 +41,53 @@ static inline void update_livedir (char const *live, char const *newcompiled, ta
memcpy(cfn, live, livelen) ;
memcpy(cfn + livelen, "/compiled", 10) ;
if (!atomic_symlink4(newcompiled, cfn, 0, 0))
- strerr_diefu4sys(111, "atomic_symlink4 ", cfn, " to ", newcompiled) ;
+ strerr_diefusys(111, "atomic_symlink4 ", cfn, " to ", newcompiled) ;
}
-
int main (int argc, char const *const *argv, char const *const *envp)
{
- tain deadline ;
- char const *live = S6RC_LIVEDIR ;
- int blocking = 0 ;
+ static gol_bool const rgolb[] =
+ {
+ { .so = 'b', .lo = "block", .clear = 0, .set = GOLB_BLOCK },
+ } ;
+ static gol_arg const rgola[] =
+ {
+ { .so = 'v', .lo = "verbosity", .i = GOLA_VERBOSITY },
+ { .so = 'l', .lo = "livedir", .i = GOLA_LIVEDIR },
+ { .so = 't', .lo = "timeout", .i = GOLA_TIMEOUT },
+ } ;
+ uint64_t wgolb = 0 ;
+ char const *wgola[GOLA_N] = { 0 } ;
+ tain deadline = TAIN_INFINITE_RELATIVE ;
int livelock ;
+ wgola[GOLA_LIVEDIR] = S6RC_LIVEDIR ;
PROG = "s6-rc-format-upgrade" ;
+
+ {
+ unsigned int golc = GOL_main(argc, argv, rgolb, rgola, &wgolb, wgola) ;
+ argc -= golc ; argv += golc ;
+ }
+
+ if (wgola[GOLA_VERBOSITY] && !uint0_scan(wgola[GOLA_VERBOSITY], &verbosity))
+ strerr_dief(100, "verbosity", " must be an unsigned integer") ;
+ if (wgola[GOLA_TIMEOUT])
{
- unsigned int t = 0 ;
- subgetopt l = SUBGETOPT_ZERO ;
- for (;;)
- {
- int opt = subgetopt_r(argc, argv, "v:t:l:b", &l) ;
- if (opt == -1) break ;
- switch (opt)
- {
- case 'v' : if (!uint0_scan(l.arg, &verbosity)) dieusage() ; break ;
- case 't' : if (!uint0_scan(l.arg, &t)) dieusage() ; break ;
- case 'l' : live = l.arg ; break ;
- case 'b' : blocking = 1 ; break ;
- default : dieusage() ;
- }
- }
- argc -= l.ind ; argv += l.ind ;
+ unsigned int t ;
+ if (!uint0_scan(wgola[GOLA_TIMEOUT], &t))
+ strerr_dief(100, "timeout", " must be an unsigned integer") ;
if (t) tain_from_millisecs(&deadline, t) ;
- else deadline = tain_infinite_relative ;
}
+
if (!argc) dieusage() ;
if (argv[0][0] != '/')
- strerr_dief2x(100, argv[0], " is not an absolute path") ;
+ strerr_dief(100, argv[0], " is not an absolute path") ;
tain_now_set_stopwatch_g() ;
tain_add_g(&deadline, &deadline) ;
- if (!s6rc_lock(live, 2, &livelock, 0, 0, 0, blocking))
- strerr_diefu2sys(111, "take lock on ", live) ;
+ if (!s6rc_lock(wgola[GOLA_LIVEDIR], 2, &livelock, 0, 0, 0, wgolb & GOLB_BLOCK))
+ strerr_diefusys(111, "take lock on ", wgola[GOLA_LIVEDIR]) ;
- update_livedir(live, argv[0], &deadline) ;
- return 0 ;
+ update_livedir(wgola[GOLA_LIVEDIR], argv[0], &deadline) ;
+ _exit(0) ;
}
diff --git a/src/s6-rc/s6-rc-init.c b/src/s6-rc/s6-rc-init.c
index b1a9624..7d41584 100644
--- a/src/s6-rc/s6-rc-init.c
+++ b/src/s6-rc/s6-rc-init.c
@@ -178,6 +178,7 @@ int main (int argc, char const *const *argv)
if (!argc) dieusage() ;
if (argv[0][0] != '/') strerr_dief(100, "scandir", " must be an absolute path") ;
+ if (wgola[GOLA_LIVEDIR][0] != '/') strerr_dief(100, "livedir", " must be an absolute path") ;
if (wgola[GOLA_TIMEOUT])
{
unsigned int t = 0 ;
@@ -212,7 +213,7 @@ int main (int argc, char const *const *argv)
{
size_t llen = strlen(wgola[GOLA_LIVEDIR]) ;
char *d = strrchr(wgola[GOLA_LIVEDIR], '/') ;
- if (!d || d == wgola[GOLA_LIVEDIR]) strerr_dief(102, "invalid existing livedir: ", wgola[GOLA_LIVEDIR]) ;
+ if (d == wgola[GOLA_LIVEDIR]) strerr_dief(102, "invalid existing livedir: ", wgola[GOLA_LIVEDIR]) ;
dirlen = d - wgola[GOLA_LIVEDIR] ;
if (find_livedir(wgola[GOLA_LIVEDIR], llen, dirlen, argv[0], wgola[GOLA_PREFIX], wgola[GOLA_BOOTDB], &sa))
{
diff --git a/src/s6-rc/s6-rc-oneshot-run.c b/src/s6-rc/s6-rc-oneshot-run.c
index dc7bf06..baa0609 100644
--- a/src/s6-rc/s6-rc-oneshot-run.c
+++ b/src/s6-rc/s6-rc-oneshot-run.c
@@ -14,14 +14,12 @@
#include
#include
-#define USAGE "s6-rc-oneshot-run [ -l live ] [ -b ] up|down servicenumber"
+#define USAGE "s6-rc-oneshot-run [ -l live ] [ -b ] up|down|reload servicenumber"
#define dieusage() strerr_dieusage(100, USAGE)
enum golb_e
{
- GOLB_UP = 0x01,
- GOLB_BLOCK = 0x02,
- GOLB_RELOAD = 0x04,
+ GOLB_BLOCK = 0x01,
} ;
enum gola_e
@@ -41,19 +39,19 @@ int main (int argc, char const *const *argv)
{
{ .so = 'l', .lo = "livedir", .i = GOLA_LIVEDIR },
} ;
+ static char const *const whatstr[3] = { "down", "up", "reload" } ;
uint64_t wgolb = 0 ;
char const *wgola[GOLA_N] = { [GOLA_LIVEDIR] = S6RC_LIVEDIR } ;
unsigned int number ;
+ unsigned int what = 0 ;
PROG = "s6-rc-oneshot-run" ;
number = GOL_main(argc, argv, rgolb, rgola, &wgolb, wgola) ;
argc -= number ; argv += number ;
if (argc < 2) dieusage() ;
- if (!strcasecmp(argv[0], "up")) wgolb |= GOLB_UP ;
- else if (!strcasecmp(argv[0], "down")) wgolb &= ~GOLB_UP ;
- else if (!strcasecmp(argv[0], "reload")) wgolb |= GOLB_UP | GOLB_RELOAD ;
- else dieusage() ;
+ for (; what < 3 ; what++) if (!strcmp(argv[0], whatstr[what])) break ;
+ if (what >= 3) dieusage() ;
if (!uint0_scan(argv[1], &number)) dieusage() ;
{
@@ -105,23 +103,15 @@ int main (int argc, char const *const *argv)
close(fdcompiled) ;
close(compiledlock) ;
+
/* Run the script */
- {
- s6rc_service_t const *sv = db.services + number ;
- unsigned int namelen = strlen(db.string + sv->name) ;
- unsigned int sargc = sv->x.oneshot.argc[!!(wgolb & GOLB_UP)] ;
- char const *const *sargv = db.argvs + sv->x.oneshot.argv[!!(wgolb & GOLB_UP)] ;
- char const *newargv[sargc + 1] ;
- char const **p = newargv ;
- char modif[namelen + 21] ;
- memcpy(modif, "RC_NAME=", 8) ;
- memcpy(modif + 8, db.string + sv->name, namelen + 1) ;
- if (wgolb & GOLB_RELOAD) memcpy(modif + 9 + namelen, "RC_RELOAD=1", 12) ;
- while (sargc--) *p++ = *sargv++ ;
- *p = 0 ;
- xmexec0_n(newargv, modif, namelen + (wgolb & GOLB_RELOAD ? 21 : 9), 1 + !!(wgolb & GOLB_RELOAD)) ;
- }
+ s6rc_service_t const *sv = db.services + number ;
+ size_t namelen = strlen(db.string + sv->name) ;
+ char modif[namelen + 9] ;
+ memcpy(modif, "RC_NAME=", 8) ;
+ memcpy(modif + 8, db.string + sv->name, namelen + 1) ;
+ xmexec0_n(db.argvs + sv->x.oneshot.argv[what], modif, namelen + 9, 1) ;
}
}
}
diff --git a/src/s6-rc/s6-rc.c b/src/s6-rc/s6-rc.c
index b74b902..38f4a13 100644
--- a/src/s6-rc/s6-rc.c
+++ b/src/s6-rc/s6-rc.c
@@ -80,6 +80,20 @@ static tain deadline = TAIN_INFINITE_RELATIVE ;
static int lameduck = 0 ;
static char dryrun[UINT_FMT] = "" ;
+ /*
+ state bits:
+ - exported to state file
+ 0x01 - up or down
+ 0x02 - explicitly wanted up
+ 0x04 - unused
+ 0x08 - unused
+ - not exported, reserved for s6-rc internal work
+ 0x10 - in the selection
+ 0x20 - mark for recursive stuff
+ 0x40 - unused
+ 0x80 - unused
+ */
+
static inline void announce (void)
{
unsigned int i = n ;
@@ -88,9 +102,9 @@ static inline void announce (void)
if (dryrun[0]) return ;
memcpy(fn, live, livelen) ;
memcpy(fn + livelen, "/state", 7) ;
- while (i--) tmpstate[i] = !!(state[i] & 1) ;
+ while (i--) tmpstate[i] = state[i] & 0x0f ;
if (!openwritenclose_suffix(fn, tmpstate, n, ".new"))
- strerr_diefu2sys(111, "write ", fn) ;
+ strerr_diefusys(111, "write ", fn) ;
}
static inline int print_services (void)
@@ -98,7 +112,7 @@ static inline int print_services (void)
for (unsigned int i = 0 ; i < n ; i++)
{
if (wgolb & GOLB_HIDEESSENTIALS && db->services[i].flags & S6RC_DB_FLAG_ESSENTIAL) continue ;
- if (state[i] & 2)
+ if (state[i] & 0x10)
{
if (buffer_puts(buffer_1, db->string + db->services[i].name) < 0
|| buffer_put(buffer_1, "\n", 1) < 0) goto err ;
@@ -108,7 +122,7 @@ static inline int print_services (void)
return 0 ;
err:
- strerr_diefu1sys(111, "write to stdout") ;
+ strerr_diefusys(111, "write to stdout") ;
}
static inline int print_diff (void)
@@ -124,7 +138,7 @@ static inline int print_diff (void)
memcpy(fn + livelen, "/servicedirs/", 13) ;
memcpy(fn + livelen + 13, db->string + db->services[i].name, namelen + 1) ;
if (!s6_svstatus_read(fn, &status))
- strerr_diefu2sys(111, "read longrun status for ", fn) ;
+ strerr_diefusys(111, "read longrun status for ", fn) ;
if ((state[i] & 1) != status.flagwantup)
{
e = 1 ;
@@ -137,12 +151,12 @@ static inline int print_diff (void)
return e ;
err:
- strerr_diefu1sys(111, "write to stdout") ;
+ strerr_diefusys(111, "write to stdout") ;
}
static uint32_t compute_timeout (unsigned int i, int h)
{
- uint32_t t = db->services[i].timeout[h] ;
+ uint32_t t = db->services[i].timeout[!!h] ;
int globalt ;
tain globaltto ;
tain_sub(&globaltto, &deadline, &STAMP) ;
@@ -153,6 +167,12 @@ static uint32_t compute_timeout (unsigned int i, int h)
return t ;
}
+static void invert_selection (void)
+{
+ unsigned int i = n ;
+ while (i--) state[i] ^= 0x10 ;
+}
+
static inline pid_t start_oneshot (unsigned int i, int h)
{
unsigned int m = 0 ;
@@ -183,7 +203,7 @@ static inline pid_t start_oneshot (unsigned int i, int h)
newargv[m++] = tfmt ;
newargv[m++] = "--" ;
newargv[m++] = socketfn ;
- newargv[m++] = h == 3 ? "reload" : h ? "up" : "down" ;
+ newargv[m++] = h == 2 ? "reload" : h ? "up" : "down" ;
newargv[m++] = ifmt ;
if (dryrun[0])
{
@@ -205,14 +225,14 @@ static inline pid_t start_longrun (unsigned int i, int h)
memcpy(servicefn, live, livelen) ;
memcpy(servicefn + livelen, "/servicedirs/", 13) ;
memcpy(servicefn + livelen + 13, db->string + db->services[i].name, svdlen) ;
- if (h)
+ if (h == 1)
{
memcpy(servicefn + livelen + 13 + svdlen, "/notification-fd", 17) ;
- if (access(servicefn, F_OK) < 0)
+ if (access(servicefn, F_OK) == -1)
{
- h = 2 ;
+ h = 5 ;
if (verbosity >= 2 && errno != ENOENT)
- strerr_warnwu2sys("access ", servicefn) ;
+ strerr_warnwusys("access ", servicefn) ;
}
}
servicefn[livelen + 13 + svdlen] = 0 ;
@@ -228,7 +248,7 @@ static inline pid_t start_longrun (unsigned int i, int h)
newargv[m++] = "--" ;
}
newargv[m++] = S6_EXTBINPREFIX "s6-svc" ;
- newargv[m++] = h == 3 ? "-l" : h ? h == 2 ? "-uwu" : "-uwU" : "-dwD" ;
+ newargv[m++] = h == 2 ? "-l" : h ? h & 4 ? "-uwu" : "-uwU" : "-dwD" ;
newargv[m++] = "-T" ;
newargv[m++] = fmt ;
newargv[m++] = "--" ;
@@ -250,7 +270,7 @@ static inline void success_longrun (unsigned int i, int h)
if (h)
{
if (unlink(fn) == -1 && verbosity)
- strerr_warnwu2sys("unlink ", fn) ;
+ strerr_warnwusys("unlink ", fn) ;
}
else
{
@@ -258,7 +278,7 @@ static inline void success_longrun (unsigned int i, int h)
if (fd == -1)
{
if (verbosity)
- strerr_warnwu2sys("touch ", fn) ;
+ strerr_warnwusys("touch ", fn) ;
}
else fd_close(fd) ;
}
@@ -276,7 +296,7 @@ static inline void failure_longrun (unsigned int i, int h)
memcpy(fn + livelen, "/servicedirs/", 13) ;
memcpy(fn + livelen + 13, db->string + db->services[i].name, svdlen + 1) ;
if (!cspawn(newargv[0], newargv, (char const *const *)environ, CSPAWN_FLAGS_SELFPIPE_FINISH, 0, 0))
- strerr_warnwu2sys("spawn ", newargv[0]) ;
+ strerr_warnwusys("spawn ", newargv[0]) ;
}
}
@@ -284,20 +304,20 @@ static void broadcast_success (unsigned int, int) ;
static void examine (unsigned int i, int h)
{
- if (state[i] & 2 && !pendingdeps[i] && !(state[i] & 4))
+ if (state[i] & 0x10 && !pendingdeps[i] && !(state[i] & 0x20))
{
char const *name = db->string + db->services[i].name ;
- state[i] |= 4 ;
- if ((state[i] & 1) == h)
+ state[i] |= 0x20 ;
+ if ((state[i] & 0x01) == h)
{
if (verbosity >= 3)
- strerr_warni4x("service ", name, ": already ", h ? "up" : "down") ;
+ strerr_warni("service ", name, ": already ", h ? "up" : "down") ;
broadcast_success(i, h) ;
}
else if (!h && !(wgolb & GOLB_HIDEESSENTIALS) && db->services[i].flags & S6RC_DB_FLAG_ESSENTIAL)
{
if (verbosity)
- strerr_warnw3x("service ", name, " is marked as essential, not stopping it") ;
+ strerr_warnw("service ", name, " is marked as essential, not stopping it") ;
}
else
{
@@ -307,15 +327,15 @@ static void examine (unsigned int i, int h)
pidindex[npids++].i = i ;
if (verbosity >= 2)
{
- strerr_warni5x(dryrun[0] ? "dry run: " : "", "service ", name, ": ", h ? "starting" : "stopping") ;
+ strerr_warni(dryrun[0] ? "dry run: " : "", "service ", name, ": ", h ? "starting" : "stopping") ;
}
}
else
{
if (verbosity)
- strerr_warnwu2sys("spawn subprocess for ", name) ;
+ strerr_warnwusys("spawn subprocess for ", name) ;
if (verbosity >= 2)
- strerr_warni4x("service ", name, ": failed to ", h ? "start" : "stop") ;
+ strerr_warni("service ", name, ": failed to ", h ? "start" : "stop") ;
}
}
}
@@ -334,29 +354,28 @@ static void broadcast_success (unsigned int i, int h)
static inline void on_success (unsigned int i, int h)
{
- if (h != 3)
+ if (h < 2)
{
if (i < db->nlong) success_longrun(i, h) ;
if (h) state[i] |= 1 ; else state[i] &= 254 ;
announce() ;
+ if (!lameduck) broadcast_success(i, h) ;
}
if (verbosity >= 2)
- strerr_warni5x(dryrun[0] ? "dry run: " : "", "service ", db->string + db->services[i].name, " successfully ", h == 3 ? "reloaded" : h ? "started" : "stopped") ;
- if (!lameduck && h != 3) broadcast_success(i, h) ;
+ strerr_warni(dryrun[0] ? "dry run: " : "", "service ", db->string + db->services[i].name, " successfully ", h == 2 ? "reloaded" : h ? "started" : "stopped") ;
}
static inline void on_failure (unsigned int i, int h, int crashed, unsigned int code)
{
- if (h != 3 && i < db->nlong) failure_longrun(i, h) ;
+ if (h < 2 && i < db->nlong) failure_longrun(i, h) ;
if (verbosity)
{
char fmt[UINT_FMT] ;
fmt[uint_fmt(fmt, code)] = 0 ;
- strerr_warnwu7x(dryrun[0] ? "(dry run) " : "", h == 3 ? "reload" : h ? "start" : "stop", " service ", db->string + db->services[i].name, ": command ", crashed ? "crashed with signal " : "exited ", fmt) ;
+ strerr_warnwu(dryrun[0] ? "(dry run) " : "", h == 2 ? "reload" : h ? "start" : "stop", " service ", db->string + db->services[i].name, ": command ", crashed ? "crashed with signal " : "exited ", fmt) ;
}
}
-/*
static inline void kill_oneshots (void)
{
char fn[livelen + S6RC_ONESHOT_RUNNER_LEN + 14] ;
@@ -367,7 +386,6 @@ static inline void kill_oneshots (void)
if (!cspawn(newargv[0], newargv, (char const *const *)environ, CSPAWN_FLAGS_SELFPIPE_FINISH, 0, 0))
strerr_warnwu2sys("spawn ", newargv[0]) ;
}
-*/
static inline void kill_longruns (void)
{
@@ -384,7 +402,7 @@ static inline int handle_signals (int h)
int sig = selfpipe_read() ;
switch (sig)
{
- case -1 : strerr_diefu1sys(111, "selfpipe_read()") ;
+ case -1 : strerr_diefusys(111, "selfpipe_read()") ;
case 0 : return ok ;
case SIGCHLD :
for (;;)
@@ -392,9 +410,9 @@ static inline int handle_signals (int h)
unsigned int j = 0 ;
int wstat ;
pid_t r = wait_nohang(&wstat) ;
- if (r < 0)
+ if (r == -1)
if (errno == ECHILD) break ;
- else strerr_diefu1sys(111, "wait for children") ;
+ else strerr_diefusys(111, "wait for children") ;
else if (!r) break ;
for (; j < npids ; j++) if (pidindex[j].pid == r) break ;
if (j < npids)
@@ -414,81 +432,70 @@ static inline int handle_signals (int h)
case SIGTERM :
case SIGINT :
if (verbosity >= 2)
- strerr_warnw3x("received ", sig_name(sig), ", aborting longrun transitions and exiting asap") ;
- /* kill_oneshots() ; */
+ strerr_warnw("received ", sig_name(sig), ", aborting pending processes and exiting asap") ;
+ if (h == 2) kill_oneshots() ;
kill_longruns() ;
lameduck = 1 ;
break ;
- default : strerr_dief1x(101, "inconsistent signal state") ;
+ default : strerr_dief(101, "inconsistent signal state") ;
}
}
}
-static int doit (int h)
+static inline int reload (void)
{
iopause_fd x = { .fd = selfpipe_fd(), .events = IOPAUSE_READ } ;
int exitcode = 0 ;
- unsigned int i = n ;
- pidindex_t pidindexblob[n] ;
- unsigned int pendingdepsblob[n] ;
- pidindex = pidindexblob ;
- pendingdeps = pendingdepsblob ;
-
- if (verbosity >= 3)
- strerr_warni2x("bringing selected services ", h ? "up" : "down") ;
-
- while (i--)
+ for (unsigned int i = 0 ; i < n ; i++) if (state[i] & 0x10) npids++ ;
+ if (!npids) return 0 ;
+ pidindex_t pidi[npids] ;
+ pidindex = pidi ;
+ npids = 0 ;
+ for (unsigned int i = 0 ; i < n ; i++) if (state[i] & 0x10)
{
- state[i] &= 251 ;
- pendingdeps[i] = db->services[i].ndeps[h] ;
+ pidi[npids].i = i ;
+ pidi[npids].pid = i < db->nlong ? start_longrun(i, 2) : start_oneshot(i, 2) ;
+ if (!pidi[npids].pid) strerr_diefusys(111, "send reload command to service ", db->string + db->services[i].name) ;
+ npids++ ;
}
- i = n ;
- while (i--) examine(i, h) ;
while (npids)
{
int r = iopause_g(&x, 1, &deadline) ;
- if (r < 0) strerr_diefu1sys(111, "iopause") ;
- if (!r) strerr_dief1x(2, "timed out") ;
- if (!handle_signals(h)) exitcode = 1 ;
+ if (r == -1) strerr_diefusys(111, "iopause") ;
+ if (!r) strerr_dief(2, "timed out") ;
+ if (!handle_signals(2)) exitcode = 1 ;
}
return exitcode ;
}
-static void invert_selection (void)
-{
- unsigned int i = n ;
- while (i--) state[i] ^= 2 ;
-}
-
-static int reload (void)
+static int change (int h)
{
iopause_fd x = { .fd = selfpipe_fd(), .events = IOPAUSE_READ } ;
int exitcode = 0 ;
unsigned int i = n ;
pidindex_t pidindexblob[n] ;
+ unsigned int pendingdepsblob[n] ;
pidindex = pidindexblob ;
+ pendingdeps = pendingdepsblob ;
- while (i--) if (state[i] & 2)
+ if (verbosity >= 3)
+ strerr_warni("bringing selected services ", h ? "up" : "down") ;
+
+ while (i--)
{
- pid_t pid ;
- if (!(state[i] & 1))
- {
- if (verbosity) strerr_warnw("service ", db->string + db->services[i].name, " is down - not reloading") ;
- continue ;
- }
- pid = i < db->nlong ? start_longrun(i, 3) : start_oneshot(i, 3) ;
- if (!pid) strerr_diefusys(111, "send reload command to service ", db->string + db->services[i].name) ;
- pidindex[npids].pid = pid ;
- pidindex[npids++].i = i ;
+ state[i] &= ~0x20 ;
+ pendingdeps[i] = db->services[i].ndeps[h] ;
}
+ i = n ;
+ while (i--) examine(i, h) ;
while (npids)
{
int r = iopause_g(&x, 1, &deadline) ;
- if (r < 0) strerr_diefu1sys(111, "iopause") ;
+ if (r < 0) strerr_diefusys(111, "iopause") ;
if (!r) strerr_dief(2, "timed out") ;
- if (!handle_signals(3)) exitcode = 1 ;
+ if (!handle_signals(h)) exitcode = 1 ;
}
return exitcode ;
}
@@ -507,7 +514,7 @@ static inline enum what_e parse_command (char const *command)
{ .s = "stop", .e = WHAT_STOP },
} ;
struct what_s const *p = bsearch(command, command_table, sizeof(command_table)/sizeof(struct what_s), sizeof(struct what_s), &stringkey_bcmp) ;
- if (!p) strerr_dief2x(100, "unknown command: ", command) ;
+ if (!p) strerr_dief(100, "unknown command: ", command) ;
return p->e ;
}
@@ -520,7 +527,7 @@ static inline void print_help (void)
"s6-rc [ -l live ] diff\n"
"s6-rc [ -l live ] [ -a ] [ -u | -d | -D ] [ -p ] [ -v verbosity ] [ -t timeout ] [ -n dryrunthrottle ] change [ servicenames... ]\n" ;
if (buffer_putsflush(buffer_1, help) < 0)
- strerr_diefu1sys(111, "write to stdout") ;
+ strerr_diefusys(111, "write to stdout") ;
}
int main (int argc, char const *const *argv)
@@ -554,19 +561,19 @@ int main (int argc, char const *const *argv)
}
if (wgola[GOLA_VERBOSITY] && !uint0_scan(wgola[GOLA_VERBOSITY], &verbosity))
- strerr_dief1x(100, "verbosity must be an unsigned integer") ;
+ strerr_dief(100, "verbosity must be an unsigned integer") ;
if (wgola[GOLA_DRYRUN])
{
unsigned int d ;
if (!uint0_scan(wgola[GOLA_DRYRUN], &d))
- strerr_dief1x(100, "dry-run must be an unsigned integer") ;
+ strerr_dief(100, "dry-run must be an unsigned integer") ;
dryrun[uint_fmt(dryrun, d)] = 0 ;
}
if (wgola[GOLA_TIMEOUT])
{
unsigned int t ;
if (!uint0_scan(wgola[GOLA_TIMEOUT], &t))
- strerr_dief1x(100, "verbosity must be an unsigned integer") ;
+ strerr_dief(100, "verbosity must be an unsigned integer") ;
if (t) tain_from_millisecs(&deadline, t) ;
}
if (wgola[GOLA_LIVEDIR]) live = wgola[GOLA_LIVEDIR] ;
@@ -604,11 +611,11 @@ int main (int argc, char const *const *argv)
{
int livelock, compiledlock ;
if (!s6rc_lock(live, 1 + (what >= 4), &livelock, dbfn, 1, &compiledlock, !!(wgolb & GOLB_BLOCK)))
- strerr_diefu1sys(111, "take locks") ;
+ strerr_diefusys(111, "take locks") ;
if (coe(livelock) < 0)
- strerr_diefu3sys(111, "coe ", live, "/lock") ;
+ strerr_diefusys(111, "coe ", live, "/lock") ;
if (compiledlock >= 0 && coe(compiledlock) < 0)
- strerr_diefu4sys(111, "coe ", live, "/compiled", "/lock") ;
+ strerr_diefusys(111, "coe ", live, "/compiled", "/lock") ;
/* locks leak, but we don't care */
}
@@ -617,7 +624,7 @@ int main (int argc, char const *const *argv)
fdcompiled = open_readb(dbfn) ;
if (!s6rc_db_read_sizes(fdcompiled, &dbblob))
- strerr_diefu3sys(111, "read ", dbfn, "/n") ;
+ strerr_diefusys(111, "read ", dbfn, "/n") ;
n = dbblob.nshort + dbblob.nlong ;
@@ -639,16 +646,16 @@ int main (int argc, char const *const *argv)
state = stateblob ;
- /* Read live state in bit 0 of state */
+ /* Read live state */
memcpy(dbfn + livelen + 1, "state", 6) ;
{
ssize_t r = openreadnclose(dbfn, (char *)state, n) ;
- if (r == -1) strerr_diefu2sys(111, "read ", dbfn) ;
- if (r < n) strerr_diefu2x(4, "read valid state in ", dbfn) ;
+ if (r == -1) strerr_diefusys(111, "read ", dbfn) ;
+ if (r < n) strerr_diefu(4, "read valid state in ", dbfn) ;
{
unsigned int i = n ;
- while (i--) state[i] &= 1 ;
+ while (i--) state[i] &= 0x0f ;
}
}
dbfn[livelen] = 0 ;
@@ -658,7 +665,7 @@ int main (int argc, char const *const *argv)
{
int r = s6rc_db_read(fdcompiled, &dbblob) ;
if (r < 0) strerr_diefu3sys(111, "read ", dbfn, "/db") ;
- if (!r) strerr_dief3x(4, "invalid service database in ", dbfn, "/db") ;
+ if (!r) strerr_dief(4, "invalid service database in ", dbfn, "/db") ;
}
@@ -672,24 +679,28 @@ int main (int argc, char const *const *argv)
{
cdb c = CDB_ZERO ;
if (!cdb_init_at(&c, fdcompiled, "resolve.cdb"))
- strerr_diefu3sys(111, "cdb_init ", dbfn, "/resolve.cdb") ;
+ strerr_diefusys(111, "cdb_init ", dbfn, "/resolve.cdb") ;
for (; *argv ; argv++)
{
cdb_data data ;
int r = cdb_find(&c, &data, *argv, strlen(*argv)) ;
- if (r < 0) strerr_dief3x(4, "invalid cdb in ", dbfn, "/resolve.cdb") ;
- if (!r) strerr_dief4x(3, *argv, " is not a recognized identifier in ", dbfn, "/resolve.cdb") ;
+ if (r < 0) strerr_dief(4, "invalid cdb in ", dbfn, "/resolve.cdb") ;
+ if (!r) strerr_dief(3, *argv, " is not a recognized identifier in ", dbfn, "/resolve.cdb") ;
if (data.len & 3)
- strerr_dief3x(4, "invalid resolve database in ", dbfn, "/resolve.cdb") ;
+ strerr_dief(4, "invalid resolve database in ", dbfn, "/resolve.cdb") ;
if (data.len >> 2 > n)
- strerr_dief3x(4, "invalid resolve database in ", dbfn, "/resolve.cdb") ;
+ strerr_dief(4, "invalid resolve database in ", dbfn, "/resolve.cdb") ;
while (data.len)
{
uint32_t x ;
uint32_unpack_big(data.s, &x) ; data.s += 4 ; data.len -= 4 ;
if (x >= n)
- strerr_dief3x(4, "invalid resolve database in ", dbfn, "/resolve.cdb") ;
- state[x] |= 2 ;
+ strerr_dief(4, "invalid resolve database in ", dbfn, "/resolve.cdb") ;
+ state[x] |= 0x10 ;
+ if (what == WHAT_CHANGE)
+ {
+ if (wgolb & GOLB_DOWN) state[x] &= ~0x02 ; else state[x] |= 0x02 ;
+ }
}
}
cdb_free(&c) ;
@@ -697,21 +708,12 @@ int main (int argc, char const *const *argv)
close(fdcompiled) ;
- /* s6-rc reload */
-
- if (what == WHAT_RELOAD)
- {
- if (!argc) strerr_dief(100, "reload: too few arguments") ;
- _exit(reload()) ;
- }
-
-
/* Add live state to selection */
if (wgolb & GOLB_SELECTLIVE)
{
unsigned int i = n ;
- while (i--) if (state[i] & 1) state[i] |= 2 ;
+ while (i--) if (state[i] & 0x01) state[i] |= 0x10 ;
}
@@ -723,7 +725,7 @@ int main (int argc, char const *const *argv)
_exit(print_services()) ;
}
- s6rc_graph_closure(db, state, 1, !(wgolb & GOLB_DOWN)) ;
+ if (what != WHAT_RELOAD) s6rc_graph_closure(db, state, 4, !(wgolb & GOLB_DOWN)) ;
/* Print the selection after closure */
@@ -734,10 +736,10 @@ int main (int argc, char const *const *argv)
tain_add_g(&deadline, &deadline) ;
- /* Perform a state change */
+ /* Reload or state change: we need a selfpipe */
if (selfpipe_init() == -1)
- strerr_diefu1sys(111, "init selfpipe") ;
+ strerr_diefusys(111, "init selfpipe") ;
{
sigset_t set ;
@@ -746,19 +748,21 @@ int main (int argc, char const *const *argv)
sigaddset(&set, SIGTERM) ;
sigaddset(&set, SIGINT) ;
if (!selfpipe_trapset(&set))
- strerr_diefu1sys(111, "trap signals") ;
+ strerr_diefusys(111, "trap signals") ;
}
+ if (what == WHAT_RELOAD) _exit(reload()) ;
+
if (wgolb & GOLB_PRUNE)
{
int r ;
if (!(wgolb & GOLB_DOWN)) invert_selection() ;
- r = doit(0) ;
+ r = change(0) ;
if (r) return r ;
invert_selection() ;
- _exit(doit(1)) ;
+ _exit(change(1)) ;
}
- else _exit(doit(!(wgolb & GOLB_DOWN))) ;
+ else _exit(change(!(wgolb & GOLB_DOWN))) ;
}
}
}
--
cgit v1.3.1