diff options
author | Lennart Poettering <lennart@poettering.net> | 2018-06-29 15:57:49 +0200 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2018-11-29 20:21:39 +0100 |
commit | 846b3bd61e1d575b0b28f73c4d15385f94bb1662 (patch) | |
tree | 6c5a149cf229086e30ee76a0c9d0a55f67ea8e3a /src/test/test-stat-util.c | |
parent | 8e8b5d2e6d91180a57844b09cdbdcbc1fa466bfa (diff) | |
download | systemd-846b3bd61e1d575b0b28f73c4d15385f94bb1662.tar.gz |
stat-util: add new APIs device_path_make_{major_minor|canonical}() and device_path_parse_major_minor()
device_path_make_{major_minor|canonical) generate device node paths
given a mode_t and a dev_t. We have similar code all over the place,
let's unify this in one place. The former will generate a "/dev/char/"
or "/dev/block" path, and never go to disk. The latter then goes to disk
and resolves that path to the actual path of the device node.
device_path_parse_major_minor() reverses device_path_make_major_minor(),
also withozut going to disk.
We have similar code doing something like this at various places, let's
unify this in a single set of functions. This also allows us to teach
them special tricks, for example handling of the
/run/systemd/inaccessible/{blk|chr} device nodes, which we use for
masking device nodes, and which do not exist in /dev/char/* and
/dev/block/*
Diffstat (limited to 'src/test/test-stat-util.c')
-rw-r--r-- | src/test/test-stat-util.c | 40 |
1 files changed, 40 insertions, 0 deletions
diff --git a/src/test/test-stat-util.c b/src/test/test-stat-util.c index 713fbc9a08..4201edac97 100644 --- a/src/test/test-stat-util.c +++ b/src/test/test-stat-util.c @@ -11,6 +11,7 @@ #include "missing.h" #include "mount-util.h" #include "stat-util.h" +#include "path-util.h" static void test_files_same(void) { _cleanup_close_ int fd = -1; @@ -116,6 +117,44 @@ static void test_device_major_minor_valid(void) { assert_se(DEVICE_MINOR_VALID(minor(0))); } +static void test_device_path_make_canonical_one(const char *path) { + _cleanup_free_ char *resolved = NULL, *raw = NULL; + struct stat st; + dev_t devno; + mode_t mode; + int r; + + assert_se(stat(path, &st) >= 0); + r = device_path_make_canonical(st.st_mode, st.st_rdev, &resolved); + if (r == -ENOENT) /* maybe /dev/char/x:y and /dev/block/x:y are missing in this test environment, because we + * run in a container or so? */ + return; + + assert_se(r >= 0); + assert_se(path_equal(path, resolved)); + + assert_se(device_path_make_major_minor(st.st_mode, st.st_rdev, &raw) >= 0); + assert_se(device_path_parse_major_minor(raw, &mode, &devno) >= 0); + + assert_se(st.st_rdev == devno); + assert_se((st.st_mode & S_IFMT) == (mode & S_IFMT)); +} + +static void test_device_path_make_canonical(void) { + + test_device_path_make_canonical_one("/dev/null"); + test_device_path_make_canonical_one("/dev/zero"); + test_device_path_make_canonical_one("/dev/full"); + test_device_path_make_canonical_one("/dev/random"); + test_device_path_make_canonical_one("/dev/urandom"); + test_device_path_make_canonical_one("/dev/tty"); + + if (is_device_node("/run/systemd/inaccessible/chr") > 0) { + test_device_path_make_canonical_one("/run/systemd/inaccessible/chr"); + test_device_path_make_canonical_one("/run/systemd/inaccessible/blk"); + } +} + int main(int argc, char *argv[]) { test_files_same(); test_is_symlink(); @@ -123,6 +162,7 @@ int main(int argc, char *argv[]) { test_path_is_temporary_fs(); test_fd_is_network_ns(); test_device_major_minor_valid(); + test_device_path_make_canonical(); return 0; } |