From 5ae4d543cb9b45ad6c6b82b78da1d6abc2291cdb Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 13 Jun 2014 19:45:52 +0200 Subject: [PATCH] os-release: define /usr/lib/os-release as fallback for /etc/os-release The file should have been in /usr/lib/ in the first place, since it describes the OS container in /usr (and not the configuration in /etc), hence, let's support os-release files in /usr/lib as fallback if no version in /etc exists, following the usual override logic. A prior commit already enabled tmpfiles to create /etc/os-release as a symlink to /usr/lib/os-release should it be missing, thus providing nice compatibility with applications only checking in /etc. While it's probably a good idea if all apps check both locations via a fallback logic, it is only necessary in the early boot process, as long as the /etc/os-release symlink has not been restored, in case we boot with an empty /etc. --- man/kernel-install.xml | 17 +++++++--- man/os-release.xml | 38 +++++++++++++++++------ man/systemd-nspawn.xml | 5 +-- src/bootchart/bootchart.c | 8 ++--- src/core/dbus-manager.c | 2 +- src/core/main.c | 8 ++++- src/hostname/hostnamed.c | 7 +++++ src/journal/journal-gatewayd.c | 3 +- src/kernel-install/90-loaderentry.install | 2 ++ src/nspawn/nspawn.c | 2 +- src/shared/path-util.c | 10 ++++-- 11 files changed, 76 insertions(+), 26 deletions(-) diff --git a/man/kernel-install.xml b/man/kernel-install.xml index 3612b7d93..178ad1d2b 100644 --- a/man/kernel-install.xml +++ b/man/kernel-install.xml @@ -95,14 +95,20 @@ along with systemd; If not, see . The kernel-install plugin 50-depmod.install runs depmod for the KERNEL-VERSION. - The kernel-install plugin 90-loaderentry.install copies + The kernel-install plugin + 90-loaderentry.install copies KERNEL-IMAGE to /boot/MACHINE-ID/KERNEL-VERSION/linux. - It also creates a boot loader entry according to the boot loader specification in + It also creates a boot loader entry according to the boot + loader specification in /boot/loader/entries/MACHINE-ID-KERNEL-VERSION.conf. - The title of the entry is the PRETTY_NAME parameter specified in /etc/os-release, - or "Linux KERNEL-VERSION", if unset. - If the file initrd is found next to the + The title of the entry is the + PRETTY_NAME parameter specified + in /etc/os-release or + /usr/lib/os-release (if the former is + missing), or "Linux + KERNEL-VERSION", if unset. If + the file initrd is found next to the linux file, the initrd will be added to the configuration. @@ -165,6 +171,7 @@ along with systemd; If not, see . /etc/os-release + /usr/lib/os-release The content of the file specifies the operating system title PRETTY_NAME. diff --git a/man/os-release.xml b/man/os-release.xml index c1dd62f71..11443638e 100644 --- a/man/os-release.xml +++ b/man/os-release.xml @@ -49,13 +49,15 @@ /etc/os-release + /usr/lib/os-release Description - The /etc/os-release file - contains operating system identification data. + The /etc/os-release and + /usr/lib/os-release files contain + operating system identification data. The basic file format of os-release is a newline-separated @@ -78,20 +80,38 @@ strings. Lines beginning with "#" shall be ignored as comments. - /etc/os-release contains - data that is defined by the operating system vendor - and should not be changed by the administrator. + The file /etc/os-release + takes precedence over + /usr/lib/os-release. Applications + should check for the former, and exclusively use its + data if it exists, and only fall back to + /usr/lib/os-release if it is + missing. Applications should not read data from both + files at the same + time. /usr/lib/os-release is the + recommended place to store OS release information as + part of vendor trees. Frequently + /etc/os-release is simply a + symlink to /usr/lib/os-release, + to provide compatibility with applications only + looking at /etc. + + os-release contains data + that is defined by the operating system vendor and + should generally not be changed by the + administrator. As this file only encodes names and identifiers it should not be localized. - The file /etc/os-release might - be a symlink to another file, but it is important that + The /etc/os-release and + /usr/lib/os-release files might + be symlinks to other files, but it is important that the file is available from earliest boot on, and hence must be located on the root file system. For a longer rationale for - /etc/os-release please refer to + os-release please refer to the Announcement of /etc/os-release. @@ -100,7 +120,7 @@ Options The following OS identifications parameters may be set using - /etc/os-release: + os-release: diff --git a/man/systemd-nspawn.xml b/man/systemd-nspawn.xml index d6687038a..950558fee 100644 --- a/man/systemd-nspawn.xml +++ b/man/systemd-nspawn.xml @@ -136,8 +136,9 @@ As a safety check systemd-nspawn will verify the - existence of /etc/os-release in - the container tree before starting the container (see + existence of /usr/lib/os-release + or /etc/os-release in the + container tree before starting the container (see os-release5). It might be necessary to add this file to the container tree manually if the OS of the container is too old to diff --git a/src/bootchart/bootchart.c b/src/bootchart/bootchart.c index 958a668ac..01a5bf18e 100644 --- a/src/bootchart/bootchart.c +++ b/src/bootchart/bootchart.c @@ -386,10 +386,10 @@ int main(int argc, char *argv[]) { if (sysfd < 0) sysfd = open("/sys", O_RDONLY|O_CLOEXEC); - if (!build) - parse_env_file("/etc/os-release", NEWLINE, - "PRETTY_NAME", &build, - NULL); + if (!build) { + if (parse_env_file("/etc/os-release", NEWLINE, "PRETTY_NAME", &build, NULL) == -ENOENT) + parse_env_file("/usr/lib/os-release", NEWLINE, "PRETTY_NAME", &build, NULL); + } /* wait for /proc to become available, discarding samples */ if (graph_start <= 0.0) diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index 333c1d46e..68a68a2d9 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -1191,7 +1191,7 @@ static int method_switch_root(sd_bus *bus, sd_bus_message *message, void *userda /* Safety check */ if (isempty(init)) { if (! path_is_os_tree(root)) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified switch root path %s does not seem to be an OS tree. /etc/os-release is missing.", root); + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Specified switch root path %s does not seem to be an OS tree. os-release file is missing.", root); } else { _cleanup_free_ char *p = NULL; diff --git a/src/core/main.c b/src/core/main.c index d5d1ee2b0..29f2d5a2a 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -1251,9 +1251,15 @@ static int status_welcome(void) { "PRETTY_NAME", &pretty_name, "ANSI_COLOR", &ansi_color, NULL); + if (r == -ENOENT) { + r = parse_env_file("/usr/lib/os-release", NEWLINE, + "PRETTY_NAME", &pretty_name, + "ANSI_COLOR", &ansi_color, + NULL); + } if (r < 0 && r != -ENOENT) - log_warning("Failed to read /etc/os-release: %s", strerror(-r)); + log_warning("Failed to read os-release file: %s", strerror(-r)); return status_printf(NULL, false, false, "\nWelcome to \x1B[%sm%s\x1B[0m!\n", diff --git a/src/hostname/hostnamed.c b/src/hostname/hostnamed.c index a3504904a..241d29691 100644 --- a/src/hostname/hostnamed.c +++ b/src/hostname/hostnamed.c @@ -108,6 +108,13 @@ static int context_read_data(Context *c) { "PRETTY_NAME", &c->data[PROP_OS_PRETTY_NAME], "CPE_NAME", &c->data[PROP_OS_CPE_NAME], NULL); + if (r == -ENOENT) { + r = parse_env_file("/usr/lib/os-release", NEWLINE, + "PRETTY_NAME", &c->data[PROP_OS_PRETTY_NAME], + "CPE_NAME", &c->data[PROP_OS_CPE_NAME], + NULL); + } + if (r < 0 && r != -ENOENT) return r; diff --git a/src/journal/journal-gatewayd.c b/src/journal/journal-gatewayd.c index 9a8867624..c682666a2 100644 --- a/src/journal/journal-gatewayd.c +++ b/src/journal/journal-gatewayd.c @@ -767,7 +767,8 @@ static int request_handler_machine( if (r < 0) return mhd_respondf(connection, MHD_HTTP_INTERNAL_SERVER_ERROR, "Failed to determine disk usage: %s\n", strerror(-r)); - parse_env_file("/etc/os-release", NEWLINE, "PRETTY_NAME", &os_name, NULL); + if (parse_env_file("/etc/os-release", NEWLINE, "PRETTY_NAME", &os_name, NULL) == -ENOENT) + parse_env_file("/usr/lib/os-release", NEWLINE, "PRETTY_NAME", &os_name, NULL); get_virtualization(&v); diff --git a/src/kernel-install/90-loaderentry.install b/src/kernel-install/90-loaderentry.install index a6a8abc2b..c17b8a98d 100644 --- a/src/kernel-install/90-loaderentry.install +++ b/src/kernel-install/90-loaderentry.install @@ -32,6 +32,8 @@ fi if [[ -f /etc/os-release ]]; then . /etc/os-release +elif [[ -f /usr/lib/os-release ]]; then + . /usr/lib/os-release fi if ! [[ $PRETTY_NAME ]]; then diff --git a/src/nspawn/nspawn.c b/src/nspawn/nspawn.c index 29ddfbb1f..8270348c1 100644 --- a/src/nspawn/nspawn.c +++ b/src/nspawn/nspawn.c @@ -2799,7 +2799,7 @@ int main(int argc, char *argv[]) { if (arg_boot) { if (path_is_os_tree(arg_directory) <= 0) { - log_error("Directory %s doesn't look like an OS root directory (/etc/os-release is missing). Refusing.", arg_directory); + log_error("Directory %s doesn't look like an OS root directory (os-release file is missing). Refusing.", arg_directory); goto finish; } } else { diff --git a/src/shared/path-util.c b/src/shared/path-util.c index 5863429c3..efe464d70 100644 --- a/src/shared/path-util.c +++ b/src/shared/path-util.c @@ -526,12 +526,18 @@ int path_is_os_tree(const char *path) { char *p; int r; - /* We use /etc/os-release as flag file if something is an OS */ + /* We use /usr/lib/os-release as flag file if something is an OS */ + p = strappenda(path, "/usr/lib/os-release"); + r = access(p, F_OK); + + if (r >= 0) + return 1; + /* Also check for the old location in /etc, just in case. */ p = strappenda(path, "/etc/os-release"); r = access(p, F_OK); - return r < 0 ? 0 : 1; + return r >= 0; } int find_binary(const char *name, char **filename) { -- 2.30.2