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
+18
-14
@@ -31,6 +31,7 @@
|
||||
#include "label.h"
|
||||
#include "label-util.h"
|
||||
#include "libcrypt-util.h"
|
||||
#include "locale-setup.h"
|
||||
#include "locale-util.h"
|
||||
#include "lock-util.h"
|
||||
#include "loop-util.h"
|
||||
@@ -408,7 +409,7 @@ static int process_locale(int rfd) {
|
||||
|
||||
assert(rfd >= 0);
|
||||
|
||||
pfd = chase_and_open_parent_at(rfd, "/etc/locale.conf",
|
||||
pfd = chase_and_open_parent_at(rfd, etc_locale_conf(),
|
||||
CHASE_AT_RESOLVE_IN_ROOT|CHASE_MKDIR_0755|CHASE_WARN|CHASE_NOFOLLOW,
|
||||
&f);
|
||||
if (pfd < 0)
|
||||
@@ -425,7 +426,7 @@ static int process_locale(int rfd) {
|
||||
return log_error_errno(r, "Failed to check if directory file descriptor is root: %m");
|
||||
|
||||
if (arg_copy_locale && r == 0) {
|
||||
r = copy_file_atomic_at(AT_FDCWD, "/etc/locale.conf", pfd, f, 0644, COPY_REFLINK);
|
||||
r = copy_file_atomic_at(AT_FDCWD, etc_locale_conf(), pfd, f, 0644, COPY_REFLINK);
|
||||
if (r != -ENOENT) {
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to copy host's /etc/locale.conf: %m");
|
||||
@@ -520,7 +521,7 @@ static int process_keymap(int rfd) {
|
||||
|
||||
assert(rfd >= 0);
|
||||
|
||||
pfd = chase_and_open_parent_at(rfd, "/etc/vconsole.conf",
|
||||
pfd = chase_and_open_parent_at(rfd, etc_vconsole_conf(),
|
||||
CHASE_AT_RESOLVE_IN_ROOT|CHASE_MKDIR_0755|CHASE_WARN|CHASE_NOFOLLOW,
|
||||
&f);
|
||||
if (pfd < 0)
|
||||
@@ -537,7 +538,7 @@ static int process_keymap(int rfd) {
|
||||
return log_error_errno(r, "Failed to check if directory file descriptor is root: %m");
|
||||
|
||||
if (arg_copy_keymap && r == 0) {
|
||||
r = copy_file_atomic_at(AT_FDCWD, "/etc/vconsole.conf", pfd, f, 0644, COPY_REFLINK);
|
||||
r = copy_file_atomic_at(AT_FDCWD, etc_vconsole_conf(), pfd, f, 0644, COPY_REFLINK);
|
||||
if (r != -ENOENT) {
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to copy host's /etc/vconsole.conf: %m");
|
||||
@@ -617,13 +618,13 @@ static int prompt_timezone(int rfd) {
|
||||
|
||||
static int process_timezone(int rfd) {
|
||||
_cleanup_close_ int pfd = -EBADF;
|
||||
_cleanup_free_ char *f = NULL;
|
||||
_cleanup_free_ char *f = NULL, *relpath = NULL;
|
||||
const char *e;
|
||||
int r;
|
||||
|
||||
assert(rfd >= 0);
|
||||
|
||||
pfd = chase_and_open_parent_at(rfd, "/etc/localtime",
|
||||
pfd = chase_and_open_parent_at(rfd, etc_localtime(),
|
||||
CHASE_AT_RESOLVE_IN_ROOT|CHASE_MKDIR_0755|CHASE_WARN|CHASE_NOFOLLOW,
|
||||
&f);
|
||||
if (pfd < 0)
|
||||
@@ -642,7 +643,7 @@ static int process_timezone(int rfd) {
|
||||
if (arg_copy_timezone && r == 0) {
|
||||
_cleanup_free_ char *s = NULL;
|
||||
|
||||
r = readlink_malloc("/etc/localtime", &s);
|
||||
r = readlink_malloc(etc_localtime(), &s);
|
||||
if (r != -ENOENT) {
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to read host's /etc/localtime: %m");
|
||||
@@ -663,9 +664,12 @@ static int process_timezone(int rfd) {
|
||||
if (isempty(arg_timezone))
|
||||
return 0;
|
||||
|
||||
e = strjoina("../usr/share/zoneinfo/", arg_timezone);
|
||||
e = strjoina("/usr/share/zoneinfo/", arg_timezone);
|
||||
r = path_make_relative_parent(etc_localtime(), e, &relpath);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = symlinkat_atomic_full(e, pfd, f, SYMLINK_LABEL);
|
||||
r = symlinkat_atomic_full(relpath, pfd, f, SYMLINK_LABEL);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to create /etc/localtime symlink: %m");
|
||||
|
||||
@@ -712,7 +716,7 @@ static int process_hostname(int rfd) {
|
||||
|
||||
assert(rfd >= 0);
|
||||
|
||||
pfd = chase_and_open_parent_at(rfd, "/etc/hostname",
|
||||
pfd = chase_and_open_parent_at(rfd, etc_hostname(),
|
||||
CHASE_AT_RESOLVE_IN_ROOT|CHASE_MKDIR_0755|CHASE_WARN,
|
||||
&f);
|
||||
if (pfd < 0)
|
||||
@@ -1228,12 +1232,12 @@ static int process_reset(int rfd) {
|
||||
return 0;
|
||||
|
||||
FOREACH_STRING(p,
|
||||
"/etc/locale.conf",
|
||||
"/etc/vconsole.conf",
|
||||
"/etc/hostname",
|
||||
etc_locale_conf(),
|
||||
etc_vconsole_conf(),
|
||||
etc_hostname(),
|
||||
"/etc/machine-id",
|
||||
"/etc/kernel/cmdline",
|
||||
"/etc/localtime") {
|
||||
etc_localtime()) {
|
||||
r = reset_one(rfd, p);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
Reference in New Issue
Block a user