mirror of
https://github.com/systemd/systemd.git
synced 2025-03-19 22:50:17 +03:00
Merge adf65b0d293afca0e938f5bb5c51b4afa2da48a2 into 104587314ff25a5c35390eeb42308f083e1e0488
This commit is contained in:
commit
fdb37b7ebe
@ -297,6 +297,9 @@ All tools:
|
||||
first existing unit listed in the environment variable, and
|
||||
`timedatectl set-ntp off` disables and stops all listed units.
|
||||
|
||||
* `$SYSTEMD_ETC_ADJTIME` - override the path to the hardware clock setting.
|
||||
The default is `/etc/adjtime`.
|
||||
|
||||
`systemd-sulogin-shell`:
|
||||
|
||||
* `$SYSTEMD_SULOGIN_FORCE=1` — This skips asking for the root password if the
|
||||
@ -779,3 +782,24 @@ Tools using the Varlink protocol (such as `varlinkctl`) or sd-bus (such as
|
||||
`systemd.factory_reset=` kernel command line option: if set to false,
|
||||
requesting a TPM clearing is skipped, and the command immediately exits
|
||||
successfully.
|
||||
|
||||
`systemd-timedated`, `systemd-firstboot`:
|
||||
|
||||
* `$SYSTEMD_ETC_LOCALTIME` - override the path to the timezone symlink. The
|
||||
default is `/etc/localtime`.
|
||||
|
||||
`systemd-hostnamed`, `systemd-firstboot`:
|
||||
|
||||
* `$SYSTEMD_ETC_HOSTNAME` - override the path to local system name
|
||||
configuration. The default is `/etc/hostname`.
|
||||
|
||||
* `$SYSTEMD_ETC_MACHINE_INFO` - override the path to the machine metadata. The
|
||||
default is `/etc/machine-info`.
|
||||
|
||||
`systemd-localed`, `systemd-firstboot`:
|
||||
|
||||
* `$SYSTEMD_ETC_LOCALE_CONF` - override the path to the system-wide locale
|
||||
configuration. The default is `/etc/locale.conf`.
|
||||
|
||||
* `$SYSTEMD_ETC_VCONSOLE_CONF` - override the path to the virtual console
|
||||
configuration. The default is `/etc/vconsole.conf`.
|
||||
|
@ -160,13 +160,21 @@ bool is_localhost(const char *hostname) {
|
||||
endswith_no_case(hostname, ".localhost.localdomain.");
|
||||
}
|
||||
|
||||
const char* etc_hostname(void) {
|
||||
return secure_getenv("SYSTEMD_ETC_HOSTNAME") ?: "/etc/hostname";
|
||||
}
|
||||
|
||||
const char* etc_machine_info(void) {
|
||||
return secure_getenv("SYSTEMD_ETC_MACHINE_INFO") ?: "/etc/machine-info";
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
|
@ -40,4 +40,7 @@ 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);
|
||||
|
@ -1605,19 +1605,27 @@ bool clock_supported(clockid_t clock) {
|
||||
}
|
||||
|
||||
int get_timezone(char **ret) {
|
||||
_cleanup_free_ char *t = NULL;
|
||||
_cleanup_free_ char *t = NULL, *link_dir = NULL, *abspath = NULL;
|
||||
int r;
|
||||
|
||||
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");
|
||||
if (r < 0)
|
||||
return r; /* Return EINVAL if not a symlink */
|
||||
|
||||
const char *e = PATH_STARTSWITH_SET(t, "/usr/share/zoneinfo/", "../usr/share/zoneinfo/");
|
||||
r = path_extract_directory(etc_localtime(), &link_dir);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
abspath = path_make_absolute(t, link_dir);
|
||||
if (!abspath)
|
||||
return -ENOMEM;
|
||||
|
||||
const char *e = path_startswith(abspath, "/usr/share/zoneinfo/");
|
||||
if (!e)
|
||||
return -EINVAL;
|
||||
if (!timezone_is_valid(e, LOG_DEBUG))
|
||||
@ -1626,6 +1634,10 @@ int get_timezone(char **ret) {
|
||||
return strdup_to(ret, e);
|
||||
}
|
||||
|
||||
const char* etc_localtime(void) {
|
||||
return secure_getenv("SYSTEMD_ETC_LOCALTIME") ?: "/etc/localtime";
|
||||
}
|
||||
|
||||
int mktime_or_timegm_usec(
|
||||
struct tm *tm, /* input + normalized output */
|
||||
bool utc,
|
||||
|
@ -176,6 +176,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);
|
||||
|
@ -428,7 +428,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;
|
||||
@ -465,7 +465,7 @@ 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
|
||||
|
@ -28,6 +28,7 @@
|
||||
#include "hostname-util.h"
|
||||
#include "kbd-util.h"
|
||||
#include "libcrypt-util.h"
|
||||
#include "locale-setup.h"
|
||||
#include "locale-util.h"
|
||||
#include "lock-util.h"
|
||||
#include "main-func.h"
|
||||
@ -400,7 +401,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)
|
||||
@ -417,7 +418,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");
|
||||
@ -507,7 +508,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)
|
||||
@ -524,7 +525,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");
|
||||
@ -604,13 +605,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, *link_dir = 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)
|
||||
@ -629,7 +630,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");
|
||||
@ -650,9 +651,15 @@ static int process_timezone(int rfd) {
|
||||
if (isempty(arg_timezone))
|
||||
return 0;
|
||||
|
||||
e = strjoina("../usr/share/zoneinfo/", arg_timezone);
|
||||
r = path_extract_directory(etc_localtime(), &link_dir);
|
||||
if (r < 0)
|
||||
return r;
|
||||
e = strjoina("/usr/share/zoneinfo/", arg_timezone);
|
||||
r = path_make_relative(link_dir, e, &relpath);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = symlinkat_atomic_full(e, pfd, f, /* make_relative= */ false);
|
||||
r = symlinkat_atomic_full(relpath, pfd, f, /* make_relative= */ false);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to create /etc/localtime symlink: %m");
|
||||
|
||||
@ -699,7 +706,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)
|
||||
@ -1215,12 +1222,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;
|
||||
|
@ -122,7 +122,7 @@ static void context_read_etc_hostname(Context *c) {
|
||||
|
||||
assert(c);
|
||||
|
||||
if (stat("/etc/hostname", ¤t_stat) >= 0 &&
|
||||
if (stat(etc_hostname(), ¤t_stat) >= 0 &&
|
||||
stat_inode_unmodified(&c->etc_hostname_stat, ¤t_stat))
|
||||
return;
|
||||
|
||||
@ -155,7 +155,7 @@ static void context_read_machine_info(Context *c) {
|
||||
|
||||
assert(c);
|
||||
|
||||
if (stat("/etc/machine-info", ¤t_stat) >= 0 &&
|
||||
if (stat(etc_machine_info(), ¤t_stat) >= 0 &&
|
||||
stat_inode_unmodified(&c->etc_machine_info_stat, ¤t_stat))
|
||||
return;
|
||||
|
||||
@ -168,7 +168,7 @@ static void context_read_machine_info(Context *c) {
|
||||
(UINT64_C(1) << PROP_HARDWARE_VENDOR) |
|
||||
(UINT64_C(1) << PROP_HARDWARE_MODEL));
|
||||
|
||||
r = parse_env_file(NULL, "/etc/machine-info",
|
||||
r = parse_env_file(NULL, etc_machine_info(),
|
||||
"PRETTY_HOSTNAME", &c->data[PROP_PRETTY_HOSTNAME],
|
||||
"ICON_NAME", &c->data[PROP_ICON_NAME],
|
||||
"CHASSIS", &c->data[PROP_CHASSIS],
|
||||
@ -749,14 +749,14 @@ static int context_write_data_static_hostname(Context *c) {
|
||||
s = &c->etc_hostname_stat;
|
||||
|
||||
if (isempty(c->data[PROP_STATIC_HOSTNAME])) {
|
||||
if (unlink("/etc/hostname") < 0 && errno != ENOENT)
|
||||
if (unlink(etc_hostname()) < 0 && errno != ENOENT)
|
||||
return -errno;
|
||||
|
||||
TAKE_PTR(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = write_string_file("/etc/hostname", c->data[PROP_STATIC_HOSTNAME], WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_LABEL);
|
||||
r = write_string_file(etc_hostname(), c->data[PROP_STATIC_HOSTNAME], WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_LABEL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -782,7 +782,7 @@ static int context_write_data_machine_info(Context *c) {
|
||||
* already, even if we can't make it hit the disk. */
|
||||
s = &c->etc_machine_info_stat;
|
||||
|
||||
r = load_env_file(NULL, "/etc/machine-info", &l);
|
||||
r = load_env_file(NULL, etc_machine_info(), &l);
|
||||
if (r < 0 && r != -ENOENT)
|
||||
return r;
|
||||
|
||||
@ -795,14 +795,14 @@ static int context_write_data_machine_info(Context *c) {
|
||||
}
|
||||
|
||||
if (strv_isempty(l)) {
|
||||
if (unlink("/etc/machine-info") < 0 && errno != ENOENT)
|
||||
if (unlink(etc_machine_info()) < 0 && errno != ENOENT)
|
||||
return -errno;
|
||||
|
||||
TAKE_PTR(s);
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = write_env_file_label(AT_FDCWD, "/etc/machine-info", NULL, l);
|
||||
r = write_env_file_label(AT_FDCWD, etc_machine_info(), NULL, l);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -1596,7 +1596,7 @@ static int build_describe_response(Context *c, bool privileged, sd_json_variant
|
||||
(void) vsock_get_local_cid(&local_cid);
|
||||
|
||||
(void) load_os_release_pairs(/* root= */ NULL, &os_release_pairs);
|
||||
(void) load_env_file_pairs(/* f=*/ NULL, "/etc/machine-info", &machine_info_pairs);
|
||||
(void) load_env_file_pairs(/* f=*/ NULL, etc_machine_info(), &machine_info_pairs);
|
||||
|
||||
r = sd_json_buildo(
|
||||
&v,
|
||||
|
@ -148,7 +148,7 @@ int vconsole_read_data(Context *c, sd_bus_message *m) {
|
||||
c->vc_cache = sd_bus_message_ref(m);
|
||||
}
|
||||
|
||||
fd = RET_NERRNO(open("/etc/vconsole.conf", O_CLOEXEC | O_PATH));
|
||||
fd = RET_NERRNO(open(etc_vconsole_conf(), O_CLOEXEC | O_PATH));
|
||||
if (fd == -ENOENT) {
|
||||
c->vc_stat = (struct stat) {};
|
||||
vc_context_clear(&c->vc);
|
||||
@ -170,7 +170,7 @@ int vconsole_read_data(Context *c, sd_bus_message *m) {
|
||||
x11_context_clear(&c->x11_from_vc);
|
||||
|
||||
r = parse_env_file_fd(
|
||||
fd, "/etc/vconsole.conf",
|
||||
fd, etc_vconsole_conf(),
|
||||
"KEYMAP", &c->vc.keymap,
|
||||
"KEYMAP_TOGGLE", &c->vc.toggle,
|
||||
"XKBLAYOUT", &c->x11_from_vc.layout,
|
||||
@ -286,6 +286,7 @@ int x11_read_data(Context *c, sd_bus_message *m) {
|
||||
}
|
||||
|
||||
int vconsole_write_data(Context *c) {
|
||||
const char* vconsole_conf_path;
|
||||
_cleanup_strv_free_ char **l = NULL;
|
||||
const X11Context *xc;
|
||||
int r;
|
||||
@ -294,7 +295,9 @@ int vconsole_write_data(Context *c) {
|
||||
|
||||
xc = context_get_x11_context(c);
|
||||
|
||||
r = load_env_file(NULL, "/etc/vconsole.conf", &l);
|
||||
vconsole_conf_path = etc_vconsole_conf();
|
||||
|
||||
r = load_env_file(NULL, vconsole_conf_path, &l);
|
||||
if (r < 0 && r != -ENOENT)
|
||||
return r;
|
||||
|
||||
@ -303,18 +306,18 @@ int vconsole_write_data(Context *c) {
|
||||
return r;
|
||||
|
||||
if (strv_isempty(l)) {
|
||||
if (unlink("/etc/vconsole.conf") < 0)
|
||||
if (unlink(vconsole_conf_path) < 0)
|
||||
return errno == ENOENT ? 0 : -errno;
|
||||
|
||||
c->vc_stat = (struct stat) {};
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = write_vconsole_conf_label(l);
|
||||
r = write_vconsole_conf_label(vconsole_conf_path, l);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (stat("/etc/vconsole.conf", &c->vc_stat) < 0)
|
||||
if (stat(vconsole_conf_path, &c->vc_stat) < 0)
|
||||
return -errno;
|
||||
|
||||
return 0;
|
||||
|
@ -20,14 +20,14 @@ int write_env_file_label(int dir_fd, const char *fname, char **headers, char **l
|
||||
return r;
|
||||
}
|
||||
|
||||
int write_vconsole_conf_label(char **l) {
|
||||
int write_vconsole_conf_label(const char* vconsole_conf_path, char **l) {
|
||||
int r;
|
||||
|
||||
r = mac_selinux_create_file_prepare("/etc/vconsole.conf", S_IFREG);
|
||||
r = mac_selinux_create_file_prepare(vconsole_conf_path, S_IFREG);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = write_vconsole_conf(AT_FDCWD, "/etc/vconsole.conf", l);
|
||||
r = write_vconsole_conf(AT_FDCWD, vconsole_conf_path, l);
|
||||
|
||||
mac_selinux_create_file_clear();
|
||||
|
||||
|
@ -7,4 +7,4 @@
|
||||
|
||||
int write_env_file_label(int dir_fd, const char *fname, char **headers, char **l);
|
||||
|
||||
int write_vconsole_conf_label(char **l);
|
||||
int write_vconsole_conf_label(const char* vconsole_conf_path, char **l);
|
||||
|
@ -142,7 +142,7 @@ int read_etc_hostname(const char *path, bool substitute_wildcards, char **ret) {
|
||||
assert(ret);
|
||||
|
||||
if (!path)
|
||||
path = "/etc/hostname";
|
||||
path = etc_hostname();
|
||||
|
||||
f = fopen(path, "re");
|
||||
if (!f)
|
||||
|
@ -64,7 +64,7 @@ static int locale_context_load_conf(LocaleContext *c, LocaleLoadFlag flag) {
|
||||
if (!FLAGS_SET(flag, LOCALE_LOAD_LOCALE_CONF))
|
||||
return 0;
|
||||
|
||||
fd = RET_NERRNO(open("/etc/locale.conf", O_CLOEXEC | O_PATH));
|
||||
fd = RET_NERRNO(open(etc_locale_conf(), O_CLOEXEC | O_PATH));
|
||||
if (fd == -ENOENT)
|
||||
return 0;
|
||||
if (fd < 0)
|
||||
@ -80,7 +80,7 @@ static int locale_context_load_conf(LocaleContext *c, LocaleLoadFlag flag) {
|
||||
c->st = st;
|
||||
locale_context_clear(c);
|
||||
|
||||
r = parse_env_file_fd(fd, "/etc/locale.conf",
|
||||
r = parse_env_file_fd(fd, etc_locale_conf(),
|
||||
"LANG", &c->locale[VARIABLE_LANG],
|
||||
"LANGUAGE", &c->locale[VARIABLE_LANGUAGE],
|
||||
"LC_CTYPE", &c->locale[VARIABLE_LC_CTYPE],
|
||||
@ -196,7 +196,7 @@ int locale_context_save(LocaleContext *c, char ***ret_set, char ***ret_unset) {
|
||||
return r;
|
||||
|
||||
if (strv_isempty(set)) {
|
||||
if (unlink("/etc/locale.conf") < 0)
|
||||
if (unlink(etc_locale_conf()) < 0)
|
||||
return errno == ENOENT ? 0 : -errno;
|
||||
|
||||
c->st = (struct stat) {};
|
||||
@ -208,11 +208,11 @@ int locale_context_save(LocaleContext *c, char ***ret_set, char ***ret_unset) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = write_env_file_label(AT_FDCWD, "/etc/locale.conf", NULL, set);
|
||||
r = write_env_file_label(AT_FDCWD, etc_locale_conf(), NULL, set);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (stat("/etc/locale.conf", &c->st) < 0)
|
||||
if (stat(etc_locale_conf(), &c->st) < 0)
|
||||
return -errno;
|
||||
|
||||
if (ret_set)
|
||||
@ -292,3 +292,11 @@ int locale_setup(char ***environment) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char* etc_locale_conf(void) {
|
||||
return secure_getenv("SYSTEMD_ETC_LOCALE_CONF") ?: "/etc/locale.conf";
|
||||
}
|
||||
|
||||
const char* etc_vconsole_conf(void) {
|
||||
return secure_getenv("SYSTEMD_ETC_VCONSOLE_CONF") ?: "/etc/vconsole.conf";
|
||||
}
|
||||
|
@ -27,3 +27,6 @@ void locale_context_take(LocaleContext *c, char *l[_VARIABLE_LC_MAX]);
|
||||
bool locale_context_equal(const LocaleContext *c, char *l[_VARIABLE_LC_MAX]);
|
||||
|
||||
int locale_setup(char ***environment);
|
||||
|
||||
const char* etc_locale_conf(void);
|
||||
const char* etc_vconsole_conf(void);
|
||||
|
@ -292,8 +292,9 @@ static int context_read_data(Context *c) {
|
||||
}
|
||||
|
||||
static int context_write_data_timezone(Context *c) {
|
||||
_cleanup_free_ char *p = NULL;
|
||||
const char *source;
|
||||
_cleanup_free_ char *p = NULL, *link_dir = NULL, *relpath = NULL;
|
||||
const char *source, *link_path;
|
||||
int r;
|
||||
|
||||
assert(c);
|
||||
|
||||
@ -306,22 +307,36 @@ static int context_write_data_timezone(Context *c) {
|
||||
|
||||
if (access("/usr/share/zoneinfo/UTC", F_OK) < 0) {
|
||||
|
||||
if (unlink("/etc/localtime") < 0 && errno != ENOENT)
|
||||
if (unlink(etc_localtime()) < 0 && errno != ENOENT)
|
||||
return -errno;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
source = "../usr/share/zoneinfo/UTC";
|
||||
source = "/usr/share/zoneinfo/UTC";
|
||||
} else {
|
||||
p = path_join("../usr/share/zoneinfo", c->zone);
|
||||
p = path_join("/usr/share/zoneinfo", c->zone);
|
||||
if (!p)
|
||||
return -ENOMEM;
|
||||
|
||||
source = p;
|
||||
}
|
||||
|
||||
return symlink_atomic(source, "/etc/localtime");
|
||||
link_path = etc_localtime();
|
||||
|
||||
r = path_extract_directory(link_path, &link_dir);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
r = path_make_relative(link_dir, source, &relpath);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return symlink_atomic(relpath, link_path);
|
||||
}
|
||||
|
||||
static const char *etc_adjtime(void) {
|
||||
return secure_getenv("SYSTEMD_ETC_ADJTIME") ?: "/etc/adjtime";
|
||||
}
|
||||
|
||||
static int context_write_data_local_rtc(Context *c) {
|
||||
@ -330,7 +345,7 @@ static int context_write_data_local_rtc(Context *c) {
|
||||
|
||||
assert(c);
|
||||
|
||||
r = read_full_file("/etc/adjtime", &s, NULL);
|
||||
r = read_full_file(etc_adjtime(), &s, NULL);
|
||||
if (r < 0) {
|
||||
if (r != -ENOENT)
|
||||
return r;
|
||||
@ -382,7 +397,7 @@ static int context_write_data_local_rtc(Context *c) {
|
||||
*mempcpy_typesafe(stpcpy(stpcpy(mempcpy(w, s, a), prepend), c->local_rtc ? "LOCAL" : "UTC"), e, b) = 0;
|
||||
|
||||
if (streq(w, NULL_ADJTIME_UTC)) {
|
||||
if (unlink("/etc/adjtime") < 0)
|
||||
if (unlink(etc_adjtime()) < 0)
|
||||
if (errno != ENOENT)
|
||||
return -errno;
|
||||
|
||||
@ -394,7 +409,7 @@ static int context_write_data_local_rtc(Context *c) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
return write_string_file("/etc/adjtime", w, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_LABEL);
|
||||
return write_string_file(etc_adjtime(), w, WRITE_STRING_FILE_CREATE|WRITE_STRING_FILE_ATOMIC|WRITE_STRING_FILE_LABEL);
|
||||
}
|
||||
|
||||
static int context_update_ntp_status(Context *c, sd_bus *bus, sd_bus_message *m) {
|
||||
|
@ -403,6 +403,46 @@ EOF
|
||||
rm -f /run/systemd/network/ntp99.*
|
||||
}
|
||||
|
||||
teardown_timedated_alternate_paths() {
|
||||
set +eu
|
||||
|
||||
rm -rf /run/systemd/system/systemd-timedated.service.d
|
||||
systemctl daemon-reload
|
||||
systemctl restart systemd-timedated
|
||||
}
|
||||
|
||||
testcase_timedated_alternate_paths() {
|
||||
trap teardown_timedated_alternate_paths RETURN
|
||||
|
||||
mkdir -p /run/alternate-path
|
||||
mkdir -p /run/systemd/system/systemd-timedated.service.d
|
||||
cat >/run/systemd/system/systemd-timedated.service.d/override.conf <<EOF
|
||||
[Service]
|
||||
Environment=SYSTEMD_ETC_LOCALTIME=/run/alternate-path/mylocaltime
|
||||
Environment=SYSTEMD_ETC_ADJTIME=/run/alternate-path/myadjtime
|
||||
EOF
|
||||
systemctl daemon-reload
|
||||
systemctl restart systemd-timedated
|
||||
|
||||
assert_in "Local time:" "$(timedatectl --no-pager)"
|
||||
|
||||
assert_eq "$(timedatectl --no-pager set-timezone Europe/Kyiv 2>&1)" ""
|
||||
assert_eq "$(readlink /run/alternate-path/mylocaltime | sed 's#^.*zoneinfo/##')" "Europe/Kyiv"
|
||||
assert_in "Time zone: Europe/Kyiv \(EES*T, \+0[0-9]00\)" "$(timedatectl)"
|
||||
|
||||
assert_in "RTC in local TZ: no" "$(timedatectl --no-pager)"
|
||||
assert_rc 0 timedatectl set-local-rtc 1
|
||||
assert_in "RTC in local TZ: yes" "$(timedatectl --no-pager)"
|
||||
assert_eq "$(cat /run/alternate-path/myadjtime)" "0.0 0 0
|
||||
0
|
||||
LOCAL"
|
||||
assert_rc 0 timedatectl set-local-rtc 0
|
||||
if [[ -e /run/alternate-path/myadjtime ]]; then
|
||||
echo "/run/alternate-path/myadjtime still exists" >&2
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
|
||||
run_testcases
|
||||
|
||||
touch /testok
|
||||
|
@ -278,6 +278,45 @@ test_wildcard() {
|
||||
hostnamectl set-hostname "$SAVED"
|
||||
}
|
||||
|
||||
teardown_hostnamed_alternate_paths() {
|
||||
set +eu
|
||||
|
||||
rm -rf /run/systemd/system/systemd-hostnamed.service.d
|
||||
systemctl daemon-reload
|
||||
systemctl restart systemd-hostnamed
|
||||
if [[ -f /etc/hostname ]]; then
|
||||
orig=$(cat /etc/hostname)
|
||||
if [[ -n "${orig}" ]]; then
|
||||
hostnamectl hostname "${orig}"
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
testcase_hostnamed_alternate_paths() {
|
||||
trap teardown_hostnamed_alternate_paths RETURN
|
||||
|
||||
mkdir -p /run/alternate-path
|
||||
|
||||
mkdir -p /run/systemd/system/systemd-hostnamed.service.d
|
||||
cat >/run/systemd/system/systemd-hostnamed.service.d/override.conf <<EOF
|
||||
[Service]
|
||||
Environment=SYSTEMD_ETC_HOSTNAME=/run/alternate-path/myhostname
|
||||
Environment=SYSTEMD_ETC_MACHINE_INFO=/run/alternate-path/mymachine-info
|
||||
EOF
|
||||
systemctl daemon-reload
|
||||
systemctl restart systemd-hostnamed
|
||||
|
||||
assert_rc 0 hostnamectl set-hostname heisenberg
|
||||
assert_rc 0 hostnamectl chassis watch
|
||||
|
||||
output=$(hostnamectl)
|
||||
assert_in "Static hostname: heisenberg" "$output"
|
||||
assert_in "Chassis: watch" "$output"
|
||||
assert_in "heisenberg" "$(cat /run/alternate-path/myhostname)"
|
||||
assert_in "CHASSIS=watch" "$(cat /run/alternate-path/mymachine-info)"
|
||||
}
|
||||
|
||||
|
||||
run_testcases
|
||||
|
||||
touch /testok
|
||||
|
@ -647,6 +647,53 @@ testcase_locale_gen_leading_space() {
|
||||
localectl set-locale en_US.UTF-8
|
||||
}
|
||||
|
||||
teardown_localed_alternate_paths() {
|
||||
set +eu
|
||||
|
||||
rm -rf /run/systemd/system/systemd-localed.service.d
|
||||
systemctl daemon-reload
|
||||
systemctl restart systemd-localed
|
||||
}
|
||||
|
||||
testcase_localed_alternate_paths() {
|
||||
trap teardown_localed_alternate_paths RETURN
|
||||
|
||||
mkdir -p /run/alternate-path
|
||||
|
||||
mkdir -p /run/systemd/system/systemd-localed.service.d
|
||||
cat >/run/systemd/system/systemd-localed.service.d/override.conf <<EOF
|
||||
[Service]
|
||||
Environment=SYSTEMD_ETC_LOCALE_CONF=/run/alternate-path/mylocale.conf
|
||||
Environment=SYSTEMD_ETC_VCONSOLE_CONF=/run/alternate-path/myvconsole.conf
|
||||
EOF
|
||||
systemctl daemon-reload
|
||||
systemctl restart systemd-localed
|
||||
|
||||
if localectl list-locales | grep "^de_DE.UTF-8$"; then
|
||||
assert_rc 0 localectl set-locale "LANG=de_DE.UTF-8" "LC_CTYPE=C"
|
||||
else
|
||||
skip_locale=1
|
||||
fi
|
||||
|
||||
if localectl list-keymaps | grep -F "^no$"; then
|
||||
assert_rc 0 localectl set-keymap "no"
|
||||
else
|
||||
skip_keymap=1
|
||||
fi
|
||||
|
||||
output=$(localectl)
|
||||
|
||||
if [[ -z "${skip_locale-}" ]]; then
|
||||
assert_in "System Locale: LANG=de_DE.UTF-8" "$output"
|
||||
assert_in "LANG=de_DE.UTF-8" "$(cat /run/alternate-path/mylocale.conf)"
|
||||
fi
|
||||
|
||||
if [[ -z "${skip_keymap-}" ]]; then
|
||||
assert_in "VC Keymap: no" "$output"
|
||||
assert_in "KEYMAP=no" "$(cat /run/alternate-path/myvconsole.conf)"
|
||||
fi
|
||||
}
|
||||
|
||||
# Make sure the content of kbd-model-map is the one that the tests expect
|
||||
# regardless of the version installed on the distro where the testsuite is
|
||||
# running on.
|
||||
|
@ -18,6 +18,10 @@ at_exit() {
|
||||
rm -fr "$ROOT"
|
||||
fi
|
||||
|
||||
if [[ -d /etc/otherpath ]]; then
|
||||
rm -rf /etc/otherpath
|
||||
fi
|
||||
|
||||
restore_locale
|
||||
}
|
||||
|
||||
@ -282,3 +286,36 @@ rm -fv "$ROOT/etc/passwd" "$ROOT/etc/shadow"
|
||||
(! systemd-firstboot --root="$ROOT" --root-shell=/bin/nonexistentshell)
|
||||
(! systemd-firstboot --root="$ROOT" --machine-id=invalidmachineid)
|
||||
(! systemd-firstboot --root="$ROOT" --timezone=Foo/Bar)
|
||||
|
||||
mkdir -p "${ROOT}/etc/otherpath"
|
||||
mkdir -p /etc/otherpath
|
||||
echo "KEYMAP=us" >/etc/otherpath/vconsole.conf
|
||||
echo "LANG=en_US.UTF-8" >/etc/otherpath/locale.conf
|
||||
ln -s "../$(readlink /etc/localtime)" /etc/otherpath/localtime
|
||||
|
||||
SYSTEMD_ETC_LOCALE_CONF=/etc/otherpath/locale.conf \
|
||||
SYSTEMD_ETC_VCONSOLE_CONF=/etc/otherpath/vconsole.conf \
|
||||
SYSTEMD_ETC_LOCALTIME=/etc/otherpath/localtime \
|
||||
SYSTEMD_ETC_HOSTNAME=/etc/otherpath/hostname \
|
||||
systemd-firstboot --root="$ROOT" --copy-locale --copy-keymap --copy-timezone --hostname="weirdpaths"
|
||||
|
||||
diff "${ROOT}/etc/otherpath/locale.conf" "/etc/otherpath/locale.conf"
|
||||
diff "${ROOT}/etc/otherpath/vconsole.conf" "/etc/otherpath/vconsole.conf"
|
||||
grep -q "weirdpaths" "${ROOT}/etc/otherpath/hostname"
|
||||
|
||||
[[ "$(readlink /etc/otherpath/localtime)" = "$(readlink "${ROOT}/etc/otherpath/localtime")" ]]
|
||||
|
||||
SYSTEMD_ETC_LOCALE_CONF=/etc/otherpath/locale.conf \
|
||||
SYSTEMD_ETC_VCONSOLE_CONF=/etc/otherpath/vconsole.conf \
|
||||
SYSTEMD_ETC_LOCALTIME=/etc/otherpath/localtime \
|
||||
SYSTEMD_ETC_HOSTNAME=/etc/otherpath/hostname \
|
||||
systemd-firstboot --root="$ROOT" --force \
|
||||
--hostname="weirdpaths2" \
|
||||
--locale=no_NO.UTF-8 \
|
||||
--keymap=no \
|
||||
--timezone=Europe/Oslo
|
||||
|
||||
grep -q "LANG=no_NO.UTF-8" "${ROOT}/etc/otherpath/locale.conf"
|
||||
grep -q "KEYMAP=no" "${ROOT}/etc/otherpath/vconsole.conf"
|
||||
grep -q "weirdpaths2" "${ROOT}/etc/otherpath/hostname"
|
||||
[[ "$(readlink "${ROOT}/etc/otherpath/localtime")" = "../../usr/share/zoneinfo/Europe/Oslo" ]]
|
||||
|
Loading…
x
Reference in New Issue
Block a user