From b175b4a2ae403b5183234d87466cb9bf01f0ea26 Mon Sep 17 00:00:00 2001 From: Joachim Wiberg Date: Sat, 13 Feb 2021 11:23:49 +0100 Subject: [PATCH] initctl: add PID and IDENT to 'cond dump' command Instead of just walking /run/finit/cond, also show the source of each condition. The hook and net conditions are hard-coded to init[1] atm. and unknown conditions are shown as unknown[0]. Signed-off-by: Joachim Wiberg --- src/api.c | 30 ++++++++++++++++++++++++++++++ src/client.c | 18 ++++++++++++++---- src/client.h | 11 ++++++----- src/finit.h | 1 + src/initctl.c | 34 ++++++++++++++++++++++++++++------ 5 files changed, 79 insertions(+), 15 deletions(-) diff --git a/src/api.c b/src/api.c index a647e3be..f3bc15c7 100644 --- a/src/api.c +++ b/src/api.c @@ -158,6 +158,30 @@ static svc_t *do_find(char *buf, size_t len) return svc_find_by_nameid(input, id); } +static svc_t *do_find_byc(char *buf, size_t len) +{ + svc_t *svc, *iter = NULL; + char *input; + + input = sanitize(buf, len); + if (!input) { + _d("Invalid input"); + return NULL; + } + + for (svc = svc_iterator(&iter, 1); svc; svc = svc_iterator(&iter, 0)) { + char cond[MAX_COND_LEN]; + + mkcond(svc, cond, sizeof(cond)); + _d("Comparing input %s with cond %s", input, cond); + if (string_compare(cond, input)) + return svc; + } + + _d("None found"); + return NULL; +} + typedef struct { char *event; void (*cb)(void); @@ -329,6 +353,12 @@ static void api_cb(uev_t *w, void *arg, int events) send_svc(sd, do_find(rq.data, sizeof(rq.data))); goto leave; + case INIT_CMD_SVC_FIND_BYC: + _d("svc find by cond: %s", rq.data); + strterm(rq.data, sizeof(rq.data)); + send_svc(sd, do_find_byc(rq.data, sizeof(rq.data))); + goto leave; + default: _d("Unsupported cmd: %d", rq.cmd); break; diff --git a/src/client.c b/src/client.c index a7f27bab..b1412fd9 100644 --- a/src/client.c +++ b/src/client.c @@ -125,14 +125,14 @@ error: return NULL; } -svc_t *client_svc_find(const char *arg) +svc_t *do_cmd(int cmd, const char *arg) { - int sd = -1; struct init_request rq = { .magic = INIT_MAGIC, - .cmd = INIT_CMD_SVC_FIND, + .cmd = cmd, }; static svc_t svc; + int sd = -1; sd = client_connect(); if (sd == -1) @@ -152,11 +152,21 @@ svc_t *client_svc_find(const char *arg) error: client_disconnect(); perror("Failed communicating with finit"); - sd = -1; return NULL; } +svc_t *client_svc_find(const char *arg) +{ + return do_cmd(INIT_CMD_SVC_FIND, arg); +} + + +svc_t *client_svc_find_by_cond(const char *arg) +{ + return do_cmd(INIT_CMD_SVC_FIND_BYC, arg); +} + /** * Local Variables: * indent-tabs-mode: t diff --git a/src/client.h b/src/client.h index 2d5b074d..7e11efd3 100644 --- a/src/client.h +++ b/src/client.h @@ -27,11 +27,12 @@ #include "finit.h" #include "svc.h" -int client_connect (void); -int client_disconnect (void); +int client_connect (void); +int client_disconnect (void); -int client_send (struct init_request *rq, ssize_t len); -svc_t *client_svc_iterator (int first); -svc_t *client_svc_find (const char *arg); +int client_send (struct init_request *rq, ssize_t len); +svc_t *client_svc_iterator (int first); +svc_t *client_svc_find (const char *arg); +svc_t *client_svc_find_by_cond (const char *arg); #endif /* FINIT_CLIENT_H_ */ diff --git a/src/finit.h b/src/finit.h index 6745f17d..a7ce6fec 100644 --- a/src/finit.h +++ b/src/finit.h @@ -76,6 +76,7 @@ #define INIT_CMD_SVC_ITER 129 #define INIT_CMD_SVC_QUERY 130 #define INIT_CMD_SVC_FIND 131 +#define INIT_CMD_SVC_FIND_BYC 132 #define INIT_CMD_NACK 254 #define INIT_CMD_ACK 255 diff --git a/src/initctl.c b/src/initctl.c index 14be0c5f..a9c5e70a 100644 --- a/src/initctl.c +++ b/src/initctl.c @@ -210,7 +210,9 @@ static int do_restart(char *arg) { return do_startstop(INIT_CMD_RESTART_SVC, arg static int dump_one_cond(const char *fpath, const struct stat *sb, int tflag, struct FTW *ftwbuf) { - int len; + const char *cond, *asserted; + char *nm = "init"; + pid_t pid = 1; if (tflag != FTW_F) return 0; @@ -218,16 +220,36 @@ static int dump_one_cond(const char *fpath, const struct stat *sb, int tflag, st if (!strcmp(fpath, _PATH_COND "reconf")) return 0; - len = strlen(_PATH_COND); - printf("%6s %s\n", condstr(cond_get_path(fpath)), &fpath[len]); + asserted = condstr(cond_get_path(fpath)); + cond = &fpath[strlen(_PATH_COND)]; + if (strncmp("pid/", cond, 4) == 0) { + svc_t *svc; + + svc= client_svc_find_by_cond(cond); + if (!svc) { + nm = "unknown"; + pid = 0; + } else { + nm = svc_ident(svc, NULL, 0); + pid = svc->pid; + } + } + + printf("%-*d %-*s %-6s %s\n", pw, pid, iw, nm, asserted, cond); return 0; } static int do_cond_dump(char *arg) { - if (heading) - printheader(NULL, "STATUS CONDITION", 0); + col_widths(); + if (heading) { + char title[80]; + + snprintf(title, sizeof(title), "%-*s %-*s %-6s %s", pw, "PID", + iw, "IDENT", "STATUS", "CONDITION"); + printheader(NULL, title, 0); + } if (nftw(_PATH_COND, dump_one_cond, 20, 0) == -1) { warnx("Failed parsing %s", _PATH_COND); @@ -278,7 +300,7 @@ static int do_cond_show(char *arg) if (heading) { char title[80]; - snprintf(title, sizeof(title), "%-*s %-*s %6s %s", pw, "PID", + snprintf(title, sizeof(title), "%-*s %-*s %-6s %s", pw, "PID", iw, "IDENT", "STATUS", "CONDITION (+ ON, ~ FLUX, - OFF)"); printheader(NULL, title, 0); }