mirror of
https://github.com/troglobit/finit.git
synced 2026-10-29 12:40:44 +00:00
Merge pull request #115 from jonasj76/id-as-string
Add support to specify service ID as a string
This commit is contained in:
7 files changed
+91
-48
No files matched your search
@@ -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 int do_restart(char *buf, size_t len) { return call(restart, buf, len); }
|
||||||
|
|
||||||
static char query_buf[368];
|
static char query_buf[368];
|
||||||
static int missing(char *job, int id)
|
static int missing(char *job, char *id)
|
||||||
{
|
{
|
||||||
char buf[20];
|
char buf[20];
|
||||||
char idstr[13] = "";
|
|
||||||
|
|
||||||
if (!job)
|
if (!job)
|
||||||
job = "";
|
job = "";
|
||||||
if (id > 1)
|
if (!id)
|
||||||
snprintf(idstr, sizeof(idstr), ":%d", 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));
|
strlcat(query_buf, buf, sizeof(query_buf));
|
||||||
|
|
||||||
return 1;
|
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)
|
static svc_t *do_find(char *buf, size_t len)
|
||||||
{
|
{
|
||||||
int id = 1;
|
char *id = NULL;
|
||||||
char *ptr, *input;
|
char *ptr, *input;
|
||||||
|
svc_t *iter = NULL;
|
||||||
|
|
||||||
input = sanitize(buf, len);
|
input = sanitize(buf, len);
|
||||||
if (!input)
|
if (!input)
|
||||||
@@ -132,11 +132,28 @@ static svc_t *do_find(char *buf, size_t len)
|
|||||||
ptr = strchr(input, ':');
|
ptr = strchr(input, ':');
|
||||||
if (ptr) {
|
if (ptr) {
|
||||||
*ptr++ = 0;
|
*ptr++ = 0;
|
||||||
id = atonum(ptr);
|
id = ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (isdigit(input[0]))
|
if (isdigit(input[0])) {
|
||||||
return svc_find_by_jobid(atonum(input), id);
|
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);
|
return svc_find_by_nameid(input, id);
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -222,7 +222,7 @@ static void finalize(void)
|
|||||||
/*
|
/*
|
||||||
* Track bundled watchdogd in case a better one turns up
|
* 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)
|
if (svc)
|
||||||
wdog = svc;
|
wdog = svc;
|
||||||
|
|
||||||
|
|||||||
+3
-1
@@ -169,6 +169,7 @@ static void socket_cb(uev_t *w, void *arg, int events)
|
|||||||
svc_t *svc = (svc_t *)arg, *task;
|
svc_t *svc = (svc_t *)arg, *task;
|
||||||
const char *conn = " connection";
|
const char *conn = " connection";
|
||||||
char iifname[IF_NAMESIZE + 1] = "UNKNOWN";
|
char iifname[IF_NAMESIZE + 1] = "UNKNOWN";
|
||||||
|
char id[MAX_ID_LEN];
|
||||||
int stdin;
|
int stdin;
|
||||||
|
|
||||||
_d("%s: Got socket event ...", svc->cmd);
|
_d("%s: Got socket event ...", svc->cmd);
|
||||||
@@ -194,7 +195,8 @@ static void socket_cb(uev_t *w, void *arg, int events)
|
|||||||
return;
|
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) {
|
if (!task) {
|
||||||
logit(LOG_CRIT, "%s: Unable to allocate service for inetd client", svc->cmd);
|
logit(LOG_CRIT, "%s: Unable to allocate service for inetd client", svc->cmd);
|
||||||
if (svc->inetd.type == SOCK_STREAM)
|
if (svc->inetd.type == SOCK_STREAM)
|
||||||
|
|||||||
+2
-2
@@ -438,12 +438,12 @@ static int show_status(char *arg)
|
|||||||
printheader(NULL, "# STATUS PID RUNLEVELS SERVICE DESCRIPTION", 0);
|
printheader(NULL, "# STATUS PID RUNLEVELS SERVICE DESCRIPTION", 0);
|
||||||
|
|
||||||
for (svc = client_svc_iterator(1); svc; svc = client_svc_iterator(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))
|
// if (svc_is_unique(svc))
|
||||||
// snprintf(jobid, sizeof(jobid), "%d", svc->job);
|
// snprintf(jobid, sizeof(jobid), "%d", svc->job);
|
||||||
// else
|
// 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));
|
printf("%-9s %7s ", jobid, svc_status(svc));
|
||||||
if (svc_is_inetd(svc))
|
if (svc_is_inetd(svc))
|
||||||
|
|||||||
+14
-7
@@ -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 service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
||||||
{
|
{
|
||||||
int id = -1;
|
char id_str[MAX_ID_LEN];
|
||||||
#ifdef INETD_ENABLED
|
#ifdef INETD_ENABLED
|
||||||
int forking = 0;
|
int forking = 0;
|
||||||
#endif
|
#endif
|
||||||
int levels = 0;
|
int levels = 0;
|
||||||
int manual = 0;
|
int manual = 0;
|
||||||
char *line;
|
char *line;
|
||||||
|
char *id = NULL;
|
||||||
char *username = NULL, *log = NULL, *pid = NULL;
|
char *username = NULL, *log = NULL, *pid = NULL;
|
||||||
char *service = NULL, *proto = NULL, *ifaces = NULL;
|
char *service = NULL, *proto = NULL, *ifaces = NULL;
|
||||||
char *cmd, *desc, *runlevels = NULL, *cond = 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..]> */
|
else if (cmd[0] == '<') /* <[!][cond][,cond..]> */
|
||||||
cond = &cmd[1];
|
cond = &cmd[1];
|
||||||
else if (cmd[0] == ':') /* :ID */
|
else if (cmd[0] == ':') /* :ID */
|
||||||
id = atoi(&cmd[1]);
|
id = &cmd[1];
|
||||||
#ifdef INETD_ENABLED
|
#ifdef INETD_ENABLED
|
||||||
else if (!strncasecmp(cmd, "nowait", 6))
|
else if (!strncasecmp(cmd, "nowait", 6))
|
||||||
forking = 1;
|
forking = 1;
|
||||||
@@ -801,18 +802,24 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
|
|||||||
parse_cmdline_args(svc, cmd);
|
parse_cmdline_args(svc, cmd);
|
||||||
goto inetd_setup;
|
goto inetd_setup;
|
||||||
}
|
}
|
||||||
if (id <= 0)
|
if (!id) {
|
||||||
id = svc_next_id(cmd);
|
int n = svc_next_id_int(cmd);
|
||||||
|
|
||||||
|
if (n) {
|
||||||
|
snprintf(id_str, sizeof(id_str), "%d", n);
|
||||||
|
id = id_str;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
recreate:
|
recreate:
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (id <= 0)
|
if (!id)
|
||||||
id = 1;
|
id = "1";
|
||||||
|
|
||||||
svc = svc_find(cmd, id);
|
svc = svc_find(cmd, id);
|
||||||
if (!svc) {
|
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);
|
svc = svc_new(cmd, id, type);
|
||||||
if (!svc) {
|
if (!svc) {
|
||||||
_e("Out of memory, cannot register service %s", cmd);
|
_e("Out of memory, cannot register service %s", cmd);
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ static void svc_gc(void *arg)
|
|||||||
* Returns:
|
* Returns:
|
||||||
* A pointer to a new &svc_t object, or %NULL if out of empty slots.
|
* 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;
|
int job = -1;
|
||||||
svc_t *svc, *iter = NULL;
|
svc_t *svc, *iter = NULL;
|
||||||
@@ -98,7 +98,7 @@ svc_t *svc_new(char *cmd, int id, int type)
|
|||||||
|
|
||||||
svc->type = type;
|
svc->type = type;
|
||||||
svc->job = job;
|
svc->job = job;
|
||||||
svc->id = id;
|
strlcpy(svc->id, id, sizeof(svc->id));
|
||||||
strlcpy(svc->cmd, cmd, sizeof(svc->cmd));
|
strlcpy(svc->cmd, cmd, sizeof(svc->cmd));
|
||||||
|
|
||||||
/* Default description, if missing */
|
/* Default description, if missing */
|
||||||
@@ -295,12 +295,12 @@ svc_t *svc_stop_completed(void)
|
|||||||
* Returns:
|
* Returns:
|
||||||
* A pointer to an &svc_t object, or %NULL if not found.
|
* 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;
|
svc_t *svc, *iter = NULL;
|
||||||
|
|
||||||
for (svc = svc_iterator(&iter, 1); svc; svc = svc_iterator(&iter, 0)) {
|
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;
|
return svc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -334,12 +334,12 @@ svc_t *svc_find_by_pid(pid_t pid)
|
|||||||
* Returns:
|
* Returns:
|
||||||
* A pointer to an &svc_t object, or %NULL if not found.
|
* 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;
|
svc_t *svc, *iter = NULL;
|
||||||
|
|
||||||
for (svc = svc_iterator(&iter, 1); svc; svc = svc_iterator(&iter, 0)) {
|
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;
|
return svc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -354,12 +354,12 @@ svc_t *svc_find_by_jobid(int job, int id)
|
|||||||
* Returns:
|
* Returns:
|
||||||
* A pointer to an &svc_t object, or %NULL if not found.
|
* 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;
|
svc_t *svc, *iter = NULL;
|
||||||
|
|
||||||
for (svc = svc_iterator(&iter, 1); svc; svc = svc_iterator(&iter, 0)) {
|
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;
|
return svc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -496,18 +496,24 @@ int svc_enabled(svc_t *svc)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Same base service, return unique ID */
|
/* Same base service, return unique ID as an integer */
|
||||||
int svc_next_id(char *cmd)
|
int svc_next_id_int(char *cmd)
|
||||||
{
|
{
|
||||||
int id = 0;
|
int n = 1;
|
||||||
svc_t *svc, *iter = NULL;
|
svc_t *svc, *iter = NULL;
|
||||||
|
|
||||||
for (svc = svc_iterator(&iter, 1); svc; svc = svc_iterator(&iter, 0)) {
|
for (svc = svc_iterator(&iter, 1); svc; svc = svc_iterator(&iter, 0)) {
|
||||||
if (!strcmp(svc->cmd, cmd) && id < svc->id)
|
char id[MAX_ID_LEN];
|
||||||
id = svc->id;
|
|
||||||
|
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)
|
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)
|
* 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;
|
int result = 0;
|
||||||
char *input, *token, *pos;
|
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);
|
token = strtok_r(input, " ", &pos);
|
||||||
while (token) {
|
while (token) {
|
||||||
int id = 1;
|
char *id = NULL;
|
||||||
svc_t *svc, *iter = NULL;
|
svc_t *svc, *iter = NULL;
|
||||||
char *ptr = strchr(token, ':');
|
char *ptr = strchr(token, ':');
|
||||||
|
|
||||||
if (isdigit(token[0])) {
|
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) {
|
if (!ptr) {
|
||||||
svc = svc_job_iterator(&iter, 1, job);
|
svc = svc_job_iterator(&iter, 1, job);
|
||||||
if (!svc && not_found)
|
if (!svc && not_found)
|
||||||
result += not_found(NULL, job);
|
result += not_found(NULL, token);
|
||||||
|
|
||||||
while (svc) {
|
while (svc) {
|
||||||
if (found)
|
if (found)
|
||||||
@@ -564,8 +580,7 @@ int svc_parse_jobstr(char *str, size_t len, int (*found)(svc_t *), int (not_foun
|
|||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
*ptr++ = 0;
|
*ptr++ = 0;
|
||||||
id = atonum(ptr);
|
id = ptr;
|
||||||
job = atonum(token);
|
|
||||||
|
|
||||||
svc = svc_find_by_jobid(job, id);
|
svc = svc_find_by_jobid(job, id);
|
||||||
if (!svc && not_found)
|
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 {
|
} else {
|
||||||
*ptr++ = 0;
|
*ptr++ = 0;
|
||||||
id = atonum(ptr);
|
id = ptr;
|
||||||
|
|
||||||
svc = svc_find_by_nameid(token, id);
|
svc = svc_find_by_nameid(token, id);
|
||||||
if (!svc && not_found)
|
if (!svc && not_found)
|
||||||
|
|||||||
@@ -66,6 +66,7 @@ typedef enum {
|
|||||||
SVC_BLOCK_RESTARTING,
|
SVC_BLOCK_RESTARTING,
|
||||||
} svc_block_t;
|
} svc_block_t;
|
||||||
|
|
||||||
|
#define MAX_ID_LEN 16
|
||||||
#define MAX_ARG_LEN 64
|
#define MAX_ARG_LEN 64
|
||||||
#define MAX_STR_LEN 64
|
#define MAX_STR_LEN 64
|
||||||
#define MAX_COND_LEN (MAX_ARG_LEN * 3)
|
#define MAX_COND_LEN (MAX_ARG_LEN * 3)
|
||||||
@@ -86,7 +87,8 @@ typedef struct svc {
|
|||||||
TAILQ_ENTRY(svc) link;
|
TAILQ_ENTRY(svc) link;
|
||||||
|
|
||||||
/* Instance specifics */
|
/* Instance specifics */
|
||||||
int job, id; /* JOB:ID */
|
int job; /* JOB: */
|
||||||
|
char id[MAX_ID_LEN]; /* :ID */
|
||||||
|
|
||||||
/* Limits and scoping */
|
/* Limits and scoping */
|
||||||
struct rlimit rlimit[RLIMIT_NLIMITS];
|
struct rlimit rlimit[RLIMIT_NLIMITS];
|
||||||
@@ -145,13 +147,13 @@ typedef struct svc {
|
|||||||
struct timespec gc;
|
struct timespec gc;
|
||||||
} svc_t;
|
} 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);
|
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_pid (pid_t pid);
|
||||||
svc_t *svc_find_by_jobid (int job, int id);
|
svc_t *svc_find_by_jobid (int job, char *id);
|
||||||
svc_t *svc_find_by_nameid (char *name, int id);
|
svc_t *svc_find_by_nameid (char *name, char *id);
|
||||||
svc_t *svc_find_by_pidfile (char *fn);
|
svc_t *svc_find_by_pidfile (char *fn);
|
||||||
|
|
||||||
svc_t *svc_iterator (svc_t **iter, int first);
|
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);
|
void svc_prune_bootstrap (void);
|
||||||
|
|
||||||
int svc_enabled (svc_t *svc);
|
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_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 (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; }
|
static inline int svc_is_inetd_conn(svc_t *svc) { return svc && SVC_TYPE_INETD_CONN == svc->type; }
|
||||||
|
|||||||
Reference in new issue
Block a user