Use paths specified from environment variables for /etc configuration files
Some configuration files that need updates are directly under in /etc. To update them atomically, we need write access to /etc. For Ubuntu Core this is an issue as /etc is not writable. Only a selection of subdirectories can be writable. The general solution is symlinks or bind mounts to writable places. But for atomic writes in /etc, that does not work. So Ubuntu has had a patch for that that did not age well. Instead we would like to introduce some environment variables for alternate paths. * SYSTEMD_ETC_HOSTNAME: /etc/hostname * SYSTEMD_ETC_MACHINE_INFO: /etc/machine-info * SYSTEMD_ETC_LOCALTIME: /etc/localtime * SYSTEMD_ETC_LOCALE_CONF: /etc/locale.conf * SYSTEMD_ETC_VCONSOLE_CONF: /etc/vconsole.conf * SYSTEMD_ETC_ADJTIME: /etc/adjtime While it is for now expected that there is a symlink from the standard, we still try to read them from that alternate path. This is important for `/etc/localtime`, which is a symlink, so we cannot have an indirect symlink or bind mount for it. Since machine-id is typically written only once and not updated. This commit does not cover it. An initrd can properly create it and bind mount it.
This commit is contained in:
committed by
Lennart Poettering
parent
fa34fda2eb
commit
0dc39dffbd
@@ -157,13 +157,31 @@ bool is_localhost(const char *hostname) {
|
||||
endswith_no_case(hostname, ".localhost.localdomain.");
|
||||
}
|
||||
|
||||
const char* etc_hostname(void) {
|
||||
static const char *cached = NULL;
|
||||
|
||||
if (!cached)
|
||||
cached = secure_getenv("SYSTEMD_ETC_HOSTNAME") ?: "/etc/hostname";
|
||||
|
||||
return cached;
|
||||
}
|
||||
|
||||
const char* etc_machine_info(void) {
|
||||
static const char *cached = NULL;
|
||||
|
||||
if (!cached)
|
||||
cached = secure_getenv("SYSTEMD_ETC_MACHINE_INFO") ?: "/etc/machine-info";
|
||||
|
||||
return cached;
|
||||
}
|
||||
|
||||
int get_pretty_hostname(char **ret) {
|
||||
_cleanup_free_ char *n = NULL;
|
||||
int r;
|
||||
|
||||
assert(ret);
|
||||
|
||||
r = parse_env_file(NULL, "/etc/machine-info", "PRETTY_HOSTNAME", &n);
|
||||
r = parse_env_file(NULL, etc_machine_info(), "PRETTY_HOSTNAME", &n);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
|
||||
@@ -37,6 +37,9 @@ static inline bool is_dns_proxy_stub_hostname(const char *hostname) {
|
||||
return STRCASE_IN_SET(hostname, "_localdnsproxy", "_localdnsproxy.");
|
||||
}
|
||||
|
||||
const char* etc_hostname(void);
|
||||
const char* etc_machine_info(void);
|
||||
|
||||
int get_pretty_hostname(char **ret);
|
||||
|
||||
int machine_spec_valid(const char *s);
|
||||
|
||||
+10
-1
@@ -1607,7 +1607,7 @@ int get_timezone(char **ret) {
|
||||
|
||||
assert(ret);
|
||||
|
||||
r = readlink_malloc("/etc/localtime", &t);
|
||||
r = readlink_malloc(etc_localtime(), &t);
|
||||
if (r == -ENOENT)
|
||||
/* If the symlink does not exist, assume "UTC", like glibc does */
|
||||
return strdup_to(ret, "UTC");
|
||||
@@ -1623,6 +1623,15 @@ int get_timezone(char **ret) {
|
||||
return strdup_to(ret, e);
|
||||
}
|
||||
|
||||
const char* etc_localtime(void) {
|
||||
static const char *cached = NULL;
|
||||
|
||||
if (!cached)
|
||||
cached = secure_getenv("SYSTEMD_ETC_LOCALTIME") ?: "/etc/localtime";
|
||||
|
||||
return cached;
|
||||
}
|
||||
|
||||
int mktime_or_timegm_usec(
|
||||
struct tm *tm, /* input + normalized output */
|
||||
bool utc,
|
||||
|
||||
@@ -168,6 +168,7 @@ bool clock_supported(clockid_t clock);
|
||||
usec_t usec_shift_clock(usec_t, clockid_t from, clockid_t to);
|
||||
|
||||
int get_timezone(char **ret);
|
||||
const char* etc_localtime(void);
|
||||
|
||||
int mktime_or_timegm_usec(struct tm *tm, bool utc, usec_t *ret);
|
||||
int localtime_or_gmtime_usec(usec_t t, bool utc, struct tm *ret);
|
||||
|
||||
Reference in New Issue
Block a user