• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

systemd / systemd / 22508817992

27 Feb 2026 10:57PM UTC coverage: 72.532% (-0.04%) from 72.575%
22508817992

push

github

poettering
NEWS: add various more features added in v260, and introduce more sections

315698 of 435256 relevant lines covered (72.53%)

1132137.23 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

88.73
/src/test/test-mstack.c
1
/* SPDX-License-Identifier: LGPL-2.1-or-later */
2

3
#include <sys/mount.h>
4
#include <sys/stat.h>
5

6
#include "capability-util.h"
7
#include "errno-util.h"
8
#include "fd-util.h"
9
#include "fs-util.h"
10
#include "mountpoint-util.h"
11
#include "mstack.h"
12
#include "path-util.h"
13
#include "process-util.h"
14
#include "rm-rf.h"
15
#include "tests.h"
16
#include "tmpfile-util.h"
17
#include "virt.h"
18

19
static bool overlayfs_set_fd_lowerdir_plus_supported(void) {
6✔
20
        int r;
6✔
21

22
        _cleanup_close_ int sb_fd = fsopen("overlay", FSOPEN_CLOEXEC);
12✔
23
        if (sb_fd < 0 && (ERRNO_IS_NOT_SUPPORTED(errno) || errno == ENODEV))
6✔
24
                return false;
25
        ASSERT_OK_ERRNO(sb_fd);
×
26

27
        _cleanup_close_ int layer_fd = open("/", O_DIRECTORY|O_CLOEXEC);
12✔
28
        ASSERT_OK_ERRNO(layer_fd);
6✔
29

30
        r = RET_NERRNO(fsconfig(sb_fd, FSCONFIG_SET_FD, "lowerdir+", /* value= */ NULL, layer_fd));
6✔
31
        if (r < 0 && (ERRNO_IS_NEG_NOT_SUPPORTED(r) || r == -EINVAL))
×
32
                return false;
33

34
        ASSERT_OK_ERRNO(r);
6✔
35
        return true;
36
}
37

