1
0
mirror of https://github.com/systemd/systemd.git synced 2025-02-15 09:57:39 +03:00

hostname: re-read file later when failed to update file

Previously, even when writing e.g. /etc/hostname fails, the static
hostname in Context is not restored. So, the subsequent call of the same
method succeeds:
```
$ sudo chattr +i /etc/hostname
$ sudo hostnamectl --static set-hostname aaa
Could not set static hostname: Access denied
$ echo $?
1
$ sudo hostnamectl --static set-hostname aaa
$ echo $?
0
```

This makes when updating file is failed, the saved stat is cleared. So,
the static hostname or machine information in the context are always
consistent to the corresponding files.
This commit is contained in:
Yu Watanabe 2021-01-22 16:38:52 +09:00
parent c388618ec0
commit ba12e41d05

View File

@ -367,20 +367,41 @@ static int context_update_kernel_hostname(
return r; /* 0 if no change, 1 if something was done */
}
static void unset_statp(struct stat **p) {
if (!*p)
return;
**p = (struct stat) {};
}
static int context_write_data_static_hostname(Context *c) {
_cleanup_(unset_statp) struct stat *s = NULL;
int r;
assert(c);
/* Make sure that if we fail here, we invalidate the cached information, since it was updated
* already, even if we can't make it hit the disk. */
s = &c->etc_hostname_stat;
if (isempty(c->data[PROP_STATIC_HOSTNAME])) {
if (unlink("/etc/hostname") < 0)
return errno == ENOENT ? 0 : -errno;
if (unlink("/etc/hostname") < 0 && errno != ENOENT)
return -errno;
TAKE_PTR(s);
return 0;
}
return write_string_file_atomic_label("/etc/hostname", c->data[PROP_STATIC_HOSTNAME]);
r = write_string_file_atomic_label("/etc/hostname", c->data[PROP_STATIC_HOSTNAME]);
if (r < 0)
return r;
TAKE_PTR(s);
return 0;
}
static int context_write_data_machine_info(Context *c) {
_cleanup_(unset_statp) struct stat *s = NULL;
static const char * const name[_PROP_MAX] = {
[PROP_PRETTY_HOSTNAME] = "PRETTY_HOSTNAME",
[PROP_ICON_NAME] = "ICON_NAME",
@ -388,12 +409,15 @@ static int context_write_data_machine_info(Context *c) {
[PROP_DEPLOYMENT] = "DEPLOYMENT",
[PROP_LOCATION] = "LOCATION",
};
_cleanup_strv_free_ char **l = NULL;
int r;
assert(c);
/* Make sure that if we fail here, we invalidate the cached information, since it was updated
* 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);
if (r < 0 && r != -ENOENT)
return r;
@ -421,13 +445,19 @@ static int context_write_data_machine_info(Context *c) {
}
if (strv_isempty(l)) {
if (unlink("/etc/machine-info") < 0)
return errno == ENOENT ? 0 : -errno;
if (unlink("/etc/machine-info") < 0 && errno != ENOENT)
return -errno;
TAKE_PTR(s);
return 0;
}
return write_env_file_label("/etc/machine-info", l);
r = write_env_file_label("/etc/machine-info", l);
if (r < 0)
return r;
TAKE_PTR(s);
return 0;
}
static int property_get_hardware_vendor(