Merge pull request #115 from jonasj76/id-as-string

Add support to specify service ID as a string
This commit is contained in:
Joachim Nilsson
2018-12-11 21:12:50 +01:00
committed by GitHub
7 changed files with 91 additions and 48 deletions
+26 -9
View File
@@ -93,17 +93,16 @@ static int do_stop (char *buf, size_t len) { return call(stop, buf, len); }
static int do_restart(char *buf, size_t len) { return call(restart, buf, len); }
static char query_buf[368];
static int missing(char *job, int id)
static int missing(char *job, char *id)
{
char buf[20];
char idstr[13] = "";
if (!job)
job = "";
if (id > 1)
snprintf(idstr, sizeof(idstr), ":%d", id);
if (!id)
id = "";
snprintf(buf, sizeof(buf), "%s%s ", job, idstr);
snprintf(buf, sizeof(buf), "%s:%s ", job, id);
strlcat(query_buf, buf, sizeof(query_buf));
return 1;
@@ -122,8 +121,9 @@ static int do_query(struct init_request *rq, size_t len)
static svc_t *do_find(char *buf, size_t len)
{
int id = 1;
char *id = NULL;
char *ptr, *input;
svc_t *iter = NULL;
input = sanitize(buf, len);
if (!input)
@@ -132,11 +132,28 @@ static svc_t *do_find(char *buf, size_t len)
ptr = strchr(input, ':');
if (ptr) {
*ptr++ = 0;
id = atonum(ptr);
id = ptr;
}
if (isdigit(input[0]))
return svc_find_by_jobid(atonum(input), id);
if (isdigit(input[0])) {
char *ep;
long job = 0;
errno = 0;
job = strtol(input, &ep, 10);
if ((errno == ERANGE && (job == LONG_MAX || job == LONG_MIN)) ||
(errno != 0 && job == 0) ||
(input == ep))
return NULL;
if (!id)
return svc_job_iterator(&iter, 1, job);
return svc_find_by_jobid(job, id);
}
if (!id)
return svc_named_iterator(&iter, 1, input);
return svc_find_by_nameid(input, id);
}
+1 -1
View File
@@ -222,7 +222,7 @@ static void finalize(void)
/*
* Track bundled watchdogd in case a better one turns up
*/
svc = svc_find(FINIT_LIBPATH_ "/watchdogd", 1);
svc = svc_find(FINIT_LIBPATH_ "/watchdogd", "1");
if (svc)
wdog = svc;
+3 -1
View File
@@ -169,6 +169,7 @@ static void socket_cb(uev_t *w, void *arg, int events)
svc_t *svc = (svc_t *)arg, *task;
const char *conn = " connection";
char iifname[IF_NAMESIZE + 1] = "UNKNOWN";
char id[MAX_ID_LEN];
int stdin;
_d("%s: Got socket event ...", svc->cmd);
@@ -194,7 +195,8 @@ static void socket_cb(uev_t *w, void *arg, int events)
return;
}
task = svc_new(svc->cmd, svc->inetd.next_id++, SVC_TYPE_INETD_CONN);
snprintf(id, sizeof(id), "%d", svc->inetd.next_id++);
task = svc_new(svc->cmd, id, SVC_TYPE_INETD_CONN);
if (!task) {
logit(LOG_CRIT, "%s: Unable to allocate service for inetd client", svc->cmd);
if (svc->inetd.type == SOCK_STREAM)
+2 -2
View File
@@ -438,12 +438,12 @@ static int show_status(char *arg)
printheader(NULL, "# STATUS PID RUNLEVELS SERVICE DESCRIPTION", 0);
for (svc = client_svc_iterator(1); svc; svc = client_svc_iterator(0)) {
char jobid[10], args[512] = "", *lvls;
char jobid[20], args[512] = "", *lvls;
// if (svc_is_unique(svc))
// snprintf(jobid, sizeof(jobid), "%d", svc->job);
// else
snprintf(jobid, sizeof(jobid), "%d:%d", svc->job, svc->id);
snprintf(jobid, sizeof(jobid), "%d:%s", svc->job, svc->id);
printf("%-9s %7s ", jobid, svc_status(svc));
if (svc_is_inetd(svc))
+14 -7
View File
@@ -672,13 +672,14 @@ static void parse_cmdline_args(svc_t *svc, char *cmd)
*/
int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
{
int id = -1;
char id_str[MAX_ID_LEN];
#ifdef INETD_ENABLED
int forking = 0;
#endif
int levels = 0;
int manual = 0;
char *line;
char *id = NULL;
char *username = NULL, *log = NULL, *pid = NULL;
char *service = NULL, *proto = NULL, *ifaces = NULL;
char *cmd, *desc, *runlevels = NULL, *cond = NULL;
@@ -729,7 +730,7 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
else if (cmd[0] == '<') /* <[!][cond][,cond..]> */
cond = &cmd[1];
else if (cmd[0] == ':') /* :ID */
id = atoi(&cmd[1]);
id = &cmd[1];
#ifdef INETD_ENABLED
else if (!strncasecmp(cmd, "nowait", 6))
forking = 1;
@@ -801,18 +802,24 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
parse_cmdline_args(svc, cmd);
goto inetd_setup;
}
if (id <= 0)
id = svc_next_id(cmd);
if (!id) {
int n = svc_next_id_int(cmd);
if (n) {
snprintf(id_str, sizeof(id_str), "%d", n);
id = id_str;
}
}
}
recreate:
#endif
if (id <= 0)
id = 1;
if (!id)
id = "1";
svc = svc_find(cmd, id);
if (!svc) {
_d("Creating new svc for %s id #%d type %d", cmd, id, type);
_d("Creating new svc for %s id #%s type %d", cmd, id, type);
svc = svc_new(cmd, id, type);
if (!svc) {
_e("Out of memory, cannot register service %s", cmd);
+36 -21
View File
@@ -77,7 +77,7 @@ static void svc_gc(void *arg)
* Returns:
* A pointer to a new &svc_t object, or %NULL if out of empty slots.
*/
svc_t *svc_new(char *cmd, int id, int type)
svc_t *svc_new(char *cmd, char *id, int type)
{
int job = -1;
svc_t *svc, *iter = NULL;
@@ -98,7 +98,7 @@ svc_t *svc_new(char *cmd, int id, int type)
svc->type = type;
svc->job = job;
svc->id = id;
strlcpy(svc->id, id, sizeof(svc->id));
strlcpy(svc->cmd, cmd, sizeof(svc->cmd));
/* Default description, if missing */
@@ -295,12 +295,12 @@ svc_t *svc_stop_completed(void)
* Returns:
* A pointer to an &svc_t object, or %NULL if not found.
*/
svc_t *svc_find(char *cmd, int id)
svc_t *svc_find(char *cmd, char *id)
{
svc_t *svc, *iter = NULL;
for (svc = svc_iterator(&iter, 1); svc; svc = svc_iterator(&iter, 0)) {
if (svc->id == id && !strncmp(svc->cmd, cmd, strlen(svc->cmd)))
if (svc->id && !strcmp(svc->id, id) && !strncmp(svc->cmd, cmd, strlen(svc->cmd)))
return svc;
}
@@ -334,12 +334,12 @@ svc_t *svc_find_by_pid(pid_t pid)
* Returns:
* A pointer to an &svc_t object, or %NULL if not found.
*/
svc_t *svc_find_by_jobid(int job, int id)
svc_t *svc_find_by_jobid(int job, char *id)
{
svc_t *svc, *iter = NULL;
for (svc = svc_iterator(&iter, 1); svc; svc = svc_iterator(&iter, 0)) {
if (svc->job == job && svc->id == id)
if (svc->job == job && svc->id && !strcmp(svc->id, id))
return svc;
}
@@ -354,12 +354,12 @@ svc_t *svc_find_by_jobid(int job, int id)
* Returns:
* A pointer to an &svc_t object, or %NULL if not found.
*/
svc_t *svc_find_by_nameid(char *name, int id)
svc_t *svc_find_by_nameid(char *name, char *id)
{
svc_t *svc, *iter = NULL;
for (svc = svc_iterator(&iter, 1); svc; svc = svc_iterator(&iter, 0)) {
if (svc->id == id && !strcmp(name, svc->name))
if (svc->id && !strcmp(svc->id, id) && !strcmp(name, svc->name))
return svc;
}
@@ -496,18 +496,24 @@ int svc_enabled(svc_t *svc)
return 1;
}
/* Same base service, return unique ID */
int svc_next_id(char *cmd)
/* Same base service, return unique ID as an integer */
int svc_next_id_int(char *cmd)
{
int id = 0;
int n = 1;
svc_t *svc, *iter = NULL;
for (svc = svc_iterator(&iter, 1); svc; svc = svc_iterator(&iter, 0)) {
if (!strcmp(svc->cmd, cmd) && id < svc->id)
id = svc->id;
char id[MAX_ID_LEN];
snprintf(id, sizeof(id), "%d", n);
if (!strcmp(svc->cmd, cmd) && svc->id && strcmp(svc->id, id))
return n;
n++;
}
return id + 1;
return 0;
}
int svc_is_unique(svc_t *svc)
@@ -534,7 +540,7 @@ int svc_is_unique(svc_t *svc)
/*
* Used by api.c (to start/stop/restart) and initctl.c (for input validation)
*/
int svc_parse_jobstr(char *str, size_t len, int (*found)(svc_t *), int (not_found)(char *, int))
int svc_parse_jobstr(char *str, size_t len, int (*found)(svc_t *), int (not_found)(char *, char *))
{
int result = 0;
char *input, *token, *pos;
@@ -545,17 +551,27 @@ int svc_parse_jobstr(char *str, size_t len, int (*found)(svc_t *), int (not_foun
token = strtok_r(input, " ", &pos);
while (token) {
int id = 1;
char *id = NULL;
svc_t *svc, *iter = NULL;
char *ptr = strchr(token, ':');
if (isdigit(token[0])) {
int job = atonum(token);
char *ep;
long job = 0;
errno = 0;
job = strtol(token, &ep, 10);
if ((errno == ERANGE && (job == LONG_MAX || job == LONG_MIN)) ||
(errno != 0 && job == 0) ||
(token == ep)) {
result++;
continue;
}
if (!ptr) {
svc = svc_job_iterator(&iter, 1, job);
if (!svc && not_found)
result += not_found(NULL, job);
result += not_found(NULL, token);
while (svc) {
if (found)
@@ -564,8 +580,7 @@ int svc_parse_jobstr(char *str, size_t len, int (*found)(svc_t *), int (not_foun
}
} else {
*ptr++ = 0;
id = atonum(ptr);
job = atonum(token);
id = ptr;
svc = svc_find_by_jobid(job, id);
if (!svc && not_found)
@@ -586,7 +601,7 @@ int svc_parse_jobstr(char *str, size_t len, int (*found)(svc_t *), int (not_foun
}
} else {
*ptr++ = 0;
id = atonum(ptr);
id = ptr;
svc = svc_find_by_nameid(token, id);
if (!svc && not_found)
+9 -7
View File
@@ -66,6 +66,7 @@ typedef enum {
SVC_BLOCK_RESTARTING,
} svc_block_t;
#define MAX_ID_LEN 16
#define MAX_ARG_LEN 64
#define MAX_STR_LEN 64
#define MAX_COND_LEN (MAX_ARG_LEN * 3)
@@ -86,7 +87,8 @@ typedef struct svc {
TAILQ_ENTRY(svc) link;
/* Instance specifics */
int job, id; /* JOB:ID */
int job; /* JOB: */
char id[MAX_ID_LEN]; /* :ID */
/* Limits and scoping */
struct rlimit rlimit[RLIMIT_NLIMITS];
@@ -145,13 +147,13 @@ typedef struct svc {
struct timespec gc;
} svc_t;
svc_t *svc_new (char *cmd, int id, int type);
svc_t *svc_new (char *cmd, char *id, int type);
int svc_del (svc_t *svc);
svc_t *svc_find (char *cmd, int id);
svc_t *svc_find (char *cmd, char *id);
svc_t *svc_find_by_pid (pid_t pid);
svc_t *svc_find_by_jobid (int job, int id);
svc_t *svc_find_by_nameid (char *name, int id);
svc_t *svc_find_by_jobid (int job, char *id);
svc_t *svc_find_by_nameid (char *name, char *id);
svc_t *svc_find_by_pidfile (char *fn);
svc_t *svc_iterator (svc_t **iter, int first);
@@ -172,10 +174,10 @@ int svc_clean_bootstrap (svc_t *svc);
void svc_prune_bootstrap (void);
int svc_enabled (svc_t *svc);
int svc_next_id (char *cmd);
int svc_next_id_int (char *cmd);
int svc_is_unique (svc_t *svc);
int svc_parse_jobstr (char *str, size_t len, int (*found)(svc_t *), int (not_found)(char *, int));
int svc_parse_jobstr (char *str, size_t len, int (*found)(svc_t *), int (not_found)(char *, char *));
static inline int svc_is_inetd (svc_t *svc) { return svc && SVC_TYPE_INETD == svc->type; }
static inline int svc_is_inetd_conn(svc_t *svc) { return svc && SVC_TYPE_INETD_CONN == svc->type; }