]>
Commit | Line | Data |
---|---|---|
7176f06c LP |
1 | /* SPDX-License-Identifier: LGPL-2.1-or-later */ |
2 | ||
3 | #include <sys/stat.h> | |
4 | ||
5 | #include "devnum-util.h" | |
6 | #include "path-util.h" | |
7 | #include "stat-util.h" | |
8 | #include "tests.h" | |
9 | ||
10 | TEST(parse_devnum) { | |
11 | dev_t dev; | |
12 | ||
13 | assert_se(parse_devnum("", &dev) == -EINVAL); | |
14 | assert_se(parse_devnum("junk", &dev) == -EINVAL); | |
15 | assert_se(parse_devnum("0", &dev) == -EINVAL); | |
16 | assert_se(parse_devnum("5", &dev) == -EINVAL); | |
17 | assert_se(parse_devnum("5:", &dev) == -EINVAL); | |
18 | assert_se(parse_devnum(":5", &dev) == -EINVAL); | |
19 | assert_se(parse_devnum("-1:-1", &dev) == -EINVAL); | |
20 | #if SIZEOF_DEV_T < 8 | |
21 | assert_se(parse_devnum("4294967295:4294967295", &dev) == -EINVAL); | |
22 | #endif | |
23 | assert_se(parse_devnum("8:11", &dev) >= 0 && major(dev) == 8 && minor(dev) == 11); | |
24 | assert_se(parse_devnum("0:0", &dev) >= 0 && major(dev) == 0 && minor(dev) == 0); | |
25 | } | |
26 | ||
27 | TEST(device_major_minor_valid) { | |
da890466 | 28 | /* on glibc dev_t is 64-bit, even though in the kernel it is only 32-bit */ |
7176f06c LP |
29 | assert_cc(sizeof(dev_t) == sizeof(uint64_t)); |
30 | ||
31 | assert_se(DEVICE_MAJOR_VALID(0U)); | |
32 | assert_se(DEVICE_MINOR_VALID(0U)); | |
33 | ||
34 | assert_se(DEVICE_MAJOR_VALID(1U)); | |
35 | assert_se(DEVICE_MINOR_VALID(1U)); | |
36 | ||
37 | assert_se(!DEVICE_MAJOR_VALID(-1U)); | |
38 | assert_se(!DEVICE_MINOR_VALID(-1U)); | |
39 | ||
40 | assert_se(DEVICE_MAJOR_VALID(1U << 10)); | |
41 | assert_se(DEVICE_MINOR_VALID(1U << 10)); | |
42 | ||
43 | assert_se(DEVICE_MAJOR_VALID((1U << 12) - 1)); | |
44 | assert_se(DEVICE_MINOR_VALID((1U << 20) - 1)); | |
45 | ||
46 | assert_se(!DEVICE_MAJOR_VALID((1U << 12))); | |
47 | assert_se(!DEVICE_MINOR_VALID((1U << 20))); | |
48 | ||
49 | assert_se(!DEVICE_MAJOR_VALID(1U << 25)); | |
50 | assert_se(!DEVICE_MINOR_VALID(1U << 25)); | |
51 | ||
52 | assert_se(!DEVICE_MAJOR_VALID(UINT32_MAX)); | |
53 | assert_se(!DEVICE_MINOR_VALID(UINT32_MAX)); | |
54 | ||
55 | assert_se(!DEVICE_MAJOR_VALID(UINT64_MAX)); | |
56 | assert_se(!DEVICE_MINOR_VALID(UINT64_MAX)); | |
57 | ||
58 | assert_se(DEVICE_MAJOR_VALID(major(0))); | |
59 | assert_se(DEVICE_MINOR_VALID(minor(0))); | |
60 | } | |
61 | ||
62 | static void test_device_path_make_canonical_one(const char *path) { | |
63 | _cleanup_free_ char *resolved = NULL, *raw = NULL; | |
64 | struct stat st; | |
65 | dev_t devno; | |
66 | mode_t mode; | |
67 | int r; | |
68 | ||
69 | log_debug("> %s", path); | |
70 | ||
71 | if (stat(path, &st) < 0) { | |
72 | assert_se(errno == ENOENT); | |
73 | log_notice("Path %s not found, skipping test", path); | |
74 | return; | |
75 | } | |
76 | ||
77 | r = device_path_make_canonical(st.st_mode, st.st_rdev, &resolved); | |
78 | if (r == -ENOENT) { | |
79 | /* maybe /dev/char/x:y and /dev/block/x:y are missing in this test environment, because we | |
80 | * run in a container or so? */ | |
81 | log_notice("Device %s cannot be resolved, skipping test", path); | |
82 | return; | |
83 | } | |
84 | ||
85 | assert_se(r >= 0); | |
86 | assert_se(path_equal(path, resolved)); | |
87 | ||
88 | assert_se(device_path_make_major_minor(st.st_mode, st.st_rdev, &raw) >= 0); | |
89 | assert_se(device_path_parse_major_minor(raw, &mode, &devno) >= 0); | |
90 | ||
91 | assert_se(st.st_rdev == devno); | |
92 | assert_se((st.st_mode & S_IFMT) == (mode & S_IFMT)); | |
93 | } | |
94 | ||
95 | TEST(device_path_make_canonical) { | |
96 | test_device_path_make_canonical_one("/dev/null"); | |
97 | test_device_path_make_canonical_one("/dev/zero"); | |
98 | test_device_path_make_canonical_one("/dev/full"); | |
99 | test_device_path_make_canonical_one("/dev/random"); | |
100 | test_device_path_make_canonical_one("/dev/urandom"); | |
101 | test_device_path_make_canonical_one("/dev/tty"); | |
102 | ||
103 | if (is_device_node("/run/systemd/inaccessible/blk") > 0) { | |
104 | test_device_path_make_canonical_one("/run/systemd/inaccessible/chr"); | |
105 | test_device_path_make_canonical_one("/run/systemd/inaccessible/blk"); | |
106 | } | |
107 | } | |
108 | ||
ec61371f LP |
109 | static void test_devnum_format_str_one(dev_t devnum, const char *s) { |
110 | dev_t x; | |
111 | ||
112 | assert_se(streq(FORMAT_DEVNUM(devnum), s)); | |
113 | assert_se(parse_devnum(s, &x) >= 0); | |
114 | assert_se(x == devnum); | |
115 | } | |
116 | ||
117 | TEST(devnum_format_str) { | |
118 | test_devnum_format_str_one(makedev(0, 0), "0:0"); | |
119 | test_devnum_format_str_one(makedev(1, 2), "1:2"); | |
120 | test_devnum_format_str_one(makedev(99, 100), "99:100"); | |
121 | test_devnum_format_str_one(makedev(4095, 1048575), "4095:1048575"); | |
122 | } | |
123 | ||
7176f06c | 124 | DEFINE_TEST_MAIN(LOG_INFO); |