]>
Commit | Line | Data |
---|---|---|
db9ecf05 | 1 | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
d7ccca2e | 2 | |
d7ccca2e LP |
3 | #include <fcntl.h> |
4 | #include <sys/mount.h> | |
618234a5 | 5 | #include <unistd.h> |
d7ccca2e | 6 | |
e516c4d2 | 7 | #include "sd-daemon.h" |
618234a5 | 8 | #include "sd-id128.h" |
81527be1 | 9 | |
b5efdb8a | 10 | #include "alloc-util.h" |
a9f48db5 | 11 | #include "chase.h" |
deb0d489 | 12 | #include "creds-util.h" |
3ffd4af2 | 13 | #include "fd-util.h" |
69a283c5 | 14 | #include "fs-util.h" |
910fd145 | 15 | #include "id128-util.h" |
e516c4d2 | 16 | #include "initrd-util.h" |
3023f2fe | 17 | #include "io-util.h" |
618234a5 | 18 | #include "log.h" |
3ffd4af2 | 19 | #include "machine-id-setup.h" |
21935150 | 20 | #include "mount-util.h" |
049af8ad | 21 | #include "mountpoint-util.h" |
0cb8e3d1 | 22 | #include "namespace-util.h" |
fe970a8a | 23 | #include "path-util.h" |
0b452006 | 24 | #include "process-util.h" |
8fcde012 | 25 | #include "stat-util.h" |
07630cea | 26 | #include "string-util.h" |
69a283c5 | 27 | #include "strv.h" |
bf819d3a | 28 | #include "sync-util.h" |
affb60b1 | 29 | #include "umask-util.h" |
618234a5 | 30 | #include "virt.h" |
8d41a963 | 31 | |
274a38c7 | 32 | static int acquire_machine_id_from_credential(sd_id128_t *ret_machine_id) { |
deb0d489 LP |
33 | _cleanup_free_ char *buf = NULL; |
34 | int r; | |
35 | ||
274a38c7 MJ |
36 | assert(ret_machine_id); |
37 | ||
deb0d489 LP |
38 | r = read_credential_with_decryption("system.machine_id", (void**) &buf, /* ret_size= */ NULL); |
39 | if (r < 0) | |
40 | return log_warning_errno(r, "Failed to read system.machine_id credential, ignoring: %m"); | |
274a38c7 MJ |
41 | if (r == 0) { |
42 | /* not found */ | |
43 | *ret_machine_id = SD_ID128_NULL; | |
44 | return 0; | |
45 | } | |
46 | ||
47 | if (streq(buf, "firmware")) { | |
48 | *ret_machine_id = SD_ID128_NULL; | |
49 | return 1; | |
50 | } | |
deb0d489 | 51 | |
274a38c7 | 52 | r = sd_id128_from_string(buf, ret_machine_id); |
deb0d489 LP |
53 | if (r < 0) |
54 | return log_warning_errno(r, "Failed to parse system.machine_id credential, ignoring: %m"); | |
55 | ||
56 | log_info("Initializing machine ID from credential."); | |
274a38c7 | 57 | return 1; |
deb0d489 LP |
58 | } |
59 | ||
274a38c7 | 60 | static int acquire_machine_id(const char *root, bool machine_id_from_firmware, sd_id128_t *ret) { |
254d1313 | 61 | _cleanup_close_ int fd = -EBADF; |
4b1afed0 | 62 | int r; |
d7ccca2e | 63 | |
4b1afed0 | 64 | assert(ret); |
92f2f92e | 65 | |
16718dcf | 66 | /* First, try reading the machine ID from /run/machine-id, which may not be mounted on |
d2a11fd3 YW |
67 | * /etc/machine-id yet. This is important on switching root especially on soft-reboot, Otherwise, |
68 | * machine ID may be changed after the transition. */ | |
9ab78ad1 | 69 | if (isempty(root) && running_in_chroot() <= 0 && |
16718dcf YW |
70 | id128_read("/run/machine-id", ID128_FORMAT_PLAIN, ret) >= 0) { |
71 | log_info("Reusing machine ID stored in /run/machine-id."); | |
72 | return 1; /* Indicate that the machine ID is reused. */ | |
73 | } | |
74 | ||
274a38c7 | 75 | /* Then, try reading the D-Bus machine ID, unless it is a symlink */ |
90b9f7a0 | 76 | fd = chase_and_open("/var/lib/dbus/machine-id", root, CHASE_PREFIX_ROOT|CHASE_NOFOLLOW|CHASE_MUST_BE_REGULAR, O_RDONLY|O_CLOEXEC|O_NOCTTY, NULL); |
a9f48db5 YW |
77 | if (fd >= 0 && id128_read_fd(fd, ID128_FORMAT_PLAIN | ID128_REFUSE_NULL, ret) >= 0) { |
78 | log_info("Initializing machine ID from D-Bus machine ID."); | |
79 | return 0; | |
d7ccca2e LP |
80 | } |
81 | ||
9ab78ad1 | 82 | if (isempty(root) && running_in_chroot() <= 0) { |
deb0d489 | 83 | /* Let's use a system credential for the machine ID if we can */ |
274a38c7 MJ |
84 | sd_id128_t from_credential; |
85 | r = acquire_machine_id_from_credential(&from_credential); | |
86 | if (r > 0) { | |
87 | if (!sd_id128_is_null(from_credential)) { | |
88 | /* got a valid machine id from creds */ | |
89 | *ret = from_credential; | |
90 | return 0; | |
91 | } | |
92 | ||
93 | /* We got a credential, and it was set to "firmware", hence definitely try that */ | |
94 | machine_id_from_firmware = true; | |
95 | } | |
deb0d489 | 96 | |
5dd6d0f8 LP |
97 | /* If that didn't work, see if we are running in a container, |
98 | * and a machine ID was passed in via $container_uuid the way | |
99 | * libvirt/LXC does it */ | |
75f86906 LP |
100 | |
101 | if (detect_container() > 0) { | |
5dd6d0f8 | 102 | _cleanup_free_ char *e = NULL; |
0b36bbc4 | 103 | |
4b1afed0 LP |
104 | if (getenv_for_pid(1, "container_uuid", &e) > 0 && |
105 | sd_id128_from_string(e, ret) >= 0) { | |
106 | log_info("Initializing machine ID from container UUID."); | |
107 | return 0; | |
0b36bbc4 | 108 | } |
5dd6d0f8 | 109 | |
113c159b | 110 | } else if (IN_SET(detect_vm(), VIRTUALIZATION_KVM, VIRTUALIZATION_AMAZON, VIRTUALIZATION_QEMU, VIRTUALIZATION_XEN, VIRTUALIZATION_BHYVE) || machine_id_from_firmware) { |
75f86906 | 111 | |
382a46d1 BJ |
112 | /* If we are not running in a container, see if we are running in a VM that provides |
113 | * a system UUID via the SMBIOS/DMI interfaces. Such environments include QEMU/KVM | |
114 | * with the -uuid on the qemu command line or the Amazon EC2 Nitro hypervisor. */ | |
5dd6d0f8 | 115 | |
b4be4ff8 | 116 | if (id128_get_product(ret) >= 0) { |
274a38c7 | 117 | log_info("Initializing machine ID from SMBIOS/DMI UUID."); |
8fa0de65 DJL |
118 | return 0; |
119 | } | |
0b36bbc4 | 120 | } |
d4eb120a LP |
121 | } |
122 | ||
274a38c7 | 123 | /* If that didn't work, generate a random machine ID */ |
4b1afed0 | 124 | r = sd_id128_randomize(ret); |
23bbb0de | 125 | if (r < 0) |
5e1ee764 | 126 | return log_error_errno(r, "Failed to generate randomized machine ID: %m"); |
d7ccca2e LP |
127 | |
128 | log_info("Initializing machine ID from random generator."); | |
d7ccca2e LP |
129 | return 0; |
130 | } | |
131 | ||
274a38c7 | 132 | int machine_id_setup(const char *root, sd_id128_t machine_id, MachineIdSetupFlags flags, sd_id128_t *ret) { |
64d52739 | 133 | _cleanup_free_ char *etc_machine_id = NULL, *run_machine_id = NULL; |
16718dcf | 134 | bool writable, write_run_machine_id = true; |
64d52739 LP |
135 | _cleanup_close_ int fd = -EBADF, run_fd = -EBADF; |
136 | bool unlink_run_machine_id = false; | |
c6ac7e4b | 137 | int r; |
9496e375 | 138 | |
2053593f | 139 | WITH_UMASK(0000) { |
64d52739 | 140 | _cleanup_close_ int inode_fd = -EBADF; |
9496e375 | 141 | |
90b9f7a0 | 142 | r = chase("/etc/machine-id", root, CHASE_PREFIX_ROOT|CHASE_MUST_BE_REGULAR, &etc_machine_id, &inode_fd); |
64d52739 LP |
143 | if (r == -ENOENT) { |
144 | _cleanup_close_ int etc_fd = -EBADF; | |
145 | _cleanup_free_ char *etc = NULL; | |
146 | ||
90b9f7a0 | 147 | r = chase("/etc/", root, CHASE_PREFIX_ROOT|CHASE_MKDIR_0755|CHASE_MUST_BE_DIRECTORY, &etc, &etc_fd); |
64d52739 | 148 | if (r < 0) |
42ba9974 | 149 | return log_error_errno(r, "Failed to open %s: %m", "/etc/"); |
c6ac7e4b | 150 | |
64d52739 LP |
151 | etc_machine_id = path_join(etc, "machine-id"); |
152 | if (!etc_machine_id) | |
153 | return log_oom(); | |
154 | ||
155 | /* We create this 0444, to indicate that this isn't really something you should ever | |
156 | * modify. Of course, since the file will be owned by root it doesn't matter much, but maybe | |
157 | * people look. */ | |
158 | ||
159 | fd = openat(etc_fd, "machine-id", O_CREAT|O_EXCL|O_RDWR|O_NOFOLLOW|O_CLOEXEC, 0444); | |
c6ac7e4b | 160 | if (fd < 0) { |
64d52739 | 161 | if (errno == EROFS) |
d49a7143 | 162 | return log_error_errno(errno, |
64d52739 LP |
163 | "System cannot boot: Missing %s and %s/ is read-only.\n" |
164 | "Booting up is supported only when:\n" | |
165 | "1) /etc/machine-id exists and is populated.\n" | |
166 | "2) /etc/machine-id exists and is empty.\n" | |
167 | "3) /etc/machine-id is missing and /etc/ is writable.", | |
168 | etc_machine_id, | |
169 | etc); | |
170 | ||
171 | return log_error_errno(errno, "Cannot create '%s': %m", etc_machine_id); | |
c6ac7e4b | 172 | } |
9496e375 | 173 | |
64d52739 | 174 | log_debug("Successfully opened new '%s' file.", etc_machine_id); |
4b1afed0 | 175 | writable = true; |
64d52739 LP |
176 | } else if (r < 0) |
177 | return log_error_errno(r, "Cannot open '/etc/machine-id': %m"); | |
178 | else { | |
179 | /* We pinned the inode, now try to convert it into a writable file */ | |
180 | ||
181 | fd = xopenat_full(inode_fd, /* path= */ NULL, O_RDWR|O_CLOEXEC, XO_REGULAR, 0444); | |
182 | if (fd < 0) { | |
c8650d0d | 183 | log_debug_errno(fd, "Failed to open '%s' in writable mode, retrying in read-only mode: %m", etc_machine_id); |
64d52739 LP |
184 | |
185 | /* If that didn't work, convert it into a readable file */ | |
186 | fd = xopenat_full(inode_fd, /* path= */ NULL, O_RDONLY|O_CLOEXEC, XO_REGULAR, MODE_INVALID); | |
187 | if (fd < 0) | |
188 | return log_error_errno(fd, "Cannot open '%s' in neither writable nor read-only mode: %m", etc_machine_id); | |
189 | ||
190 | log_debug("Successfully opened existing '%s' file in read-only mode.", etc_machine_id); | |
191 | writable = false; | |
192 | } else { | |
193 | log_debug("Successfully opened existing '%s' file in writable mode.", etc_machine_id); | |
194 | writable = true; | |
195 | } | |
196 | } | |
c6ac7e4b LP |
197 | } |
198 | ||
4b1afed0 | 199 | /* A we got a valid machine ID argument, that's what counts */ |
274a38c7 | 200 | if (sd_id128_is_null(machine_id) || FLAGS_SET(flags, MACHINE_ID_SETUP_FORCE_FIRMWARE)) { |
9496e375 | 201 | |
4b1afed0 | 202 | /* Try to read any existing machine ID */ |
64d52739 LP |
203 | r = id128_read_fd(fd, ID128_FORMAT_PLAIN, &machine_id); |
204 | if (r >= 0) | |
e516c4d2 | 205 | goto finish; |
c6ac7e4b | 206 | |
64d52739 LP |
207 | log_debug_errno(r, "Unable to read current machine ID, acquiring new one: %m"); |
208 | ||
16718dcf | 209 | /* Hmm, so, the id currently stored is not useful, then let's acquire one. */ |
274a38c7 | 210 | r = acquire_machine_id(root, FLAGS_SET(flags, MACHINE_ID_SETUP_FORCE_FIRMWARE), &machine_id); |
ee48dbd5 NC |
211 | if (r < 0) |
212 | return r; | |
64d52739 LP |
213 | |
214 | write_run_machine_id = !r; /* acquire_machine_id() returns 1 in case we read this machine ID | |
215 | * from /run/machine-id */ | |
fcb24270 | 216 | } |
4b1afed0 | 217 | |
fcb24270 | 218 | if (writable) { |
86cbbc6d | 219 | if (lseek(fd, 0, SEEK_SET) < 0) |
fcb24270 EV |
220 | return log_error_errno(errno, "Failed to seek %s: %m", etc_machine_id); |
221 | ||
222 | if (ftruncate(fd, 0) < 0) | |
223 | return log_error_errno(errno, "Failed to truncate %s: %m", etc_machine_id); | |
c6ac7e4b | 224 | |
3023f2fe HS |
225 | /* If the caller requested a transient machine-id, write the string "uninitialized\n" to |
226 | * disk and overmount it with a transient file. | |
227 | * | |
228 | * Otherwise write the machine-id directly to disk. */ | |
274a38c7 | 229 | if (FLAGS_SET(flags, MACHINE_ID_SETUP_FORCE_TRANSIENT)) { |
e22c60a9 | 230 | r = loop_write(fd, "uninitialized\n", SIZE_MAX); |
3023f2fe HS |
231 | if (r < 0) |
232 | return log_error_errno(r, "Failed to write uninitialized %s: %m", etc_machine_id); | |
233 | ||
234 | r = fsync_full(fd); | |
235 | if (r < 0) | |
236 | return log_error_errno(r, "Failed to sync %s: %m", etc_machine_id); | |
237 | } else { | |
b40c8ebd | 238 | r = id128_write_fd(fd, ID128_FORMAT_PLAIN | ID128_SYNC_ON_WRITE, machine_id); |
3023f2fe HS |
239 | if (r < 0) |
240 | return log_error_errno(r, "Failed to write %s: %m", etc_machine_id); | |
3773d4dd LP |
241 | |
242 | goto finish; | |
3023f2fe | 243 | } |
fcb24270 | 244 | } |
c6ac7e4b | 245 | |
64d52739 LP |
246 | /* Hmm, we couldn't or shouldn't write the machine-id to /etc/? So let's write it to /run/machine-id |
247 | * as a replacement */ | |
c6ac7e4b | 248 | |
64d52739 LP |
249 | if (write_run_machine_id) { |
250 | _cleanup_free_ char *run = NULL; | |
c6ac7e4b | 251 | |
90b9f7a0 | 252 | r = chase("/run/", root, CHASE_PREFIX_ROOT|CHASE_MKDIR_0755|CHASE_MUST_BE_DIRECTORY, &run, &run_fd); |
64d52739 | 253 | if (r < 0) |
42ba9974 | 254 | return log_error_errno(r, "Failed to open %s: %m", "/run/"); |
4b1afed0 | 255 | |
64d52739 LP |
256 | run_machine_id = path_join(run, "machine-id"); |
257 | if (!run_machine_id) | |
258 | return log_oom(); | |
259 | ||
260 | WITH_UMASK(0022) { | |
261 | r = id128_write_at(run_fd, "machine-id", ID128_FORMAT_PLAIN, machine_id); | |
f3895067 MY |
262 | if (r < 0) { |
263 | (void) unlinkat(run_fd, "machine-id", /* flags = */ 0); | |
64d52739 | 264 | return log_error_errno(r, "Cannot write '%s': %m", run_machine_id); |
f3895067 | 265 | } |
16718dcf | 266 | } |
64d52739 LP |
267 | |
268 | unlink_run_machine_id = true; | |
269 | } else { | |
457ce7d9 | 270 | r = chase("/run/machine-id", root, CHASE_PREFIX_ROOT|CHASE_MUST_BE_REGULAR, &run_machine_id, /* ret_fd= */ NULL); |
64d52739 | 271 | if (r < 0) |
42ba9974 | 272 | return log_error_errno(r, "Failed to open %s: %m", "/run/machine-id"); |
c6ac7e4b LP |
273 | } |
274 | ||
275 | /* And now, let's mount it over */ | |
64d52739 | 276 | r = mount_follow_verbose(LOG_ERR, run_machine_id, FORMAT_PROC_FD_PATH(fd), /* fstype= */ NULL, MS_BIND, /* options= */ NULL); |
f3895067 MY |
277 | if (r < 0) { |
278 | if (unlink_run_machine_id) | |
279 | (void) unlinkat(ASSERT_FD(run_fd), "machine-id", /* flags = */ 0); | |
21935150 | 280 | return r; |
f3895067 | 281 | } |
c6ac7e4b | 282 | |
64d52739 | 283 | log_full(FLAGS_SET(flags, MACHINE_ID_SETUP_FORCE_TRANSIENT) ? LOG_DEBUG : LOG_INFO, "Installed transient '%s' file.", etc_machine_id); |
c6ac7e4b | 284 | |
64d52739 | 285 | /* Mark the mount read-only (note: we are not going via FORMAT_PROC_FD_PATH() here because that fd is not updated to our new bind mount) */ |
457ce7d9 | 286 | (void) mount_follow_verbose(LOG_WARNING, /* what= */ NULL, etc_machine_id, /* fstype= */ NULL, MS_BIND|MS_RDONLY|MS_REMOUNT, /* options= */ NULL); |
4b1afed0 LP |
287 | |
288 | finish: | |
e516c4d2 LP |
289 | if (!in_initrd()) |
290 | (void) sd_notifyf(/* unset_environment= */ false, "X_SYSTEMD_MACHINE_ID=" SD_ID128_FORMAT_STR, SD_ID128_FORMAT_VAL(machine_id)); | |
291 | ||
4b1afed0 LP |
292 | if (ret) |
293 | *ret = machine_id; | |
c6ac7e4b LP |
294 | |
295 | return 0; | |
9496e375 DR |
296 | } |
297 | ||
979ef53a | 298 | int machine_id_commit(const char *root) { |
15b1248a | 299 | sd_id128_t id; |
979ef53a DR |
300 | int r; |
301 | ||
4d0fb50e LP |
302 | if (empty_or_root(root)) { |
303 | /* Before doing anything, sync everything to ensure any changes by first-boot units are | |
304 | * persisted. | |
305 | * | |
306 | * First, explicitly sync the file systems we care about and check if it worked. */ | |
307 | FOREACH_STRING(sync_path, "/etc/", "/var/") { | |
308 | r = syncfs_path(AT_FDCWD, sync_path); | |
309 | if (r < 0) | |
310 | return log_error_errno(r, "Cannot sync %s: %m", sync_path); | |
311 | } | |
c261a5d0 | 312 | |
4d0fb50e LP |
313 | /* Afterwards, sync() the rest too, but we can't check the return value for these. */ |
314 | sync(); | |
315 | } | |
c261a5d0 | 316 | |
15b1248a LP |
317 | /* Replaces a tmpfs bind mount of /etc/machine-id by a proper file, atomically. For this, the umount is removed |
318 | * in a mount namespace, a new file is created at the right place. Afterwards the mount is also removed in the | |
319 | * original mount namespace, thus revealing the file that was just created. */ | |
320 | ||
efabf4e0 LP |
321 | _cleanup_close_ int etc_fd = -EBADF; |
322 | _cleanup_free_ char *etc = NULL; | |
90b9f7a0 | 323 | r = chase("/etc/", root, CHASE_PREFIX_ROOT|CHASE_MUST_BE_DIRECTORY, &etc, &etc_fd); |
efabf4e0 | 324 | if (r < 0) |
42ba9974 | 325 | return log_error_errno(r, "Failed to open %s: %m", "/etc/"); |
efabf4e0 LP |
326 | |
327 | _cleanup_free_ char *etc_machine_id = path_join(etc, "machine-id"); | |
328 | if (!etc_machine_id) | |
329 | return log_oom(); | |
979ef53a | 330 | |
7ce2c1bb | 331 | r = is_mount_point_at(etc_fd, "machine-id", /* flags= */ 0); |
979ef53a | 332 | if (r < 0) |
f131770b | 333 | return log_error_errno(r, "Failed to determine whether %s is a mount point: %m", etc_machine_id); |
979ef53a | 334 | if (r == 0) { |
61233823 | 335 | log_debug("%s is not a mount point. Nothing to do.", etc_machine_id); |
979ef53a DR |
336 | return 0; |
337 | } | |
338 | ||
339 | /* Read existing machine-id */ | |
efabf4e0 LP |
340 | |
341 | _cleanup_close_ int fd = xopenat_full(etc_fd, "machine-id", O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW, XO_REGULAR, MODE_INVALID); | |
979ef53a | 342 | if (fd < 0) |
efabf4e0 LP |
343 | return log_error_errno(fd, "Cannot open %s: %m", etc_machine_id); |
344 | ||
345 | etc_fd = safe_close(etc_fd); | |
979ef53a | 346 | |
c6878637 | 347 | r = fd_is_temporary_fs(fd); |
979ef53a DR |
348 | if (r < 0) |
349 | return log_error_errno(r, "Failed to determine whether %s is on a temporary file system: %m", etc_machine_id); | |
baaa35ad ZJS |
350 | if (r == 0) |
351 | return log_error_errno(SYNTHETIC_ERRNO(EROFS), | |
352 | "%s is not on a temporary file system.", | |
353 | etc_machine_id); | |
979ef53a | 354 | |
057bf780 | 355 | r = id128_read_fd(fd, ID128_FORMAT_PLAIN, &id); |
15b1248a | 356 | if (r < 0) |
5e1ee764 | 357 | return log_error_errno(r, "We didn't find a valid machine ID in %s: %m", etc_machine_id); |
15b1248a | 358 | |
979ef53a | 359 | /* Store current mount namespace */ |
efabf4e0 | 360 | _cleanup_close_ int initial_mntns_fd = namespace_open_by_type(NAMESPACE_MOUNT); |
8c0da3af LP |
361 | if (initial_mntns_fd < 0) |
362 | return log_error_errno(initial_mntns_fd, "Can't fetch current mount namespace: %m"); | |
979ef53a DR |
363 | |
364 | /* Switch to a new mount namespace, isolate ourself and unmount etc_machine_id in our new namespace */ | |
e2ec9c4d LP |
365 | r = detach_mount_namespace(); |
366 | if (r < 0) | |
367 | return log_error_errno(r, "Failed to set up new mount namespace: %m"); | |
979ef53a | 368 | |
efabf4e0 LP |
369 | /* Open /etc/ again after we transitioned into our own private mount namespace */ |
370 | _cleanup_close_ int etc_fd_again = -EBADF; | |
90b9f7a0 | 371 | r = chase("/etc/", root, CHASE_PREFIX_ROOT|CHASE_MUST_BE_DIRECTORY, /* ret_path= */ NULL, &etc_fd_again); |
efabf4e0 | 372 | if (r < 0) |
42ba9974 | 373 | return log_error_errno(r, "Failed to open %s: %m", "/etc/"); |
efabf4e0 LP |
374 | |
375 | r = umountat_detach_verbose(LOG_ERR, etc_fd_again, "machine-id"); | |
21935150 LP |
376 | if (r < 0) |
377 | return r; | |
979ef53a DR |
378 | |
379 | /* Update a persistent version of etc_machine_id */ | |
efabf4e0 | 380 | r = id128_write_at(etc_fd_again, "machine-id", ID128_FORMAT_PLAIN | ID128_SYNC_ON_WRITE, id); |
979ef53a | 381 | if (r < 0) |
15b1248a | 382 | return log_error_errno(r, "Cannot write %s. This is mandatory to get a persistent machine ID: %m", etc_machine_id); |
979ef53a | 383 | |
efabf4e0 LP |
384 | etc_fd_again = safe_close(etc_fd_again); |
385 | ||
979ef53a | 386 | /* Return to initial namespace and proceed a lazy tmpfs unmount */ |
d2881ef9 YW |
387 | r = namespace_enter(/* pidns_fd = */ -EBADF, |
388 | initial_mntns_fd, | |
389 | /* netns_fd = */ -EBADF, | |
390 | /* userns_fd = */ -EBADF, | |
391 | /* root_fd = */ -EBADF); | |
979ef53a | 392 | if (r < 0) |
efabf4e0 LP |
393 | return log_warning_errno(r, |
394 | "Failed to switch back to initial mount namespace: %m.\n" | |
395 | "We'll keep transient %s file until next reboot.", etc_machine_id); | |
979ef53a | 396 | |
457ce7d9 | 397 | r = umountat_detach_verbose(LOG_DEBUG, fd, /* where= */ NULL); |
efabf4e0 LP |
398 | if (r < 0) |
399 | return log_warning_errno(r, | |
400 | "Failed to unmount transient %s file: %m.\n" | |
401 | "We keep that mount until next reboot.", etc_machine_id); | |
979ef53a DR |
402 | |
403 | return 0; | |
404 | } |