diff --git a/nixos/doc/manual/release-notes/rl-1903.xml b/nixos/doc/manual/release-notes/rl-1903.xml
index 3e42294a5f87..0a51e5b1a936 100644
--- a/nixos/doc/manual/release-notes/rl-1903.xml
+++ b/nixos/doc/manual/release-notes/rl-1903.xml
@@ -459,10 +459,16 @@
- Symlinks in /etc are now relative instead of absolute,
- so that the links can be followed if the NixOS installation is not mounted as filesystem root.
- In particular, this makes /etc/os-release adhere to
- the standard.
+ Symlinks in /etc (except /etc/static)
+ are now relative instead of absolute. This makes possible to examine
+ NixOS container's /etc directory from host system
+ (previously it pointed to host /etc when viewed from host,
+ and to container /etc when viewed from container chroot).
+
+
+ This also makes /etc/os-release adhere to
+ the standard
+ for NixOS containers.
diff --git a/nixos/modules/system/etc/setup-etc.pl b/nixos/modules/system/etc/setup-etc.pl
index 6cbf0e17793d..82ef49a2a27e 100644
--- a/nixos/modules/system/etc/setup-etc.pl
+++ b/nixos/modules/system/etc/setup-etc.pl
@@ -13,18 +13,26 @@ sub atomicSymlink {
my ($source, $target) = @_;
my $tmp = "$target.tmp";
unlink $tmp;
- # Create relative symlinks, so that the links can be followed if
- # the NixOS installation is not mounted as filesystem root.
- # Absolute symlinks violate the os-release format
- # at https://www.freedesktop.org/software/systemd/man/os-release.html
- # and break e.g. systemd-nspawn and os-prober.
+ symlink $source, $tmp or return 0;
+ rename $tmp, $target or return 0;
+ return 1;
+}
+
+# Create relative symlinks, so that the links can be followed if
+# the NixOS installation is not mounted as filesystem root.
+# Absolute symlinks violate the os-release format
+# at https://www.freedesktop.org/software/systemd/man/os-release.html
+# and break e.g. systemd-nspawn and os-prober.
+sub atomicRelativeSymlink {
+ my ($source, $target) = @_;
+ my $tmp = "$target.tmp";
+ unlink $tmp;
my $rel = File::Spec->abs2rel($source, dirname $target);
symlink $rel, $tmp or return 0;
rename $tmp, $target or return 0;
return 1;
}
-
# Atomically update /etc/static to point at the etc files of the
# current configuration.
atomicSymlink $etc, $static or die;
@@ -37,8 +45,7 @@ sub isStatic {
if (-l $path) {
my $target = readlink $path;
- my $rel = File::Spec->abs2rel("/etc/static", dirname $path);
- return substr($target, 0, length $rel) eq $rel;
+ return substr($target, 0, length "/etc/static/") eq "/etc/static/";
}
if (-d $path) {
@@ -111,7 +118,7 @@ sub link {
if (-e "$_.mode") {
my $mode = read_file("$_.mode"); chomp $mode;
if ($mode eq "direct-symlink") {
- atomicSymlink readlink("$static/$fn"), $target or warn;
+ atomicRelativeSymlink readlink("$static/$fn"), $target or warn;
} else {
my $uid = read_file("$_.uid"); chomp $uid;
my $gid = read_file("$_.gid"); chomp $gid;
@@ -125,7 +132,7 @@ sub link {
push @copied, $fn;
print CLEAN "$fn\n";
} elsif (-l "$_") {
- atomicSymlink "$static/$fn", $target or warn;
+ atomicRelativeSymlink "$static/$fn", $target or warn;
}
}