diff options
author | Michael Biebl <biebl@debian.org> | 2018-06-22 13:38:31 +0200 |
---|---|---|
committer | Michael Biebl <biebl@debian.org> | 2018-06-22 13:38:31 +0200 |
commit | b012e92123bdc9fa10c2f079ec5bd9313b23e21a (patch) | |
tree | 94b74f04796e0da187092db7c2487aaf30f0faf1 /src/basic/blockdev-util.c | |
parent | 98393f852f2f66a74f7370aa63c07b26d610343c (diff) | |
download | systemd-b012e92123bdc9fa10c2f079ec5bd9313b23e21a.tar.gz |
New upstream version 239
Diffstat (limited to 'src/basic/blockdev-util.c')
-rw-r--r-- | src/basic/blockdev-util.c | 84 |
1 files changed, 32 insertions, 52 deletions
diff --git a/src/basic/blockdev-util.c b/src/basic/blockdev-util.c index 3a8f8d1c27..42b311eccd 100644 --- a/src/basic/blockdev-util.c +++ b/src/basic/blockdev-util.c @@ -1,22 +1,4 @@ /* SPDX-License-Identifier: LGPL-2.1+ */ -/*** - This file is part of systemd. - - Copyright 2010 Lennart Poettering - - systemd is free software; you can redistribute it and/or modify it - under the terms of the GNU Lesser General Public License as published by - the Free Software Foundation; either version 2.1 of the License, or - (at your option) any later version. - - systemd is distributed in the hope that it will be useful, but - WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Lesser General Public License for more details. - - You should have received a copy of the GNU Lesser General Public License - along with systemd; If not, see <http://www.gnu.org/licenses/>. -***/ #include <sys/stat.h> #include <sys/statfs.h> @@ -94,38 +76,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) { @@ -153,34 +123,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; @@ -188,12 +152,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; } |