aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2026-07-09 08:13:55 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2026-07-09 08:13:55 +0000
commit6209d961fd35c1d4e92d26c76a8ba0e98f1a6415 (patch)
treec81dd76930b52f5010e1a55a7906b0f3b28bb662
parent50f4e65aa2776e0916ad90130dcd28043154dfd5 (diff)
downloads6-rc-6209d961fd35c1d4e92d26c76a8ba0e98f1a6415.tar.gz
Add -c|--clean option to s6-rc (untested)
-rw-r--r--doc/s6-rc.html28
-rw-r--r--package/deps.mak12
-rw-r--r--src/include/s6-rc/s6rc-db.h1
-rw-r--r--src/include/s6-rc/s6rc-utils.h1
-rw-r--r--src/libs6rc/deps-lib/s6rc1
-rw-r--r--src/libs6rc/s6rc_graph_clean.c42
-rw-r--r--src/s6-rc/s6-rc.c44
7 files changed, 112 insertions, 17 deletions
diff --git a/doc/s6-rc.html b/doc/s6-rc.html
index afd6795..bf861eb 100644
--- a/doc/s6-rc.html
+++ b/doc/s6-rc.html
@@ -48,10 +48,10 @@ root privileges.
<pre>
s6-rc help
- s6-rc [ -l live ] [ -b ] [ -a ] [ -u | -d ] [ -E | -e ] list <em>servicenames...</em>
+ s6-rc [ -l live ] [ -b ] [ -a | -c ] [ -u | -d ] [ -E | -e ] list <em>servicenames...</em>
s6-rc [ -l live ] [ -b ] [ -a ] [ -u | -d ] [ -E | -e ] listall <em>servicenames...</em>
s6-rc [ -l live ] [ -b ] diff
- s6-rc [ -l live ] [ -b ] [ -a ] [ -u | -d | -D ] [ -p ] [ -v <em>verbosity</em> ] [ -n <em>dryrunthrottle</em> ] [ -t timeout ] change [ <em>servicenames...</em> ]
+ s6-rc [ -l live ] [ -b ] [ -a ] [ -c ] [ -u | -d | -D ] [ -p ] [ -v <em>verbosity</em> ] [ -n <em>dryrunthrottle</em> ] [ -t timeout ] change [ <em>servicenames...</em> ]
</pre>
<ul>
@@ -161,6 +161,14 @@ the meaning is reversed: the state will be brought to the maximum
possible set that does not include selected services. The change, however,
is always performed in the same manner: first the unwanted services are
all brought down, then the wanted services are all brought up. </li>
+ <li> <tt>-c</tt>&nbsp;: clean. After the machine state transition, if
+there are services that are <em>up</em> but not <em>explicit</em>, i.e.
+explicitly listed when s6-rc brought them up the last time, stop these services.
+This is only useful with <tt>s6-rc stop</tt> or <tt>s6-rc -d change</tt>.
+A service is marked as <em>explicit</em> if it appears in the arguments of
+an <tt>s6-rc start</tt> or <tt>s6-rc -u change</tt> command, or is part of
+a bundle given as an argument. A service that is not <em>explicit</em> is called
+<em>pulled</em>, because it has been pulled by dependencies. </li>
</ul>
<h2> Subcommands </h2>
@@ -191,6 +199,22 @@ essential (i.e. which have the <tt>flag-essential</tt> file in
their source definition directories) will not be printed.
</p>
+<p>
+ If the <tt>-c</tt> option has been given, the command changes
+a bit. Instead of printing the selection, it prints <em>all</em>
+the atomic services available in the database (except essential ones
+if the <tt>-e</tt> option has also been given), along with their
+state, one service per line; the fields are separated with slashes (<tt>/</tt>).
+The fields are:
+</p>
+
+<ul>
+ <li> <tt>longrun</tt> or <tt>oneshot</tt> </li>
+ <li> <tt>up</tt> or <tt>down</tt> </li>
+ <li> <tt>explicit</tt> or <tt>pulled</tt> (or nothing if the service is down) </li>
+ <li> <tt>essential</tt> or <tt>recommended</tt> or nothing </li>
+</ul>
+
<h3> s6-rc listall <em>servicenames...</em> </h3>
<ul>
diff --git a/package/deps.mak b/package/deps.mak
index c4e15c4..65cef4d 100644
--- a/package/deps.mak
+++ b/package/deps.mak
@@ -10,6 +10,7 @@ src/libs6rc/s6rc_db_check_revdeps.o src/libs6rc/s6rc_db_check_revdeps.lo: src/li
src/libs6rc/s6rc_db_read.o src/libs6rc/s6rc_db_read.lo: src/libs6rc/s6rc_db_read.c src/include/s6-rc/s6rc-db.h
src/libs6rc/s6rc_db_read_sizes.o src/libs6rc/s6rc_db_read_sizes.lo: src/libs6rc/s6rc_db_read_sizes.c src/include/s6-rc/s6rc-db.h
src/libs6rc/s6rc_db_read_uint32.o src/libs6rc/s6rc_db_read_uint32.lo: src/libs6rc/s6rc_db_read_uint32.c src/include/s6-rc/s6rc-db.h
+src/libs6rc/s6rc_graph_clean.o src/libs6rc/s6rc_graph_clean.lo: src/libs6rc/s6rc_graph_clean.c src/include/s6-rc/s6rc-db.h src/include/s6-rc/s6rc-utils.h
src/libs6rc/s6rc_graph_closure.o src/libs6rc/s6rc_graph_closure.lo: src/libs6rc/s6rc_graph_closure.c src/include/s6-rc/s6rc-db.h src/include/s6-rc/s6rc-utils.h
src/libs6rc/s6rc_live_state_read.o src/libs6rc/s6rc_live_state_read.lo: src/libs6rc/s6rc_live_state_read.c src/include/s6-rc/s6rc-db.h src/include/s6-rc/s6rc-utils.h
src/libs6rc/s6rc_live_state_size.o src/libs6rc/s6rc_live_state_size.lo: src/libs6rc/s6rc_live_state_size.c src/include/s6-rc/s6rc-db.h src/include/s6-rc/s6rc-utils.h
@@ -52,7 +53,7 @@ src/repo/s6rc_repo_listalldeps.o src/repo/s6rc_repo_listalldeps.lo: src/repo/s6r
src/repo/s6rc_repo_listcontents.o src/repo/s6rc_repo_listcontents.lo: src/repo/s6rc_repo_listcontents.c src/include/s6-rc/config.h src/include/s6-rc/repo.h
src/repo/s6rc_repo_listdeps.o src/repo/s6rc_repo_listdeps.lo: src/repo/s6rc_repo_listdeps.c src/include/s6-rc/repo.h
src/repo/s6rc_repo_listdeps_internal.o src/repo/s6rc_repo_listdeps_internal.lo: src/repo/s6rc_repo_listdeps_internal.c src/include/s6-rc/config.h src/include/s6-rc/repo.h
-src/repo/s6rc_repo_listsub.o src/repo/s6rc_repo_listsub.lo: src/repo/s6rc_repo_listsub.c src/include/s6-rc/repo.h
+src/repo/s6rc_repo_listrx.o src/repo/s6rc_repo_listrx.lo: src/repo/s6rc_repo_listrx.c src/include/s6-rc/repo.h
src/repo/s6rc_repo_lock.o src/repo/s6rc_repo_lock.lo: src/repo/s6rc_repo_lock.c src/include/s6-rc/repo.h
src/repo/s6rc_repo_ls.o src/repo/s6rc_repo_ls.lo: src/repo/s6rc_repo_ls.c src/include/s6-rc/repo.h
src/repo/s6rc_repo_makedefbundle.o src/repo/s6rc_repo_makedefbundle.lo: src/repo/s6rc_repo_makedefbundle.c src/include/s6-rc/repo.h
@@ -75,7 +76,6 @@ src/repo/s6rc_repo_syncset_tmp.o src/repo/s6rc_repo_syncset_tmp.lo: src/repo/s6r
src/repo/s6rc_repo_touch.o src/repo/s6rc_repo_touch.lo: src/repo/s6rc_repo_touch.c src/include/s6-rc/repo.h
src/repo/s6rc_repo_touchset.o src/repo/s6rc_repo_touchset.lo: src/repo/s6rc_repo_touchset.c src/include/s6-rc/repo.h
src/repo/s6rc_repo_type_check.o src/repo/s6rc_repo_type_check.lo: src/repo/s6rc_repo_type_check.c src/include/s6-rc/repo.h
-src/s6-rc/s6-rc-bundle.o src/s6-rc/s6-rc-bundle.lo: src/s6-rc/s6-rc-bundle.c src/include/s6-rc/config.h src/include/s6-rc/s6rc.h
src/s6-rc/s6-rc-compile.o src/s6-rc/s6-rc-compile.lo: src/s6-rc/s6-rc-compile.c src/include/s6-rc/config.h src/include/s6-rc/s6rc.h
src/s6-rc/s6-rc-db.o src/s6-rc/s6-rc-db.lo: src/s6-rc/s6-rc-db.c src/include/s6-rc/config.h src/include/s6-rc/s6rc.h
src/s6-rc/s6-rc-dryrun.o src/s6-rc/s6-rc-dryrun.lo: src/s6-rc/s6-rc-dryrun.c
@@ -87,15 +87,15 @@ src/s6-rc/s6-rc-update.o src/s6-rc/s6-rc-update.lo: src/s6-rc/s6-rc-update.c src
src/s6-rc/s6-rc.o src/s6-rc/s6-rc.lo: src/s6-rc/s6-rc.c src/include/s6-rc/config.h src/include/s6-rc/s6rc.h
ifeq ($(strip $(STATIC_LIBS_ARE_PIC)),)
-libs6rc.a.xyzzy: src/libs6rc/s6rc_db_check_depcycles.o src/libs6rc/s6rc_db_check_pipelines.o src/libs6rc/s6rc_db_check_revdeps.o src/libs6rc/s6rc_db_read.o src/libs6rc/s6rc_db_read_sizes.o src/libs6rc/s6rc_db_read_uint32.o src/libs6rc/s6rc_graph_closure.o src/libs6rc/s6rc_live_state_size.o src/libs6rc/s6rc_live_state_read.o src/libs6rc/s6rc_livedir_canon.o src/libs6rc/s6rc_livedir_create.o src/libs6rc/s6rc_livedir_prefix.o src/libs6rc/s6rc_livedir_prefixsize.o src/libs6rc/s6rc_lock.o src/libs6rc/s6rc_read_uint.o src/libs6rc/s6rc_sanitize_dir.o src/libs6rc/s6rc_servicedir_internal.o src/libs6rc/s6rc_servicedir_block.o src/libs6rc/s6rc_servicedir_unblock.o src/libs6rc/s6rc_servicedir_copy_offline.o src/libs6rc/s6rc_servicedir_copy_online.o src/libs6rc/s6rc_servicedir_manage.o src/libs6rc/s6rc_servicedir_unsupervise.o
+libs6rc.a.xyzzy: src/libs6rc/s6rc_db_check_depcycles.o src/libs6rc/s6rc_db_check_pipelines.o src/libs6rc/s6rc_db_check_revdeps.o src/libs6rc/s6rc_db_read.o src/libs6rc/s6rc_db_read_sizes.o src/libs6rc/s6rc_db_read_uint32.o src/libs6rc/s6rc_graph_closure.o src/libs6rc/s6rc_graph_clean.o src/libs6rc/s6rc_live_state_size.o src/libs6rc/s6rc_live_state_read.o src/libs6rc/s6rc_livedir_canon.o src/libs6rc/s6rc_livedir_create.o src/libs6rc/s6rc_livedir_prefix.o src/libs6rc/s6rc_livedir_prefixsize.o src/libs6rc/s6rc_lock.o src/libs6rc/s6rc_read_uint.o src/libs6rc/s6rc_sanitize_dir.o src/libs6rc/s6rc_servicedir_internal.o src/libs6rc/s6rc_servicedir_block.o src/libs6rc/s6rc_servicedir_unblock.o src/libs6rc/s6rc_servicedir_copy_offline.o src/libs6rc/s6rc_servicedir_copy_online.o src/libs6rc/s6rc_servicedir_manage.o src/libs6rc/s6rc_servicedir_unsupervise.o
else
-libs6rc.a.xyzzy:src/libs6rc/s6rc_db_check_depcycles.lo src/libs6rc/s6rc_db_check_pipelines.lo src/libs6rc/s6rc_db_check_revdeps.lo src/libs6rc/s6rc_db_read.lo src/libs6rc/s6rc_db_read_sizes.lo src/libs6rc/s6rc_db_read_uint32.lo src/libs6rc/s6rc_graph_closure.lo src/libs6rc/s6rc_live_state_size.lo src/libs6rc/s6rc_live_state_read.lo src/libs6rc/s6rc_livedir_canon.lo src/libs6rc/s6rc_livedir_create.lo src/libs6rc/s6rc_livedir_prefix.lo src/libs6rc/s6rc_livedir_prefixsize.lo src/libs6rc/s6rc_lock.lo src/libs6rc/s6rc_read_uint.lo src/libs6rc/s6rc_sanitize_dir.lo src/libs6rc/s6rc_servicedir_internal.lo src/libs6rc/s6rc_servicedir_block.lo src/libs6rc/s6rc_servicedir_unblock.lo src/libs6rc/s6rc_servicedir_copy_offline.lo src/libs6rc/s6rc_servicedir_copy_online.lo src/libs6rc/s6rc_servicedir_manage.lo src/libs6rc/s6rc_servicedir_unsupervise.lo
+libs6rc.a.xyzzy:src/libs6rc/s6rc_db_check_depcycles.lo src/libs6rc/s6rc_db_check_pipelines.lo src/libs6rc/s6rc_db_check_revdeps.lo src/libs6rc/s6rc_db_read.lo src/libs6rc/s6rc_db_read_sizes.lo src/libs6rc/s6rc_db_read_uint32.lo src/libs6rc/s6rc_graph_closure.lo src/libs6rc/s6rc_graph_clean.lo src/libs6rc/s6rc_live_state_size.lo src/libs6rc/s6rc_live_state_read.lo src/libs6rc/s6rc_livedir_canon.lo src/libs6rc/s6rc_livedir_create.lo src/libs6rc/s6rc_livedir_prefix.lo src/libs6rc/s6rc_livedir_prefixsize.lo src/libs6rc/s6rc_lock.lo src/libs6rc/s6rc_read_uint.lo src/libs6rc/s6rc_sanitize_dir.lo src/libs6rc/s6rc_servicedir_internal.lo src/libs6rc/s6rc_servicedir_block.lo src/libs6rc/s6rc_servicedir_unblock.lo src/libs6rc/s6rc_servicedir_copy_offline.lo src/libs6rc/s6rc_servicedir_copy_online.lo src/libs6rc/s6rc_servicedir_manage.lo src/libs6rc/s6rc_servicedir_unsupervise.lo
endif
libs6rc.pc: EXTRA_LIBS := -ls6 -lskarnet ${SPAWN_LIB}
libs6rc.so.xyzzy: EXTRA_LIBS := -ls6 -lskarnet ${SPAWN_LIB}
-libs6rc.so.xyzzy:src/libs6rc/s6rc_db_check_depcycles.lo src/libs6rc/s6rc_db_check_pipelines.lo src/libs6rc/s6rc_db_check_revdeps.lo src/libs6rc/s6rc_db_read.lo src/libs6rc/s6rc_db_read_sizes.lo src/libs6rc/s6rc_db_read_uint32.lo src/libs6rc/s6rc_graph_closure.lo src/libs6rc/s6rc_live_state_size.lo src/libs6rc/s6rc_live_state_read.lo src/libs6rc/s6rc_livedir_canon.lo src/libs6rc/s6rc_livedir_create.lo src/libs6rc/s6rc_livedir_prefix.lo src/libs6rc/s6rc_livedir_prefixsize.lo src/libs6rc/s6rc_lock.lo src/libs6rc/s6rc_read_uint.lo src/libs6rc/s6rc_sanitize_dir.lo src/libs6rc/s6rc_servicedir_internal.lo src/libs6rc/s6rc_servicedir_block.lo src/libs6rc/s6rc_servicedir_unblock.lo src/libs6rc/s6rc_servicedir_copy_offline.lo src/libs6rc/s6rc_servicedir_copy_online.lo src/libs6rc/s6rc_servicedir_manage.lo src/libs6rc/s6rc_servicedir_unsupervise.lo
+libs6rc.so.xyzzy:src/libs6rc/s6rc_db_check_depcycles.lo src/libs6rc/s6rc_db_check_pipelines.lo src/libs6rc/s6rc_db_check_revdeps.lo src/libs6rc/s6rc_db_read.lo src/libs6rc/s6rc_db_read_sizes.lo src/libs6rc/s6rc_db_read_uint32.lo src/libs6rc/s6rc_graph_closure.lo src/libs6rc/s6rc_graph_clean.lo src/libs6rc/s6rc_live_state_size.lo src/libs6rc/s6rc_live_state_read.lo src/libs6rc/s6rc_livedir_canon.lo src/libs6rc/s6rc_livedir_create.lo src/libs6rc/s6rc_livedir_prefix.lo src/libs6rc/s6rc_livedir_prefixsize.lo src/libs6rc/s6rc_lock.lo src/libs6rc/s6rc_read_uint.lo src/libs6rc/s6rc_sanitize_dir.lo src/libs6rc/s6rc_servicedir_internal.lo src/libs6rc/s6rc_servicedir_block.lo src/libs6rc/s6rc_servicedir_unblock.lo src/libs6rc/s6rc_servicedir_copy_offline.lo src/libs6rc/s6rc_servicedir_copy_online.lo src/libs6rc/s6rc_servicedir_manage.lo src/libs6rc/s6rc_servicedir_unsupervise.lo
libs6rc.dylib.xyzzy: EXTRA_LIBS := -ls6 -lskarnet ${SPAWN_LIB}
-libs6rc.dylib.xyzzy:src/libs6rc/s6rc_db_check_depcycles.lo src/libs6rc/s6rc_db_check_pipelines.lo src/libs6rc/s6rc_db_check_revdeps.lo src/libs6rc/s6rc_db_read.lo src/libs6rc/s6rc_db_read_sizes.lo src/libs6rc/s6rc_db_read_uint32.lo src/libs6rc/s6rc_graph_closure.lo src/libs6rc/s6rc_live_state_size.lo src/libs6rc/s6rc_live_state_read.lo src/libs6rc/s6rc_livedir_canon.lo src/libs6rc/s6rc_livedir_create.lo src/libs6rc/s6rc_livedir_prefix.lo src/libs6rc/s6rc_livedir_prefixsize.lo src/libs6rc/s6rc_lock.lo src/libs6rc/s6rc_read_uint.lo src/libs6rc/s6rc_sanitize_dir.lo src/libs6rc/s6rc_servicedir_internal.lo src/libs6rc/s6rc_servicedir_block.lo src/libs6rc/s6rc_servicedir_unblock.lo src/libs6rc/s6rc_servicedir_copy_offline.lo src/libs6rc/s6rc_servicedir_copy_online.lo src/libs6rc/s6rc_servicedir_manage.lo src/libs6rc/s6rc_servicedir_unsupervise.lo
+libs6rc.dylib.xyzzy:src/libs6rc/s6rc_db_check_depcycles.lo src/libs6rc/s6rc_db_check_pipelines.lo src/libs6rc/s6rc_db_check_revdeps.lo src/libs6rc/s6rc_db_read.lo src/libs6rc/s6rc_db_read_sizes.lo src/libs6rc/s6rc_db_read_uint32.lo src/libs6rc/s6rc_graph_closure.lo src/libs6rc/s6rc_graph_clean.lo src/libs6rc/s6rc_live_state_size.lo src/libs6rc/s6rc_live_state_read.lo src/libs6rc/s6rc_livedir_canon.lo src/libs6rc/s6rc_livedir_create.lo src/libs6rc/s6rc_livedir_prefix.lo src/libs6rc/s6rc_livedir_prefixsize.lo src/libs6rc/s6rc_lock.lo src/libs6rc/s6rc_read_uint.lo src/libs6rc/s6rc_sanitize_dir.lo src/libs6rc/s6rc_servicedir_internal.lo src/libs6rc/s6rc_servicedir_block.lo src/libs6rc/s6rc_servicedir_unblock.lo src/libs6rc/s6rc_servicedir_copy_offline.lo src/libs6rc/s6rc_servicedir_copy_online.lo src/libs6rc/s6rc_servicedir_manage.lo src/libs6rc/s6rc_servicedir_unsupervise.lo
ifeq ($(strip $(STATIC_LIBS_ARE_PIC)),)
libs6rcrepo.a.xyzzy: src/repo/s6rc_repo_badpipeline.o src/repo/s6rc_repo_badrx.o src/repo/s6rc_repo_checkset.o src/repo/s6rc_repo_cleanup.o src/repo/s6rc_repo_compile.o src/repo/s6rc_repo_fillset.o src/repo/s6rc_repo_fixset.o src/repo/s6rc_repo_flattenservices.o src/repo/s6rc_repo_getserviceflags.o src/repo/s6rc_repo_list_sets.o src/repo/s6rc_repo_listalldeps.o src/repo/s6rc_repo_listcontents.o src/repo/s6rc_repo_listdeps.o src/repo/s6rc_repo_listdeps_internal.o src/repo/s6rc_repo_listrx.o src/repo/s6rc_repo_lock.o src/repo/s6rc_repo_ls.o src/repo/s6rc_repo_makedefbundle.o src/repo/s6rc_repo_makesetbundles.o src/repo/s6rc_repo_makestores.o src/repo/s6rc_repo_makesvlist.o src/repo/s6rc_repo_makesvlist_byname.o src/repo/s6rc_repo_moveservices.o src/repo/s6rc_repo_removeinternals.o src/repo/s6rc_repo_rxnames.o src/repo/s6rc_repo_sanitize_setname.o src/repo/s6rc_repo_sanitize_svname.o src/repo/s6rc_repo_setcompile.o src/repo/s6rc_repo_setuptodate.o src/repo/s6rc_repo_sv_bcmpr.o src/repo/s6rc_repo_sv_cmpr.o src/repo/s6rc_repo_sync.o src/repo/s6rc_repo_syncset.o src/repo/s6rc_repo_syncset_tmp.o src/repo/s6rc_repo_touch.o src/repo/s6rc_repo_touchset.o src/repo/s6rc_repo_type_check.o
else
diff --git a/src/include/s6-rc/s6rc-db.h b/src/include/s6-rc/s6rc-db.h
index 9b156f8..49b6dae 100644
--- a/src/include/s6-rc/s6rc-db.h
+++ b/src/include/s6-rc/s6rc-db.h
@@ -13,6 +13,7 @@
#define S6RC_DB_BANNER_END_LEN (sizeof(S6RC_DB_BANNER_END) - 1)
#define S6RC_DB_FLAG_ESSENTIAL 0x00000001U
+#define S6RC_DB_FLAG_RECOMMENDED 0x00000002U
typedef struct s6rc_oneshot_s s6rc_oneshot_t, *s6rc_oneshot_t_ref ;
diff --git a/src/include/s6-rc/s6rc-utils.h b/src/include/s6-rc/s6rc-utils.h
index 84f035b..15a3b74 100644
--- a/src/include/s6-rc/s6rc-utils.h
+++ b/src/include/s6-rc/s6rc-utils.h
@@ -11,6 +11,7 @@
#include <s6-rc/s6rc-db.h>
extern void s6rc_graph_closure (s6rc_db_t const *, unsigned char *, unsigned int, int) ;
+extern void s6rc_graph_clean (s6rc_db_t const *, unsigned char *, unsigned int, unsigned int, unsigned int) ;
extern int s6rc_lock (char const *, int, int *, char const *, int, int *, int) ;
extern int s6rc_read_uint (char const *, unsigned int *) ;
extern int s6rc_sanitize_dir (stralloc *, char const *, size_t *) ;
diff --git a/src/libs6rc/deps-lib/s6rc b/src/libs6rc/deps-lib/s6rc
index 9f677f7..f1a8370 100644
--- a/src/libs6rc/deps-lib/s6rc
+++ b/src/libs6rc/deps-lib/s6rc
@@ -5,6 +5,7 @@ s6rc_db_read.o
s6rc_db_read_sizes.o
s6rc_db_read_uint32.o
s6rc_graph_closure.o
+s6rc_graph_clean.o
s6rc_live_state_size.o
s6rc_live_state_read.o
s6rc_livedir_canon.o
diff --git a/src/libs6rc/s6rc_graph_clean.c b/src/libs6rc/s6rc_graph_clean.c
new file mode 100644
index 0000000..d450d65
--- /dev/null
+++ b/src/libs6rc/s6rc_graph_clean.c
@@ -0,0 +1,42 @@
+/* ISC license. */
+
+#include <stdint.h>
+
+#include <skalibs/bitarray.h>
+
+#include <s6-rc/s6rc-db.h>
+#include <s6-rc/s6rc-utils.h>
+
+typedef struct recinfo_s recinfo_t, *recinfo_t_ref ;
+struct recinfo_s
+{
+ s6rc_db_t const *db ;
+ unsigned char *bits ;
+ unsigned char statemask ;
+ unsigned char volmask ;
+ unsigned char resmask ;
+} ;
+
+static void s6rc_graph_clean_rec (recinfo_t *info, uint32_t i)
+{
+ if (!(info->bits[i] & info->volmask))
+ {
+ uint32_t j = 0 ;
+ for (; j < info->db->services[i].ndeps[0] ; j++)
+ if (info->bits[j] & info->statemask && !(info->bits[j] & info->resmask)) break ;
+ if (j >= info->db->services[i].ndeps[0])
+ {
+ info->bits[i] |= info->resmask ;
+ for (j = 0 ; j < info->db->services[i].ndeps[1] ; j++)
+ s6rc_graph_clean_rec(info, info->db->deps[info->db->ndeps + info->db->services[i].deps[1] + j]) ;
+ }
+ }
+}
+
+void s6rc_graph_clean (s6rc_db_t const *db, unsigned char *bits, unsigned int statebit, unsigned int volbit, unsigned int resbit)
+{
+ uint32_t n = db->nshort + db->nlong ;
+ recinfo_t info = { .db = db, .bits = bits, .statemask = 1 << statebit, .volmask = 1 << volbit, .resmask = 1 << resbit } ;
+ for (uint32_t i = 0 ; i < n ; i++) bits[i] &= ~info.resmask ;
+ for (uint32_t i = 0 ; i < n ; i++) if (bits[i] & info.statemask) s6rc_graph_clean_rec(&info, i) ;
+}
diff --git a/src/s6-rc/s6-rc.c b/src/s6-rc/s6-rc.c
index 7185935..f11544d 100644
--- a/src/s6-rc/s6-rc.c
+++ b/src/s6-rc/s6-rc.c
@@ -19,7 +19,7 @@
#include <s6-rc/config.h>
#include <s6-rc/s6rc.h>
-#define USAGE "s6-rc [ -v verbosity ] [ -n dryrunthrottle ] [ -t timeout ] [ -l live ] [ -b ] [ -E | -e ] [ -u | -d | -D ] [ -p ] [ -a ] help|list|listall|diff|start|stop|change [ servicenames... ]"
+#define USAGE "s6-rc [ -v verbosity ] [ -n dryrunthrottle ] [ -t timeout ] [ -l live ] [ -b ] [ -E | -e ] [ -u | -d | -D ] [ -p ] [ -a ] [ -c ] help|list|listall|diff|start|stop|change [ servicenames... ]"
#define dieusage() strerr_dieusage(100, USAGE)
typedef struct pidindex_s pidindex_t ;
@@ -54,6 +54,7 @@ enum golb_e
GOLB_PRUNE = 0x04,
GOLB_SELECTLIVE = 0x08,
GOLB_BLOCK = 0x10,
+ GOLB_CLEAN = 0x20,
GOLB_NOLOCK = 0x80
} ;
@@ -112,10 +113,17 @@ 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] & 0x10)
+ if (wgolb & GOLB_CLEAN || state[i] & 0x10)
{
- if (buffer_puts(buffer_1, db->string + db->services[i].name) < 0
- || buffer_put(buffer_1, "\n", 1) < 0) goto err ;
+ if (buffer_puts(buffer_1, db->string + db->services[i].name) < 0) goto err ;
+ if (wgolb & GOLB_CLEAN)
+ {
+ if (buffer_puts(buffer_1, i < db->nlong ? "/longrun" : "/oneshot") < 0
+ || buffer_puts(buffer_1, state[i] & 0x01 ? state[i] & 0x02 ? "/up/explicit" : "/up/pulled" : "/down/ ") < 0
+ || buffer_puts(buffer_1, db->services[i].flags & S6RC_DB_FLAG_ESSENTIAL ? "/essential" : db->services[i].flags & S6RC_DB_FLAG_RECOMMENDED ? "/recommended" : "/ ") < 0)
+ goto err ;
+ }
+ if (buffer_put(buffer_1, "\n", 1) < 0) goto err ;
}
}
if (!buffer_flush(buffer_1)) goto err ;
@@ -522,10 +530,10 @@ static inline void print_help (void)
{
static char const *help =
"s6-rc help\n"
-"s6-rc [ -l live ] [ -a ] list [ servicenames... ]\n"
+"s6-rc [ -l live ] [ -a ] [ -c ] list [ servicenames... ]\n"
"s6-rc [ -l live ] [ -a ] [ -u | -d ] listall [ servicenames... ]\n"
"s6-rc [ -l live ] diff\n"
-"s6-rc [ -l live ] [ -a ] [ -u | -d | -D ] [ -p ] [ -v verbosity ] [ -t timeout ] [ -n dryrunthrottle ] change [ servicenames... ]\n" ;
+"s6-rc [ -l live ] [ -a ] [ -c ] [ -u | -d | -D ] [ -p ] [ -v verbosity ] [ -t timeout ] [ -n dryrunthrottle ] change [ servicenames... ]\n" ;
if (buffer_putsflush(buffer_1, help) < 0)
strerr_diefusys(111, "write to stdout") ;
}
@@ -542,6 +550,7 @@ int main (int argc, char const *const *argv)
{ .so = 'b', .lo = "block", .clear = 0, .set = GOLB_BLOCK },
{ .so = 'E', .lo = "with-essentials", .clear = GOLB_HIDEESSENTIALS, .set = 0 },
{ .so = 'e', .lo = "without-essentials", .clear = 0, .set = GOLB_HIDEESSENTIALS },
+ { .so = 'c', .lo = "clean", .clear = 0, .set = GOLB_CLEAN },
{ .so = 0, .lo = "no-lock", .clear = 0, .set = GOLB_NOLOCK },
} ;
static gol_arg const rgola[] =
@@ -587,7 +596,7 @@ int main (int argc, char const *const *argv)
}
if (what == WHAT_START)
{
- what = WHAT_CHANGE ; wgolb &= ~(GOLB_DOWN | GOLB_PRUNE) ;
+ what = WHAT_CHANGE ; wgolb &= ~(GOLB_DOWN | GOLB_PRUNE | GOLB_CLEAN) ;
}
else if (what == WHAT_STOP)
{
@@ -721,6 +730,7 @@ int main (int argc, char const *const *argv)
if (what == WHAT_LIST)
{
+ if (wgolb & GOLB_CLEAN) s6rc_graph_clean(db, state, 0, 1, 4) ;
if (wgolb & GOLB_DOWN) invert_selection() ;
_exit(print_services()) ;
}
@@ -760,9 +770,25 @@ int main (int argc, char const *const *argv)
r = change(0) ;
if (r) _exit(r) ;
invert_selection() ;
- _exit(change(1)) ;
+ r = change(1) ;
+ if (r) _exit(r) ;
+ }
+ else
+ {
+ int r = change(!(wgolb & GOLB_DOWN)) ;
+ if (r) _exit(r) ;
+ }
+
+ if (wgolb & GOLB_CLEAN)
+ {
+ int r ;
+ if (verbosity >= 2)
+ strerr_warni("stopping non-explicitly started services") ;
+ s6rc_graph_clean(db, state, 0, 1, 4) ;
+ r = change(0) ;
+ if (r) _exit(r) ;
}
- else _exit(change(!(wgolb & GOLB_DOWN))) ;
}
}
+ _exit(0) ;
}