From 45c2e0685463b9d47fb647b1a94467fefd21b05c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 11 Jun 2018 12:17:32 +0200 Subject: [PATCH] cgroup: beef up device lookup logic for block devices Let's chase block devices through btrfs and LUKS like we do elsewhere. --- src/core/cgroup.c | 37 ++++++++++++++++++++++--------------- 1 file changed, 22 insertions(+), 15 deletions(-) diff --git a/src/core/cgroup.c b/src/core/cgroup.c index adc3e4a..eb350d7 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -11,6 +11,7 @@ #include "alloc-util.h" #include "blockdev-util.h" #include "bpf-firewall.h" +#include "btrfs-util.h" #include "bus-error.h" #include "cgroup-util.h" #include "cgroup.h" @@ -306,30 +307,36 @@ void cgroup_context_dump(CGroupContext *c, FILE* f, const char *prefix) { } } -static int lookup_block_device(const char *p, dev_t *dev) { +static int lookup_block_device(const char *p, dev_t *ret) { struct stat st; + int r; assert(p); - assert(dev); + assert(ret); if (stat(p, &st) < 0) - return log_warning_errno(errno, "Couldn't stat device %s: %m", p); + return log_warning_errno(errno, "Couldn't stat device '%s': %m", p); if (S_ISBLK(st.st_mode)) - *dev = st.st_rdev; - else if (major(st.st_dev) != 0) { - /* If this is not a device node then find the block - * device this file is stored on */ - *dev = st.st_dev; - - /* If this is a partition, try to get the originating - * block device */ - (void) block_get_whole_disk(*dev, dev); - } else { - log_warning("%s is not a block device and file system block device cannot be determined or is not local.", p); - return -ENODEV; + *ret = st.st_rdev; + else if (major(st.st_dev) != 0) + *ret = st.st_dev; /* If this is not a device node then use the block device this file is stored on */ + else { + /* If this is btrfs, getting the backing block device is a bit harder */ + r = btrfs_get_block_device(p, ret); + if (r < 0 && r != -ENOTTY) + return log_warning_errno(r, "Failed to determine block device backing btrfs file system '%s': %m", p); + if (r == -ENOTTY) { + log_warning("'%s' is not a block device node, and file system block device cannot be determined or is not local.", p); + return -ENODEV; + } } + /* If this is a LUKS device, try to get the originating block device */ + (void) block_get_originating(*ret, ret); + + /* If this is a partition, try to get the originating block device */ + (void) block_get_whole_disk(*ret, ret); return 0; } -- 2.7.4