Merge remote-tracking branch 'upstream/master' into wip-tests

This commit is contained in:
Magnus Malm committed 2021-02-24 10:22:57 +01:00
commit 6027e94c65
9 files changed
+471 -152

No files matched your search

+2
View File
@@ -167,6 +167,8 @@ static void setup(void *arg)
makedir("/var/run/pluto", 0755); /* Needed by Openswan */
makedir("/var/run/quagga", 0755); /* Needed by Quagga */
makedir("/var/log/quagga", 0755); /* Needed by Quagga */
makedir("/var/run/frr", 0755); /* Needed by FRR */
makedir("/var/log/frr", 0755); /* Needed by FRR */
makedir("/var/run/sshd", 01755); /* OpenSSH */
gid = getgroup("tty");
+49 -116
View File
@@ -22,11 +22,10 @@
* THE SOFTWARE.
*/
#include <fnmatch.h>
#include <glob.h>
#include <limits.h>
#include <paths.h>
#include <lite/queue.h>
#include <sys/inotify.h>
#include "finit.h"
#include "cond.h"
@@ -34,28 +33,15 @@
#include "pid.h"
#include "plugin.h"
#include "service.h"
#include "iwatch.h"
struct wd_entry {
TAILQ_ENTRY(wd_entry) link;
char *path;
int fd;
};
static struct iwatch iw_pidfile;
struct context {
int fd;
TAILQ_HEAD(, wd_entry) wd_list;
};
static struct context pidfile_ctx;
static int watcher_add(struct context *ctx, char *path)
static int pidfile_add_path(struct iwatch *iw, char *path)
{
struct wd_entry *wd;
uint32_t mask = IN_ONLYDIR | IN_CREATE | IN_ATTRIB | IN_DELETE | IN_MODIFY | IN_MOVED_TO;
char *ptr;
int fd;
_d("pidfile: Adding new watcher for path %s", path);
ptr = strstr(path, "run/");
if (ptr) {
char *slash;
@@ -66,44 +52,16 @@ static int watcher_add(struct context *ctx, char *path)
ptr = slash++;
slash = strchr(ptr, '/');
if (slash) {
_d("pidfile: Path too deep, skipping.");
_d("Path too deep, skipping.");
return -1;
}
}
}
fd = inotify_add_watch(ctx->fd, path, mask);
if (fd < 0) {
_pe("inotify_add_watch()");
return -1;
}
wd = malloc(sizeof(struct wd_entry));
if (!wd) {
_pe("Failed allocating new `struct wd_entry`");
inotify_rm_watch(ctx->fd, fd);
return -1;
}
wd->path = path;
wd->fd = fd;
TAILQ_INSERT_HEAD(&ctx->wd_list, wd, link);
return 0;
return iwatch_add(iw, path, IN_ONLYDIR);
}
static int watcher_del(struct context *ctx, struct wd_entry *wde)
{
_d("pidfile: Removing watcher for removed path %s", wde->path);
TAILQ_REMOVE(&ctx->wd_list, wde, link);
inotify_rm_watch(ctx->fd, wde->fd);
free(wde->path);
free(wde);
return 0;
}
static void update_conds(char *dir, char *name, uint32_t mask)
static void pidfile_update_conds(char *dir, char *name, uint32_t mask)
{
char cond[MAX_COND_LEN];
char fn[PATH_MAX];
@@ -112,13 +70,16 @@ static void update_conds(char *dir, char *name, uint32_t mask)
_d("Got dir: %s, name: %s, mask: %08x", dir, name, mask);
snprintf(fn, sizeof(fn), "%s/%s", dir, name);
if (fnmatch("*\\.pid", fn, 0) && fnmatch("*/pid", fn, 0))
return;
svc = svc_find_by_pidfile(fn);
if (!svc) {
_d("pidfile: No matching svc for %s", fn);
_d("No matching svc for %s", fn);
return;
}
_d("pidfile: Found svc %s for %s with pid %d", svc->name, fn, svc->pid);
_d("Found svc %s for %s with pid %d", svc->name, fn, svc->pid);
mkcond(svc, cond, sizeof(cond));
if (mask & (IN_CREATE | IN_ATTRIB | IN_MODIFY | IN_MOVED_TO)) {
@@ -138,7 +99,7 @@ static void update_conds(char *dir, char *name, uint32_t mask)
}
/* synthesize events in case of new run dirs */
static void scan_for_pidfiles(struct context *ctx, char *dir, int len)
static void pidfile_scandir(struct iwatch *iw, char *dir, int len)
{
glob_t gl;
size_t i;
@@ -157,47 +118,33 @@ static void scan_for_pidfiles(struct context *ctx, char *dir, int len)
for (i = 0; i < gl.gl_pathc; i++) {
_d("scan found %s", gl.gl_pathv[i]);
update_conds(dir, gl.gl_pathv[i], IN_CREATE);
pidfile_update_conds(dir, gl.gl_pathv[i], IN_CREATE);
}
globfree(&gl);
}
static void handle_dir(struct context *ctx, struct wd_entry *wde, char *name, int mask)
/*
* create/remove sub-directory in monitored directory
*/
static void pidfile_handle_dir(struct iwatch *iw, char *dir, char *name, int mask)
{
char *path;
int plen;
int exist = 0;
char path[strlen(dir) + strlen(name) + 2];
struct iwatch_path *iwp;
plen = snprintf(NULL, 0, "%s/%s", wde->path, name) + 1;
path = malloc(plen);
if (!path) {
_pe("Failed allocating path buffer for watcher");
return;
}
snprintf(path, plen, "%s/%s", wde->path, name);
_d("pidfile: path is %s", path);
snprintf(path, sizeof(path), "%s/%s", dir, name);
_d("path: %s", path);
TAILQ_FOREACH(wde, &ctx->wd_list, link) {
if (!strcmp(wde->path, path)) {
exist = 1;
break;
}
}
iwp = iwatch_find_by_path(iw, path);
if (mask & IN_CREATE) {
if (!exist) {
int rc = watcher_add(ctx, path);
scan_for_pidfiles(ctx, path, plen);
if (!rc)
return;
if (!iwp) {
pidfile_add_path(iw, path);
pidfile_scandir(iw, path, sizeof(path));
}
} else if (mask & IN_DELETE) {
if (exist)
watcher_del(&pidfile_ctx, wde);
if (iwp)
iwatch_del(&iw_pidfile, iwp);
}
free(path);
}
static void pidfile_callback(void *arg, int fd, int events)
@@ -213,43 +160,42 @@ static void pidfile_callback(void *arg, int fd, int events)
return;
}
_d("pidfile: Entering ... reading %zu bytes into ev_buf[]", buflen - 1);
_d("Entering ... reading %zu bytes into ev_buf[]", buflen - 1);
sz = read(fd, buf, buflen - 1);
if (sz <= 0) {
_pe("invalid inotify event");
goto done;
}
buf[sz] = 0;
_d("pidfile: Read %zd bytes, processing ...", sz);
_d("Read %zd bytes, processing ...", sz);
off = 0;
for (off = 0; off < sz; off += sizeof(*ev) + ev->len) {
struct wd_entry *wde;
struct iwatch_path *iwp;
ev = (struct inotify_event *)&buf[off];
_d("pidfile: path %s, event: 0x%08x", ev->name, ev->mask);
_d("path %s, event: 0x%08x", ev->name, ev->mask);
if (!ev->mask)
continue;
/* Find base path for this event */
TAILQ_FOREACH(wde, &pidfile_ctx.wd_list, link) {
if (wde->fd == ev->wd)
break;
}
iwp = iwatch_find_by_wd(&iw_pidfile, ev->wd);
if (!iwp)
continue;
if (ev->mask & IN_ISDIR) {
handle_dir(&pidfile_ctx, wde, ev->name, ev->mask);
pidfile_handle_dir(&iw_pidfile, iwp->path, ev->name, ev->mask);
continue;
}
if (ev->mask & IN_DELETE) {
_d("pidfile %s/%s removed ...", wde->path, ev->name);
_d("pidfile %s/%s removed ...", iwp->path, ev->name);
continue;
}
if (ev->mask & (IN_CREATE | IN_ATTRIB | IN_MODIFY | IN_MOVED_TO))
update_conds(wde->path, ev->name, ev->mask);
pidfile_update_conds(iwp->path, ev->name, ev->mask);
}
done:
free(buf);
@@ -305,14 +251,10 @@ static void pidfile_init(void *arg)
return;
}
TAILQ_INIT(&pidfile_ctx.wd_list);
if (watcher_add(&pidfile_ctx, path))
close(pidfile_ctx.fd);
_d("pidfile monitor active");
if (pidfile_add_path(&iw_pidfile, path))
iwatch_exit(&iw_pidfile);
}
static struct context pidfile_ctx;
/*
* When performing an `initctl reload` with one (unchanged) service
* depending on, e.g. `net/iface/lo`, its condition will not be set
@@ -331,36 +273,27 @@ static plugin_t plugin = {
.name = __FILE__,
.hook[HOOK_BASEFS_UP] = { .cb = pidfile_init },
.hook[HOOK_SVC_RECONF] = { .cb = pidfile_reconf },
.io = {
.cb = pidfile_callback,
.flags = PLUGIN_IO_READ,
},
.depends = { "netlink" },
};
PLUGIN_INIT(plugin_init)
{
pidfile_ctx.fd = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
if (pidfile_ctx.fd < 0) {
_pe("inotify_init()");
int fd;
fd = iwatch_init(&iw_pidfile);
if (fd < 0)
return;
}
plugin.io.fd = fd;
plugin.io.cb = pidfile_callback;
plugin.io.flags = PLUGIN_IO_READ;
plugin.io.fd = pidfile_ctx.fd;
plugin_register(&plugin);
}
PLUGIN_EXIT(plugin_exit)
{
struct wd_entry *wde, *tmp;
TAILQ_FOREACH_SAFE(wde, &pidfile_ctx.wd_list, link, tmp) {
inotify_rm_watch(pidfile_ctx.fd, wde->fd);
free(wde->path);
free(wde);
}
close(pidfile_ctx.fd);
iwatch_exit(&iw_pidfile);
plugin_unregister(&plugin);
}
+1
View File
@@ -26,6 +26,7 @@ finit_SOURCES = api.c cgroup.c cgroup.h \
exec.c finit.c finit.h \
getty.c stty.c \
helpers.c helpers.h \
iwatch.c iwatch.h \
log.c log.h \
mdadm.c mount.c \
pid.c pid.h \
+1
View File
@@ -494,6 +494,7 @@ static int show_status(char *arg)
printf("Service : %s\n", svc->cmd);
printf("Description : %s\n", svc->desc);
printf("Identity : %s\n", svc_ident(svc, ident, sizeof(ident)));
printf("Environment : %s\n", svc->env);
printf("PID : %d\n", svc->pid);
printf("Uptime : %s\n", svc->pid ? uptime(now - svc->start_time, buf, sizeof(buf)) : buf);
printf("Runlevels : %s\n", runlevel_string(runlevel, svc->runlevels));
+164
View File
@@ -0,0 +1,164 @@
/* inotify watcher for files or directories
*
* Copyright (c) 2015-2016 Tobias Waldekranz <tobias@waldekranz.com>
* Copyright (c) 2016-2021 Joachim Wiberg <troglobit@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include <errno.h>
#include "finit.h"
#include "iwatch.h"
#include "log.h"
/*
* iwatch is initialized and used mainly by the pidfile plugin, which is
* one of the cornerstones in the condition subsystem. Other parts of
* Finit may use iwatch too, like env: watchers, but are disabled if the
* pidfile plugin hasn't called iwatch_init() -- this is by design.
*/
static int initialized = 0;
int iwatch_init(struct iwatch *iw)
{
if (!iw) {
errno = EINVAL;
return -1;
}
TAILQ_INIT(&iw->iwp_list);
iw->fd = inotify_init1(IN_NONBLOCK | IN_CLOEXEC);
if (iw->fd < 0) {
_pe("inotify_init()");
return -1;
}
initialized = 1;
return iw->fd;
}
void iwatch_exit(struct iwatch *iw)
{
struct iwatch_path *iwp, *tmp;
TAILQ_FOREACH_SAFE(iwp, &iw->iwp_list, link, tmp) {
TAILQ_REMOVE(&iw->iwp_list, iwp, link);
inotify_rm_watch(iw->fd, iwp->wd);
free(iwp->path);
free(iwp);
}
close(iw->fd);
initialized = 0;
}
int iwatch_add(struct iwatch *iw, char *file, uint32_t mask)
{
struct iwatch_path *iwp;
char *path;
int wd;
if (!initialized)
return -1;
_d("Adding new watcher for path %s", file);
path = strdup(file);
if (!path) {
_pe("Out of memory");
return -1;
}
wd = inotify_add_watch(iw->fd, path, IWATCH_MASK | mask);
if (wd < 0) {
_pe("inotify_add_watch(%s)", path);
free(path);
return -1;
}
iwp = malloc(sizeof(struct iwatch_path));
if (!iwp) {
_pe("Failed allocating new `struct iwatch_path`");
inotify_rm_watch(iw->fd, wd);
free(path);
return -1;
}
iwp->path = path;
iwp->wd = wd;
TAILQ_INSERT_HEAD(&iw->iwp_list, iwp, link);
return 0;
}
int iwatch_del(struct iwatch *iw, struct iwatch_path *iwp)
{
if (!initialized)
return -1;
_d("Removing watcher for removed path %s", iwp->path);
TAILQ_REMOVE(&iw->iwp_list, iwp, link);
inotify_rm_watch(iw->fd, iwp->wd);
free(iwp->path);
free(iwp);
return 0;
}
struct iwatch_path *iwatch_find_by_wd(struct iwatch *iw, int wd)
{
struct iwatch_path *iwp;
if (!initialized)
return NULL;
TAILQ_FOREACH(iwp, &iw->iwp_list, link) {
if (iwp->wd == wd)
return iwp;
}
return NULL;
}
struct iwatch_path *iwatch_find_by_path(struct iwatch *iw, const char *path)
{
struct iwatch_path *iwp;
if (!initialized)
return NULL;
TAILQ_FOREACH(iwp, &iw->iwp_list, link) {
if (!strcmp(iwp->path, path))
return iwp;
}
return NULL;
}
/**
* Local Variables:
* indent-tabs-mode: t
* c-file-style: "linux"
* End:
*/
+64
View File
@@ -0,0 +1,64 @@
/* inotify watcher for files or directories
*
* Copyright (c) 2015-2016 Tobias Waldekranz <tobias@waldekranz.com>
* Copyright (c) 2016-2021 Joachim Wiberg <troglobit@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#ifndef FINIT_IWATCH_H_
#define FINIT_IWATCH_H_
#include <stdint.h>
#include <lite/queue.h>
#include <sys/inotify.h>
/* Monitors changes to both directories and files by default */
#define IWATCH_MASK (IN_CREATE | IN_DELETE | IN_MODIFY | IN_ATTRIB | IN_MOVE)
struct iwatch_path {
TAILQ_ENTRY(iwatch_path) link;
char *path;
int wd;
};
struct iwatch {
int fd;
TAILQ_HEAD(, iwatch_path) iwp_list;
};
int iwatch_init (struct iwatch *iw);
void iwatch_exit (struct iwatch *iw);
int iwatch_add (struct iwatch *iw, char *file, uint32_t mask);
int iwatch_del (struct iwatch *iw, struct iwatch_path *iwp);
struct iwatch_path *iwatch_find_by_wd (struct iwatch *iw, int wd);
struct iwatch_path *iwatch_find_by_path (struct iwatch *iw, const char *path);
#endif /* FINIT_IWATCH_H_ */
/**
* Local Variables:
* indent-tabs-mode: t
* c-file-style: "linux"
* End:
*/
+185 -13
View File
@@ -32,6 +32,7 @@
#include <sys/wait.h>
#include <net/if.h>
#include <lite/lite.h>
#include <wordexp.h>
#include "cgroup.h"
#include "conf.h"
@@ -261,6 +262,121 @@ static int redirect(svc_t *svc)
return 0;
}
/*
* non-zero env, no checking if file exists or not
*/
static char *svc_getenv(svc_t *svc)
{
int v = 0;
if (!svc->env[0])
return NULL;
if (svc->env[0] == '-')
v = 1;
return &svc->env[v];
}
/*
* Check if svc has env, if env file exists returns true
* if it doesn't exist, but has '-', also true. if svc
* doesn't have env, also true.
*/
static int check_env(svc_t *svc)
{
char *env = svc_getenv(svc);
if (!env)
return 1;
return fexist(env);
}
/*
* Source environment file, if it exists
* Note: must be called from privsepped child
*/
static void source_env(svc_t *svc)
{
char buf[LINE_SIZE];
char *line;
size_t len;
FILE *fp;
char *fn;
fn = svc_getenv(svc);
if (!fn)
return;
/* Warning in service_start() after check_env() */
fp = fopen(fn, "r");
if (!fp)
return;
line = buf;
len = sizeof(buf);
while (fgets(line, len, fp)) {
char *key = chomp(line);
char *value, *end;
/* skip any leading whitespace */
while (isspace(*key))
key++;
/* skip comments */
if (*key == '#' || *key == ';')
continue;
/* find end of line */
end = key;
while (*end)
end++;
/* strip trailing whitespace */
if (end > key) {
end--;
while (isspace(*end))
*end-- = 0;
}
value = strchr(key, '=');
if (!value)
continue;
*value++ = 0;
/* strip leading whitespace from value */
while (isspace(*value))
value++;
/* unquote value, if quoted */
if (value[0] == '"' || value[0] == '\'') {
char q = value[0];
if (*end == q) {
value = &value[1];
*end = 0;
}
}
/* find end of key */
end = key;
while (*end)
end++;
/* strip trailing whitespace */
if (end > key) {
end--;
while (isspace(*end))
*end-- = 0;
}
setenv(key, value, 1);
}
fclose(fp);
}
static int is_norespawn(void)
{
return sig_stopped() ||
@@ -277,9 +393,10 @@ static int is_norespawn(void)
*/
static int service_start(svc_t *svc)
{
int i, result = 0, do_progress = 1;
pid_t pid;
int result = 0, do_progress = 1;
sigset_t nmask, omask;
pid_t pid;
size_t i;
if (!svc)
return 1;
@@ -290,11 +407,17 @@ static int service_start(svc_t *svc)
/* Don't try and start service if it doesn't exist. */
if (!whichp(svc->cmd)) {
print(1, "Service %s does not exist", svc->cmd);
print(1, "%s: does not exist", svc->cmd);
svc_missing(svc);
return 1;
}
/* Unlike systemd we do not allow starting service if env is missing, unless - */
if (!check_env(svc)) {
print(1, "%s: environment file %s does not exist (yet)", svc->cmd, svc->env);
return 1;
}
if (svc_is_sysv(svc))
logit(LOG_CONSOLE | LOG_NOTICE, "Calling '%s start' ...", svc->cmd);
@@ -355,12 +478,45 @@ static int service_start(svc_t *svc)
}
}
/* Source any environment from env:/path/to/file */
source_env(svc);
if (!svc_is_sysv(svc)) {
wordexp_t we = { 0 };
int rc;
if ((rc = wordexp(svc->cmd, &we, 0))) {
nomem:
_e("%s: failed wordexp(): %d", svc->cmd, rc);
wordfree(&we);
_exit(1);
}
for (i = 0; i < MAX_NUM_SVC_ARGS; i++) {
if (strlen(svc->args[i]) == 0)
break;
if ((rc = wordexp(svc->args[i], &we, WRDE_APPEND)))
goto nomem;
}
if (we.we_wordc > MAX_NUM_SVC_ARGS) {
logit(LOG_ERR, "%s: too man args after expansion.", svc->cmd);
goto nomem;
}
for (i = 0; i < we.we_wordc; i++) {
if (strlen(we.we_wordv[i]) >= sizeof(svc->args[i])) {
logit(LOG_ERR, "%s: expanded arg. '%s' too long", we.we_wordv[i]);
rc = WRDE_NOSPACE;
goto nomem;
}
/* overwrite the child's svc with expanded args */
strlcpy(svc->args[i], we.we_wordv[i], sizeof(svc->args[i]));
args[i] = svc->args[i];
}
wordfree(&we);
} else {
i = 0;
args[i++] = svc->cmd;
@@ -372,12 +528,11 @@ static int service_start(svc_t *svc)
sig_unblock();
/*
* The setsid() call is the most humble of all in this
* function. It takes care to detach the process from
* its controlling terminal, preventing daemons from
* leaking to the console, and allowing us to run such
* programs like `lxc-start -F` in the foreground to
* properly monitor them.
* The setsid() call takes care to detach the process
* from its controlling terminal, preventing daemons
* from leaking to the console, and allowing us to run
* such programs like `lxc-start -F` in the foreground
* to properly monitor them.
*
* If you find yourself here wanting to fix the output
* to the console at boot, for debugging or similar,
@@ -386,9 +541,9 @@ static int service_start(svc_t *svc)
setsid();
if (svc_is_runtask(svc))
status = exec_runtask(svc->cmd, args);
status = exec_runtask(args[0], &args[1]);
else
status = execvp(svc->cmd, args);
status = execvp(args[0], &args[1]);
_exit(status);
} else if (debug) {
@@ -396,7 +551,7 @@ static int service_start(svc_t *svc)
for (i = 0; i < MAX_NUM_SVC_ARGS; i++) {
if (strlen(svc->args[i]) == 0)
continue;
break;
if (buf[0])
strlcat(buf, " ", sizeof(buf));
strlcat(buf, svc->args[i], sizeof(buf));
@@ -661,6 +816,19 @@ static void parse_log(svc_t *svc, char *arg)
}
}
static void parse_env(svc_t *svc, char *env)
{
if (!env)
return;
if (strlen(env) >= sizeof(svc->env)) {
_e("%s: env file is too long (>%d chars)", svc->cmd, sizeof(svc->env));
return;
}
strlcpy(svc->env, env, sizeof(svc->env));
}
static void parse_sighalt(svc_t *svc, char *arg)
{
int signo;
@@ -798,7 +966,7 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
char *cmd, *desc, *runlevels = NULL, *cond = NULL;
char *username = NULL, *log = NULL, *pid = NULL;
char *name = NULL, *halt = NULL, *delay = NULL;
char *id = NULL;
char *id = NULL, *env = NULL;
int levels = 0;
int manual = 0;
char *line;
@@ -860,6 +1028,8 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
halt = &cmd[5];
else if (!strncasecmp(cmd, "kill:", 5))
delay = &cmd[5];
else if (!strncasecmp(cmd, "env:", 4))
env = &cmd[4];
else
break;
@@ -925,6 +1095,8 @@ int service_register(int type, char *cfg, struct rlimit rlimit[], char *file)
parse_log(svc, log);
if (desc)
strlcpy(svc->desc, desc, sizeof(svc->desc));
if (env)
parse_env(svc, env);
/* Set configured limits */
memcpy(svc->rlimit, rlimit, sizeof(svc->rlimit));
+4 -23
View File
@@ -395,7 +395,7 @@ svc_t *svc_find_by_nameid(char *name, char *id)
}
/**
* svc_find_by_plidfile - Find an service object by its PID file
* svc_find_by_plidfile - Find a service by its PID file
* @fn: PID file, can be absolute path or relative to /run
*
* This function is primarily used by the pidfile plugin to track the
@@ -412,32 +412,13 @@ svc_t *svc_find_by_nameid(char *name, char *id)
svc_t *svc_find_by_pidfile(char *fn)
{
svc_t *svc, *iter = NULL;
char adjpath[strlen(fn) + 10]; /* + sizeof("/var/run/") */
char fnpath[PATH_MAX];
pid_t pid;
pid_runpath(fn, adjpath, sizeof(adjpath));
if (!realpath(adjpath, fnpath)) {
if (errno != ENOENT)
_pe("adjpath: %s, errno %d", adjpath, errno);
pid = pid_file_read(fn);
if (pid == -1)
return NULL;
}
for (svc = svc_iterator(&iter, 1); svc; svc = svc_iterator(&iter, 0)) {
char path[PATH_MAX];
char *pidfn;
pid_t pid;
pidfn = pid_file(svc);
if (!pidfn || !realpath(pidfn, path)) {
if (errno != ENOENT)
_pe("pidfn: %s, errno %d", pidfn ?: "<NULL>", errno);
continue;
}
if (!string_compare(fnpath, path))
continue;
pid = pid_file_read(path);
if (svc->pid != pid)
continue;
+1
View File
@@ -134,6 +134,7 @@ typedef struct svc {
char cmd[MAX_ARG_LEN];
char args[MAX_NUM_SVC_ARGS][MAX_ARG_LEN];
char desc[MAX_STR_LEN];
char env[MAX_ARG_LEN];
/*
* Used to forcefully kill services that won't shutdown on