1 /* SPDX-License-Identifier: LGPL-2.1+ */
3 This file is part of systemd.
5 Copyright 2013 Lennart Poettering
7 systemd is free software; you can redistribute it and/or modify it
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
10 (at your option) any later version.
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Lesser General Public License for more details.
17 You should have received a copy of the GNU Lesser General Public License
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
32 #include "alloc-util.h"
33 #include "btrfs-util.h"
34 #include "chattr-util.h"
36 #include "dirent-util.h"
41 #include "lockfile-util.h"
43 #include "machine-image.h"
46 #include "path-util.h"
48 #include "string-table.h"
49 #include "string-util.h"
51 #include "time-util.h"
54 #include "xattr-util.h"
56 static const char image_search_path
[] =
58 "/var/lib/container\0" /* legacy */
59 "/usr/local/lib/machines\0"
60 "/usr/lib/machines\0";
62 Image
*image_unref(Image
*i
) {
71 static char **image_settings_path(Image
*image
) {
72 _cleanup_strv_free_
char **l
= NULL
;
83 fn
= strjoina(image
->name
, ".nspawn");
85 FOREACH_STRING(s
, "/etc/systemd/nspawn/", "/run/systemd/nspawn/") {
86 l
[i
] = strappend(s
, fn
);
93 l
[i
] = file_in_same_dir(image
->path
, fn
);
103 static char *image_roothash_path(Image
*image
) {
108 fn
= strjoina(image
->name
, ".roothash");
110 return file_in_same_dir(image
->path
, fn
);
113 static int image_new(
117 const char *filename
,
123 _cleanup_(image_unrefp
) Image
*i
= NULL
;
126 assert(t
< _IMAGE_TYPE_MAX
);
136 i
->read_only
= read_only
;
139 i
->usage
= i
->usage_exclusive
= (uint64_t) -1;
140 i
->limit
= i
->limit_exclusive
= (uint64_t) -1;
142 i
->name
= strdup(pretty
);
147 i
->path
= strjoin(path
, "/", filename
);
149 i
->path
= strdup(filename
);
154 path_kill_slashes(i
->path
);
162 static int image_make(
166 const char *filename
,
175 /* We explicitly *do* follow symlinks here, since we want to allow symlinking trees, raw files and block
176 * devices into /var/lib/machines/, and treat them normally. */
178 if (fstatat(dfd
, filename
, &st
, 0) < 0)
182 (path
&& path_startswith(path
, "/usr")) ||
183 (faccessat(dfd
, filename
, W_OK
, AT_EACCESS
) < 0 && errno
== EROFS
);
185 if (S_ISDIR(st
.st_mode
)) {
186 _cleanup_close_
int fd
= -1;
187 unsigned file_attr
= 0;
195 fd
= openat(dfd
, filename
, O_CLOEXEC
|O_NOCTTY
|O_DIRECTORY
);
199 /* btrfs subvolumes have inode 256 */
200 if (st
.st_ino
== 256) {
202 r
= btrfs_is_filesystem(fd
);
206 BtrfsSubvolInfo info
;
208 /* It's a btrfs subvolume */
210 r
= btrfs_subvol_get_info_fd(fd
, 0, &info
);
214 r
= image_new(IMAGE_SUBVOLUME
,
218 info
.read_only
|| read_only
,
225 if (btrfs_quota_scan_ongoing(fd
) == 0) {
226 BtrfsQuotaInfo quota
;
228 r
= btrfs_subvol_get_subtree_quota_fd(fd
, 0, "a
);
230 (*ret
)->usage
= quota
.referenced
;
231 (*ret
)->usage_exclusive
= quota
.exclusive
;
233 (*ret
)->limit
= quota
.referenced_max
;
234 (*ret
)->limit_exclusive
= quota
.exclusive_max
;
242 /* If the IMMUTABLE bit is set, we consider the
243 * directory read-only. Since the ioctl is not
244 * supported everywhere we ignore failures. */
245 (void) read_attr_fd(fd
, &file_attr
);
247 /* It's just a normal directory. */
248 r
= image_new(IMAGE_DIRECTORY
,
252 read_only
|| (file_attr
& FS_IMMUTABLE_FL
),
261 } else if (S_ISREG(st
.st_mode
) && endswith(filename
, ".raw")) {
264 /* It's a RAW disk image */
269 fd_getcrtime_at(dfd
, filename
, &crtime
, 0);
272 pretty
= strndupa(filename
, strlen(filename
) - 4);
274 r
= image_new(IMAGE_RAW
,
278 !(st
.st_mode
& 0222) || read_only
,
280 timespec_load(&st
.st_mtim
),
285 (*ret
)->usage
= (*ret
)->usage_exclusive
= st
.st_blocks
* 512;
286 (*ret
)->limit
= (*ret
)->limit_exclusive
= st
.st_size
;
290 } else if (S_ISBLK(st
.st_mode
)) {
291 _cleanup_close_
int block_fd
= -1;
292 uint64_t size
= UINT64_MAX
;
302 block_fd
= openat(dfd
, filename
, O_RDONLY
|O_NONBLOCK
|O_CLOEXEC
|O_NOCTTY
);
304 log_debug_errno(errno
, "Failed to open block device %s/%s, ignoring: %m", path
, filename
);
306 if (fstat(block_fd
, &st
) < 0)
308 if (!S_ISBLK(st
.st_mode
)) /* Verify that what we opened is actually what we think it is */
314 if (ioctl(block_fd
, BLKROGET
, &state
) < 0)
315 log_debug_errno(errno
, "Failed to issue BLKROGET on device %s/%s, ignoring: %m", path
, filename
);
320 if (ioctl(block_fd
, BLKGETSIZE64
, &size
) < 0)
321 log_debug_errno(errno
, "Failed to issue BLKFLSBUF on device %s/%s, ignoring: %m", path
, filename
);
323 block_fd
= safe_close(block_fd
);
326 r
= image_new(IMAGE_BLOCK
,
330 !(st
.st_mode
& 0222) || read_only
,
337 if (size
!= 0 && size
!= UINT64_MAX
)
338 (*ret
)->usage
= (*ret
)->usage_exclusive
= (*ret
)->limit
= (*ret
)->limit_exclusive
= size
;
346 int image_find(const char *name
, Image
**ret
) {
352 /* There are no images with invalid names */
353 if (!image_name_is_valid(name
))
356 NULSTR_FOREACH(path
, image_search_path
) {
357 _cleanup_closedir_
DIR *d
= NULL
;
367 r
= image_make(NULL
, dirfd(d
), path
, name
, ret
);
368 if (IN_SET(r
, 0, -ENOENT
)) {
369 _cleanup_free_
char *raw
= NULL
;
371 raw
= strappend(name
, ".raw");
375 r
= image_make(NULL
, dirfd(d
), path
, raw
, ret
);
376 if (IN_SET(r
, 0, -ENOENT
))
385 if (streq(name
, ".host"))
386 return image_make(".host", AT_FDCWD
, NULL
, "/", ret
);
391 int image_discover(Hashmap
*h
) {
397 NULSTR_FOREACH(path
, image_search_path
) {
398 _cleanup_closedir_
DIR *d
= NULL
;
409 FOREACH_DIRENT_ALL(de
, d
, return -errno
) {
410 _cleanup_(image_unrefp
) Image
*image
= NULL
;
412 if (!image_name_is_valid(de
->d_name
))
415 if (hashmap_contains(h
, de
->d_name
))
418 r
= image_make(NULL
, dirfd(d
), path
, de
->d_name
, &image
);
419 if (IN_SET(r
, 0, -ENOENT
))
424 r
= hashmap_put(h
, image
->name
, image
);
432 if (!hashmap_contains(h
, ".host")) {
433 _cleanup_(image_unrefp
) Image
*image
= NULL
;
435 r
= image_make(".host", AT_FDCWD
, NULL
, "/", &image
);
439 r
= hashmap_put(h
, image
->name
, image
);
450 void image_hashmap_free(Hashmap
*map
) {
453 while ((i
= hashmap_steal_first(map
)))
459 int image_remove(Image
*i
) {
460 _cleanup_release_lock_file_ LockFile global_lock
= LOCK_FILE_INIT
, local_lock
= LOCK_FILE_INIT
;
461 _cleanup_strv_free_
char **settings
= NULL
;
462 _cleanup_free_
char *roothash
= NULL
;
468 if (IMAGE_IS_VENDOR(i
) || IMAGE_IS_HOST(i
))
471 settings
= image_settings_path(i
);
475 roothash
= image_roothash_path(i
);
479 /* Make sure we don't interfere with a running nspawn */
480 r
= image_path_lock(i
->path
, LOCK_EX
|LOCK_NB
, &global_lock
, &local_lock
);
486 case IMAGE_SUBVOLUME
:
488 /* Let's unlink first, maybe it is a symlink? If that works we are happy. Otherwise, let's get out the
490 if (unlink(i
->path
) < 0) {
491 r
= btrfs_subvol_remove(i
->path
, BTRFS_REMOVE_RECURSIVE
|BTRFS_REMOVE_QUOTA
);
498 case IMAGE_DIRECTORY
:
499 /* Allow deletion of read-only directories */
500 (void) chattr_path(i
->path
, 0, FS_IMMUTABLE_FL
);
501 r
= rm_rf(i
->path
, REMOVE_ROOT
|REMOVE_PHYSICAL
|REMOVE_SUBVOLUME
);
509 /* If this is inside of /dev, then it's a real block device, hence let's not touch the device node
510 * itself (but let's remove the stuff stored alongside it). If it's anywhere else, let's try to unlink
511 * the thing (it's most likely a symlink after all). */
513 if (path_startswith(i
->path
, "/dev"))
519 if (unlink(i
->path
) < 0)
527 STRV_FOREACH(j
, settings
) {
528 if (unlink(*j
) < 0 && errno
!= ENOENT
)
529 log_debug_errno(errno
, "Failed to unlink %s, ignoring: %m", *j
);
532 if (unlink(roothash
) < 0 && errno
!= ENOENT
)
533 log_debug_errno(errno
, "Failed to unlink %s, ignoring: %m", roothash
);
538 static int rename_auxiliary_file(const char *path
, const char *new_name
, const char *suffix
) {
539 _cleanup_free_
char *rs
= NULL
;
542 fn
= strjoina(new_name
, suffix
);
544 rs
= file_in_same_dir(path
, fn
);
548 return rename_noreplace(AT_FDCWD
, path
, AT_FDCWD
, rs
);
551 int image_rename(Image
*i
, const char *new_name
) {
552 _cleanup_release_lock_file_ LockFile global_lock
= LOCK_FILE_INIT
, local_lock
= LOCK_FILE_INIT
, name_lock
= LOCK_FILE_INIT
;
553 _cleanup_free_
char *new_path
= NULL
, *nn
= NULL
, *roothash
= NULL
;
554 _cleanup_strv_free_
char **settings
= NULL
;
555 unsigned file_attr
= 0;
561 if (!image_name_is_valid(new_name
))
564 if (IMAGE_IS_VENDOR(i
) || IMAGE_IS_HOST(i
))
567 settings
= image_settings_path(i
);
571 roothash
= image_roothash_path(i
);
575 /* Make sure we don't interfere with a running nspawn */
576 r
= image_path_lock(i
->path
, LOCK_EX
|LOCK_NB
, &global_lock
, &local_lock
);
580 /* Make sure nobody takes the new name, between the time we
581 * checked it is currently unused in all search paths, and the
582 * time we take possession of it */
583 r
= image_name_lock(new_name
, LOCK_EX
|LOCK_NB
, &name_lock
);
587 r
= image_find(new_name
, NULL
);
595 case IMAGE_DIRECTORY
:
596 /* Turn of the immutable bit while we rename the image, so that we can rename it */
597 (void) read_attr_path(i
->path
, &file_attr
);
599 if (file_attr
& FS_IMMUTABLE_FL
)
600 (void) chattr_path(i
->path
, 0, FS_IMMUTABLE_FL
);
604 case IMAGE_SUBVOLUME
:
605 new_path
= file_in_same_dir(i
->path
, new_name
);
610 /* Refuse renaming raw block devices in /dev, the names are picked by udev after all. */
611 if (path_startswith(i
->path
, "/dev"))
614 new_path
= file_in_same_dir(i
->path
, new_name
);
620 fn
= strjoina(new_name
, ".raw");
621 new_path
= file_in_same_dir(i
->path
, fn
);
632 nn
= strdup(new_name
);
636 r
= rename_noreplace(AT_FDCWD
, i
->path
, AT_FDCWD
, new_path
);
640 /* Restore the immutable bit, if it was set before */
641 if (file_attr
& FS_IMMUTABLE_FL
)
642 (void) chattr_path(new_path
, FS_IMMUTABLE_FL
, FS_IMMUTABLE_FL
);
652 STRV_FOREACH(j
, settings
) {
653 r
= rename_auxiliary_file(*j
, new_name
, ".nspawn");
654 if (r
< 0 && r
!= -ENOENT
)
655 log_debug_errno(r
, "Failed to rename settings file %s, ignoring: %m", *j
);
658 r
= rename_auxiliary_file(roothash
, new_name
, ".roothash");
659 if (r
< 0 && r
!= -ENOENT
)
660 log_debug_errno(r
, "Failed to rename roothash file %s, ignoring: %m", roothash
);
665 static int clone_auxiliary_file(const char *path
, const char *new_name
, const char *suffix
) {
666 _cleanup_free_
char *rs
= NULL
;
669 fn
= strjoina(new_name
, suffix
);
671 rs
= file_in_same_dir(path
, fn
);
675 return copy_file_atomic(path
, rs
, 0664, 0, COPY_REFLINK
);
678 int image_clone(Image
*i
, const char *new_name
, bool read_only
) {
679 _cleanup_release_lock_file_ LockFile name_lock
= LOCK_FILE_INIT
;
680 _cleanup_strv_free_
char **settings
= NULL
;
681 _cleanup_free_
char *roothash
= NULL
;
682 const char *new_path
;
688 if (!image_name_is_valid(new_name
))
691 settings
= image_settings_path(i
);
695 roothash
= image_roothash_path(i
);
699 /* Make sure nobody takes the new name, between the time we
700 * checked it is currently unused in all search paths, and the
701 * time we take possession of it */
702 r
= image_name_lock(new_name
, LOCK_EX
|LOCK_NB
, &name_lock
);
706 r
= image_find(new_name
, NULL
);
714 case IMAGE_SUBVOLUME
:
715 case IMAGE_DIRECTORY
:
716 /* If we can we'll always try to create a new btrfs subvolume here, even if the source is a plain
719 new_path
= strjoina("/var/lib/machines/", new_name
);
721 r
= btrfs_subvol_snapshot(i
->path
, new_path
,
722 (read_only
? BTRFS_SNAPSHOT_READ_ONLY
: 0) |
723 BTRFS_SNAPSHOT_FALLBACK_COPY
|
724 BTRFS_SNAPSHOT_FALLBACK_DIRECTORY
|
725 BTRFS_SNAPSHOT_FALLBACK_IMMUTABLE
|
726 BTRFS_SNAPSHOT_RECURSIVE
|
727 BTRFS_SNAPSHOT_QUOTA
);
729 /* Enable "subtree" quotas for the copy, if we didn't copy any quota from the source. */
730 (void) btrfs_subvol_auto_qgroup(new_path
, 0, true);
735 new_path
= strjoina("/var/lib/machines/", new_name
, ".raw");
737 r
= copy_file_atomic(i
->path
, new_path
, read_only
? 0444 : 0644, FS_NOCOW_FL
, COPY_REFLINK
);
748 STRV_FOREACH(j
, settings
) {
749 r
= clone_auxiliary_file(*j
, new_name
, ".nspawn");
750 if (r
< 0 && r
!= -ENOENT
)
751 log_debug_errno(r
, "Failed to clone settings %s, ignoring: %m", *j
);
754 r
= clone_auxiliary_file(roothash
, new_name
, ".roothash");
755 if (r
< 0 && r
!= -ENOENT
)
756 log_debug_errno(r
, "Failed to clone root hash file %s, ignoring: %m", roothash
);
761 int image_read_only(Image
*i
, bool b
) {
762 _cleanup_release_lock_file_ LockFile global_lock
= LOCK_FILE_INIT
, local_lock
= LOCK_FILE_INIT
;
766 if (IMAGE_IS_VENDOR(i
) || IMAGE_IS_HOST(i
))
769 /* Make sure we don't interfere with a running nspawn */
770 r
= image_path_lock(i
->path
, LOCK_EX
|LOCK_NB
, &global_lock
, &local_lock
);
776 case IMAGE_SUBVOLUME
:
778 /* Note that we set the flag only on the top-level
779 * subvolume of the image. */
781 r
= btrfs_subvol_set_read_only(i
->path
, b
);
787 case IMAGE_DIRECTORY
:
788 /* For simple directory trees we cannot use the access
789 mode of the top-level directory, since it has an
790 effect on the container itself. However, we can
791 use the "immutable" flag, to at least make the
792 top-level directory read-only. It's not as good as
793 a read-only subvolume, but at least something, and
794 we can read the value back. */
796 r
= chattr_path(i
->path
, b
? FS_IMMUTABLE_FL
: 0, FS_IMMUTABLE_FL
);
805 if (stat(i
->path
, &st
) < 0)
808 if (chmod(i
->path
, (st
.st_mode
& 0444) | (b
? 0000 : 0200)) < 0)
811 /* If the images is now read-only, it's a good time to
812 * defrag it, given that no write patterns will
813 * fragment it again. */
815 (void) btrfs_defrag(i
->path
);
820 _cleanup_close_
int fd
= -1;
824 fd
= open(i
->path
, O_CLOEXEC
|O_RDONLY
|O_NONBLOCK
|O_NOCTTY
);
828 if (fstat(fd
, &st
) < 0)
830 if (!S_ISBLK(st
.st_mode
))
833 if (ioctl(fd
, BLKROSET
, &state
) < 0)
846 int image_path_lock(const char *path
, int operation
, LockFile
*global
, LockFile
*local
) {
847 _cleanup_free_
char *p
= NULL
;
848 LockFile t
= LOCK_FILE_INIT
;
856 /* Locks an image path. This actually creates two locks: one
857 * "local" one, next to the image path itself, which might be
858 * shared via NFS. And another "global" one, in /run, that
859 * uses the device/inode number. This has the benefit that we
860 * can even lock a tree that is a mount point, correctly. */
862 if (!path_is_absolute(path
))
865 if (getenv_bool("SYSTEMD_NSPAWN_LOCK") == 0) {
866 *local
= *global
= (LockFile
) LOCK_FILE_INIT
;
870 if (path_equal(path
, "/"))
873 if (stat(path
, &st
) >= 0) {
874 if (S_ISBLK(st
.st_mode
))
875 r
= asprintf(&p
, "/run/systemd/nspawn/locks/block-%u:%u", major(st
.st_rdev
), minor(st
.st_rdev
));
876 else if (S_ISDIR(st
.st_mode
) || S_ISREG(st
.st_mode
))
877 r
= asprintf(&p
, "/run/systemd/nspawn/locks/inode-%lu:%lu", (unsigned long) st
.st_dev
, (unsigned long) st
.st_ino
);
885 /* For block devices we don't need the "local" lock, as the major/minor lock above should be sufficient, since
886 * block devices are device local anyway. */
887 if (!path_startswith(path
, "/dev")) {
888 r
= make_lock_file_for(path
, operation
, &t
);
894 mkdir_p("/run/systemd/nspawn/locks", 0700);
896 r
= make_lock_file(p
, operation
, global
);
898 release_lock_file(&t
);
902 *global
= (LockFile
) LOCK_FILE_INIT
;
908 int image_set_limit(Image
*i
, uint64_t referenced_max
) {
911 if (IMAGE_IS_VENDOR(i
) || IMAGE_IS_HOST(i
))
914 if (i
->type
!= IMAGE_SUBVOLUME
)
917 /* We set the quota both for the subvolume as well as for the
918 * subtree. The latter is mostly for historical reasons, since
919 * we didn't use to have a concept of subtree quota, and hence
920 * only modified the subvolume quota. */
922 (void) btrfs_qgroup_set_limit(i
->path
, 0, referenced_max
);
923 (void) btrfs_subvol_auto_qgroup(i
->path
, 0, true);
924 return btrfs_subvol_set_subtree_quota_limit(i
->path
, 0, referenced_max
);
927 int image_name_lock(const char *name
, int operation
, LockFile
*ret
) {
933 /* Locks an image name, regardless of the precise path used. */
935 if (!image_name_is_valid(name
))
938 if (getenv_bool("SYSTEMD_NSPAWN_LOCK") == 0) {
939 *ret
= (LockFile
) LOCK_FILE_INIT
;
943 if (streq(name
, ".host"))
946 mkdir_p("/run/systemd/nspawn/locks", 0700);
947 p
= strjoina("/run/systemd/nspawn/locks/name-", name
);
949 return make_lock_file(p
, operation
, ret
);
952 bool image_name_is_valid(const char *s
) {
953 if (!filename_is_valid(s
))
956 if (string_has_cc(s
, NULL
))
959 if (!utf8_is_valid(s
))
962 /* Temporary files for atomically creating new files */
963 if (startswith(s
, ".#"))
969 static const char* const image_type_table
[_IMAGE_TYPE_MAX
] = {
970 [IMAGE_DIRECTORY
] = "directory",
971 [IMAGE_SUBVOLUME
] = "subvolume",
973 [IMAGE_BLOCK
] = "block",
976 DEFINE_STRING_TABLE_LOOKUP(image_type
, ImageType
);