From 5d2ebe5301bbc1c9c5a272ef1ceb81b553cddae7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20H=C3=B6ppner?= Date: Wed, 3 Apr 2019 13:26:14 +0200 Subject: [PATCH] libutil: Introduce util_sys and util_sys_get_dev_addr() MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Many tools need to identify the device address of a given device. So far, either the tool had its own implementation, or u2s_getbusid() was used. Though, u2s_getbusid() was mainly designed for and used by the DASD tools. Introduce util_sys with a first function util_sys_get_dev_addr() which provides a more universal way to identify the device address which is not limited to one particular device type. The device address represents either a busid (e.g. DASD), slot address (NVMe), H:C:T:L tuple (SCSI), or other id types associated with a device. Signed-off-by: Jan Höppner --- include/lib/util_sys.h | 17 ++++++++++ libutil/Makefile | 3 +- libutil/util_sys.c | 77 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 96 insertions(+), 1 deletion(-) create mode 100644 include/lib/util_sys.h create mode 100644 libutil/util_sys.c diff --git a/include/lib/util_sys.h b/include/lib/util_sys.h new file mode 100644 index 00000000..e0f078b0 --- /dev/null +++ b/include/lib/util_sys.h @@ -0,0 +1,17 @@ +/* + * @defgroup util_sys_h util_sys: SysFS interface + * @{ + * @brief Work with SysFS + * + * Copyright IBM Corp. 2019 + * + * s390-tools is free software; you can redistribute it and/or modify + * it under the terms of the MIT license. See LICENSE for details. + */ + +#ifndef LIB_UTIL_SYS_H +#define LIB_UTIL_SYS_H + +int util_sys_get_dev_addr(const char *dev, char *addr); + +#endif /** LIB_UTIL_SYS_H @} */ diff --git a/libutil/Makefile b/libutil/Makefile index ca90f2a4..4ab97fa4 100644 --- a/libutil/Makefile +++ b/libutil/Makefile @@ -27,7 +27,8 @@ objects = util_base.o \ util_part.o \ util_prg.o \ util_proc.o \ - util_rec.o + util_rec.o \ + util_sys.o util_base_example: util_base_example.o $(lib) util_panic_example: util_panic_example.o $(lib) diff --git a/libutil/util_sys.c b/libutil/util_sys.c new file mode 100644 index 00000000..93eac609 --- /dev/null +++ b/libutil/util_sys.c @@ -0,0 +1,77 @@ +/* + * util - Utility function library + * + * SysFS helper functions + * + * Copyright IBM Corp. 2019 + * + * s390-tools is free software; you can redistribute it and/or modify + * it under the terms of the MIT license. See LICENSE for details. + */ + +#include +#include +#include +#include +#include +#include +#include + +#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 + +/** + * Identify device address + * + * Identifying the device address with this function works for almost any + * character and block device (e.g. NVMe, SCSI, DASD, etc). + * The user must provide a buffer that is large enough for the desired device + * address to be read into \p addr. + * + * @param[in] dev Device node of interest + * @param[out] addr Identified device address + * + * @retval 0 Success + * @retval -1 Error while reading device information or + * constructed path + */ +int util_sys_get_dev_addr(const char *dev, char *addr) +{ + char device[READLINK_SIZE], *result; + unsigned int maj, min; + struct stat s; + ssize_t len; + char *path; + + if (stat(dev, &s) != 0) + return -1; + + maj = major(s.st_rdev); + min = minor(s.st_rdev); + + if (S_ISBLK(s.st_mode)) + path = util_path_sysfs("dev/block/%u:%u/device", maj, min); + else if (S_ISCHR(s.st_mode)) + path = util_path_sysfs("dev/char/%u:%u/device", maj, min); + else + return -1; + + len = readlink(path, device, READLINK_SIZE - 1); + free(path); + if (len != -1) + device[len] = '\0'; + else + return -1; + + result = strrchr(device, '/'); + if (result) + result++; + else + result = device; + strcpy(addr, result); + + return 0; +}