Skip to content

Commit

Permalink
librc, rc, supervise-daemon: Repace hardcoded paths with function calls.
Browse files Browse the repository at this point in the history
This lays the groundwork for other features like user services, or
a different root prefix, by allowing us to change where openrc looks up
for files at runtime.

As a side effect of this change, now all sysconfdirs (aka RC_PKG_PREFIX
and RC_LOCAL_PREFIX) are checked for configuration files (rc.conf and
rc.conf.d).
  • Loading branch information
navi-desu committed Sep 20, 2024
1 parent 171ba6d commit 089f500
Show file tree
Hide file tree
Showing 11 changed files with 368 additions and 258 deletions.
8 changes: 4 additions & 4 deletions src/librc/librc-daemon.c
Original file line number Diff line number Diff line change
Expand Up @@ -411,7 +411,7 @@ rc_service_daemon_set(const char *service, const char *exec,
return false;
}

xasprintf(&dirpath, RC_SVCDIR "/daemons/%s", basename_c(service));
xasprintf(&dirpath, "%s/daemons/%s", rc_service_dir(), basename_c(service));

/* Regardless, erase any existing daemon info */
if ((dp = opendir(dirpath))) {
Expand Down Expand Up @@ -491,7 +491,7 @@ rc_service_started_daemon(const char *service,
if (!service || !exec)
return false;

xasprintf(&dirpath, RC_SVCDIR "/daemons/%s", basename_c(service));
xasprintf(&dirpath, "%s/daemons/%s", rc_service_dir(), basename_c(service));
match = _match_list(exec, argv, NULL);

if (indx > 0) {
Expand Down Expand Up @@ -543,8 +543,8 @@ rc_service_daemons_crashed(const char *service)
char *ch_root;
char *spidfile;

path += snprintf(dirpath, sizeof(dirpath), RC_SVCDIR "/daemons/%s",
basename_c(service));
path += snprintf(dirpath, sizeof(dirpath),
"%s/daemons/%s", rc_service_dir(), basename_c(service));

if (!(dp = opendir(dirpath)))
return false;
Expand Down
97 changes: 55 additions & 42 deletions src/librc/librc-depend.c
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@

#define GENDEP RC_LIBEXECDIR "/sh/gendepends.sh"

#define RC_DEPCONFIG RC_SVCDIR "/depconfig"

static const char *bootlevel = NULL;

static char *
Expand Down Expand Up @@ -149,7 +147,14 @@ make_deptree(void) {

RC_DEPTREE *
rc_deptree_load(void) {
return rc_deptree_load_file(RC_DEPTREE_CACHE);
char *deptree_cache;
RC_DEPTREE *deptree;

xasprintf(&deptree_cache, "%s/deptree", rc_service_dir());
deptree = rc_deptree_load_file(deptree_cache);
free(deptree_cache);

return deptree;
}

RC_DEPTREE *
Expand Down Expand Up @@ -689,19 +694,19 @@ static const DEPPAIR deppairs[] = {

static const char *const depdirs[] =
{
RC_SVCDIR,
RC_SVCDIR "/starting",
RC_SVCDIR "/started",
RC_SVCDIR "/stopping",
RC_SVCDIR "/inactive",
RC_SVCDIR "/wasinactive",
RC_SVCDIR "/failed",
RC_SVCDIR "/hotplugged",
RC_SVCDIR "/daemons",
RC_SVCDIR "/options",
RC_SVCDIR "/exclusive",
RC_SVCDIR "/scheduled",
RC_SVCDIR "/tmp",
"",
"starting",
"started",
"stopping",
"inactive",
"wasinactive",
"failed",
"hotplugged",
"daemons",
"options",
"exclusive",
"scheduled",
"tmp",
NULL
};

Expand All @@ -714,16 +719,23 @@ rc_deptree_update_needed(time_t *newest, char *file)
int i;
struct stat buf;
time_t mtime;
char *dir;
char *deptree_cache, *depconfig;
const char *service_dir = rc_service_dir();

/* Create base directories if needed */
for (i = 0; depdirs[i]; i++)
if (mkdir(depdirs[i], 0755) != 0 && errno != EEXIST)
for (i = 0; depdirs[i]; i++) {
xasprintf(&dir, "%s/%s", service_dir, depdirs[i]);
if (mkdir(dir, 0755) != 0 && errno != EEXIST)
fprintf(stderr, "mkdir `%s': %s\n", depdirs[i], strerror(errno));
free(dir);
}

/* Quick test to see if anything we use has changed and we have
* data in our deptree. */

if (stat(RC_DEPTREE_CACHE, &buf) == 0) {
xasprintf(&deptree_cache, "%s/deptree", service_dir);
if (stat(deptree_cache, &buf) == 0) {
mtime = buf.st_mtime;
} else {
/* No previous cache found.
Expand All @@ -733,30 +745,27 @@ rc_deptree_update_needed(time_t *newest, char *file)
newer = true;
mtime = time(NULL);
}

newer |= !deep_mtime_check(RC_INITDIR,true,&mtime,file);
newer |= !deep_mtime_check(RC_CONFDIR,true,&mtime,file);
#ifdef RC_PKG_INITDIR
newer |= !deep_mtime_check(RC_PKG_INITDIR,true,&mtime,file);
#endif
#ifdef RC_PKG_CONFDIR
newer |= !deep_mtime_check(RC_PKG_CONFDIR,true,&mtime,file);
#endif
#ifdef RC_LOCAL_INITDIRs
newer |= !deep_mtime_check(RC_LOCAL_INITDIR,true,&mtime,file);
#endif
#ifdef RC_LOCAL_CONFDIR
newer |= !deep_mtime_check(RC_LOCAL_CONFDIR,true,&mtime,file);
#endif
newer |= !deep_mtime_check(RC_CONF,true,&mtime,file);
free(deptree_cache);

for (const char * const *dirs = rc_sysconf_dirs(); *dirs; dirs++) {
static const char *subdirs[] = { "init.d", "conf.d", "rc.conf", NULL };
for (const char **subdir = subdirs; *subdir; subdir++) {
char *path;
xasprintf(&path, "%s/%s", *dirs, *subdir);
newer |= !deep_mtime_check(path, true, &mtime, file);
free(path);
}
}

/* Some init scripts dependencies change depending on config files
* outside of baselayout, like syslog-ng, so we check those too. */
config = rc_config_list(RC_DEPCONFIG);
xasprintf(&depconfig, "%s/depconfig", service_dir);
config = rc_config_list(depconfig);
TAILQ_FOREACH(s, config, entries) {
newer |= !deep_mtime_check(s->value, true, &mtime, file);
}
rc_stringlist_free(config);
free(depconfig);

/* Return newest file time, if requested */
if ((newer) && (newest != NULL)) {
Expand Down Expand Up @@ -791,6 +800,7 @@ rc_deptree_update(void)
size_t len = 0;
ssize_t size;
char *depend, *depends, *service, *type;
char *deptree_cache, *depconfig;
size_t i, l;
bool retval = true;
const char *sys = rc_sys();
Expand Down Expand Up @@ -1051,7 +1061,8 @@ rc_deptree_update(void)
This works and should be entirely shell parseable provided that depend
names don't have any non shell variable characters in
*/
if ((fp = fopen(RC_DEPTREE_CACHE, "w"))) {
xasprintf(&deptree_cache, "%s/deptree", rc_service_dir());
if ((fp = fopen(deptree_cache, "w"))) {
i = 0;
TAILQ_FOREACH(depinfo, deptree, entries) {
fprintf(fp, "depinfo_%zu_service='%s'\n", i, depinfo->service);
Expand All @@ -1066,24 +1077,26 @@ rc_deptree_update(void)
}
fclose(fp);
} else {
fprintf(stderr, "fopen `%s': %s\n",
RC_DEPTREE_CACHE, strerror(errno));
fprintf(stderr, "fopen '%s': %s\n", deptree_cache, strerror(errno));
retval = false;
}
free(deptree_cache);

/* Save our external config files to disk */
xasprintf(&depconfig, "%s/depconfig", rc_service_dir());
if (TAILQ_FIRST(config)) {
if ((fp = fopen(RC_DEPCONFIG, "w"))) {
if ((fp = fopen(depconfig, "w"))) {
TAILQ_FOREACH(s, config, entries)
fprintf(fp, "%s\n", s->value);
fclose(fp);
} else {
fprintf(stderr, "fopen `%s': %s\n", RC_DEPCONFIG, strerror(errno));
fprintf(stderr, "fopen '%s': %s\n", depconfig, strerror(errno));
retval = false;
}
} else {
unlink(RC_DEPCONFIG);
unlink(depconfig);
}
free(depconfig);

rc_stringlist_free(config);
rc_deptree_free(deptree);
Expand Down
65 changes: 41 additions & 24 deletions src/librc/librc-misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ static RC_STRINGLIST *rc_config_kcl(RC_STRINGLIST *config)
return config;
}

static RC_STRINGLIST * rc_config_directory(RC_STRINGLIST *config)
static RC_STRINGLIST * rc_config_directory(RC_STRINGLIST *config, char *dir)
{
DIR *dp;
struct dirent *d;
Expand All @@ -337,7 +337,7 @@ static RC_STRINGLIST * rc_config_directory(RC_STRINGLIST *config)
char path[PATH_MAX];
RC_STRING *line;

if ((dp = opendir(RC_CONF_D)) != NULL) {
if ((dp = opendir(dir)) != NULL) {
rc_conf_d_files = rc_stringlist_new();
while ((d = readdir(dp)) != NULL) {
if (fnmatch("*.conf", d->d_name, FNM_PATHNAME) == 0) {
Expand All @@ -350,7 +350,7 @@ static RC_STRINGLIST * rc_config_directory(RC_STRINGLIST *config)
TAILQ_FOREACH(fname, rc_conf_d_files, entries) {
if (!fname->value)
continue;
sprintf(path, "%s/%s", RC_CONF_D, fname->value);
sprintf(path, "%s/%s", dir, fname->value);
rc_conf_d_list = rc_config_list(path);
TAILQ_FOREACH(line, rc_conf_d_list, entries)
if (line->value)
Expand Down Expand Up @@ -409,35 +409,52 @@ _free_rc_conf(void)
rc_stringlist_free(rc_conf);
}

static inline void
rc_conf_append(const char *file)
{
RC_STRINGLIST *conf = rc_config_load(file);
TAILQ_CONCAT(rc_conf, conf, entries);
rc_stringlist_free(conf);
}

char *
rc_conf_value(const char *setting)
{
RC_STRINGLIST *old;
RC_STRING *s;
char *p;

if (!rc_conf) {
rc_conf = rc_config_load(RC_CONF);
atexit(_free_rc_conf);
if (rc_conf)
return rc_config_value(rc_conf, setting);

/* Support old configs. */
if (exists(RC_CONF_OLD)) {
old = rc_config_load(RC_CONF_OLD);
TAILQ_CONCAT(rc_conf, old, entries);
rc_stringlist_free(old);
}
rc_conf = rc_stringlist_new();
atexit(_free_rc_conf);

rc_conf = rc_config_directory(rc_conf);
rc_conf = rc_config_kcl(rc_conf);
for (const char * const *dirs = rc_sysconf_dirs(); *dirs; dirs++) {
char *conf;
xasprintf(&conf, "%s/%s", *dirs, "rc.conf");
rc_conf_append(conf);
free(conf);
}

/* Convert old uppercase to lowercase */
TAILQ_FOREACH(s, rc_conf, entries) {
p = s->value;
while (p && *p && *p != '=') {
if (isupper((unsigned char)*p))
*p = tolower((unsigned char)*p);
p++;
}
/* Support old configs. */
if (exists(RC_CONF_OLD))
rc_conf_append(RC_CONF_OLD);

for (const char * const *dirs = rc_sysconf_dirs(); *dirs; dirs++) {
char *conf;
xasprintf(&conf, "%s/%s", *dirs, "rc.conf.d");
rc_conf = rc_config_directory(rc_conf, conf);
free(conf);
}

rc_conf = rc_config_kcl(rc_conf);

/* Convert old uppercase to lowercase */
TAILQ_FOREACH(s, rc_conf, entries) {
char *p = s->value;
while (p && *p && *p != '=') {
if (isupper((unsigned char)*p))
*p = tolower((unsigned char)*p);
p++;
}
}

Expand Down
Loading

0 comments on commit 089f500

Please sign in to comment.