summaryrefslogtreecommitdiffstats
path: root/src/core
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2018-06-29 15:57:49 +0200
committerLennart Poettering <lennart@poettering.net>2018-11-29 20:21:39 +0100
commit846b3bd61e1d575b0b28f73c4d15385f94bb1662 (patch)
tree6c5a149cf229086e30ee76a0c9d0a55f67ea8e3a /src/core
parentcgroups: beef up DeviceAllow= syntax a bit (diff)
downloadsystemd-846b3bd61e1d575b0b28f73c4d15385f94bb1662.tar.xz
systemd-846b3bd61e1d575b0b28f73c4d15385f94bb1662.zip
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/core')
-rw-r--r--src/core/cgroup.c52
1 files changed, 2 insertions, 50 deletions
diff --git a/src/core/cgroup.c b/src/core/cgroup.c
index dd9b992ef1..72af5e855f 100644
--- a/src/core/cgroup.c
+++ b/src/core/cgroup.c
@@ -408,56 +408,8 @@ static int lookup_block_device(const char *p, dev_t *ret) {
return 0;
}
-static int shortcut_special_device_path(const char *p, struct stat *ret) {
- const char *w;
- mode_t mode;
- dev_t devt;
- int r;
-
- assert(p);
- assert(ret);
-
- if (path_equal(p, "/run/systemd/inaccessible/chr")) {
- *ret = (struct stat) {
- .st_mode = S_IFCHR,
- .st_rdev = makedev(0, 0),
- };
- return 0;
- }
-
- if (path_equal(p, "/run/systemd/inaccessible/blk")) {
- *ret = (struct stat) {
- .st_mode = S_IFBLK,
- .st_rdev = makedev(0, 0),
- };
- return 0;
- }
-
- w = path_startswith(p, "/dev/block/");
- if (w)
- mode = S_IFBLK;
- else {
- w = path_startswith(p, "/dev/char/");
- if (!w)
- return -ENODEV;
-
- mode = S_IFCHR;
- }
-
- r = parse_dev(w, &devt);
- if (r < 0)
- return r;
-
- *ret = (struct stat) {
- .st_mode = mode,
- .st_rdev = devt,
- };
-
- return 0;
-}
-
static int whitelist_device(BPFProgram *prog, const char *path, const char *node, const char *acc) {
- struct stat st;
+ struct stat st = {};
int r;
assert(path);
@@ -466,7 +418,7 @@ static int whitelist_device(BPFProgram *prog, const char *path, const char *node
/* Some special handling for /dev/block/%u:%u, /dev/char/%u:%u, /run/systemd/inaccessible/chr and
* /run/systemd/inaccessible/blk paths. Instead of stat()ing these we parse out the major/minor directly. This
* means clients can use these path without the device node actually around */
- r = shortcut_special_device_path(node, &st);
+ r = device_path_parse_major_minor(node, &st.st_mode, &st.st_rdev);
if (r < 0) {
if (r != -ENODEV)
return log_warning_errno(r, "Couldn't parse major/minor from device path '%s': %m", node);