Subject: zdev: use libutil provided path functions From: Peter Oberparleiter Summary: zdev: Add support for handling I/O configuration data Description: LPARs that are running in IBM Dynamic Partition Manager (DPM) mode can access a firmware-generated I/O configuration data file that contains s390-specific information about available I/O devices such as qeth device numbers and parameters, and FCP device IDs. This data file is intended to remove the need for users to manually enter the corresponding device data during installation. Linux kernels with the corresponding support make the I/O configuration data available at the following location: /sys/firmware/sclp_sd/config/data This patch set adds support for handling this data file using the chzdev and lszdev tools: - I/O configuration data can be applied using chzdev's --import option - Initial RAM-Disk scripts automatically apply the I/O configuration data to the system configuration - lszdev can be used to display the applied auto-configuration data - chzdev can be used to manually override the auto-configuration data Upstream-ID: d542138868153a36c3de6a21c3dea56125157e26 Problem-ID: LS1604 Upstream-Description: zdev: use libutil provided path functions Closes: #20 Signed-off-by: Rafael Fonseca Acked-by: Peter Oberparleiter Signed-off-by: Michael Holzheu Signed-off-by: Peter Oberparleiter --- zdev/include/misc.h | 4 -- zdev/src/ccw.c | 20 ++++-------- zdev/src/ccwgroup.c | 7 ++-- zdev/src/chzdev.c | 3 + zdev/src/ctc_auto.c | 6 ++- zdev/src/device.c | 5 ++- zdev/src/devnode.c | 8 +++- zdev/src/generic_ccw.c | 4 +- zdev/src/lcs_auto.c | 6 ++- zdev/src/misc.c | 63 --------------------------------------- zdev/src/modprobe.c | 8 +++- zdev/src/module.c | 8 +++- zdev/src/qeth_auto.c | 4 +- zdev/src/root.c | 4 +- zdev/src/scsi.c | 4 +- zdev/src/select.c | 4 +- zdev/src/udev.c | 4 +- zdev/src/udev_ccw.c | 10 +++--- zdev/src/udev_ccwgroup.c | 10 +++--- zdev/src/udev_zfcp_lun.c | 8 +++- zdev/src/zfcp_lun.c | 16 +++++---- 21 files changed, 84 insertions(+), 122 deletions(-) --- a/zdev/include/misc.h +++ b/zdev/include/misc.h @@ -157,10 +157,6 @@ char *misc_asprintf(const char *, ...); int misc_system(err_t, const char *, ...); bool misc_read_dir(const char *, struct util_list *, bool (*)(const char *, void *), void *); -bool path_exists(const char *); -bool file_exists(const char *); -bool file_writable(const char *); -bool dir_exists(const char *); bool file_is_devnode(const char *); exit_code_t remove_file(const char *); char *misc_read_text_file(const char *, int, err_t); --- a/zdev/src/ccw.c +++ b/zdev/src/ccw.c @@ -14,6 +14,7 @@ #include #include "lib/util_base.h" +#include "lib/util_path.h" #include "attrib.h" #include "ccw.h" @@ -1165,15 +1166,10 @@ out: static void read_grouped(struct ccw_devinfo *info, const char *path) { - char *file_path; - - file_path = misc_asprintf("%s/group_device", path); - if (path_exists(file_path)) + if (util_path_exists("%s/group_device", path)) info->grouped = 1; else info->grouped = 0; - - free(file_path); } static void read_cutype(struct ccw_devinfo *info, const char *path) @@ -1229,7 +1225,7 @@ static struct ccw_devinfo *ccw_devinfo_r id = ccw_devid_to_str(devid); path = path_get_ccw_device(NULL, id); - if (!dir_exists(path)) + if (!util_path_is_dir(path)) goto out; info->exists = 1; @@ -1354,7 +1350,7 @@ bool ccw_exists(const char *drv, const c if (!path) return false; - rc = dir_exists(path); + rc = util_path_is_dir(path); free(path); return rc; @@ -1428,7 +1424,7 @@ static exit_code_t ccw_st_read_active(st state->definable = 0; path = path_get_ccw_device(drv, id); - if (path_exists(path)) { + if (util_path_exists(path)) { state->exists = 1; device_read_active_settings(dev, scope); } else @@ -1641,7 +1637,7 @@ static void ccw_st_add_errors(struct sub if (!path) return; - if (!path_exists(path)) { + if (!util_path_exists(path)) { strlist_add(errors, "CCW device %s does not exist", id); goto out; } @@ -1662,9 +1658,7 @@ static void ccw_st_add_errors(struct sub "paths", id); goto out; } - free(apath); - apath = misc_asprintf("%s/driver", path); - if (!path_exists(apath)) { + if (!util_path_exists("%s/driver", path)) { strlist_add(errors, "CCW device %s is not bound to a driver", id); goto out; --- a/zdev/src/ccwgroup.c +++ b/zdev/src/ccwgroup.c @@ -12,6 +12,7 @@ #include #include "lib/util_base.h" +#include "lib/util_path.h" #include "attrib.h" #include "ccw.h" @@ -557,7 +558,7 @@ static bool read_full_id(struct ccwgroup bool result = false; path = path_get_ccwgroup_device(drv, id); - if (!dir_exists(path)) + if (!util_path_is_dir(path)) goto out; memset(&devid, 0, sizeof(struct ccwgroup_devid)); @@ -625,7 +626,7 @@ static void ccwgroup_add_ids(const char path = path_get_ccwgroup_devices(drv); if (mod) module_try_load_once(mod, path); - if (dir_exists(path)) + if (util_path_is_dir(path)) path_for_each(path, get_ids_cb, &cb_data); free(path); } @@ -663,7 +664,7 @@ static exit_code_t ccwgroup_st_read_acti state->definable = 0; path = ccwgroup_get_dev_path_by_devid(drv, devid); - if (path_exists(path)) { + if (util_path_exists(path)) { state->exists = 1; device_read_active_settings(dev, scope); } else --- a/zdev/src/chzdev.c +++ b/zdev/src/chzdev.c @@ -16,6 +16,7 @@ #include #include +#include "lib/util_path.h" #include "lib/zt_common.h" #include "attrib.h" @@ -2502,7 +2503,7 @@ static exit_code_t do_export(struct opti info("Exporting configuration data to standard output\n"); } else { info("Exporting configuration data to %s\n", opts->export); - if (!path_exists(opts->export)) { + if (!util_path_exists(opts->export)) { rc = path_create(opts->export); if (rc) return rc; --- a/zdev/src/ctc_auto.c +++ b/zdev/src/ctc_auto.c @@ -9,6 +9,8 @@ #include +#include "lib/util_path.h" + #include "ccw.h" #include "ccwgroup.h" #include "ctc.h" @@ -125,13 +127,13 @@ static struct util_list *read_sorted_ctc /* Add CCW devices bound to the CTC CCW device driver. */ module_try_load_once(CTC_MOD_NAME, NULL); path = path_get_sys_bus_drv(CCW_BUS_NAME, CTC_CCWDRV_NAME); - if (dir_exists(path)) + if (util_path_is_dir(path)) path_for_each(path, add_cb, infos); free(path); /* Add CCW devices bound to the LCS CCW device driver. */ path = path_get_sys_bus_drv(CCW_BUS_NAME, LCS_CCWDRV_NAME); - if (dir_exists(path)) + if (util_path_is_dir(path)) path_for_each(path, add_cb, infos); free(path); --- a/zdev/src/device.c +++ b/zdev/src/device.c @@ -11,6 +11,8 @@ #include #include +#include "lib/util_path.h" + #include "attrib.h" #include "device.h" #include "devtype.h" @@ -480,7 +482,8 @@ void device_read_active_settings(struct a = attrib_find(st->dev_attribs, name); s = setting_list_apply_actual(dev->active.settings, a, name, value); - if (link || (scope == scope_all && !file_writable(path))) + if (link || (scope == scope_all && + !util_path_is_writable(path))) s->readonly = 1; if (link) free(link); --- a/zdev/src/devnode.c +++ b/zdev/src/devnode.c @@ -15,6 +15,8 @@ #include #include +#include "lib/util_path.h" + #include "devnode.h" #include "misc.h" #include "path.h" @@ -230,7 +232,7 @@ static exit_code_t add_block_cb(const ch /* Add additional nodes. */ cb_data->prefix = filename; - if (dir_exists(path)) + if (util_path_is_dir(path)) path_for_each(path, add_part_cb, cb_data); return EXIT_OK; @@ -249,7 +251,7 @@ int devnode_add_block_from_sysfs(struct cb_data.prefix = NULL; blkpath = misc_asprintf("%s/block", path); - if (dir_exists(blkpath)) + if (util_path_is_dir(blkpath)) path_for_each(blkpath, add_block_cb, &cb_data); free(blkpath); @@ -283,7 +285,7 @@ int devnode_add_net_from_sysfs(struct ut cb_data.prefix = NULL; netpath = misc_asprintf("%s/net", path); - if (dir_exists(netpath)) + if (util_path_is_dir(netpath)) path_for_each(netpath, add_net_cb, &cb_data); free(netpath); --- a/zdev/src/generic_ccw.c +++ b/zdev/src/generic_ccw.c @@ -9,6 +9,8 @@ #include +#include "lib/util_path.h" + #include "attrib.h" #include "ccw.h" #include "ccwgroup.h" @@ -162,7 +164,7 @@ static void generic_ccw_st_add_devnodes( cb_data.devnodes = devnodes; cb_data.id = id; path = path_get_sys_dev_char_devices(); - if (dir_exists(path)) + if (util_path_is_dir(path)) path_for_each(path, add_cb, &cb_data); free(path); } --- a/zdev/src/lcs_auto.c +++ b/zdev/src/lcs_auto.c @@ -9,6 +9,8 @@ #include +#include "lib/util_path.h" + #include "ccw.h" #include "ccwgroup.h" #include "ctc.h" @@ -129,13 +131,13 @@ static struct util_list *read_sorted_lcs /* Add CCW devices bound to the LCS CCW device driver. */ module_try_load_once(LCS_MOD_NAME, NULL); path = path_get_sys_bus_drv(CCW_BUS_NAME, LCS_CCWDRV_NAME); - if (dir_exists(path)) + if (util_path_is_dir(path)) path_for_each(path, add_cb, infos); free(path); /* Add CCW devices bound to the CTC CCW device driver. */ path = path_get_sys_bus_drv(CCW_BUS_NAME, CTC_CCWDRV_NAME); - if (dir_exists(path)) + if (util_path_is_dir(path)) path_for_each(path, add_cb, infos); free(path); --- a/zdev/src/misc.c +++ b/zdev/src/misc.c @@ -889,69 +889,6 @@ void ptrlist_move(struct util_list *to, util_list_add_tail(to, node); } -/* Check if a path exists. */ -bool path_exists(const char *path) -{ - struct stat s; - - debug("Checking if file exists: %s\n", path); - if (stat(path, &s) != 0) - return false; - - return true; -} - -/* Check if a file exists. */ -bool file_exists(const char *path) -{ - struct stat s; - - debug("Checking if regular file exists: %s\n", path); - if (stat(path, &s) != 0) - return false; - - if (!S_ISREG(s.st_mode)) - return false; - - return true; -} - -/* Check if a file is writable. */ -bool file_writable(const char *path) -{ - struct stat s; - - debug("Checking if regular file is writable: %s\n", path); - if (stat(path, &s) != 0) - return false; - - if (!S_ISREG(s.st_mode)) - return false; - - if (!(s.st_mode & (S_IWUSR | S_IWGRP | S_IWOTH))) - return false; - - return true; -} - -/* Check if a directory exists. */ -bool dir_exists(const char *path) -{ - bool result = false; - struct stat s; - - debug("Checking if directory exists: %s\n", path); - if (stat(path, &s) != 0) - goto out; - if (!S_ISDIR(s.st_mode)) - goto out; - result = true; -out: - debug("Result: %d\n", result); - - return result; -} - /* Check if file is a block or character special file. */ bool file_is_devnode(const char *path) { --- a/zdev/src/modprobe.c +++ b/zdev/src/modprobe.c @@ -14,6 +14,8 @@ #include #include +#include "lib/util_path.h" + #include "attrib.h" #include "misc.h" #include "modprobe.h" @@ -376,7 +378,7 @@ exit_code_t modprobe_read_settings(const struct modprobe_file *mf; exit_code_t rc; - if (!file_exists(path)) { + if (!util_path_is_reg_file(path)) { *settings = NULL; return EXIT_OK; } @@ -398,7 +400,7 @@ exit_code_t modprobe_write_settings(cons exit_code_t rc; unsigned long lines; - if (file_exists(path)) { + if (util_path_is_reg_file(path)) { rc = modprobe_read(path, &mf); if (rc) return rc; @@ -414,7 +416,7 @@ exit_code_t modprobe_write_settings(cons lines = util_list_len(&mf->lines); if (lines == 0 || (lines == 1 && find_chzdev_comment(mf))) { /* Do not write empty files. */ - if (file_exists(path)) + if (util_path_is_reg_file(path)) rc = remove_file(path); } else rc = modprobe_write(mf); --- a/zdev/src/module.c +++ b/zdev/src/module.c @@ -12,6 +12,8 @@ #include #include +#include "lib/util_path.h" + #include "attrib.h" #include "misc.h" #include "module.h" @@ -34,7 +36,7 @@ bool module_loaded(const char *mod) char *path = path_get_sys_module(mod); bool rc; - rc = dir_exists(path); + rc = util_path_is_dir(path); free(path); return rc; @@ -229,7 +231,7 @@ void module_try_load_once(const char *mo } else tried_loading = strlist_new(); strlist_add(tried_loading, mod); - if (path && path_exists(path)) + if (path && util_path_exists(path)) return; if (module_loaded(mod)) return; @@ -275,7 +277,7 @@ bool module_set_params(const char *mod, return false; } path = path_get_sys_module_param(mod, s->name); - result = file_writable(path); + result = util_path_is_writable(path); free(path); if (!result) { /* Sysfs file is not writable. */ --- a/zdev/src/qeth_auto.c +++ b/zdev/src/qeth_auto.c @@ -11,6 +11,8 @@ #include #include +#include "lib/util_path.h" + #include "ccw.h" #include "ccwgroup.h" #include "device.h" @@ -277,7 +279,7 @@ static struct util_list *read_sorted_qet /* Get CHPID information for all devices bound to the QETH driver. */ infos = ptrlist_new(); path = path_get_sys_bus_drv(CCW_BUS_NAME, QETH_CCWDRV_NAME); - if (dir_exists(path)) + if (util_path_is_dir(path)) path_for_each(path, add_cb, infos); free(path); --- a/zdev/src/root.c +++ b/zdev/src/root.c @@ -9,6 +9,8 @@ #include +#include "lib/util_path.h" + #include "device.h" #include "devtype.h" #include "misc.h" @@ -74,7 +76,7 @@ exit_code_t root_check(void) "required.\n"); /* Check if script is available. */ - if (!file_exists(PATH_ROOT_SCRIPT)) + if (!util_path_is_reg_file(PATH_ROOT_SCRIPT)) goto out; /* Ask for confirmation. */ --- a/zdev/src/scsi.c +++ b/zdev/src/scsi.c @@ -12,6 +12,8 @@ #include #include +#include "lib/util_path.h" + #include "misc.h" #include "path.h" #include "scsi.h" @@ -253,7 +255,7 @@ static struct util_list *read_scsi_zfcp_ list = ptrlist_new(); path = path_get_sys_bus_dev("scsi", NULL); - if (dir_exists(path)) + if (util_path_is_dir(path)) path_for_each(path, add_ids_cb, list); free(path); --- a/zdev/src/select.c +++ b/zdev/src/select.c @@ -10,6 +10,8 @@ #include #include +#include "lib/util_path.h" + #include "blkinfo.h" #include "ccw.h" #include "device.h" @@ -622,7 +624,7 @@ exit_code_t select_by_path(struct select struct ptrlist_node *p; exit_code_t rc; - if (!path_exists(path)) { + if (!util_path_exists(path)) { err_t_print(err, "Path not found: %s\n", path); return EXIT_DEVICE_NOT_FOUND; } --- a/zdev/src/udev.c +++ b/zdev/src/udev.c @@ -13,6 +13,8 @@ #include #include +#include "lib/util_path.h" + #include "attrib.h" #include "ccw.h" #include "device.h" @@ -391,7 +393,7 @@ exit_code_t udev_remove_rule(const char exit_code_t rc = EXIT_OK; path = path_get_udev_rule(type, id); - if (file_exists(path)) + if (util_path_is_reg_file(path)) rc = remove_file(path); free(path); --- a/zdev/src/udev_ccw.c +++ b/zdev/src/udev_ccw.c @@ -13,6 +13,8 @@ #include #include +#include "lib/util_path.h" + #include "attrib.h" #include "ccw.h" #include "device.h" @@ -33,7 +35,7 @@ bool udev_ccw_exists(const char *type, c return false; path = path_get_udev_rule(type, normid); - rc = file_exists(path); + rc = util_path_is_reg_file(path); free(path); free(normid); @@ -150,7 +152,7 @@ exit_code_t udev_ccw_write_device(struct path = path_get_udev_rule(type, id); debug("Writing %s udev rule file %s\n", type, path); - if (!path_exists(path)) { + if (!util_path_exists(path)) { rc = path_create(path); if (rc) goto out; @@ -243,7 +245,7 @@ exit_code_t udev_ccw_write_cio_ignore(co if (!*id_list) { /* Empty id_list string - remove file. */ - if (!file_exists(path)) { + if (!util_path_is_reg_file(path)) { /* Already removed. */ goto out; } @@ -256,7 +258,7 @@ exit_code_t udev_ccw_write_cio_ignore(co goto out; debug("Writing cio-ignore udev rule file %s\n", path); - if (!path_exists(path)) { + if (!util_path_exists(path)) { rc = path_create(path); if (rc) goto out; --- a/zdev/src/udev_ccwgroup.c +++ b/zdev/src/udev_ccwgroup.c @@ -13,6 +13,8 @@ #include #include +#include "lib/util_path.h" + #include "attrib.h" #include "ccwgroup.h" #include "device.h" @@ -53,7 +55,7 @@ bool udev_ccwgroup_exists(const char *ty path = get_rule_path(type, id); if (!path) return false; - rc = file_exists(path); + rc = util_path_is_reg_file(path); free(path); return rc; @@ -215,7 +217,7 @@ exit_code_t udev_ccwgroup_write_device(s list = setting_list_get_sorted(dev->persistent.settings); debug("Writing %s udev rule file %s\n", type, path); - if (!path_exists(path)) { + if (!util_path_exists(path)) { rc = path_create(path); if (rc) goto out; @@ -364,7 +366,7 @@ void udev_ccwgroup_add_device_ids(const cb_data.prefix = misc_asprintf("%s-%s-", UDEV_PREFIX, type); cb_data.ids = list; - if (dir_exists(path)) + if (util_path_is_dir(path)) path_for_each(path, get_ids_cb, &cb_data); free(cb_data.prefix); @@ -382,7 +384,7 @@ exit_code_t udev_ccwgroup_remove_rule(co return EXIT_INVALID_ID; path = path_get_udev_rule(type, partial_id); - if (file_exists(path)) + if (util_path_is_reg_file(path)) rc = remove_file(path); free(path); free(partial_id); --- a/zdev/src/udev_zfcp_lun.c +++ b/zdev/src/udev_zfcp_lun.c @@ -14,6 +14,8 @@ #include #include +#include "lib/util_path.h" + #include "attrib.h" #include "device.h" #include "misc.h" @@ -376,7 +378,7 @@ void udev_zfcp_lun_add_device_ids(struct cb_data.list = list; path = path_get_udev_rules(); - if (dir_exists(path)) + if (util_path_is_dir(path)) path_for_each(path, lun_cb, &cb_data); free(path); @@ -497,7 +499,7 @@ static exit_code_t write_luns_rule(const return EXIT_INTERNAL_ERROR; hba_id = ccw_devid_to_str(&node->id.fcp_dev); debug("Writing FCP LUN udev rule file %s\n", path); - if (!path_exists(path)) { + if (!util_path_exists(path)) { rc = path_create(path); if (rc) goto out; @@ -614,7 +616,7 @@ static exit_code_t update_lun_rule(const /* Get previous rule data. */ luns = zfcp_lun_node_list_new(); - exists = file_exists(path); + exists = util_path_is_reg_file(path); if (exists) udev_read_zfcp_lun_rule(path, luns); --- a/zdev/src/zfcp_lun.c +++ b/zdev/src/zfcp_lun.c @@ -13,6 +13,8 @@ #include #include +#include "lib/util_path.h" + #include "attrib.h" #include "ccw.h" #include "device.h" @@ -430,7 +432,7 @@ static exit_code_t zfcp_lun_st_read_acti /* Check for FC unit. */ fc_path = path_get_zfcp_lun_dev(dev->devid); - fc_exists = path_exists(fc_path); + fc_exists = util_path_exists(fc_path); free(fc_path); /* Check for SCSI device. */ @@ -478,7 +480,7 @@ static exit_code_t zfcp_lun_add(struct d /* Check if LUN already exists. */ fcp_dev_id = ccw_devid_to_str(&devid->fcp_dev); lunpath = path_get_zfcp_lun_dev(devid); - if (dir_exists(lunpath)) { + if (util_path_is_dir(lunpath)) { hctl = scsi_hctl_from_zfcp_lun_devid(devid); if (!hctl) goto check_failed; @@ -486,7 +488,7 @@ static exit_code_t zfcp_lun_add(struct d } portpath = path_get_zfcp_port_dev(devid); - if (!dir_exists(portpath)) { + if (!util_path_is_dir(portpath)) { delayed_err("Target port not found\n"); rc = EXIT_ZFCP_WWPN_NOT_FOUND; goto out; @@ -681,14 +683,14 @@ static exit_code_t zfcp_lun_st_device_un remove_lun: path = path_get_zfcp_lun_dev(devid); - if (!path_exists(path)) + if (!util_path_exists(path)) goto out; free(path); path = NULL; /* Remove FCP LUN. */ devpath = path_get_zfcp_port_dev(devid); - if (!dir_exists(devpath)) { + if (!util_path_is_dir(devpath)) { rc = EXIT_ZFCP_WWPN_NOT_FOUND; goto out; } @@ -779,7 +781,7 @@ static bool zfcp_lun_fc_lun_exists(const if (zfcp_lun_parse_devid(&devid, id, err_ignore) != EXIT_OK) return false; path = path_get_zfcp_lun_dev(&devid); - result = path_exists(path); + result = util_path_exists(path); free(path); return result; @@ -910,7 +912,7 @@ static void add_sg_from_sysfs(struct uti char *sgpath; sgpath = misc_asprintf("%s/scsi_generic", path); - if (dir_exists(sgpath)) + if (util_path_is_dir(sgpath)) path_for_each(sgpath, add_sg_cb, list); free(sgpath); }