38
TEST(mstack) {
6✔
39
        _cleanup_(rm_rf_physical_and_freep) char *t = NULL;
×
40
        _cleanup_close_ int tfd = -EBADF;
1✔
41
        int r;
6✔
42

43
        tfd = mkdtemp_open("/tmp/mstack-what-XXXXXX", O_PATH, &t);
6✔
44
        ASSERT_OK(tfd);
6✔
45

46
        ASSERT_OK_ERRNO(mkdirat(tfd, "rw", 0755));
6✔
47
        ASSERT_OK_ERRNO(mkdirat(tfd, "rw/data", 0755));
6✔
48
        ASSERT_OK_ERRNO(mkdirat(tfd, "rw/data/check1", 0755));
6✔
49
        ASSERT_OK_ERRNO(mkdirat(tfd, "layer@0", 0755));
6✔
50
        ASSERT_OK_ERRNO(mkdirat(tfd, "layer@0/check2", 0755));
6✔
51
        ASSERT_OK_ERRNO(mkdirat(tfd, "layer@0/zzz", 0755));
6✔
52
        ASSERT_OK_ERRNO(mkdirat(tfd, "layer@1", 0755));
6✔
53
        ASSERT_OK_ERRNO(mkdirat(tfd, "layer@1/check3", 0755));
6✔
54
        ASSERT_OK_ERRNO(mkdirat(tfd, "layer@0/yyy", 0755));
6✔
55
        ASSERT_OK_ERRNO(mkdirat(tfd, "bind@zzz", 0755));
6✔
56
        ASSERT_OK_ERRNO(mkdirat(tfd, "bind@zzz/check4", 0755));
6✔
57
        ASSERT_OK_ERRNO(mkdirat(tfd, "robind@yyy", 0755));
6✔
58
        ASSERT_OK_ERRNO(mkdirat(tfd, "robind@yyy/check5", 0755));
6✔
59

60
        _cleanup_(mstack_freep) MStack *mstack = NULL;
1✔
61
        ASSERT_OK(mstack_load(t, tfd, &mstack));
6✔
62

63
        ASSERT_OK_ZERO(mstack_is_read_only(mstack));
6✔
64
        ASSERT_OK_ZERO(mstack_is_foreign_uid_owned(mstack));
6✔
65

66
        if (!have_effective_cap(CAP_SYS_ADMIN))
6✔
67
                return (void) log_tests_skipped("not attaching mstack, lacking privs");
×
68
        if (!mount_new_api_supported())
6✔
69
                return (void) log_tests_skipped("kernel does not support new mount API, skipping mstack attachment test.");
×
70
        if (!overlayfs_set_fd_lowerdir_plus_supported())
6✔
71
                return (void) log_tests_skipped("overlayfs does not support FSCONFIG_SET_FD with lowerdir+, skipping mstack attachment test.");
×
72
        if (running_in_chroot() > 0) /* we cannot disable mount prop if we are in a chroot without the root inode being a proper mount point */
6✔
73
                return (void) log_tests_skipped("running in chroot(), skipping mstack attachment test.");
×
74

75
        mstack = mstack_free(mstack);
6✔
76

77
        /* For with a new mountns */
78
        r = pidref_safe_fork("(mstack-test", FORK_DEATHSIG_SIGTERM|FORK_LOG|FORK_WAIT|FORK_NEW_MOUNTNS|FORK_MOUNTNS_SLAVE, /* ret= */ NULL);
6✔
79
        ASSERT_OK(r);
6✔
80

81
        if (r == 0) {
6✔
82
                MStackFlags flags = 0;
5✔
83

84
                /* Close the original temporary fd, it still points to an inode of the original mountns,
85
                 * which we cannot use to generate mounts from */
86
                tfd = safe_close(tfd);
5✔
87

88
                {
89
                        ASSERT_OK(mstack_load(t, -EBADF, &mstack));
5✔
90

91
                        ASSERT_OK(mstack_open_images(
5✔
92
                                                  mstack,
93
                                                  /* mountfsd_link= */ NULL,
94
                                                  /* userns_fd= */ -EBADF,
95
                                                  /* image_policy= */ NULL,
96
                                                  /* image_filter= */ NULL,
97
                                                  flags));
98

99
                        _cleanup_(rmdir_and_freep) char *m = NULL;
1✔
100
                        ASSERT_OK(mkdtemp_malloc("/tmp/mstack-temporary-XXXXXX", &m));
5✔
101

102
                        ASSERT_OK(mstack_make_mounts(mstack, m, flags));
5✔
103

104
                        _cleanup_(rmdir_and_freep) char *w = NULL;
×
105
                        ASSERT_OK(mkdtemp_malloc("/tmp/mstack-where-XXXXXX", &w));
1✔
106

107
                        _cleanup_close_ int rfd = -EBADF;
1✔
108
                        ASSERT_OK(mstack_bind_mounts(mstack, w, /* where_fd= */ -EBADF, flags, &rfd));
1✔
109

110
                        _cleanup_close_ int ofd = open(w, O_PATH|O_CLOEXEC);
2✔
111
                        ASSERT_OK_ERRNO(ofd);
1✔
112

113
                        ASSERT_OK_ERRNO(faccessat(ofd, "check1", F_OK, AT_SYMLINK_NOFOLLOW));
1✔
114
                        ASSERT_OK_ERRNO(faccessat(ofd, "check2/", F_OK, AT_SYMLINK_NOFOLLOW));
1✔
115
                        ASSERT_OK_ERRNO(faccessat(ofd, "check3/", F_OK, AT_SYMLINK_NOFOLLOW));
1✔
116
                        ASSERT_OK_ERRNO(faccessat(ofd, "zzz/check4/", F_OK, AT_SYMLINK_NOFOLLOW));
1✔
117
                        ASSERT_OK_ERRNO(faccessat(ofd, "yyy/check5/", F_OK, AT_SYMLINK_NOFOLLOW));
1✔
118

119
                        _cleanup_free_ char *j = ASSERT_PTR(path_join(w, "zzz"));
1✔
120
                        ASSERT_OK_ERRNO(umount2(j, MNT_DETACH));
1✔
121
                        _cleanup_free_ char *jj = ASSERT_PTR(path_join(w, "yyy"));
2✔
122
                        ASSERT_OK_ERRNO(umount2(jj, MNT_DETACH));
1✔
123
                        ASSERT_OK_ERRNO(umount2(w, MNT_DETACH));
1✔
124
                }
125

126
                mstack = mstack_free(mstack);
1✔
127

128
                _exit(EXIT_SUCCESS);
1✔
129
        }
130
}
131

132
DEFINE_TEST_MAIN(LOG_INFO);
6✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc