diff options
author | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2018-06-12 12:53:37 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-06-12 12:53:37 +0200 |
commit | 24d169e092b31c7f54fa49a86b8167aac4385ed3 (patch) | |
tree | f085c41ad9e41e9d1c8790e6a02f0e3c74cd98c2 /src/basic | |
parent | journal: forward messages from /dev/log unmodified to syslog.socket (diff) | |
parent | tree-wide: use PATH_STARTSWITH_SET() at two more places (diff) | |
download | systemd-24d169e092b31c7f54fa49a86b8167aac4385ed3.tar.xz systemd-24d169e092b31c7f54fa49a86b8167aac4385ed3.zip |
Merge pull request #9255 from poettering/block-dev-fixes
some block device handling fixes
Diffstat (limited to 'src/basic')
-rw-r--r-- | src/basic/blockdev-util.c | 66 | ||||
-rw-r--r-- | src/basic/blockdev-util.h | 1 | ||||
-rw-r--r-- | src/basic/btrfs-util.c | 4 | ||||
-rw-r--r-- | src/basic/path-util.c | 35 | ||||
-rw-r--r-- | src/basic/path-util.h | 4 |
5 files changed, 66 insertions, 44 deletions
diff --git a/src/basic/blockdev-util.c b/src/basic/blockdev-util.c index b15b8cf770..0b090bb2ed 100644 --- a/src/basic/blockdev-util.c +++ b/src/basic/blockdev-util.c @@ -81,38 +81,26 @@ int get_block_device(const char *path, dev_t *dev) { if (F_TYPE_EQUAL(sfs.f_type, BTRFS_SUPER_MAGIC)) return btrfs_get_block_device(path, dev); + *dev = 0; return 0; } -int get_block_device_harder(const char *path, dev_t *dev) { +int block_get_originating(dev_t dt, dev_t *ret) { _cleanup_closedir_ DIR *d = NULL; _cleanup_free_ char *t = NULL; char p[SYS_BLOCK_PATH_MAX("/slaves")]; struct dirent *de, *found = NULL; - const char *q; unsigned maj, min; - dev_t dt; + const char *q; int r; - assert(path); - assert(dev); - - /* Gets the backing block device for a file system, and - * handles LUKS encrypted file systems, looking for its - * immediate parent, if there is one. */ - - r = get_block_device(path, &dt); - if (r <= 0) - return r; + /* For the specified block device tries to chase it through the layers, in case LUKS-style DM stacking is used, + * trying to find the next underlying layer. */ xsprintf_sys_block_path(p, "/slaves", dt); d = opendir(p); - if (!d) { - if (errno == ENOENT) - goto fallback; - + if (!d) return -errno; - } FOREACH_DIRENT_ALL(de, d, return -errno) { @@ -140,34 +128,28 @@ int get_block_device_harder(const char *path, dev_t *dev) { return -ENOMEM; r = read_one_line_file(u, &a); - if (r < 0) { - log_debug_errno(r, "Failed to read %s: %m", u); - goto fallback; - } + if (r < 0) + return log_debug_errno(r, "Failed to read %s: %m", u); r = read_one_line_file(v, &b); - if (r < 0) { - log_debug_errno(r, "Failed to read %s: %m", v); - goto fallback; - } + if (r < 0) + return log_debug_errno(r, "Failed to read %s: %m", v); /* Check if the parent device is the same. If not, then the two backing devices are on * different physical devices, and we don't support that. */ if (!streq(a, b)) - goto fallback; + return -ENOTUNIQ; } found = de; } if (!found) - goto fallback; + return -ENOENT; q = strjoina(p, "/", found->d_name, "/dev"); r = read_one_line_file(q, &t); - if (r == -ENOENT) - goto fallback; if (r < 0) return r; @@ -175,12 +157,28 @@ int get_block_device_harder(const char *path, dev_t *dev) { return -EINVAL; if (maj == 0) - goto fallback; + return -ENOENT; - *dev = makedev(maj, min); + *ret = makedev(maj, min); return 1; +} + +int get_block_device_harder(const char *path, dev_t *ret) { + int r; + + assert(path); + assert(ret); + + /* Gets the backing block device for a file system, and handles LUKS encrypted file systems, looking for its + * immediate parent, if there is one. */ + + r = get_block_device(path, ret); + if (r <= 0) + return r; + + r = block_get_originating(*ret, ret); + if (r < 0) + log_debug_errno(r, "Failed to chase block device '%s', ignoring: %m", path); -fallback: - *dev = dt; return 1; } diff --git a/src/basic/blockdev-util.h b/src/basic/blockdev-util.h index 500fbcdff1..34cbffd98f 100644 --- a/src/basic/blockdev-util.h +++ b/src/basic/blockdev-util.h @@ -19,6 +19,7 @@ xsprintf(buf, "/sys/dev/block/%u:%u%s", major(devno), minor(devno), strempty(suffix)) int block_get_whole_disk(dev_t d, dev_t *ret); +int block_get_originating(dev_t d, dev_t *ret); int get_block_device(const char *path, dev_t *dev); diff --git a/src/basic/btrfs-util.c b/src/basic/btrfs-util.c index 7720d98009..32a022f7ce 100644 --- a/src/basic/btrfs-util.c +++ b/src/basic/btrfs-util.c @@ -277,8 +277,10 @@ int btrfs_get_block_device_fd(int fd, dev_t *dev) { return -errno; /* We won't do this for btrfs RAID */ - if (fsi.num_devices != 1) + if (fsi.num_devices != 1) { + *dev = 0; return 0; + } for (id = 1; id <= fsi.max_id; id++) { struct btrfs_ioctl_dev_info_args di = { diff --git a/src/basic/path-util.c b/src/basic/path-util.c index f36301ccf5..2e68de9e63 100644 --- a/src/basic/path-util.c +++ b/src/basic/path-util.c @@ -886,17 +886,36 @@ bool hidden_or_backup_file(const char *filename) { bool is_device_path(const char *path) { - /* Returns true on paths that refer to a device, either in - * sysfs or in /dev */ + /* Returns true on paths that likely refer to a device, either by path in sysfs or to something in /dev */ - return path_startswith(path, "/dev/") || - path_startswith(path, "/sys/"); + return PATH_STARTSWITH_SET(path, "/dev/", "/sys/"); } -bool is_deviceallow_pattern(const char *path) { - return path_startswith(path, "/dev/") || - startswith(path, "block-") || - startswith(path, "char-"); +bool valid_device_node_path(const char *path) { + + /* Some superficial checks whether the specified path is a valid device node path, all without looking at the + * actual device node. */ + + if (!PATH_STARTSWITH_SET(path, "/dev/", "/run/systemd/inaccessible/")) + return false; + + if (endswith(path, "/")) /* can't be a device node if it ends in a slash */ + return false; + + return path_is_normalized(path); +} + +bool valid_device_allow_pattern(const char *path) { + assert(path); + + /* Like valid_device_node_path(), but also allows full-subsystem expressions, like DeviceAllow= and DeviceDeny= + * accept it */ + + if (startswith(path, "block-") || + startswith(path, "char-")) + return true; + + return valid_device_node_path(path); } int systemd_installation_has_version(const char *root, unsigned minimal_version) { diff --git a/src/basic/path-util.h b/src/basic/path-util.h index d8a923d3cd..486046f861 100644 --- a/src/basic/path-util.h +++ b/src/basic/path-util.h @@ -147,7 +147,9 @@ char *file_in_same_dir(const char *path, const char *filename); bool hidden_or_backup_file(const char *filename) _pure_; bool is_device_path(const char *path); -bool is_deviceallow_pattern(const char *path); + +bool valid_device_node_path(const char *path); +bool valid_device_allow_pattern(const char *path); int systemd_installation_has_version(const char *root, unsigned minimal_version); |