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
+10
-4
@@ -420,7 +420,7 @@ static int manager_read_timezone_stat(Manager *m) {
|
||||
assert(m);
|
||||
|
||||
/* Read the current stat() data of /etc/localtime so that we detect changes */
|
||||
if (lstat("/etc/localtime", &st) < 0) {
|
||||
if (lstat(etc_localtime(), &st) < 0) {
|
||||
log_debug_errno(errno, "Failed to stat /etc/localtime, ignoring: %m");
|
||||
changed = m->etc_localtime_accessible;
|
||||
m->etc_localtime_accessible = false;
|
||||
@@ -457,14 +457,20 @@ static int manager_setup_timezone_change(Manager *m) {
|
||||
* Note that we create the new event source first here, before releasing the old one. This should optimize
|
||||
* behaviour as this way sd-event can reuse the old watch in case the inode didn't change. */
|
||||
|
||||
r = sd_event_add_inotify(m->event, &new_event, "/etc/localtime",
|
||||
r = sd_event_add_inotify(m->event, &new_event, etc_localtime(),
|
||||
IN_ATTRIB|IN_MOVE_SELF|IN_CLOSE_WRITE|IN_DONT_FOLLOW, manager_dispatch_timezone_change, m);
|
||||
if (r == -ENOENT) {
|
||||
/* If the file doesn't exist yet, subscribe to /etc instead, and wait until it is created either by
|
||||
* O_CREATE or by rename() */
|
||||
_cleanup_free_ char *localtime_dir = NULL;
|
||||
|
||||
log_debug_errno(r, "/etc/localtime doesn't exist yet, watching /etc instead.");
|
||||
r = sd_event_add_inotify(m->event, &new_event, "/etc",
|
||||
int dir_r = path_extract_directory(etc_localtime(), &localtime_dir);
|
||||
if (dir_r < 0)
|
||||
return log_error_errno(dir_r, "Failed to extract directory from path '%s': %m", etc_localtime());
|
||||
|
||||
log_debug_errno(r, "%s doesn't exist yet, watching %s instead.", etc_localtime(), localtime_dir);
|
||||
|
||||
r = sd_event_add_inotify(m->event, &new_event, localtime_dir,
|
||||
IN_CREATE|IN_MOVED_TO|IN_ONLYDIR, manager_dispatch_timezone_change, m);
|
||||
}
|
||||
if (r < 0)
|
||||
|
||||
Reference in New Issue
Block a user