mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
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 Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
committed by
Jan Höppner
parent
7eb04cdc54
commit
fa7a4dafa3
@@ -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 @} */
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user