diff options
| author | Laurent Bercot <ska-skaware@skarnet.org> | 2026-07-09 08:13:55 +0000 |
|---|---|---|
| committer | Laurent Bercot <ska-skaware@skarnet.org> | 2026-07-09 08:13:55 +0000 |
| commit | 6209d961fd35c1d4e92d26c76a8ba0e98f1a6415 (patch) | |
| tree | c81dd76930b52f5010e1a55a7906b0f3b28bb662 /src | |
| parent | 50f4e65aa2776e0916ad90130dcd28043154dfd5 (diff) | |
| download | s6-rc-6209d961fd35c1d4e92d26c76a8ba0e98f1a6415.tar.gz | |
Add -c|--clean option to s6-rc (untested)
Diffstat (limited to 'src')
| -rw-r--r-- | src/include/s6-rc/s6rc-db.h | 1 | ||||
| -rw-r--r-- | src/include/s6-rc/s6rc-utils.h | 1 | ||||
| -rw-r--r-- | src/libs6rc/deps-lib/s6rc | 1 | ||||
| -rw-r--r-- | src/libs6rc/s6rc_graph_clean.c | 42 | ||||
| -rw-r--r-- | src/s6-rc/s6-rc.c | 44 |
5 files changed, 80 insertions, 9 deletions
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) ; } |
