Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
openSUSE:Leap:15.4:Update
s390-tools.18357
s390-tools-sles15sp2-01-libutil-add-function-to...
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File s390-tools-sles15sp2-01-libutil-add-function-to-get-base-device-for-bloc.patch of Package s390-tools.18357
Subject: [PATCH] [BZ 190371] libutil: add function to get base device for blockdevice From: Stefan Haberland <sth@linux.ibm.com> Description: zipl: fix multi volume dump creation Symptom: zipl -M is not working. Problem: util_sys_get_dev_addr() returns the device address for a given blockdevice. This does not work for partitions but some tools like zipl rely on the ability to get the device address for partitions. Solution: Add code that determines the base device for a partition. Reproduction: Run zipl -M. Upstream-ID: fa7a4dafa3d89b2e8787de102e4362e895d44b05 Problem-ID: 190371 Upstream-Description: libutil: add function to get base device for blockdevice Some operations are only possible on base devices not on partitions. Add functions to determine if a given device is a partition or a base device and to get the base device to a given partition. Signed-off-by: Stefan Haberland <sth@linux.ibm.com> Reviewed-by: Jan Hoeppner <hoeppner@linux.ibm.com> Reviewed-by: Philipp Rudo <prudo@linux.ibm.com> Signed-off-by: Jan Hoeppner <hoeppner@linux.ibm.com> Signed-off-by: Stefan Haberland <sth@linux.ibm.com> --- include/lib/util_sys.h | 5 ++ libutil/util_sys.c | 97 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 102 insertions(+) --- a/include/lib/util_sys.h +++ b/include/lib/util_sys.h @@ -12,6 +12,11 @@ #ifndef LIB_UTIL_SYS_H #define LIB_UTIL_SYS_H +#include <stdbool.h> + int util_sys_get_dev_addr(const char *dev, char *addr); +bool util_sys_dev_is_partition(dev_t dev); +int util_sys_get_partnum(dev_t dev); +int util_sys_get_base_dev(dev_t dev, dev_t *base_dev); #endif /** LIB_UTIL_SYS_H @} */ --- a/libutil/util_sys.c +++ b/libutil/util_sys.c @@ -11,17 +11,114 @@ #include <err.h> #include <errno.h> +#include <linux/fs.h> #include <stdlib.h> +#include <stdio.h> #include <string.h> #include <sys/stat.h> #include <sys/sysmacros.h> #include <unistd.h> +#include "lib/util_file.h" +#include "lib/util_libc.h" #include "lib/util_path.h" #include "lib/util_sys.h" /* lstat() doesn't work for sysfs files, a fixed size is therefore inevitable */ #define READLINK_SIZE 256 +#define PAGE_SIZE 4096 + +/** + * Return the partition number of a given partition. + * + * @param[in] dev Device node of interest + * + * @retval int Partition number of the device + * @retval -1 Error when trying to read the partition number. + */ +int util_sys_get_partnum(dev_t dev) +{ + int partnum = -1; + char *path; + + path = util_path_sysfs("dev/block/%u:%u/partition", + major(dev), minor(dev)); + if (util_file_read_i(&partnum, 10, path)) { + warnx("Could not read from path '%s'", path); + goto out; + } + if (partnum <= 0) { + warnx("Bad partition number in '%s'", path); + partnum = -1; + goto out; + } + +out: + free(path); + return partnum; +} + +/** + * Determine if the given device is a partition. + * + * @param[in] dev Device node of interest + * + * @retval true Device is partition + * @retval false Device is not a partition + */ +bool util_sys_dev_is_partition(dev_t dev) +{ + bool is_part; + char *path; + + path = util_path_sysfs("dev/block/%u:%u/partition", + major(dev), minor(dev)); + is_part = util_path_exists(path); + free(path); + + return is_part; +} + +/** + * Determine base device + * + * This function determines the base device \p base_dev of a given + * device \p dev. If \p dev is a base device, \p base_dev becomes \p dev. + * + * @param[in] dev Device node of interest + * @param[out] base_dev Identified base device + * + * @retval 0 Success + * @retval -1 Error while reading device information or + * constructed path + */ +int util_sys_get_base_dev(dev_t dev, dev_t *base_dev) +{ + int base_major, base_minor; + char buf[PAGE_SIZE]; + char *path; + + /* check if the device already is a base device */ + if (!util_sys_dev_is_partition(dev)) { + *base_dev = makedev(major(dev), minor(dev)); + return 0; + } + path = util_path_sysfs("dev/block/%d:%d/../dev", + major(dev), minor(dev)); + if (util_file_read_line(buf, sizeof(buf), path)) { + warnx("Could not read from path '%s'", path); + free(path); + return -1; + } + free(path); + if (sscanf(buf, "%i:%i", &base_major, &base_minor) != 2) { + warn("Could not parse major:minor from string '%s'", buf); + return -1; + } + *base_dev = makedev(base_major, base_minor); + + return 0; +} /** * Identify device address
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor