forked from pool/s390-tools
Accepting request 655900 from home:markkp:branches:Base:System
- Added the following patches for Fate#326825 (bsc#1113329) I/O device pre-configuration * s390-tools-sles15sp1-01-zdev-use-libutil-provided-path-functions.patch * s390-tools-sles15sp1-02-zdev-Prepare-for-firmware-configuration-file-support.patch * s390-tools-sles15sp1-03-zdev-Add-support-for-reading-firmware-configuration-.patch * s390-tools-sles15sp1-04-zdev-Implement-no-settle.patch * s390-tools-sles15sp1-05-zdev-Write-zfcp-lun-udev-rules-to-separate-files.patch * s390-tools-sles15sp1-06-zdev-Add-support-for-handling-auto-configuration-dat.patch * s390-tools-sles15sp1-07-zdev-Integrate-firmware-auto-configuration-with-drac.patch * s390-tools-sles15sp1-08-zdev-Integrate-firmware-auto-configuration-with-init.patch * s390-tools-sles15sp1-09-zdev-Implement-internal-device-attributes.patch * s390-tools-sles15sp1-10-zdev-Implement-support-for-early-device-configuratio.patch * s390-tools-sles15sp1-11-zdev-Do-not-call-zipl-on-initrd-update.patch - Removed the obsolete customize-zdev-root-update-script.patch - Replaced s390-tools-sles15-zdev-fix-qeth-BridgePort-and-VNICC-conflict-checking.patch with s390-tools-sles15sp1-zdev-fix-qeth-BridgePort-and-VNICC-conflict-checking.patch to fit the current version. OBS-URL: https://build.opensuse.org/request/show/655900 OBS-URL: https://build.opensuse.org/package/show/Base:System/s390-tools?expand=0&rev=61
This commit is contained in:
parent
6f83d79828
commit
5500b3a5bc
@ -0,0 +1,797 @@
|
|||||||
|
Subject: zdev: use libutil provided path functions
|
||||||
|
From: Peter Oberparleiter <oberpar@linux.ibm.com>
|
||||||
|
|
||||||
|
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 <r4f4rfs@gmail.com>
|
||||||
|
Acked-by: Peter Oberparleiter <oberpar@linux.vnet.ibm.com>
|
||||||
|
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
|
||||||
|
|
||||||
|
|
||||||
|
Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
|
||||||
|
---
|
||||||
|
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 <string.h>
|
||||||
|
|
||||||
|
#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 <string.h>
|
||||||
|
|
||||||
|
#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 <string.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
+#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 <string.h>
|
||||||
|
|
||||||
|
+#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 <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
+#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 <sys/sysmacros.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
|
||||||
|
+#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 <string.h>
|
||||||
|
|
||||||
|
+#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 <string.h>
|
||||||
|
|
||||||
|
+#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 <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
+#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 <string.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
|
||||||
|
+#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 <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
+#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 <stdlib.h>
|
||||||
|
|
||||||
|
+#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 <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
+#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 <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
+#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 <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
+#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 <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
+#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 <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
+#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 <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
+#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 <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
+#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);
|
||||||
|
}
|
@ -0,0 +1,287 @@
|
|||||||
|
Subject: zdev: Prepare for firmware configuration file support
|
||||||
|
From: Peter Oberparleiter <oberpar@linux.ibm.com>
|
||||||
|
|
||||||
|
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: ab4445c261749caa7aee2154e3b26c767b6c5e60
|
||||||
|
Problem-ID: LS1604
|
||||||
|
|
||||||
|
Upstream-Description:
|
||||||
|
|
||||||
|
zdev: Prepare for firmware configuration file support
|
||||||
|
|
||||||
|
Apply some changes to existing functions and data structures to simplify
|
||||||
|
the firmware configuration file support implementation.
|
||||||
|
|
||||||
|
- Make qeth and dasd subtype objects non-static
|
||||||
|
- Change the existing helper functions for reading file contents into
|
||||||
|
memory to also support binary functions
|
||||||
|
- Move some configuration file import functions to make them available
|
||||||
|
for use in other source files
|
||||||
|
|
||||||
|
Signed-off-by: Peter Oberparleiter <oberpar@linux.vnet.ibm.com>
|
||||||
|
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
||||||
|
|
||||||
|
|
||||||
|
Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
|
||||||
|
---
|
||||||
|
zdev/include/dasd.h | 3 ++
|
||||||
|
zdev/include/device.h | 2 +
|
||||||
|
zdev/include/export.h | 1
|
||||||
|
zdev/include/misc.h | 1
|
||||||
|
zdev/include/qeth.h | 2 +
|
||||||
|
zdev/src/dasd.c | 4 +--
|
||||||
|
zdev/src/device.c | 13 +++++++++++
|
||||||
|
zdev/src/export.c | 17 +-------------
|
||||||
|
zdev/src/misc.c | 48 ++++++++++++++++++++++++++++++------------
|
||||||
|
zdev/src/qeth.c | 2 -
|
||||||
|
10 files changed, 62 insertions(+), 31 deletions(-)
|
||||||
|
|
||||||
|
--- a/zdev/include/dasd.h
|
||||||
|
+++ b/zdev/include/dasd.h
|
||||||
|
@@ -11,7 +11,10 @@
|
||||||
|
#define DASD_H
|
||||||
|
|
||||||
|
struct devtype;
|
||||||
|
+struct subtype;
|
||||||
|
|
||||||
|
extern struct devtype dasd_devtype;
|
||||||
|
+extern struct subtype dasd_subtype_eckd;
|
||||||
|
+extern struct subtype dasd_subtype_fba;
|
||||||
|
|
||||||
|
#endif /* DASD_H */
|
||||||
|
--- a/zdev/include/device.h
|
||||||
|
+++ b/zdev/include/device.h
|
||||||
|
@@ -94,5 +94,7 @@ void device_list_add(struct device_list
|
||||||
|
struct device *device_list_find(struct device_list *, const char *,
|
||||||
|
struct device *);
|
||||||
|
void device_list_print(struct device_list *, int);
|
||||||
|
+struct setting_list *device_get_setting_list(struct device *dev,
|
||||||
|
+ config_t config);
|
||||||
|
|
||||||
|
#endif /* DEVICE_H */
|
||||||
|
--- a/zdev/include/export.h
|
||||||
|
+++ b/zdev/include/export.h
|
||||||
|
@@ -31,6 +31,7 @@ struct export_object {
|
||||||
|
} ptr;
|
||||||
|
};
|
||||||
|
|
||||||
|
+struct export_object *object_new(export_t type, void *ptr);
|
||||||
|
exit_code_t export_write_device(FILE *, struct device *, config_t, int *);
|
||||||
|
exit_code_t export_write_devtype(FILE *, struct devtype *, config_t, int *);
|
||||||
|
exit_code_t export_read(FILE *, const char *, struct util_list *);
|
||||||
|
--- a/zdev/include/misc.h
|
||||||
|
+++ b/zdev/include/misc.h
|
||||||
|
@@ -159,6 +159,7 @@ bool misc_read_dir(const char *, struct
|
||||||
|
bool (*)(const char *, void *), void *);
|
||||||
|
bool file_is_devnode(const char *);
|
||||||
|
exit_code_t remove_file(const char *);
|
||||||
|
+exit_code_t misc_read_fd(FILE *fd, void **buffer, size_t *size_ptr);
|
||||||
|
char *misc_read_text_file(const char *, int, err_t);
|
||||||
|
char *misc_read_cmd_output(const char *, int, err_t);
|
||||||
|
char *config_read_cmd_output(const char *, int, err_t);
|
||||||
|
--- a/zdev/include/qeth.h
|
||||||
|
+++ b/zdev/include/qeth.h
|
||||||
|
@@ -17,9 +17,11 @@
|
||||||
|
#define QETH_NUM_DEVS 3
|
||||||
|
|
||||||
|
struct devtype;
|
||||||
|
+struct subtype;
|
||||||
|
struct namespace;
|
||||||
|
|
||||||
|
extern struct devtype qeth_devtype;
|
||||||
|
+extern struct subtype qeth_subtype_qeth;
|
||||||
|
extern struct namespace qeth_namespace;
|
||||||
|
|
||||||
|
#endif /* QETH_H */
|
||||||
|
--- a/zdev/src/dasd.c
|
||||||
|
+++ b/zdev/src/dasd.c
|
||||||
|
@@ -589,7 +589,7 @@ static struct ccw_subtype_data dasd_eckd
|
||||||
|
.mod = "dasd_eckd_mod",
|
||||||
|
};
|
||||||
|
|
||||||
|
-static struct subtype dasd_subtype_eckd = {
|
||||||
|
+struct subtype dasd_subtype_eckd = {
|
||||||
|
.super = &ccw_subtype,
|
||||||
|
.devtype = &dasd_devtype,
|
||||||
|
.name = "dasd-eckd",
|
||||||
|
@@ -626,7 +626,7 @@ static struct ccw_subtype_data dasd_fba_
|
||||||
|
.mod = "dasd_fba_mod",
|
||||||
|
};
|
||||||
|
|
||||||
|
-static struct subtype dasd_subtype_fba = {
|
||||||
|
+struct subtype dasd_subtype_fba = {
|
||||||
|
.super = &ccw_subtype,
|
||||||
|
.devtype = &dasd_devtype,
|
||||||
|
.name = "dasd-fba",
|
||||||
|
--- a/zdev/src/device.c
|
||||||
|
+++ b/zdev/src/device.c
|
||||||
|
@@ -570,3 +570,16 @@ exit_code_t device_check_settings(struct
|
||||||
|
|
||||||
|
return EXIT_OK;
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+struct setting_list *device_get_setting_list(struct device *dev,
|
||||||
|
+ config_t config)
|
||||||
|
+{
|
||||||
|
+ struct setting_list *settings = NULL;
|
||||||
|
+
|
||||||
|
+ if (config == config_active)
|
||||||
|
+ settings = dev->active.settings;
|
||||||
|
+ else
|
||||||
|
+ settings = dev->persistent.settings;
|
||||||
|
+
|
||||||
|
+ return settings;
|
||||||
|
+}
|
||||||
|
--- a/zdev/src/export.c
|
||||||
|
+++ b/zdev/src/export.c
|
||||||
|
@@ -282,19 +282,6 @@ static bool parse_setting(const char *li
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static struct setting_list *dev_get_setting_list(struct device *dev,
|
||||||
|
- config_t config)
|
||||||
|
-{
|
||||||
|
- struct setting_list *settings = NULL;
|
||||||
|
-
|
||||||
|
- if (config == config_active)
|
||||||
|
- settings = dev->active.settings;
|
||||||
|
- else
|
||||||
|
- settings = dev->persistent.settings;
|
||||||
|
-
|
||||||
|
- return settings;
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
static struct setting_list *dt_get_setting_list(struct devtype *dt,
|
||||||
|
config_t config)
|
||||||
|
{
|
||||||
|
@@ -426,7 +413,7 @@ static exit_code_t handle_setting(const
|
||||||
|
} else if (dev) {
|
||||||
|
/* We're inside a device section. */
|
||||||
|
attribs = dev->subtype->dev_attribs;
|
||||||
|
- list = dev_get_setting_list(dev, config);
|
||||||
|
+ list = device_get_setting_list(dev, config);
|
||||||
|
} else
|
||||||
|
return EXIT_OK;
|
||||||
|
|
||||||
|
@@ -444,7 +431,7 @@ static exit_code_t handle_setting(const
|
||||||
|
return EXIT_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
-static struct export_object *object_new(export_t type, void *ptr)
|
||||||
|
+struct export_object *object_new(export_t type, void *ptr)
|
||||||
|
{
|
||||||
|
struct export_object *obj;
|
||||||
|
|
||||||
|
--- a/zdev/src/misc.c
|
||||||
|
+++ b/zdev/src/misc.c
|
||||||
|
@@ -98,26 +98,47 @@ static void dryrun_end_data(void)
|
||||||
|
|
||||||
|
#define READ_CHUNK_SIZE 4096
|
||||||
|
|
||||||
|
-/* Read text from @fd and return resulting NULL-terminated text buffer.
|
||||||
|
- * If @chomp is non-zero, remove trailing newline character. Return %NULL
|
||||||
|
- * on error or when unprintable characters are read. */
|
||||||
|
-static char *read_fd(FILE *fd, int chomp)
|
||||||
|
+/* Read all data from @fd and return address of resulting buffer in
|
||||||
|
+ * @buffer_ptr. If @size_ptr is non-zero, use it to store the size of the
|
||||||
|
+ * resulting buffer. Return %EXIT_OK on success. */
|
||||||
|
+exit_code_t misc_read_fd(FILE *fd, void **buffer_ptr, size_t *size_ptr)
|
||||||
|
{
|
||||||
|
char *buffer = NULL;
|
||||||
|
- size_t done, i;
|
||||||
|
+ size_t done = 0;
|
||||||
|
|
||||||
|
- done = 0;
|
||||||
|
while (!feof(fd)) {
|
||||||
|
- buffer = realloc(buffer, done + READ_CHUNK_SIZE + 1);
|
||||||
|
+ buffer = realloc(buffer, done + READ_CHUNK_SIZE);
|
||||||
|
if (!buffer)
|
||||||
|
oom();
|
||||||
|
done += fread(&buffer[done], 1, READ_CHUNK_SIZE, fd);
|
||||||
|
if (ferror(fd)) {
|
||||||
|
free(buffer);
|
||||||
|
- return NULL;
|
||||||
|
+ return EXIT_RUNTIME_ERROR;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
+ buffer = realloc(buffer, done);
|
||||||
|
+ if (!buffer && done > 0)
|
||||||
|
+ oom();
|
||||||
|
+
|
||||||
|
+ *buffer_ptr = buffer;
|
||||||
|
+ if (size_ptr)
|
||||||
|
+ *size_ptr = done;
|
||||||
|
+
|
||||||
|
+ return EXIT_OK;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Read text from @fd and return resulting NULL-terminated text buffer.
|
||||||
|
+ * If @chomp is non-zero, remove trailing newline character. Return %NULL
|
||||||
|
+ * on error or when unprintable characters are read. */
|
||||||
|
+static char *read_fd(FILE *fd, int chomp)
|
||||||
|
+{
|
||||||
|
+ char *buffer;
|
||||||
|
+ size_t done, i;
|
||||||
|
+
|
||||||
|
+ if (misc_read_fd(fd, (void **) &buffer, &done))
|
||||||
|
+ return NULL;
|
||||||
|
+
|
||||||
|
/* Check if this is a text file at all (required to filter out
|
||||||
|
* binary sysfs attributes). */
|
||||||
|
for (i = 0; i < done; i++) {
|
||||||
|
@@ -131,12 +152,13 @@ static char *read_fd(FILE *fd, int chomp
|
||||||
|
if (chomp && done > 0 && buffer[done - 1] == '\n')
|
||||||
|
done--;
|
||||||
|
|
||||||
|
- if (buffer) {
|
||||||
|
- /* NULL-terminate. */
|
||||||
|
- buffer[done++] = 0;
|
||||||
|
- }
|
||||||
|
+ /* NULL-terminate. */
|
||||||
|
+ buffer = realloc(buffer, done + 1);
|
||||||
|
+ if (!buffer)
|
||||||
|
+ oom();
|
||||||
|
+ buffer[done] = 0;
|
||||||
|
|
||||||
|
- return realloc(buffer, done);
|
||||||
|
+ return buffer;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int count_newline(const char *str)
|
||||||
|
--- a/zdev/src/qeth.c
|
||||||
|
+++ b/zdev/src/qeth.c
|
||||||
|
@@ -1369,7 +1369,7 @@ static struct ccwgroup_subtype_data qeth
|
||||||
|
.num_devs = QETH_NUM_DEVS,
|
||||||
|
};
|
||||||
|
|
||||||
|
-static struct subtype qeth_subtype_qeth = {
|
||||||
|
+struct subtype qeth_subtype_qeth = {
|
||||||
|
.super = &ccwgroup_subtype,
|
||||||
|
.devtype = &qeth_devtype,
|
||||||
|
.name = "qeth",
|
@ -0,0 +1,874 @@
|
|||||||
|
Subject: zdev: Add support for reading firmware configuration files
|
||||||
|
From: Peter Oberparleiter <oberpar@linux.ibm.com>
|
||||||
|
|
||||||
|
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: 7d355b0fec964ad84ecaf88eb946121d39486070
|
||||||
|
Problem-ID: LS1604
|
||||||
|
|
||||||
|
Upstream-Description:
|
||||||
|
|
||||||
|
zdev: Add support for reading firmware configuration files
|
||||||
|
|
||||||
|
Add support for reading firmware-provided I/O configuration data files.
|
||||||
|
Such configuration files are generated by the Dynamic Partition Manager
|
||||||
|
and made available via a kernel interface for consumption by Linux.
|
||||||
|
|
||||||
|
To read a firmware configuration file, use the existing --import option:
|
||||||
|
|
||||||
|
# chzdev --import /sys/firmware/sclp_sd/config/data
|
||||||
|
|
||||||
|
This will apply all I/O configuration data found in the specified file
|
||||||
|
to the persistent configuration.
|
||||||
|
|
||||||
|
Signed-off-by: Peter Oberparleiter <oberpar@linux.vnet.ibm.com>
|
||||||
|
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
||||||
|
|
||||||
|
|
||||||
|
Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
|
||||||
|
---
|
||||||
|
zdev/include/firmware.h | 25 +
|
||||||
|
zdev/man/chzdev.8 | 16
|
||||||
|
zdev/src/Makefile | 2
|
||||||
|
zdev/src/chzdev.c | 21 -
|
||||||
|
zdev/src/firmware.c | 676 ++++++++++++++++++++++++++++++++++++++++
|
||||||
|
5 files changed, 730 insertions(+), 10 deletions(-)
|
||||||
|
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/zdev/include/firmware.h
|
||||||
|
@@ -0,0 +1,25 @@
|
||||||
|
+/*
|
||||||
|
+ * zdev - Modify and display the persistent configuration of devices
|
||||||
|
+ *
|
||||||
|
+ * Copyright IBM Corp. 2017
|
||||||
|
+ *
|
||||||
|
+ * 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 FIRMWARE_H
|
||||||
|
+#define FIRMWARE_H
|
||||||
|
+
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <stdbool.h>
|
||||||
|
+
|
||||||
|
+#include "exit_code.h"
|
||||||
|
+#include "misc.h"
|
||||||
|
+
|
||||||
|
+struct util_list;
|
||||||
|
+
|
||||||
|
+bool firmware_detect(FILE *fd);
|
||||||
|
+exit_code_t firmware_read(FILE *fd, const char *filename, long skip,
|
||||||
|
+ config_t config, struct util_list *objects);
|
||||||
|
+
|
||||||
|
+#endif /* FIRMWARE_H */
|
||||||
|
--- a/zdev/man/chzdev.8
|
||||||
|
+++ b/zdev/man/chzdev.8
|
||||||
|
@@ -409,13 +409,23 @@ default value.
|
||||||
|
.PP
|
||||||
|
.
|
||||||
|
.OD import "" "FILENAME" "|-"
|
||||||
|
-Import configuration data from a text file.
|
||||||
|
+Import configuration data from a text or machine-provided file.
|
||||||
|
|
||||||
|
Reads configuration data from FILENAME and applies it. If a single hyphen ("-")
|
||||||
|
is specified as FILENAME data is read from the standard input stream. The
|
||||||
|
-input format of the data read must be the same format as produced by the
|
||||||
|
-chzdev \-\-export action.
|
||||||
|
+input format must be either in the format as produced by the chzdev \-\-export
|
||||||
|
+action, or in the format of a machine-provided I/O configuration data file.
|
||||||
|
|
||||||
|
+.B Machine-provided data:
|
||||||
|
+Some machine models provide I/O configuration data which is made available
|
||||||
|
+by the Linux kernel via a sysfs interface. While this data is intended for
|
||||||
|
+automatic consumption during the boot phase, you can also apply it manually
|
||||||
|
+using the \-\-import action like in the following example
|
||||||
|
+
|
||||||
|
+.B Example:
|
||||||
|
+.CL chzdev --import /sys/firmware/sclp_sd/config/data
|
||||||
|
+
|
||||||
|
+.B Note:
|
||||||
|
By default all configuration data that is read is also applied. To reduce the
|
||||||
|
scope of imported configuration data, you can select specific devices, a device
|
||||||
|
type, or define whether only data for the active or persistent configuration
|
||||||
|
--- a/zdev/src/Makefile
|
||||||
|
+++ b/zdev/src/Makefile
|
||||||
|
@@ -8,7 +8,7 @@ ALL_CPPFLAGS += -I ../include -std=gnu99
|
||||||
|
chzdev_objects += attrib.o chzdev.o device.o devnode.o devtype.o exit_code.o \
|
||||||
|
export.o hash.o inuse.o misc.o namespace.o opts.o path.o \
|
||||||
|
root.o select.o setting.o subtype.o table.o table_attribs.o \
|
||||||
|
- table_types.o net.o
|
||||||
|
+ table_types.o net.o firmware.o
|
||||||
|
|
||||||
|
# Devtype Helpers
|
||||||
|
chzdev_objects += blkinfo.o ccw.o ccwgroup.o findmnt.o modprobe.o module.o \
|
||||||
|
--- a/zdev/src/chzdev.c
|
||||||
|
+++ b/zdev/src/chzdev.c
|
||||||
|
@@ -27,6 +27,7 @@
|
||||||
|
#include "devnode.h"
|
||||||
|
#include "devtype.h"
|
||||||
|
#include "export.h"
|
||||||
|
+#include "firmware.h"
|
||||||
|
#include "inuse.h"
|
||||||
|
#include "misc.h"
|
||||||
|
#include "module.h"
|
||||||
|
@@ -2500,9 +2501,9 @@ static exit_code_t do_export(struct opti
|
||||||
|
/* Open output stream. */
|
||||||
|
if (strcmp(opts->export, "-") == 0) {
|
||||||
|
fd = stdout;
|
||||||
|
- info("Exporting configuration data to standard output\n");
|
||||||
|
+ info("Exporting data to standard output\n");
|
||||||
|
} else {
|
||||||
|
- info("Exporting configuration data to %s\n", opts->export);
|
||||||
|
+ info("Exporting data to %s\n", opts->export);
|
||||||
|
if (!util_path_exists(opts->export)) {
|
||||||
|
rc = path_create(opts->export);
|
||||||
|
if (rc)
|
||||||
|
@@ -2735,6 +2736,7 @@ static exit_code_t do_import(struct opti
|
||||||
|
exit_code_t drc = EXIT_OK;
|
||||||
|
const char *filename;
|
||||||
|
int found;
|
||||||
|
+ bool is_firmware;
|
||||||
|
|
||||||
|
/* Open input stream. */
|
||||||
|
if (strcmp(opts->import, "-") == 0) {
|
||||||
|
@@ -2744,16 +2746,23 @@ static exit_code_t do_import(struct opti
|
||||||
|
fd = fopen(opts->import, "r");
|
||||||
|
filename = opts->import;
|
||||||
|
}
|
||||||
|
- info("Importing configuration data from %s\n", filename);
|
||||||
|
+
|
||||||
|
if (!fd) {
|
||||||
|
error("Could not open file %s: %s\n", opts->import,
|
||||||
|
strerror(errno));
|
||||||
|
return EXIT_RUNTIME_ERROR;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ is_firmware = firmware_detect(fd);
|
||||||
|
+ info("Importing data from %s%s\n", filename,
|
||||||
|
+ is_firmware ? " (firmware format)" : "");
|
||||||
|
+
|
||||||
|
/* Read data. */
|
||||||
|
objects = ptrlist_new();
|
||||||
|
- rc = export_read(fd, filename, objects);
|
||||||
|
+ if (is_firmware)
|
||||||
|
+ rc = firmware_read(fd, filename, -1, opts->config, objects);
|
||||||
|
+ else
|
||||||
|
+ rc = export_read(fd, filename, objects);
|
||||||
|
if (rc)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
@@ -2766,8 +2775,8 @@ static exit_code_t do_import(struct opti
|
||||||
|
"selection\n", filename);
|
||||||
|
rc = EXIT_EMPTY_SELECTION;
|
||||||
|
} else {
|
||||||
|
- error("%s: No settings found to import\n", filename);
|
||||||
|
- rc = EXIT_NO_DATA;
|
||||||
|
+ info("%s: No settings found to import\n", filename);
|
||||||
|
+ rc = EXIT_OK;
|
||||||
|
}
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/zdev/src/firmware.c
|
||||||
|
@@ -0,0 +1,676 @@
|
||||||
|
+/*
|
||||||
|
+ * zdev - Modify and display the persistent configuration of devices
|
||||||
|
+ *
|
||||||
|
+ * Copyright IBM Corp. 2017
|
||||||
|
+ *
|
||||||
|
+ * 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 <err.h>
|
||||||
|
+#include <fcntl.h>
|
||||||
|
+#include <stdarg.h>
|
||||||
|
+#include <stdbool.h>
|
||||||
|
+#include <stdint.h>
|
||||||
|
+#include <stdio.h>
|
||||||
|
+#include <stdlib.h>
|
||||||
|
+#include <string.h>
|
||||||
|
+#include <sys/stat.h>
|
||||||
|
+#include <sys/types.h>
|
||||||
|
+#include <unistd.h>
|
||||||
|
+
|
||||||
|
+#include "attrib.h"
|
||||||
|
+#include "ccw.h"
|
||||||
|
+#include "ccwgroup.h"
|
||||||
|
+#include "dasd.h"
|
||||||
|
+#include "device.h"
|
||||||
|
+#include "export.h"
|
||||||
|
+#include "firmware.h"
|
||||||
|
+#include "misc.h"
|
||||||
|
+#include "qeth.h"
|
||||||
|
+#include "subtype.h"
|
||||||
|
+#include "zfcp_host.h"
|
||||||
|
+#include "zfcp_lun.h"
|
||||||
|
+
|
||||||
|
+/* In-memory firmware file representation. */
|
||||||
|
+struct fw_file {
|
||||||
|
+ const char *name;
|
||||||
|
+ char *buffer;
|
||||||
|
+ size_t size;
|
||||||
|
+ char *last_access;
|
||||||
|
+ size_t last_size;
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
+/* Record access to fields of the buffered file for use in warning messages. */
|
||||||
|
+#define fwacc(f, x) ((f)->last_access = (char *) &(x), \
|
||||||
|
+ (f)->last_size = sizeof(x), x)
|
||||||
|
+
|
||||||
|
+/*
|
||||||
|
+ * Firmware file format definitions.
|
||||||
|
+ */
|
||||||
|
+
|
||||||
|
+/* Firmware file header. */
|
||||||
|
+struct fw_filehdr {
|
||||||
|
+ uint32_t magic;
|
||||||
|
+ uint16_t ver;
|
||||||
|
+ uint16_t hdr_len;
|
||||||
|
+ uint32_t file_len;
|
||||||
|
+ uint32_t seq;
|
||||||
|
+ uint32_t zeroes;
|
||||||
|
+ uint16_t de_count;
|
||||||
|
+ char unused[10];
|
||||||
|
+} __packed;
|
||||||
|
+
|
||||||
|
+#define FW_HDR_MAGIC 0x7a646576 /* ASCII "zdev" */
|
||||||
|
+#define FW_HDR_VER_Z14 0x0000
|
||||||
|
+
|
||||||
|
+/* I/O device ID. */
|
||||||
|
+struct fw_iodevid {
|
||||||
|
+ uint8_t cssid;
|
||||||
|
+ uint8_t ssid;
|
||||||
|
+ uint16_t devno;
|
||||||
|
+} __packed;
|
||||||
|
+
|
||||||
|
+#define FW_IODEVID_FLAG_MCSS 0x01
|
||||||
|
+
|
||||||
|
+/* Device setting. */
|
||||||
|
+struct fw_setting {
|
||||||
|
+ uint16_t len;
|
||||||
|
+ uint8_t key_type;
|
||||||
|
+ uint8_t key_len;
|
||||||
|
+ uint8_t val_type;
|
||||||
|
+ uint8_t val_len;
|
||||||
|
+ char data[];
|
||||||
|
+} __packed;
|
||||||
|
+
|
||||||
|
+#define FW_SETTING_KEYTYPE_ASCII 0x00
|
||||||
|
+#define FW_SETTING_VALTYPE_ASCII 0x00
|
||||||
|
+#define FW_SETTING_VALTYPE_UINT 0x01
|
||||||
|
+
|
||||||
|
+/* Device settings list. */
|
||||||
|
+struct fw_setlist {
|
||||||
|
+ uint16_t len;
|
||||||
|
+ char data[];
|
||||||
|
+} __packed;
|
||||||
|
+
|
||||||
|
+/* Device entry header. */
|
||||||
|
+struct fw_dehdr {
|
||||||
|
+ uint16_t type;
|
||||||
|
+ uint16_t len;
|
||||||
|
+ uint32_t seq;
|
||||||
|
+} __packed;
|
||||||
|
+
|
||||||
|
+#define FW_DE_HDR_TYPE_DASD 0x0001
|
||||||
|
+#define FW_DE_HDR_TYPE_ZFCP_HOST 0x0002
|
||||||
|
+#define FW_DE_HDR_TYPE_ZFCP_LUN 0x0003
|
||||||
|
+#define FW_DE_HDR_TYPE_QETH 0x0004
|
||||||
|
+
|
||||||
|
+/* DASD device entry. */
|
||||||
|
+struct fw_dasd {
|
||||||
|
+ struct fw_dehdr hdr;
|
||||||
|
+ uint8_t id_flags;
|
||||||
|
+ struct fw_iodevid id;
|
||||||
|
+ char settings[];
|
||||||
|
+} __packed;
|
||||||
|
+
|
||||||
|
+/* zFCP host device entry. */
|
||||||
|
+struct fw_zfcp_host {
|
||||||
|
+ struct fw_dehdr hdr;
|
||||||
|
+ uint8_t id_flags;
|
||||||
|
+ struct fw_iodevid id;
|
||||||
|
+ char settings[];
|
||||||
|
+} __packed;
|
||||||
|
+
|
||||||
|
+/* zFCP LUN device entry. */
|
||||||
|
+struct fw_zfcp_lun {
|
||||||
|
+ struct fw_dehdr hdr;
|
||||||
|
+ uint8_t id_flags;
|
||||||
|
+ struct fw_iodevid id;
|
||||||
|
+ uint64_t wwpn;
|
||||||
|
+ uint64_t fcp_lun;
|
||||||
|
+ char settings[];
|
||||||
|
+} __packed;
|
||||||
|
+
|
||||||
|
+/* QETH device entry. */
|
||||||
|
+struct fw_qeth {
|
||||||
|
+ struct fw_dehdr hdr;
|
||||||
|
+ uint8_t id_flags;
|
||||||
|
+ struct fw_iodevid read_id;
|
||||||
|
+ struct fw_iodevid write_id;
|
||||||
|
+ struct fw_iodevid data_id;
|
||||||
|
+ char settings[];
|
||||||
|
+} __packed;
|
||||||
|
+
|
||||||
|
+/* Emit a warning that refers to a position in a firmware file. */
|
||||||
|
+static void fwwarn(struct fw_file *f, const char *fmt, ...)
|
||||||
|
+{
|
||||||
|
+ va_list args;
|
||||||
|
+ off_t start = (off_t) (f->last_access - f->buffer),
|
||||||
|
+ end = start + f->last_size - 1;
|
||||||
|
+
|
||||||
|
+ fprintf(stderr, "%s: ", f->name);
|
||||||
|
+ if (start == end)
|
||||||
|
+ fprintf(stderr, "Byte 0x%zx: ", start);
|
||||||
|
+ else
|
||||||
|
+ fprintf(stderr, "Bytes 0x%zx-0x%zx: ", start, end);
|
||||||
|
+
|
||||||
|
+ va_start(args, fmt);
|
||||||
|
+ vfprintf(stderr, fmt, args);
|
||||||
|
+ va_end(args);
|
||||||
|
+ fprintf(stderr, "\n");
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Basic file format header sanity check. */
|
||||||
|
+static bool check_header(struct fw_file *f, struct fw_filehdr *hdr)
|
||||||
|
+{
|
||||||
|
+ if (fwacc(f, hdr->magic) != FW_HDR_MAGIC)
|
||||||
|
+ fwwarn(f, "Invalid file magic (0x%08x)", hdr->magic);
|
||||||
|
+ else if (fwacc(f, hdr->ver) != FW_HDR_VER_Z14)
|
||||||
|
+ fwwarn(f, "Unsupported file version (0x%04x)", hdr->ver);
|
||||||
|
+ else
|
||||||
|
+ return true;
|
||||||
|
+
|
||||||
|
+ return false;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+#define READ_RETRY 3
|
||||||
|
+
|
||||||
|
+/* Read a firmware configuration file. */
|
||||||
|
+static exit_code_t read_fw(struct fw_file *file, FILE *fd, const char *filename)
|
||||||
|
+{
|
||||||
|
+ struct fw_file f = { NULL };
|
||||||
|
+ struct fw_filehdr *hdr;
|
||||||
|
+ char *buffer, *buffer2;
|
||||||
|
+ size_t size, size2;
|
||||||
|
+ int retry;
|
||||||
|
+ exit_code_t rc = EXIT_OK;
|
||||||
|
+
|
||||||
|
+ for (retry = 0; retry < READ_RETRY; retry++) {
|
||||||
|
+ /* Read complete file once */
|
||||||
|
+ rc = misc_read_fd(fd, (void **) &buffer, &size);
|
||||||
|
+ if (rc) {
|
||||||
|
+ warn("%s: Could not read file", filename);
|
||||||
|
+ return rc;
|
||||||
|
+ }
|
||||||
|
+ if (!buffer) {
|
||||||
|
+ /* Empty file - skip silently as this is the default
|
||||||
|
+ * on machines without firmware support. */
|
||||||
|
+ return rc;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Re-read complete file to detect in-flight modifications. */
|
||||||
|
+ if (fseek(fd, 0, SEEK_SET) == -1) {
|
||||||
|
+ /* Could be a pipe, socket, or FIFO - accept v1. */
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ rc = misc_read_fd(fd, (void **) &buffer2, &size2);
|
||||||
|
+ if (rc || !buffer2) {
|
||||||
|
+ /* Could not get second version - accept v1. */
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (size == size2 && memcmp(buffer, buffer2, size) == 0) {
|
||||||
|
+ /* No change */
|
||||||
|
+ free(buffer2);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ free(buffer);
|
||||||
|
+ free(buffer2);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (retry >= READ_RETRY) {
|
||||||
|
+ warnx("%s: File changed %d times while reading - aborting",
|
||||||
|
+ filename, retry);
|
||||||
|
+ return EXIT_RUNTIME_ERROR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Perform basic checks */
|
||||||
|
+ f.name = filename;
|
||||||
|
+ f.buffer = buffer;
|
||||||
|
+ f.size = size;
|
||||||
|
+ hdr = (void *) buffer;
|
||||||
|
+ if (!check_header(&f, hdr)) {
|
||||||
|
+ free(buffer);
|
||||||
|
+ return EXIT_FORMAT_ERROR;
|
||||||
|
+ }
|
||||||
|
+ if (fwacc(&f, hdr->file_len) > size) {
|
||||||
|
+ fwwarn(&f, "File length mismatch (expect %zu) - adjusting",
|
||||||
|
+ size);
|
||||||
|
+ hdr->file_len = size;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ *file = f;
|
||||||
|
+
|
||||||
|
+ return EXIT_OK;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Return textual representation of a device entry type. */
|
||||||
|
+static const char *type_to_str(uint16_t type)
|
||||||
|
+{
|
||||||
|
+ switch (type) {
|
||||||
|
+ case FW_DE_HDR_TYPE_DASD:
|
||||||
|
+ return "dasd";
|
||||||
|
+ case FW_DE_HDR_TYPE_ZFCP_HOST:
|
||||||
|
+ return "zfcp-host";
|
||||||
|
+ case FW_DE_HDR_TYPE_ZFCP_LUN:
|
||||||
|
+ return "zfcp-lun";
|
||||||
|
+ case FW_DE_HDR_TYPE_QETH:
|
||||||
|
+ return "qeth";
|
||||||
|
+ default:
|
||||||
|
+ return "<unknown>";
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Convert a binary format device setting of the specified length to integer. */
|
||||||
|
+static unsigned long parse_value(char *data, uint8_t len)
|
||||||
|
+{
|
||||||
|
+ switch (len) {
|
||||||
|
+ case 1:
|
||||||
|
+ return (unsigned long) *((uint8_t *) data);
|
||||||
|
+ case 2:
|
||||||
|
+ return (unsigned long) *((uint16_t *) data);
|
||||||
|
+ case 4:
|
||||||
|
+ return (unsigned long) *((uint32_t *) data);
|
||||||
|
+ case 8:
|
||||||
|
+ return (unsigned long) *((uint64_t *) data);
|
||||||
|
+ default:
|
||||||
|
+ return 0;
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Perform sanity checks on device setting. */
|
||||||
|
+static bool check_setting(struct fw_file *f, struct fw_setting *set)
|
||||||
|
+{
|
||||||
|
+ /* Key sanity checks */
|
||||||
|
+ if (fwacc(f, set->key_type) != FW_SETTING_KEYTYPE_ASCII) {
|
||||||
|
+ fwwarn(f, "Unsupported key type: %d", set->key_type);
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+ if (fwacc(f, set->key_len) < 1) {
|
||||||
|
+ fwwarn(f, "Unsupported key length: %d", set->key_len);
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+ if (sizeof(struct fw_setting) + fwacc(f, set->key_len) > set->len) {
|
||||||
|
+ fwwarn(f, "Key length exceeds setting");
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+ if (fwacc(f, set->data[set->key_len - 1])) {
|
||||||
|
+ fwwarn(f, "Key not null-terminated");
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* Value sanity checks */
|
||||||
|
+ if (fwacc(f, set->val_type) != FW_SETTING_VALTYPE_UINT &&
|
||||||
|
+ fwacc(f, set->val_type) != FW_SETTING_VALTYPE_ASCII) {
|
||||||
|
+ fwwarn(f, "Unsupported value type: %d", set->val_type);
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+ if (fwacc(f, set->val_len) < 1) {
|
||||||
|
+ fwwarn(f, "Unsupported value length: %d", set->val_len);
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+ if (sizeof(struct fw_setting) + set->key_len +
|
||||||
|
+ fwacc(f, set->val_len) > set->len) {
|
||||||
|
+ fwwarn(f, "Value length exceeds setting");
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+ if ((set->val_type == FW_SETTING_VALTYPE_ASCII) &&
|
||||||
|
+ fwacc(f, set->data[set->key_len + set->val_len - 1])) {
|
||||||
|
+ fwwarn(f, "Value not null-terminated");
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+ if (set->val_type == FW_SETTING_VALTYPE_UINT) {
|
||||||
|
+ switch (fwacc(f, set->val_len)) {
|
||||||
|
+ case 1:
|
||||||
|
+ case 2:
|
||||||
|
+ case 4:
|
||||||
|
+ case 8:
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ fwwarn(f, "Unsupported integer value length: %d",
|
||||||
|
+ set->val_len);
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return true;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Add a setting to the device. Emit a warning if the setting is not known. */
|
||||||
|
+static void _add_setting(const char *filename, struct device *dev,
|
||||||
|
+ config_t config, const char *key, const char *value)
|
||||||
|
+{
|
||||||
|
+ struct attrib *a;
|
||||||
|
+ struct setting_list *list;
|
||||||
|
+
|
||||||
|
+ list = device_get_setting_list(dev, config);
|
||||||
|
+ a = attrib_find(dev->subtype->dev_attribs, key);
|
||||||
|
+ if (!a) {
|
||||||
|
+ warnx("%s: Applying unknown device setting %s=%s", filename,
|
||||||
|
+ key, value);
|
||||||
|
+ }
|
||||||
|
+ setting_list_apply(list, a, key, value);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void add_setting(const char *filename, struct device *dev,
|
||||||
|
+ config_t config, const char *key, const char *value)
|
||||||
|
+{
|
||||||
|
+ if (SCOPE_ACTIVE(config))
|
||||||
|
+ _add_setting(filename, dev, config_active, key, value);
|
||||||
|
+ if (SCOPE_PERSISTENT(config))
|
||||||
|
+ _add_setting(filename, dev, config_persistent, key, value);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Parse a single device setting in firmware format and apply it to the
|
||||||
|
+ * specified device. */
|
||||||
|
+static void parse_setting(struct fw_file *f, struct fw_setting *set,
|
||||||
|
+ struct device *dev, config_t config)
|
||||||
|
+{
|
||||||
|
+ char *ascii_key, *ascii_val;
|
||||||
|
+ unsigned long ulong_val;
|
||||||
|
+
|
||||||
|
+ if (!check_setting(f, set))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ ascii_key = &set->data[0];
|
||||||
|
+ if (set->val_type == FW_SETTING_VALTYPE_UINT) {
|
||||||
|
+ ulong_val = parse_value(&set->data[set->key_len], set->val_len);
|
||||||
|
+ ascii_val = misc_asprintf("%lu", ulong_val);
|
||||||
|
+ add_setting(f->name, dev, config, ascii_key, ascii_val);
|
||||||
|
+ free(ascii_val);
|
||||||
|
+ } else {
|
||||||
|
+ ascii_val = &set->data[set->key_len];
|
||||||
|
+ add_setting(f->name, dev, config, ascii_key, ascii_val);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Parse a device settings list in firmware format and apply the resulting
|
||||||
|
+ * settings to the specified device. */
|
||||||
|
+static void parse_settings(struct fw_file *f, char *data, struct device *dev,
|
||||||
|
+ config_t config)
|
||||||
|
+{
|
||||||
|
+ struct fw_setlist *list = (struct fw_setlist *) data;
|
||||||
|
+ struct fw_setting *set;
|
||||||
|
+ uint16_t off;
|
||||||
|
+
|
||||||
|
+ for (off = sizeof(struct fw_setlist); off < list->len;
|
||||||
|
+ off += set->len) {
|
||||||
|
+ set = (struct fw_setting *) &data[off];
|
||||||
|
+ if (fwacc(f, set->len) < sizeof(struct fw_setting)) {
|
||||||
|
+ fwwarn(f, "Setting too short");
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ if (off + fwacc(f, set->len) > list->len) {
|
||||||
|
+ fwwarn(f, "Setting too long");
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ parse_setting(f, set, dev, config);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Perform sanity checks on an I/O device ID. */
|
||||||
|
+static bool check_iodevid(struct fw_file *f, uint8_t *flags,
|
||||||
|
+ struct fw_iodevid *id)
|
||||||
|
+{
|
||||||
|
+
|
||||||
|
+ if (fwacc(f, *flags) & FW_IODEVID_FLAG_MCSS) {
|
||||||
|
+ fwwarn(f, "Unsupported entry in non-default CSS");
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+ if (fwacc(f, id->cssid) != 0) {
|
||||||
|
+ fwwarn(f, "Non-zero CSS-ID");
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+ return true;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Perform sanity checks on a device entry. */
|
||||||
|
+static bool check_de_size(struct fw_file *f, struct fw_dehdr *de, size_t size)
|
||||||
|
+{
|
||||||
|
+ if (fwacc(f, de->len) < size) {
|
||||||
|
+ fwwarn(f, "Device entry too short (expect %zu)", size);
|
||||||
|
+ return false;
|
||||||
|
+ }
|
||||||
|
+ return true;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Convert an I/O device ID to CCW device ID format. */
|
||||||
|
+static void io_to_ccw(struct ccw_devid *c, struct fw_iodevid *i)
|
||||||
|
+{
|
||||||
|
+ c->cssid = i->cssid;
|
||||||
|
+ c->ssid = i->ssid;
|
||||||
|
+ c->devno = i->devno;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Register a new device configuration. */
|
||||||
|
+static struct device *add_device(struct fw_file *f, struct subtype *st,
|
||||||
|
+ const char *id, config_t config,
|
||||||
|
+ struct util_list *objects)
|
||||||
|
+{
|
||||||
|
+ struct device *dev;
|
||||||
|
+
|
||||||
|
+ if (!st->devices)
|
||||||
|
+ st->devices = device_list_new(st);
|
||||||
|
+
|
||||||
|
+ dev = device_list_find(st->devices, id, NULL);
|
||||||
|
+ if (!dev) {
|
||||||
|
+ dev = device_new(st, id);
|
||||||
|
+ if (!dev) {
|
||||||
|
+ warnx("%s: Skipping invalid %s device ID %s", f->name,
|
||||||
|
+ st->name, id);
|
||||||
|
+ return NULL;
|
||||||
|
+ }
|
||||||
|
+ device_list_add(st->devices, dev);
|
||||||
|
+ }
|
||||||
|
+ ptrlist_add(objects, object_new(export_device, dev));
|
||||||
|
+
|
||||||
|
+ /* Prepare device for new settings. */
|
||||||
|
+ if (SCOPE_ACTIVE(config)) {
|
||||||
|
+ setting_list_clear(dev->active.settings);
|
||||||
|
+ if (dev->subtype->support_definable)
|
||||||
|
+ dev->active.definable = 1;
|
||||||
|
+ else
|
||||||
|
+ dev->active.exists = 1;
|
||||||
|
+ }
|
||||||
|
+ if (SCOPE_PERSISTENT(config)) {
|
||||||
|
+ setting_list_clear(dev->persistent.settings);
|
||||||
|
+ dev->persistent.exists = 1;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return dev;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Parse a DASD device entry. */
|
||||||
|
+static void parse_dasd(struct fw_file *f, struct fw_dehdr *de, config_t config,
|
||||||
|
+ struct util_list *objects)
|
||||||
|
+{
|
||||||
|
+ struct fw_dasd *dasd = (struct fw_dasd *) de;
|
||||||
|
+ struct ccw_devid devid;
|
||||||
|
+ struct device *dev_eckd, *dev_fba;
|
||||||
|
+ char *id;
|
||||||
|
+
|
||||||
|
+ if (!check_de_size(f, de, sizeof(struct fw_dasd)))
|
||||||
|
+ return;
|
||||||
|
+ if (!check_iodevid(f, &dasd->id_flags, &dasd->id))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ /* Could be either dasd_eckd or dasd_fba - add both entries */
|
||||||
|
+ io_to_ccw(&devid, &dasd->id);
|
||||||
|
+ id = ccw_devid_to_str(&devid);
|
||||||
|
+ dev_eckd = add_device(f, &dasd_subtype_eckd, id, config, objects);
|
||||||
|
+ dev_fba = add_device(f, &dasd_subtype_fba, id, config, objects);
|
||||||
|
+ free(id);
|
||||||
|
+
|
||||||
|
+ if (dasd->hdr.len > sizeof(struct fw_dasd)) {
|
||||||
|
+ if (dev_eckd)
|
||||||
|
+ parse_settings(f, dasd->settings, dev_eckd, config);
|
||||||
|
+ if (dev_fba)
|
||||||
|
+ parse_settings(f, dasd->settings, dev_fba, config);
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Parse a zFCP host device entry. */
|
||||||
|
+static void parse_zfcp_host(struct fw_file *f, struct fw_dehdr *de,
|
||||||
|
+ config_t config, struct util_list *objects)
|
||||||
|
+{
|
||||||
|
+ struct fw_zfcp_host *zfcp_host = (struct fw_zfcp_host *) de;
|
||||||
|
+ struct ccw_devid devid;
|
||||||
|
+ struct device *dev;
|
||||||
|
+ char *id;
|
||||||
|
+
|
||||||
|
+ if (!check_de_size(f, de, sizeof(struct fw_zfcp_host)))
|
||||||
|
+ return;
|
||||||
|
+ if (!check_iodevid(f, &zfcp_host->id_flags, &zfcp_host->id))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ /* Add zfcp_host entry */
|
||||||
|
+ io_to_ccw(&devid, &zfcp_host->id);
|
||||||
|
+ id = ccw_devid_to_str(&devid);
|
||||||
|
+ dev = add_device(f, &zfcp_host_subtype, id, config, objects);
|
||||||
|
+ free(id);
|
||||||
|
+
|
||||||
|
+ if (dev && zfcp_host->hdr.len > sizeof(struct fw_zfcp_host))
|
||||||
|
+ parse_settings(f, zfcp_host->settings, dev, config);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Parse a zFCP LUN device entry. */
|
||||||
|
+static void parse_zfcp_lun(struct fw_file *f, struct fw_dehdr *de,
|
||||||
|
+ config_t config, struct util_list *objects)
|
||||||
|
+{
|
||||||
|
+ struct fw_zfcp_lun *zfcp_lun = (struct fw_zfcp_lun *) de;
|
||||||
|
+ struct zfcp_lun_devid devid;
|
||||||
|
+ struct device *dev;
|
||||||
|
+ char *id;
|
||||||
|
+
|
||||||
|
+ if (!check_de_size(f, de, sizeof(struct fw_zfcp_lun)))
|
||||||
|
+ return;
|
||||||
|
+ if (!check_iodevid(f, &zfcp_lun->id_flags, &zfcp_lun->id))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ /* Add zfcp_lun entry */
|
||||||
|
+ io_to_ccw(&devid.fcp_dev, &zfcp_lun->id);
|
||||||
|
+ devid.wwpn = zfcp_lun->wwpn;
|
||||||
|
+ devid.lun = zfcp_lun->fcp_lun;
|
||||||
|
+ id = zfcp_lun_devid_to_str(&devid);
|
||||||
|
+ dev = add_device(f, &zfcp_lun_subtype, id, config, objects);
|
||||||
|
+ free(id);
|
||||||
|
+
|
||||||
|
+ if (dev && zfcp_lun->hdr.len > sizeof(struct fw_zfcp_lun))
|
||||||
|
+ parse_settings(f, zfcp_lun->settings, dev, config);
|
||||||
|
+
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Parse a QETH device entry. */
|
||||||
|
+static void parse_qeth(struct fw_file *f, struct fw_dehdr *de, config_t config,
|
||||||
|
+ struct util_list *objects)
|
||||||
|
+{
|
||||||
|
+ struct fw_qeth *qeth = (struct fw_qeth *) de;
|
||||||
|
+ struct ccwgroup_devid devid;
|
||||||
|
+ struct device *dev;
|
||||||
|
+ char *id;
|
||||||
|
+
|
||||||
|
+ if (!check_de_size(f, de, sizeof(struct fw_qeth)))
|
||||||
|
+ return;
|
||||||
|
+ if (!check_iodevid(f, &qeth->id_flags, &qeth->read_id) ||
|
||||||
|
+ !check_iodevid(f, &qeth->id_flags, &qeth->write_id) ||
|
||||||
|
+ !check_iodevid(f, &qeth->id_flags, &qeth->data_id))
|
||||||
|
+ return;
|
||||||
|
+
|
||||||
|
+ /* Add qeth entry */
|
||||||
|
+ devid.num = 3;
|
||||||
|
+ io_to_ccw(&devid.devid[0], &qeth->read_id);
|
||||||
|
+ io_to_ccw(&devid.devid[1], &qeth->write_id);
|
||||||
|
+ io_to_ccw(&devid.devid[2], &qeth->data_id);
|
||||||
|
+ id = ccwgroup_devid_to_str(&devid);
|
||||||
|
+ dev = add_device(f, &qeth_subtype_qeth, id, config, objects);
|
||||||
|
+ free(id);
|
||||||
|
+
|
||||||
|
+ if (dev && qeth->hdr.len > sizeof(struct fw_qeth))
|
||||||
|
+ parse_settings(f, qeth->settings, dev, config);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Parse a firmware file. */
|
||||||
|
+static void parse_fw(struct fw_file *f, long skip, config_t config,
|
||||||
|
+ struct util_list *objects)
|
||||||
|
+{
|
||||||
|
+ char *data = f->buffer;
|
||||||
|
+ struct fw_filehdr *hdr = (struct fw_filehdr *) data;
|
||||||
|
+ struct fw_dehdr *de;
|
||||||
|
+ uint16_t count = 0;
|
||||||
|
+ uint32_t off;
|
||||||
|
+
|
||||||
|
+ for (off = hdr->hdr_len; off < hdr->file_len; off += de->len) {
|
||||||
|
+ count++;
|
||||||
|
+ de = (struct fw_dehdr *) &data[off];
|
||||||
|
+ if (fwacc(f, de->len) == 0) {
|
||||||
|
+ fwwarn(f, "Empty device entry");
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ if (off + fwacc(f, de->len) > hdr->file_len) {
|
||||||
|
+ fwwarn(f, "Device entry too long");
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ if (skip >= 0 && de->seq <= skip) {
|
||||||
|
+ debug("Skipping %s entry due to sequence (%08x)\n",
|
||||||
|
+ type_to_str(de->type), de->seq);
|
||||||
|
+ continue;
|
||||||
|
+ }
|
||||||
|
+ switch (fwacc(f, de->type)) {
|
||||||
|
+ case FW_DE_HDR_TYPE_DASD:
|
||||||
|
+ parse_dasd(f, de, config, objects);
|
||||||
|
+ break;
|
||||||
|
+ case FW_DE_HDR_TYPE_ZFCP_HOST:
|
||||||
|
+ parse_zfcp_host(f, de, config, objects);
|
||||||
|
+ break;
|
||||||
|
+ case FW_DE_HDR_TYPE_ZFCP_LUN:
|
||||||
|
+ parse_zfcp_lun(f, de, config, objects);
|
||||||
|
+ break;
|
||||||
|
+ case FW_DE_HDR_TYPE_QETH:
|
||||||
|
+ parse_qeth(f, de, config, objects);
|
||||||
|
+ break;
|
||||||
|
+ default:
|
||||||
|
+ fwwarn(f, "Unknown entry (type=%04x)", de->type);
|
||||||
|
+ break;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (count != fwacc(f, hdr->de_count))
|
||||||
|
+ fwwarn(f, "Device entry count mismatch");
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Read configuration objects from @fd in firmware file format. Add pointers to
|
||||||
|
+ * newly allocated struct export_objects to ptrlist @objects. If @skip is a
|
||||||
|
+ * positive number, skip over entries with a sequence number equal to or
|
||||||
|
+ * greater than @skip. */
|
||||||
|
+exit_code_t firmware_read(FILE *fd, const char *filename, long skip,
|
||||||
|
+ config_t config, struct util_list *objects)
|
||||||
|
+{
|
||||||
|
+ struct fw_file file;
|
||||||
|
+ exit_code_t rc;
|
||||||
|
+
|
||||||
|
+ rc = read_fw(&file, fd, filename);
|
||||||
|
+ if (rc)
|
||||||
|
+ return rc;
|
||||||
|
+
|
||||||
|
+ parse_fw(&file, skip, config, objects);
|
||||||
|
+ free(file.buffer);
|
||||||
|
+
|
||||||
|
+ return rc;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Check if @fd refers to a file in binary firmware format. */
|
||||||
|
+bool firmware_detect(FILE *fd)
|
||||||
|
+{
|
||||||
|
+ int c;
|
||||||
|
+
|
||||||
|
+ c = fgetc(fd);
|
||||||
|
+ ungetc(c, fd);
|
||||||
|
+
|
||||||
|
+ /* Note: A full check would require looking at least at the first 4
|
||||||
|
+ * bytes, but fd might be non-seekable (e.g. pipe). Since there is no
|
||||||
|
+ * way that a textual import file can start with a 'z', looking at
|
||||||
|
+ * the first char should be enough. */
|
||||||
|
+
|
||||||
|
+ return c == 'z';
|
||||||
|
+}
|
157
s390-tools-sles15sp1-04-zdev-Implement-no-settle.patch
Normal file
157
s390-tools-sles15sp1-04-zdev-Implement-no-settle.patch
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
Subject: zdev: Implement --no-settle
|
||||||
|
From: Peter Oberparleiter <oberpar@linux.ibm.com>
|
||||||
|
|
||||||
|
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: f32bff96881a04bb68b895c23b13ae50daa9e7b4
|
||||||
|
Problem-ID: LS1604
|
||||||
|
|
||||||
|
Upstream-Description:
|
||||||
|
|
||||||
|
zdev: Implement --no-settle
|
||||||
|
|
||||||
|
There are some situations where running "udevadm settle" can result in
|
||||||
|
a deadlock, such as in the early stages of initial RAM-disk processing.
|
||||||
|
|
||||||
|
Introduce a new command-line option --no-settle that can be used to
|
||||||
|
suppress calling "udevadm settle" to allow chzdev to be run in such
|
||||||
|
situations.
|
||||||
|
|
||||||
|
Signed-off-by: Peter Oberparleiter <oberpar@linux.vnet.ibm.com>
|
||||||
|
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
||||||
|
|
||||||
|
|
||||||
|
Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
|
||||||
|
---
|
||||||
|
zdev/include/udev.h | 1 +
|
||||||
|
zdev/man/chzdev.8 | 9 +++++++++
|
||||||
|
zdev/src/chzdev.c | 9 +++++++++
|
||||||
|
zdev/src/chzdev_usage.txt | 1 +
|
||||||
|
zdev/src/udev.c | 3 +++
|
||||||
|
5 files changed, 23 insertions(+)
|
||||||
|
|
||||||
|
--- a/zdev/include/udev.h
|
||||||
|
+++ b/zdev/include/udev.h
|
||||||
|
@@ -14,6 +14,7 @@
|
||||||
|
#include "exit_code.h"
|
||||||
|
|
||||||
|
extern int udev_need_settle;
|
||||||
|
+extern int udev_no_settle;
|
||||||
|
|
||||||
|
/* Single key-operator-value entry in a udev rule line.*/
|
||||||
|
struct udev_entry_node {
|
||||||
|
--- a/zdev/man/chzdev.8
|
||||||
|
+++ b/zdev/man/chzdev.8
|
||||||
|
@@ -528,6 +528,15 @@ device configuration persistent. Typical
|
||||||
|
initial RAM disk, or modifying the kernel command line.
|
||||||
|
.PP
|
||||||
|
.
|
||||||
|
+.OD no-settle "" ""
|
||||||
|
+Do not wait for udev processing to complete.
|
||||||
|
+
|
||||||
|
+Skips all calls to the udevadm tool that are intended to wait for udev to
|
||||||
|
+finish processing before continuing. There is typically no need to use this
|
||||||
|
+option unless chzdev is run in an environment where udev is not fully
|
||||||
|
+functional (such as in the early phase of an initial RAM disk).
|
||||||
|
+.PP
|
||||||
|
+.
|
||||||
|
.OD persistent "p" ""
|
||||||
|
Apply changes to persistent configuration only.
|
||||||
|
|
||||||
|
--- a/zdev/src/chzdev.c
|
||||||
|
+++ b/zdev/src/chzdev.c
|
||||||
|
@@ -95,6 +95,7 @@ struct options {
|
||||||
|
struct util_list *base; /* List of struct strlist_node */
|
||||||
|
unsigned int verbose:1;
|
||||||
|
unsigned int quiet:1;
|
||||||
|
+ unsigned int no_settle:1;
|
||||||
|
};
|
||||||
|
|
||||||
|
/* Makefile converts chzdev_usage.txt into C file which we include here. */
|
||||||
|
@@ -136,6 +137,7 @@ enum {
|
||||||
|
OPT_VERSION = 'v',
|
||||||
|
OPT_VERBOSE = 'V',
|
||||||
|
OPT_QUIET = 'q',
|
||||||
|
+ OPT_NO_SETTLE = (OPT_ANONYMOUS_BASE+__COUNTER__),
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct opts_conflict conflict_list[] = {
|
||||||
|
@@ -217,6 +219,7 @@ static const struct option opt_list[] =
|
||||||
|
{ "base", required_argument, NULL, OPT_BASE },
|
||||||
|
{ "verbose", no_argument, NULL, OPT_VERBOSE },
|
||||||
|
{ "quiet", no_argument, NULL, OPT_QUIET },
|
||||||
|
+ { "no-settle", no_argument, NULL, OPT_NO_SETTLE },
|
||||||
|
{ NULL, no_argument, NULL, 0 },
|
||||||
|
};
|
||||||
|
|
||||||
|
@@ -937,6 +940,11 @@ static exit_code_t parse_options(struct
|
||||||
|
opts->quiet = 1;
|
||||||
|
break;
|
||||||
|
|
||||||
|
+ case OPT_NO_SETTLE:
|
||||||
|
+ /* --no-settle */
|
||||||
|
+ opts->no_settle = 1;
|
||||||
|
+ break;
|
||||||
|
+
|
||||||
|
case ':':
|
||||||
|
/* Missing option argument. */
|
||||||
|
syntax("Option '%s' requires an argument\n",
|
||||||
|
@@ -2904,6 +2912,7 @@ int main(int argc, char *argv[])
|
||||||
|
force = opts.force;
|
||||||
|
yes = opts.yes;
|
||||||
|
dryrun = opts.dryrun;
|
||||||
|
+ udev_no_settle = opts.no_settle;
|
||||||
|
path_set_base(opts.base);
|
||||||
|
|
||||||
|
if (dryrun)
|
||||||
|
--- a/zdev/src/chzdev_usage.txt
|
||||||
|
+++ b/zdev/src/chzdev_usage.txt
|
||||||
|
@@ -54,5 +54,6 @@ OPTIONS
|
||||||
|
--no-root-update Skip root device update
|
||||||
|
--dry-run Display changes without applying
|
||||||
|
--base PATH Use PATH as base for accessing files
|
||||||
|
+ --no-settle Do not wait for udev to settle
|
||||||
|
-V, --verbose Print additional run-time information
|
||||||
|
-q, --quiet Print only minimal run-time information
|
||||||
|
--- a/zdev/src/udev.c
|
||||||
|
+++ b/zdev/src/udev.c
|
||||||
|
@@ -24,6 +24,7 @@
|
||||||
|
#include "udev.h"
|
||||||
|
|
||||||
|
int udev_need_settle = 0;
|
||||||
|
+int udev_no_settle;
|
||||||
|
|
||||||
|
/* Create a newly allocated udev entry. */
|
||||||
|
static struct udev_entry_node *udev_entry_node_new(const char *key,
|
||||||
|
@@ -403,5 +404,7 @@ exit_code_t udev_remove_rule(const char
|
||||||
|
/* Wait for all current udev events to finish. */
|
||||||
|
void udev_settle(void)
|
||||||
|
{
|
||||||
|
+ if (udev_no_settle)
|
||||||
|
+ return;
|
||||||
|
misc_system(err_ignore, "%s settle", PATH_UDEVADM);
|
||||||
|
}
|
@ -0,0 +1,217 @@
|
|||||||
|
Subject: zdev: Write zfcp-lun udev rules to separate files
|
||||||
|
From: Peter Oberparleiter <oberpar@linux.ibm.com>
|
||||||
|
|
||||||
|
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: a86fb8b09118e6de7463882f889eff7e278163cd
|
||||||
|
Problem-ID: LS1604
|
||||||
|
|
||||||
|
Upstream-Description:
|
||||||
|
|
||||||
|
zdev: Write zfcp-lun udev rules to separate files
|
||||||
|
|
||||||
|
Change chzdev's udev rule generation from the previous approach of
|
||||||
|
combining all zfcp-lun udev rules associated with an FCP device into a
|
||||||
|
single file to storing zfcp-lun udev rules in one file per zfcp-lun.
|
||||||
|
This is done to enable per-device udev rule masking.
|
||||||
|
|
||||||
|
With udev rule masking, if a udev rule file by the same name exists in
|
||||||
|
both /etc and /run, the udev daemon will only consider the rules found
|
||||||
|
in /etc.
|
||||||
|
|
||||||
|
The auto-configuration feature will make use of per-device udev rule
|
||||||
|
masking to introduce a new class of configuration data (stored in /run)
|
||||||
|
that is only active if no user-provided configuration data (in /etc)
|
||||||
|
exists.
|
||||||
|
|
||||||
|
In addition, change chzdev to allow the regeneration of udev rules by
|
||||||
|
using the --force command line like in the following example:
|
||||||
|
|
||||||
|
# chzdev zfcp-lun --configured --enable --persistent --force
|
||||||
|
|
||||||
|
This can be used to convert all existing zfcp-lun udev rules from the
|
||||||
|
old format to the new one.
|
||||||
|
|
||||||
|
Signed-off-by: Peter Oberparleiter <oberpar@linux.vnet.ibm.com>
|
||||||
|
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
||||||
|
|
||||||
|
|
||||||
|
Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
|
||||||
|
---
|
||||||
|
zdev/src/chzdev.c | 6 +++-
|
||||||
|
zdev/src/root.c | 2 -
|
||||||
|
zdev/src/udev_zfcp_lun.c | 56 ++++++++++++++++++++++++++++++++++-----
|
||||||
|
3 files changed, 55 insertions(+), 9 deletions(-)
|
||||||
|
|
||||||
|
--- a/zdev/src/chzdev.c
|
||||||
|
+++ b/zdev/src/chzdev.c
|
||||||
|
@@ -1333,7 +1333,7 @@ static exit_code_t cfg_write(struct devi
|
||||||
|
struct subtype *st = dev->subtype;
|
||||||
|
exit_code_t rc = EXIT_OK;
|
||||||
|
|
||||||
|
- if (!device_needs_writing(dev, config))
|
||||||
|
+ if (!device_needs_writing(dev, config) && !force)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
if (check_active && config == config_persistent &&
|
||||||
|
@@ -1624,6 +1624,10 @@ static exit_code_t print_config_result(s
|
||||||
|
already = device_needs_writing(dev, config) ? 0 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ /* Re-do actions if run with --force */
|
||||||
|
+ if (force)
|
||||||
|
+ already = 0;
|
||||||
|
+
|
||||||
|
if (dev) {
|
||||||
|
devname = dev->subtype->devname;
|
||||||
|
devid = dev->id;
|
||||||
|
--- a/zdev/src/root.c
|
||||||
|
+++ b/zdev/src/root.c
|
||||||
|
@@ -60,7 +60,7 @@ exit_code_t root_check(void)
|
||||||
|
/* Check devices. */
|
||||||
|
dev = device_list_find(sel->st->devices, sel->id, NULL);
|
||||||
|
if (dev && dev->persistent.exists &&
|
||||||
|
- device_needs_writing(dev, config_persistent)) {
|
||||||
|
+ (device_needs_writing(dev, config_persistent) || force)) {
|
||||||
|
strlist_add(mod, "%s %s", dev->subtype->devname,
|
||||||
|
dev->id);
|
||||||
|
}
|
||||||
|
--- a/zdev/src/udev_zfcp_lun.c
|
||||||
|
+++ b/zdev/src/udev_zfcp_lun.c
|
||||||
|
@@ -385,6 +385,8 @@ void udev_zfcp_lun_add_device_ids(struct
|
||||||
|
free(cb_data.prefix);
|
||||||
|
}
|
||||||
|
|
||||||
|
+/* Return path to zfcp lun udev rule file containing configuration data for
|
||||||
|
+ * all LUNs of a zfcp device. */
|
||||||
|
static char *get_zfcp_lun_path(const char *id)
|
||||||
|
{
|
||||||
|
char *copy, *e, *path;
|
||||||
|
@@ -399,6 +401,13 @@ static char *get_zfcp_lun_path(const cha
|
||||||
|
return path;
|
||||||
|
}
|
||||||
|
|
||||||
|
+/* Return path to zfcp lun udev rule file containing configuration data for
|
||||||
|
+ * a single LUN. */
|
||||||
|
+static char *get_single_zfcp_lun_path(const char *id)
|
||||||
|
+{
|
||||||
|
+ return path_get_udev_rule(ZFCP_LUN_NAME, id);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* Apply the settings found in NODE to STATE. */
|
||||||
|
static void zfcp_lun_node_to_state(struct zfcp_lun_node *node,
|
||||||
|
struct attrib **attribs,
|
||||||
|
@@ -437,7 +446,12 @@ exit_code_t udev_zfcp_lun_read_device(st
|
||||||
|
exit_code_t rc = EXIT_OK;
|
||||||
|
char *path;
|
||||||
|
|
||||||
|
- path = get_zfcp_lun_path(dev->id);
|
||||||
|
+ /* Check for single lun file first then try multi lun file. */
|
||||||
|
+ path = get_single_zfcp_lun_path(dev->id);
|
||||||
|
+ if (!util_path_exists(path)) {
|
||||||
|
+ free(path);
|
||||||
|
+ path = get_zfcp_lun_path(dev->id);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
/* Get previous rule data. */
|
||||||
|
luns = zfcp_lun_node_list_new();
|
||||||
|
@@ -599,8 +613,10 @@ out:
|
||||||
|
|
||||||
|
/* Update the udev rule file that configures the zfcp lun with the specified
|
||||||
|
* ID. If @state is %NULL, remove the rule, otherwise create a rule that
|
||||||
|
- * applies the corresponding parameters. */
|
||||||
|
-static exit_code_t update_lun_rule(const char *id, struct device_state *state)
|
||||||
|
+ * applies the corresponding parameters. If @single is set, update a single
|
||||||
|
+ * lun rule file, otherwise update a multi lun rule file. */
|
||||||
|
+static exit_code_t update_lun_rule(const char *id, struct device_state *state,
|
||||||
|
+ bool single)
|
||||||
|
{
|
||||||
|
struct zfcp_lun_devid devid;
|
||||||
|
struct util_list *luns;
|
||||||
|
@@ -612,7 +628,7 @@ static exit_code_t update_lun_rule(const
|
||||||
|
rc = zfcp_lun_parse_devid(&devid, id, err_delayed_print);
|
||||||
|
if (rc)
|
||||||
|
return rc;
|
||||||
|
- path = get_zfcp_lun_path(id);
|
||||||
|
+ path = single ? get_single_zfcp_lun_path(id) : get_zfcp_lun_path(id);
|
||||||
|
|
||||||
|
/* Get previous rule data. */
|
||||||
|
luns = zfcp_lun_node_list_new();
|
||||||
|
@@ -650,24 +666,50 @@ static exit_code_t update_lun_rule(const
|
||||||
|
* device state. */
|
||||||
|
exit_code_t udev_zfcp_lun_write_device(struct device *dev)
|
||||||
|
{
|
||||||
|
- return update_lun_rule(dev->id, &dev->persistent);
|
||||||
|
+ exit_code_t rc;
|
||||||
|
+
|
||||||
|
+ rc = update_lun_rule(dev->id, &dev->persistent, true);
|
||||||
|
+
|
||||||
|
+ /* We only want single lun rule files so remove any remaining
|
||||||
|
+ * references in multi lun rule files. */
|
||||||
|
+ update_lun_rule(dev->id, NULL, false);
|
||||||
|
+
|
||||||
|
+ return rc;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Remove the UDEV rule used to configure the zfcp lun with the specified ID. */
|
||||||
|
exit_code_t udev_zfcp_lun_remove_rule(const char *id)
|
||||||
|
{
|
||||||
|
- return update_lun_rule(id, NULL);
|
||||||
|
+ exit_code_t rc, rc2;
|
||||||
|
+
|
||||||
|
+ rc = update_lun_rule(id, NULL, true);
|
||||||
|
+ rc2 = update_lun_rule(id, NULL, false);
|
||||||
|
+
|
||||||
|
+ if (rc)
|
||||||
|
+ return rc;
|
||||||
|
+
|
||||||
|
+ return rc2;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Determine if a udev rule exists for configuring the specified zfcp lun. */
|
||||||
|
bool udev_zfcp_lun_exists(const char *id)
|
||||||
|
{
|
||||||
|
struct zfcp_lun_devid devid;
|
||||||
|
- char *path, *rule, *pattern = NULL;
|
||||||
|
+ char *path, *rule = NULL, *pattern = NULL;
|
||||||
|
bool rc = false;
|
||||||
|
|
||||||
|
if (zfcp_lun_parse_devid(&devid, id, err_ignore) != EXIT_OK)
|
||||||
|
return false;
|
||||||
|
+
|
||||||
|
+ /* Check for single lun rule file first. */
|
||||||
|
+ path = get_single_zfcp_lun_path(id);
|
||||||
|
+ if (util_path_exists(path)) {
|
||||||
|
+ rc = true;
|
||||||
|
+ goto out;
|
||||||
|
+ }
|
||||||
|
+ free(path);
|
||||||
|
+
|
||||||
|
+ /* Check multi lun rule file next. */
|
||||||
|
path = get_zfcp_lun_path(id);
|
||||||
|
rule = misc_read_text_file(path, 1, err_ignore);
|
||||||
|
if (!rule)
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,155 @@
|
|||||||
|
Subject: zdev: Integrate firmware auto-configuration with dracut
|
||||||
|
From: Peter Oberparleiter <oberpar@linux.ibm.com>
|
||||||
|
|
||||||
|
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: 3fb356ebd297e4384208b7688d49cb3eb8f5b3e1
|
||||||
|
Problem-ID: LS1604
|
||||||
|
|
||||||
|
Upstream-Description:
|
||||||
|
|
||||||
|
zdev: Integrate firmware auto-configuration with dracut
|
||||||
|
|
||||||
|
Add a dracut hook that applies firmware-provided I/O configuration data
|
||||||
|
as auto-configuration during boot. This way, all I/O devices configured
|
||||||
|
by DPM are automatically brought online without further user
|
||||||
|
interaction.
|
||||||
|
|
||||||
|
This mechanism is active by default. It can be deactivated by specifying
|
||||||
|
the following parameter on the kernel command line:
|
||||||
|
|
||||||
|
rd.zdev=no-auto
|
||||||
|
|
||||||
|
Signed-off-by: Peter Oberparleiter <oberpar@linux.vnet.ibm.com>
|
||||||
|
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
||||||
|
|
||||||
|
|
||||||
|
Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
|
||||||
|
---
|
||||||
|
zdev/dracut/95zdev/module-setup.sh | 19 ++++++++++----
|
||||||
|
zdev/dracut/95zdev/parse-zdev.sh | 38 +++++++++++++++++++++++++++++
|
||||||
|
zdev/dracut/Makefile | 3 ++
|
||||||
|
3 files changed, 55 insertions(+), 5 deletions(-)
|
||||||
|
|
||||||
|
--- a/zdev/dracut/95zdev/module-setup.sh
|
||||||
|
+++ b/zdev/dracut/95zdev/module-setup.sh
|
||||||
|
@@ -9,7 +9,8 @@
|
||||||
|
# 95zdev/module_setup.sh
|
||||||
|
# This module installs configuration files (udev rules and modprobe.conf
|
||||||
|
# files) required to enable the root device on s390. It will only work when
|
||||||
|
-# the root device was configured using the chzdev tool.
|
||||||
|
+# the root device was configured using the chzdev tool. In addition,
|
||||||
|
+# a hook is installed to parse rd.zdev= kernel parameters.
|
||||||
|
#
|
||||||
|
|
||||||
|
check() {
|
||||||
|
@@ -29,15 +30,23 @@ depends() {
|
||||||
|
}
|
||||||
|
|
||||||
|
installkernel() {
|
||||||
|
- local _modules=$(lszdev --by-path / --columns MODULES --no-headings 2>/dev/null)
|
||||||
|
-
|
||||||
|
- [ -z "$_modules" ] && return 0
|
||||||
|
- [ ! -z "$_modules" ] && instmods $_modules
|
||||||
|
+ # Add modules for all device types supported by chzdev (required for
|
||||||
|
+ # auto-configuration)
|
||||||
|
+ instmods lcs qeth qeth_l2 qeth_l3 dasd_mod dasd_eckd_mod dasd_fba_mod \
|
||||||
|
+ dasd_diag_mod zfcp
|
||||||
|
}
|
||||||
|
|
||||||
|
install() {
|
||||||
|
local _tempfile
|
||||||
|
|
||||||
|
+ # Ensure that required tools are available
|
||||||
|
+ inst_multiple chzdev lszdev vmcp
|
||||||
|
+
|
||||||
|
+ # Hook to parse zdev kernel parameter
|
||||||
|
+ inst_hook cmdline 95 "$moddir/parse-zdev.sh"
|
||||||
|
+
|
||||||
|
+ # Obtain root device configuration
|
||||||
|
+
|
||||||
|
# Exit early if root device type is unknown
|
||||||
|
if ! lszdev --by-path / >/dev/null 2>&1 ; then
|
||||||
|
return 0
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/zdev/dracut/95zdev/parse-zdev.sh
|
||||||
|
@@ -0,0 +1,38 @@
|
||||||
|
+#!/bin/sh
|
||||||
|
+#
|
||||||
|
+# Copyright IBM Corp. 2017
|
||||||
|
+#
|
||||||
|
+# s390-tools is free software; you can redistribute it and/or modify
|
||||||
|
+# it under the terms of the MIT license. See LICENSE for details.
|
||||||
|
+#
|
||||||
|
+# 95zdev/parse-zdev.sh
|
||||||
|
+# Parse the kernel command line for rd.zdev kernel parameters. These
|
||||||
|
+# parameters are evaluated and used to configure z Systems specific devices.
|
||||||
|
+#
|
||||||
|
+# Format:
|
||||||
|
+# rd.zdev=no-auto
|
||||||
|
+#
|
||||||
|
+# where
|
||||||
|
+#
|
||||||
|
+# no-auto: Indicates that firmware-provided I/O configuration data
|
||||||
|
+# should not be applied.
|
||||||
|
+#
|
||||||
|
+
|
||||||
|
+zdev_fw_file="/sys/firmware/sclp_sd/config/data"
|
||||||
|
+zdev_base_args="--force --yes --no-root-update --no-settle --auto-conf --quiet"
|
||||||
|
+
|
||||||
|
+if [ -e "$zdev_fw_file" ] ; then
|
||||||
|
+ zdev_auto=1
|
||||||
|
+else
|
||||||
|
+ zdev_auto=0
|
||||||
|
+fi
|
||||||
|
+
|
||||||
|
+for zdev_arg in $(getargs rd.zdev); do
|
||||||
|
+ if [ "$zdev_arg" = "no-auto" ] ; then
|
||||||
|
+ zdev_auto=0
|
||||||
|
+ fi
|
||||||
|
+done
|
||||||
|
+
|
||||||
|
+if [ $zdev_auto -eq 1 ] ; then
|
||||||
|
+ chzdev --import "$zdev_fw_file" $zdev_base_args
|
||||||
|
+fi
|
||||||
|
--- a/zdev/dracut/Makefile
|
||||||
|
+++ b/zdev/dracut/Makefile
|
||||||
|
@@ -11,11 +11,14 @@ ZDEVDIR := 95zdev
|
||||||
|
# performs the following functions when dracut is run:
|
||||||
|
#
|
||||||
|
# - copy the persistent root device configuration to the initial ram disk
|
||||||
|
+# - install a boot-time hook to apply firmware-provided configuration data
|
||||||
|
+# to the system
|
||||||
|
#
|
||||||
|
ifeq ($(HAVE_DRACUT),1)
|
||||||
|
install:
|
||||||
|
$(INSTALL) -m 755 -d $(DESTDIR)$(MODDIR)
|
||||||
|
$(INSTALL) -m 755 -d $(DESTDIR)$(MODDIR)/$(ZDEVDIR)
|
||||||
|
$(INSTALL) -m 755 $(ZDEVDIR)/module-setup.sh \
|
||||||
|
+ $(ZDEVDIR)/parse-zdev.sh \
|
||||||
|
$(DESTDIR)$(MODDIR)/$(ZDEVDIR)/
|
||||||
|
endif
|
@ -0,0 +1,216 @@
|
|||||||
|
Subject: zdev: Integrate firmware auto-configuration with initramfs-tools
|
||||||
|
From: Peter Oberparleiter <oberpar@linux.ibm.com>
|
||||||
|
|
||||||
|
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: 3c5644ccfd46aab27df6e0ed783e94a620bc3fe6
|
||||||
|
Problem-ID: LS1604
|
||||||
|
|
||||||
|
Upstream-Description:
|
||||||
|
|
||||||
|
zdev: Integrate firmware auto-configuration with initramfs-tools
|
||||||
|
|
||||||
|
Add initramfs-tools scripts that apply firmware-provided I/O
|
||||||
|
configuration data as auto-configuration during boot. This way, all I/O
|
||||||
|
devices configured by DPM are automatically brought online without
|
||||||
|
further user interaction.
|
||||||
|
|
||||||
|
This mechanism is active by default. It can be deactivated by specifying
|
||||||
|
the following parameter on the kernel command line:
|
||||||
|
|
||||||
|
rd.zdev=no-auto
|
||||||
|
|
||||||
|
Signed-off-by: Peter Oberparleiter <oberpar@linux.vnet.ibm.com>
|
||||||
|
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
||||||
|
|
||||||
|
|
||||||
|
Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
|
||||||
|
---
|
||||||
|
README.md | 1
|
||||||
|
zdev/Makefile | 1
|
||||||
|
zdev/initramfs/Makefile | 22 ++++++++
|
||||||
|
zdev/initramfs/hooks/zdev | 39 +++++++++++++++
|
||||||
|
zdev/initramfs/scripts/init-top/zdev | 67 +++++++++++++++++++++++++++
|
||||||
|
5 files changed, 130 insertions(+)
|
||||||
|
|
||||||
|
--- a/README.md
|
||||||
|
+++ b/README.md
|
||||||
|
@@ -272,6 +272,7 @@ This table lists additional build or ins
|
||||||
|
| __COMPONENT__ | __OPTION__ | __TOOLS__ |
|
||||||
|
|----------------|:----------------:|:-------------------------------:|
|
||||||
|
| dracut | `HAVE_DRACUT` | zdev |
|
||||||
|
+| initramfs-tools| `HAVE_INITRAMFS` | zdev |
|
||||||
|
|
||||||
|
The s390-tools build process uses "pkg-config" if available and hard-coded
|
||||||
|
compiler and linker options otherwise.
|
||||||
|
--- a/zdev/Makefile
|
||||||
|
+++ b/zdev/Makefile
|
||||||
|
@@ -8,6 +8,7 @@ install: all
|
||||||
|
$(MAKE) -C src install
|
||||||
|
$(MAKE) -C man install
|
||||||
|
$(MAKE) -C dracut install
|
||||||
|
+ $(MAKE) -C initramfs install
|
||||||
|
|
||||||
|
clean:
|
||||||
|
$(MAKE) -C src clean
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/zdev/initramfs/Makefile
|
||||||
|
@@ -0,0 +1,22 @@
|
||||||
|
+# Common definitions
|
||||||
|
+include ../../common.mak
|
||||||
|
+
|
||||||
|
+INITRAMFSDIR := /usr/share/initramfs-tools
|
||||||
|
+HOOKDIR := $(INITRAMFSDIR)/hooks
|
||||||
|
+INITTOP := $(INITRAMFSDIR)/scripts/init-top
|
||||||
|
+
|
||||||
|
+# HAVE_INITRAMFS
|
||||||
|
+#
|
||||||
|
+# This install time parameter determines whether the zdev initramfs support is
|
||||||
|
+# installed (HAVE_INITRAMFS=1) or not (default). When installed, the module
|
||||||
|
+# performs the following functions when mkinitramfs is run:
|
||||||
|
+#
|
||||||
|
+# - install a boot-time hook to apply firmware-provided configuration data
|
||||||
|
+# to the system
|
||||||
|
+#
|
||||||
|
+ifeq ($(HAVE_INITRAMFS),1)
|
||||||
|
+install:
|
||||||
|
+ $(INSTALL) -m 755 -d $(DESTDIR)/$(HOOKDIR) $(DESTDIR)/$(INITTOP)
|
||||||
|
+ $(INSTALL) -m 755 hooks/zdev $(DESTDIR)/$(HOOKDIR)
|
||||||
|
+ $(INSTALL) -m 755 scripts/init-top/zdev $(DESTDIR)/$(INITTOP)
|
||||||
|
+endif
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/zdev/initramfs/hooks/zdev
|
||||||
|
@@ -0,0 +1,39 @@
|
||||||
|
+#!/bin/sh
|
||||||
|
+#
|
||||||
|
+# Copyright IBM Corp. 2016, 2017
|
||||||
|
+#
|
||||||
|
+# s390-tools is free software; you can redistribute it and/or modify
|
||||||
|
+# it under the terms of the MIT license. See LICENSE for details.
|
||||||
|
+#
|
||||||
|
+# hooks/zdev
|
||||||
|
+# This hook script adds files required to apply firmware-provided I/O
|
||||||
|
+# configuration data during boot.
|
||||||
|
+#
|
||||||
|
+
|
||||||
|
+PREREQ=""
|
||||||
|
+
|
||||||
|
+prereqs()
|
||||||
|
+{
|
||||||
|
+ echo "$PREREQ"
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+case $1 in
|
||||||
|
+ prereqs)
|
||||||
|
+ prereqs
|
||||||
|
+ exit 0
|
||||||
|
+ ;;
|
||||||
|
+esac
|
||||||
|
+
|
||||||
|
+. /usr/share/initramfs-tools/hook-functions
|
||||||
|
+
|
||||||
|
+# Add modules for all device types supported by chzdev (required for
|
||||||
|
+# auto-configuration)
|
||||||
|
+zdev_modules="lcs qeth qeth_l2 qeth_l3 dasd_mod dasd_eckd_mod dasd_fba_mod dasd_diag_mod zfcp"
|
||||||
|
+
|
||||||
|
+for x in $zdev_modules ; do
|
||||||
|
+ manual_add_modules ${x}
|
||||||
|
+done
|
||||||
|
+
|
||||||
|
+copy_exec /sbin/chzdev
|
||||||
|
+copy_exec /sbin/lszdev
|
||||||
|
+copy_exec /sbin/vmcp
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/zdev/initramfs/scripts/init-top/zdev
|
||||||
|
@@ -0,0 +1,67 @@
|
||||||
|
+#!/bin/sh
|
||||||
|
+#
|
||||||
|
+# Copyright IBM Corp. 2017
|
||||||
|
+#
|
||||||
|
+# s390-tools is free software; you can redistribute it and/or modify
|
||||||
|
+# it under the terms of the MIT license. See LICENSE for details.
|
||||||
|
+#
|
||||||
|
+# scripts/init-top/zdev
|
||||||
|
+# Parse the kernel command line for rd.zdev kernel parameters. These
|
||||||
|
+# parameters are evaluated and used to configure z Systems specific devices.
|
||||||
|
+#
|
||||||
|
+# Format:
|
||||||
|
+# rd.zdev=no-auto
|
||||||
|
+#
|
||||||
|
+# where
|
||||||
|
+#
|
||||||
|
+# no-auto: Indicates that firmware-provided I/O configuration data
|
||||||
|
+# should not be applied.
|
||||||
|
+#
|
||||||
|
+
|
||||||
|
+PREREQ="udev"
|
||||||
|
+
|
||||||
|
+prereqs()
|
||||||
|
+{
|
||||||
|
+ echo "$PREREQ"
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+case $1 in
|
||||||
|
+prereqs)
|
||||||
|
+ prereqs
|
||||||
|
+ exit 0
|
||||||
|
+ ;;
|
||||||
|
+esac
|
||||||
|
+
|
||||||
|
+. /scripts/functions
|
||||||
|
+
|
||||||
|
+zdev_fw_file="/sys/firmware/sclp_sd/config/data"
|
||||||
|
+zdev_base_args="--force --yes --no-root-update --no-settle --auto-conf --quiet"
|
||||||
|
+
|
||||||
|
+if [ -e "$zdev_fw_file" ] ; then
|
||||||
|
+ zdev_auto=1
|
||||||
|
+else
|
||||||
|
+ zdev_auto=0
|
||||||
|
+fi
|
||||||
|
+
|
||||||
|
+for x in $(cat /proc/cmdline); do
|
||||||
|
+ case ${x} in
|
||||||
|
+ rd.zdev=*)
|
||||||
|
+ zdev_arg=${x#*=}
|
||||||
|
+ if [ "$zdev_arg" = "no-auto" ] ; then
|
||||||
|
+ zdev_auto=0
|
||||||
|
+ fi
|
||||||
|
+ ;;
|
||||||
|
+ esac
|
||||||
|
+done
|
||||||
|
+
|
||||||
|
+if [ $zdev_auto -eq 1 ] ; then
|
||||||
|
+ log_begin_msg "Starting firmware auto-configuration"
|
||||||
|
+ chzdev --import "$zdev_fw_file" $zdev_base_args
|
||||||
|
+ log_end_msg
|
||||||
|
+
|
||||||
|
+ # Repeat cold-plug after creating udev rules
|
||||||
|
+ udevadm control --reload
|
||||||
|
+ udevadm trigger --type=subsystems --action=add
|
||||||
|
+ udevadm trigger --action=add
|
||||||
|
+ udevadm settle || true
|
||||||
|
+fi
|
@ -0,0 +1,507 @@
|
|||||||
|
Subject: zdev: Implement internal device attributes
|
||||||
|
From: Peter Oberparleiter <oberpar@linux.ibm.com>
|
||||||
|
|
||||||
|
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: c0392efa39e48cb12fdf3524b2f9e683e46f0f14
|
||||||
|
Problem-ID: LS1604
|
||||||
|
|
||||||
|
Upstream-Description:
|
||||||
|
|
||||||
|
zdev: Implement internal device attributes
|
||||||
|
|
||||||
|
This change adds base infrastructure for implementing internal device
|
||||||
|
attributes. In the context of the zdev tools, an internal device
|
||||||
|
attribute is a new type of device attribute with the following
|
||||||
|
characteristics:
|
||||||
|
|
||||||
|
- Can be set and removed like normal device attributes
|
||||||
|
- Affects zdev-internal handling only
|
||||||
|
- Does not correspond to an actual device attribute, that is
|
||||||
|
it has no representation in SysFS
|
||||||
|
- Can not be set in the active configuration
|
||||||
|
- Name starts with "zdev:" to prevent conflicts with actual
|
||||||
|
device attributes
|
||||||
|
|
||||||
|
Values for internal device attributes are stored in udev rules alongside
|
||||||
|
the normal persistent configuration of a device. They are encoded as
|
||||||
|
udev environment variables. Note that they have no further effect on
|
||||||
|
udev processing.
|
||||||
|
|
||||||
|
Signed-off-by: Peter Oberparleiter <oberpar@linux.vnet.ibm.com>
|
||||||
|
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
||||||
|
|
||||||
|
|
||||||
|
Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
|
||||||
|
---
|
||||||
|
zdev/include/attrib.h | 2
|
||||||
|
zdev/include/internal.h | 20 +++++++++
|
||||||
|
zdev/include/misc.h | 1
|
||||||
|
zdev/include/udev.h | 7 +++
|
||||||
|
zdev/src/Makefile | 4 -
|
||||||
|
zdev/src/device.c | 15 +++++++
|
||||||
|
zdev/src/internal.c | 25 ++++++++++++
|
||||||
|
zdev/src/misc.c | 15 +++++++
|
||||||
|
zdev/src/udev.c | 32 +++++++++++++++
|
||||||
|
zdev/src/udev_ccw.c | 16 +++++++
|
||||||
|
zdev/src/udev_ccwgroup.c | 11 +++++
|
||||||
|
zdev/src/udev_zfcp_lun.c | 80 ++++++++++++++++++++++++++++++++++++---
|
||||||
|
12 files changed, 220 insertions(+), 8 deletions(-)
|
||||||
|
|
||||||
|
--- a/zdev/include/attrib.h
|
||||||
|
+++ b/zdev/include/attrib.h
|
||||||
|
@@ -189,6 +189,7 @@ struct value_map {
|
||||||
|
* in the persistent configuration
|
||||||
|
* @nounload: (Device type attributes only) This attribute can be set while
|
||||||
|
* the corresponding kernel module remains loaded.
|
||||||
|
+ * @internal: This attribute only affects internal handling
|
||||||
|
* @order: A number indicating the order in which to apply attribute
|
||||||
|
* @order_cmp: A function determining if a setting for this attribute should
|
||||||
|
* be applied before (-1) or after (1) another setting, or
|
||||||
|
@@ -216,6 +217,7 @@ struct attrib {
|
||||||
|
unsigned int activerem :1;
|
||||||
|
unsigned int defunset :1;
|
||||||
|
unsigned int nounload :1;
|
||||||
|
+ unsigned int internal :1;
|
||||||
|
|
||||||
|
/* Optional */
|
||||||
|
int order;
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/zdev/include/internal.h
|
||||||
|
@@ -0,0 +1,20 @@
|
||||||
|
+/*
|
||||||
|
+ * zdev - Modify and display the persistent configuration of devices
|
||||||
|
+ *
|
||||||
|
+ * Copyright IBM Corp. 2017
|
||||||
|
+ *
|
||||||
|
+ * 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 INTERNAL_H
|
||||||
|
+#define INTERNAL_H
|
||||||
|
+
|
||||||
|
+#include <stdbool.h>
|
||||||
|
+
|
||||||
|
+#define INTERNAL_ATTR_PREFIX "zdev:"
|
||||||
|
+
|
||||||
|
+const char *internal_get_name(const char *name);
|
||||||
|
+bool internal_by_name(const char *name);
|
||||||
|
+
|
||||||
|
+#endif /* INTERNAL_H */
|
||||||
|
--- a/zdev/include/misc.h
|
||||||
|
+++ b/zdev/include/misc.h
|
||||||
|
@@ -183,6 +183,7 @@ bool str_to_config(const char *, config_
|
||||||
|
char *quote_str(const char *, int);
|
||||||
|
char *unquote_str(const char *);
|
||||||
|
char *shrink_str(const char *);
|
||||||
|
+char *misc_strrstr(const char *haystack, const char *needle);
|
||||||
|
|
||||||
|
struct util_list *strlist_new(void);
|
||||||
|
void strlist_free(struct util_list *);
|
||||||
|
--- a/zdev/include/udev.h
|
||||||
|
+++ b/zdev/include/udev.h
|
||||||
|
@@ -13,6 +13,9 @@
|
||||||
|
#include "lib/util_list.h"
|
||||||
|
#include "exit_code.h"
|
||||||
|
|
||||||
|
+struct attrib;
|
||||||
|
+struct setting_list;
|
||||||
|
+
|
||||||
|
extern int udev_need_settle;
|
||||||
|
extern int udev_no_settle;
|
||||||
|
|
||||||
|
@@ -46,4 +49,8 @@ exit_code_t udev_remove_rule(const char
|
||||||
|
|
||||||
|
void udev_settle(void);
|
||||||
|
|
||||||
|
+void udev_add_internal_from_entry(struct setting_list *list,
|
||||||
|
+ struct udev_entry_node *entry,
|
||||||
|
+ struct attrib **attribs);
|
||||||
|
+
|
||||||
|
#endif /* UDEV_H */
|
||||||
|
--- a/zdev/src/Makefile
|
||||||
|
+++ b/zdev/src/Makefile
|
||||||
|
@@ -8,7 +8,7 @@ ALL_CPPFLAGS += -I ../include -std=gnu99
|
||||||
|
chzdev_objects += attrib.o chzdev.o device.o devnode.o devtype.o exit_code.o \
|
||||||
|
export.o hash.o inuse.o misc.o namespace.o opts.o path.o \
|
||||||
|
root.o select.o setting.o subtype.o table.o table_attribs.o \
|
||||||
|
- table_types.o net.o firmware.o
|
||||||
|
+ table_types.o net.o firmware.o internal.o
|
||||||
|
|
||||||
|
# Devtype Helpers
|
||||||
|
chzdev_objects += blkinfo.o ccw.o ccwgroup.o findmnt.o modprobe.o module.o \
|
||||||
|
@@ -38,7 +38,7 @@ chzdev_objects += generic_ccw.o
|
||||||
|
lszdev_objects += attrib.o lszdev.o device.o devnode.o devtype.o exit_code.o \
|
||||||
|
export.o hash.o inuse.o misc.o namespace.o opts.o path.o \
|
||||||
|
root.o select.o setting.o subtype.o table.o table_types.o \
|
||||||
|
- net.o
|
||||||
|
+ net.o internal.o
|
||||||
|
|
||||||
|
# Devtype Helpers
|
||||||
|
lszdev_objects += blkinfo.o ccw.o ccwgroup.o findmnt.o modprobe.o module.o \
|
||||||
|
--- a/zdev/src/device.c
|
||||||
|
+++ b/zdev/src/device.c
|
||||||
|
@@ -16,6 +16,7 @@
|
||||||
|
#include "attrib.h"
|
||||||
|
#include "device.h"
|
||||||
|
#include "devtype.h"
|
||||||
|
+#include "internal.h"
|
||||||
|
#include "misc.h"
|
||||||
|
#include "namespace.h"
|
||||||
|
#include "setting.h"
|
||||||
|
@@ -221,6 +222,9 @@ static exit_code_t apply_setting(struct
|
||||||
|
goto err_activeonly_forceable;
|
||||||
|
if (!force && SCOPE_AUTOCONF(config) && a->activeonly)
|
||||||
|
goto err_activeonly_forceable;
|
||||||
|
+ /* Check for internal. */
|
||||||
|
+ if (config == config_active && a->internal)
|
||||||
|
+ goto err_int_noactive;
|
||||||
|
/* Check for multiple values. */
|
||||||
|
if (!force && !a->multi && strlist_find(processed, key))
|
||||||
|
goto err_multi_forceable;
|
||||||
|
@@ -230,6 +234,9 @@ static exit_code_t apply_setting(struct
|
||||||
|
goto err_unknown;
|
||||||
|
if (!force)
|
||||||
|
goto err_unknown_forceable;
|
||||||
|
+ /* Check for internal. */
|
||||||
|
+ if (config == config_active && internal_by_name(key))
|
||||||
|
+ goto err_int_noactive;
|
||||||
|
}
|
||||||
|
|
||||||
|
strlist_add(processed, "%s", key);
|
||||||
|
@@ -294,6 +301,11 @@ err_activeonly_forceable:
|
||||||
|
delayed_forceable("Attribute '%s' should only be changed in the active "
|
||||||
|
"config\n", a->name);
|
||||||
|
return EXIT_INVALID_SETTING;
|
||||||
|
+
|
||||||
|
+err_int_noactive:
|
||||||
|
+ delayed_err("Internal attribute '%s' cannot be set in the active config\n",
|
||||||
|
+ key);
|
||||||
|
+ return EXIT_INVALID_SETTING;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Apply device settings from strlist to device. */
|
||||||
|
@@ -542,6 +554,9 @@ exit_code_t device_write_active_settings
|
||||||
|
s = p->ptr;
|
||||||
|
if (!s->modified || s->removed)
|
||||||
|
continue;
|
||||||
|
+ if ((s->attrib && s->attrib->internal) ||
|
||||||
|
+ internal_by_name(s->name))
|
||||||
|
+ continue;
|
||||||
|
|
||||||
|
path = subtype_get_active_attrib_path(st, dev, s->name);
|
||||||
|
if (!path) {
|
||||||
|
--- /dev/null
|
||||||
|
+++ b/zdev/src/internal.c
|
||||||
|
@@ -0,0 +1,25 @@
|
||||||
|
+/*
|
||||||
|
+ * zdev - Modify and display the persistent configuration of devices
|
||||||
|
+ *
|
||||||
|
+ * Copyright IBM Corp. 2017
|
||||||
|
+ *
|
||||||
|
+ * 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 <stdbool.h>
|
||||||
|
+
|
||||||
|
+#include "internal.h"
|
||||||
|
+#include "misc.h"
|
||||||
|
+
|
||||||
|
+/* Return identifier of internal attribute with specified @name. */
|
||||||
|
+const char *internal_get_name(const char *name)
|
||||||
|
+{
|
||||||
|
+ return name + sizeof(INTERNAL_ATTR_PREFIX) - 1;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Check if attribute is internal by name. */
|
||||||
|
+bool internal_by_name(const char *name)
|
||||||
|
+{
|
||||||
|
+ return starts_with(name, INTERNAL_ATTR_PREFIX);
|
||||||
|
+}
|
||||||
|
--- a/zdev/src/misc.c
|
||||||
|
+++ b/zdev/src/misc.c
|
||||||
|
@@ -1717,3 +1717,18 @@ void debug_init(int argc, char *argv[])
|
||||||
|
fprintf(stderr, "%s\"%s\"", i > 0 ? ", " : "", argv[i]);
|
||||||
|
fprintf(stderr, "\n");
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+/* Return the last occurrence of @needle in @haystack, or %NULL if @needle
|
||||||
|
+ * was not found. */
|
||||||
|
+char *misc_strrstr(const char *haystack, const char *needle)
|
||||||
|
+{
|
||||||
|
+ char *result, *next;
|
||||||
|
+
|
||||||
|
+ result = strstr(haystack, needle);
|
||||||
|
+ if (result) {
|
||||||
|
+ while ((next = strstr(result + 1, needle)))
|
||||||
|
+ result = next;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ return result;
|
||||||
|
+}
|
||||||
|
--- a/zdev/src/udev.c
|
||||||
|
+++ b/zdev/src/udev.c
|
||||||
|
@@ -409,3 +409,35 @@ void udev_settle(void)
|
||||||
|
return;
|
||||||
|
misc_system(err_ignore, "%s settle", PATH_UDEVADM);
|
||||||
|
}
|
||||||
|
+
|
||||||
|
+/* Extract internal attribute settings from @entry and add to @list.
|
||||||
|
+ * Associate corresponding attribute if found in @attribs. */
|
||||||
|
+void udev_add_internal_from_entry(struct setting_list *list,
|
||||||
|
+ struct udev_entry_node *entry,
|
||||||
|
+ struct attrib **attribs)
|
||||||
|
+{
|
||||||
|
+ char *copy, *name, *end, *u;
|
||||||
|
+ struct attrib *a;
|
||||||
|
+
|
||||||
|
+ /* ENV{zdev_var}="1" */
|
||||||
|
+ copy = misc_strdup(entry->key);
|
||||||
|
+
|
||||||
|
+ /* Find attribute name start. */
|
||||||
|
+ name = strchr(copy, '{');
|
||||||
|
+ end = strrchr(copy, '}');
|
||||||
|
+ if (!name || !end)
|
||||||
|
+ goto out;
|
||||||
|
+ *end = 0;
|
||||||
|
+ name++;
|
||||||
|
+
|
||||||
|
+ /* zdev_ => zdev: */
|
||||||
|
+ u = strchr(name, '_');
|
||||||
|
+ if (u)
|
||||||
|
+ *u = ':';
|
||||||
|
+
|
||||||
|
+ a = attrib_find(attribs, name);
|
||||||
|
+ setting_list_apply_actual(list, a, name, entry->value);
|
||||||
|
+
|
||||||
|
+out:
|
||||||
|
+ free(copy);
|
||||||
|
+}
|
||||||
|
--- a/zdev/src/udev_ccw.c
|
||||||
|
+++ b/zdev/src/udev_ccw.c
|
||||||
|
@@ -18,6 +18,7 @@
|
||||||
|
#include "attrib.h"
|
||||||
|
#include "ccw.h"
|
||||||
|
#include "device.h"
|
||||||
|
+#include "internal.h"
|
||||||
|
#include "misc.h"
|
||||||
|
#include "path.h"
|
||||||
|
#include "setting.h"
|
||||||
|
@@ -49,6 +50,12 @@ static void add_setting_from_entry(struc
|
||||||
|
char *copy, *name, *end;
|
||||||
|
struct attrib *a;
|
||||||
|
|
||||||
|
+ /* ENV{zdev_var}="1" */
|
||||||
|
+ if (starts_with(entry->key, "ENV{zdev_") &&
|
||||||
|
+ strcmp(entry->op, "=") == 0) {
|
||||||
|
+ udev_add_internal_from_entry(list, entry, attribs);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
/* ATTR{[ccw/0.0.37bf]online}=1 */
|
||||||
|
if (strncmp(entry->key, "ATTR{[ccw/", 10) != 0 ||
|
||||||
|
strcmp(entry->op, "=") != 0)
|
||||||
|
@@ -190,7 +197,14 @@ exit_code_t udev_ccw_write_device(struct
|
||||||
|
s = p->ptr;
|
||||||
|
if (s->removed)
|
||||||
|
continue;
|
||||||
|
- fprintf(fd, "ATTR{[ccw/%s]%s}=\"%s\"\n", id, s->name, s->value);
|
||||||
|
+ if ((s->attrib && s->attrib->internal) ||
|
||||||
|
+ internal_by_name(s->name)) {
|
||||||
|
+ fprintf(fd, "ENV{zdev_%s}=\"%s\"\n",
|
||||||
|
+ internal_get_name(s->name), s->value);
|
||||||
|
+ } else {
|
||||||
|
+ fprintf(fd, "ATTR{[ccw/%s]%s}=\"%s\"\n", id, s->name,
|
||||||
|
+ s->value);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Write udev rule epilog. */
|
||||||
|
--- a/zdev/src/udev_ccwgroup.c
|
||||||
|
+++ b/zdev/src/udev_ccwgroup.c
|
||||||
|
@@ -18,6 +18,7 @@
|
||||||
|
#include "attrib.h"
|
||||||
|
#include "ccwgroup.h"
|
||||||
|
#include "device.h"
|
||||||
|
+#include "internal.h"
|
||||||
|
#include "misc.h"
|
||||||
|
#include "path.h"
|
||||||
|
#include "setting.h"
|
||||||
|
@@ -68,6 +69,12 @@ static void add_setting_from_entry(struc
|
||||||
|
char *copy, *name, *end;
|
||||||
|
struct attrib *a;
|
||||||
|
|
||||||
|
+ /* ENV{zdev_var}="1" */
|
||||||
|
+ if (starts_with(entry->key, "ENV{zdev_") &&
|
||||||
|
+ strcmp(entry->op, "=") == 0) {
|
||||||
|
+ udev_add_internal_from_entry(list, entry, attribs);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
/* ATTR{[ccwgroup/0.0.f5f0]online}=1 */
|
||||||
|
if (strncmp(entry->key, "ATTR{[ccwgroup/", 10) != 0 ||
|
||||||
|
strcmp(entry->op, "=") != 0)
|
||||||
|
@@ -282,6 +289,10 @@ exit_code_t udev_ccwgroup_write_device(s
|
||||||
|
fprintf(fd, "ATTR{[ccwgroup/%s]%s}=\"%s\"\n",
|
||||||
|
ccw_id, s->name, str->str);
|
||||||
|
}
|
||||||
|
+ } else if ((s->attrib && s->attrib->internal) ||
|
||||||
|
+ internal_by_name(s->name)) {
|
||||||
|
+ fprintf(fd, "ENV{zdev_%s}=\"%s\"\n",
|
||||||
|
+ internal_get_name(s->name), s->value);
|
||||||
|
} else {
|
||||||
|
fprintf(fd, "ATTR{[ccwgroup/%s]%s}=\"%s\"\n", ccw_id,
|
||||||
|
s->name, s->value);
|
||||||
|
--- a/zdev/src/udev_zfcp_lun.c
|
||||||
|
+++ b/zdev/src/udev_zfcp_lun.c
|
||||||
|
@@ -18,6 +18,7 @@
|
||||||
|
|
||||||
|
#include "attrib.h"
|
||||||
|
#include "device.h"
|
||||||
|
+#include "internal.h"
|
||||||
|
#include "misc.h"
|
||||||
|
#include "path.h"
|
||||||
|
#include "scsi.h"
|
||||||
|
@@ -128,7 +129,7 @@ static bool zfcp_lun_devid_from_entry(st
|
||||||
|
struct udev_entry_node *entry)
|
||||||
|
{
|
||||||
|
struct zfcp_lun_devid id;
|
||||||
|
- char *copy = NULL, *s;
|
||||||
|
+ char *copy = NULL, *s, *e, *u;
|
||||||
|
int i;
|
||||||
|
bool rc = false;
|
||||||
|
|
||||||
|
@@ -182,6 +183,28 @@ static bool zfcp_lun_devid_from_entry(st
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ /*ENV{zdev_var__0_0_1941_0x500507630510c1ae_0x402340d400000000}="1"*/
|
||||||
|
+ if (starts_with(entry->key, "ENV{zdev_")) {
|
||||||
|
+ copy = misc_strdup(entry->key);
|
||||||
|
+
|
||||||
|
+ /* Find ID start (last __) and end (last }). */
|
||||||
|
+ s = misc_strrstr(copy, "__");
|
||||||
|
+ e = strrchr(copy, '}');
|
||||||
|
+ if (!s || !e)
|
||||||
|
+ goto out;
|
||||||
|
+ *e = 0;
|
||||||
|
+ s += 2;
|
||||||
|
+ /* Convert variable name to ID format. */
|
||||||
|
+ for (i = 0, u = s; (u = strchr(u, '_')); i++, u++) {
|
||||||
|
+ if (i < 2)
|
||||||
|
+ *u = '.';
|
||||||
|
+ else
|
||||||
|
+ *u = ':';
|
||||||
|
+ }
|
||||||
|
+ rc = zfcp_lun_parse_devid(&id, s, err_ignore) == EXIT_OK ?
|
||||||
|
+ true : false;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
out:
|
||||||
|
free(copy);
|
||||||
|
if (rc)
|
||||||
|
@@ -211,11 +234,46 @@ static struct zfcp_lun_node *zfcp_lun_no
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static void add_internal_setting_from_entry(struct udev_entry_node *entry,
|
||||||
|
+ struct zfcp_lun_node *node)
|
||||||
|
+{
|
||||||
|
+ char *copy, *name, *end, *u;
|
||||||
|
+ struct attrib *a;
|
||||||
|
+
|
||||||
|
+ /*ENV{zdev_var__0_0_1941_0x500507630510c1ae_0x402340d400000000}="1"*/
|
||||||
|
+ copy = misc_strdup(entry->key);
|
||||||
|
+
|
||||||
|
+ /* Find attribute name start and end. */
|
||||||
|
+ name = strchr(copy, '{');
|
||||||
|
+ end = misc_strrstr(copy, "__");
|
||||||
|
+ if (!name || !end)
|
||||||
|
+ goto out;
|
||||||
|
+ *end = 0;
|
||||||
|
+ name++;
|
||||||
|
+
|
||||||
|
+ /* zdev_ => zdev: */
|
||||||
|
+ u = strchr(name, '_');
|
||||||
|
+ if (u)
|
||||||
|
+ *u = ':';
|
||||||
|
+
|
||||||
|
+ a = attrib_find(zfcp_lun_subtype.dev_attribs, name);
|
||||||
|
+ setting_list_apply_actual(node->fc_settings, a, name, entry->value);
|
||||||
|
+
|
||||||
|
+out:
|
||||||
|
+ free(copy);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
static void add_fc_setting_from_entry(struct udev_entry_node *entry,
|
||||||
|
struct zfcp_lun_node *node)
|
||||||
|
{
|
||||||
|
char *copy, *s, *e;
|
||||||
|
|
||||||
|
+ /*ENV{zdev_var__0_0_1941_0x500507630510c1ae_0x402340d400000000}="1"*/
|
||||||
|
+ if (starts_with(entry->key, "ENV{zdev_") &&
|
||||||
|
+ strcmp(entry->op, "=") == 0) {
|
||||||
|
+ add_internal_setting_from_entry(entry, node);
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
/*ATTR{[ccw/0.0.1941]0x500507630510c1ae/0x402340d400000000/failed}="0"*/
|
||||||
|
if (!starts_with(entry->key, "ATTR{[ccw/"))
|
||||||
|
return;
|
||||||
|
@@ -490,7 +548,7 @@ static struct zfcp_lun_node *state_to_zf
|
||||||
|
s->value);
|
||||||
|
setting_list_add(node->scsi_settings, n);
|
||||||
|
} else {
|
||||||
|
- n = setting_new(NULL, s->name, s->value);
|
||||||
|
+ n = setting_new(s->attrib, s->name, s->value);
|
||||||
|
setting_list_add(node->fc_settings, n);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@@ -580,9 +638,21 @@ static exit_code_t write_luns_rule(const
|
||||||
|
node->id.lun);
|
||||||
|
|
||||||
|
util_list_iterate(&node->fc_settings->list, s) {
|
||||||
|
- fprintf(fd, "ATTR{[ccw/%s]0x%016" PRIx64 "/0x%016"
|
||||||
|
- PRIx64 "/%s}=\"%s\"\n", hba_id, node->id.wwpn,
|
||||||
|
- node->id.lun, s->name, s->value);
|
||||||
|
+ if ((s->attrib && s->attrib->internal) ||
|
||||||
|
+ internal_by_name(s->name)) {
|
||||||
|
+ fprintf(fd, "ENV{zdev_%s__%x_%x_%04x_0x%016"
|
||||||
|
+ PRIx64 "_0x%016" PRIx64 "}=\"%s\"\n",
|
||||||
|
+ internal_get_name(s->name),
|
||||||
|
+ node->id.fcp_dev.cssid,
|
||||||
|
+ node->id.fcp_dev.ssid,
|
||||||
|
+ node->id.fcp_dev.devno, node->id.wwpn,
|
||||||
|
+ node->id.lun, s->value);
|
||||||
|
+ } else {
|
||||||
|
+ fprintf(fd, "ATTR{[ccw/%s]0x%016" PRIx64
|
||||||
|
+ "/0x%016" PRIx64 "/%s}=\"%s\"\n",
|
||||||
|
+ hba_id, node->id.wwpn, node->id.lun,
|
||||||
|
+ s->name, s->value);
|
||||||
|
+ }
|
||||||
|
}
|
||||||
|
last_node = node;
|
||||||
|
}
|
@ -0,0 +1,505 @@
|
|||||||
|
Subject: zdev: Implement support for early device configuration
|
||||||
|
From: Peter Oberparleiter <oberpar@linux.ibm.com>
|
||||||
|
|
||||||
|
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: 156450f359bb13776fac2130a1cac00a48c2deda
|
||||||
|
Problem-ID: LS1604
|
||||||
|
|
||||||
|
Upstream-Description:
|
||||||
|
|
||||||
|
zdev: Implement support for early device configuration
|
||||||
|
|
||||||
|
Enable user to specify that a device should be configured early, that is
|
||||||
|
during the initial RAM-disk boot phase. This may be necessary, e.g. to
|
||||||
|
override auto-configuration for a device which is also applied during
|
||||||
|
that boot phase. It may also be used to manually specify devices that
|
||||||
|
are required to access the root file system, such as networking devices.
|
||||||
|
|
||||||
|
Users can mark devices as requiring early configuration by specifying
|
||||||
|
a value of 1 for the newly added internal attribute zdev:early:
|
||||||
|
|
||||||
|
# chzdev dasd-eckd 0.0.1234 -p zdev:early=1
|
||||||
|
|
||||||
|
This can be changed back by removing the attribute setting, or by
|
||||||
|
setting the attribute value to 0:
|
||||||
|
|
||||||
|
# chzdev dasd-eckd 0.0.1234 -p -r zdev:early
|
||||||
|
|
||||||
|
or
|
||||||
|
|
||||||
|
# chzdev dasd-eckd 0.0.1234 -p zdev:early=0
|
||||||
|
|
||||||
|
Signed-off-by: Peter Oberparleiter <oberpar@linux.vnet.ibm.com>
|
||||||
|
Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
|
||||||
|
|
||||||
|
|
||||||
|
Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
|
||||||
|
---
|
||||||
|
zdev/dracut/95zdev/module-setup.sh | 21 +------
|
||||||
|
zdev/include/internal.h | 5 +
|
||||||
|
zdev/initramfs/hooks/zdev | 19 ++++++
|
||||||
|
zdev/man/chzdev.8 | 29 ++++++++++
|
||||||
|
zdev/src/chzdev.c | 4 -
|
||||||
|
zdev/src/ctc.c | 2
|
||||||
|
zdev/src/dasd.c | 3 +
|
||||||
|
zdev/src/generic_ccw.c | 2
|
||||||
|
zdev/src/internal.c | 13 ++++
|
||||||
|
zdev/src/lcs.c | 2
|
||||||
|
zdev/src/qeth.c | 2
|
||||||
|
zdev/src/root.c | 82 ++++++++++++++++++++++-------
|
||||||
|
zdev/src/zfcp_host.c | 2
|
||||||
|
zdev/src/zfcp_lun.c | 2
|
||||||
|
14 files changed, 152 insertions(+), 36 deletions(-)
|
||||||
|
|
||||||
|
--- a/zdev/dracut/95zdev/module-setup.sh
|
||||||
|
+++ b/zdev/dracut/95zdev/module-setup.sh
|
||||||
|
@@ -45,23 +45,12 @@ install() {
|
||||||
|
# Hook to parse zdev kernel parameter
|
||||||
|
inst_hook cmdline 95 "$moddir/parse-zdev.sh"
|
||||||
|
|
||||||
|
- # Obtain root device configuration
|
||||||
|
-
|
||||||
|
- # Exit early if root device type is unknown
|
||||||
|
- if ! lszdev --by-path / >/dev/null 2>&1 ; then
|
||||||
|
- return 0
|
||||||
|
- fi
|
||||||
|
-
|
||||||
|
+ # Obtain early + root device configuration
|
||||||
|
_tempfile=$(mktemp --tmpdir dracut-zdev.XXXXXX)
|
||||||
|
-
|
||||||
|
- if chzdev --export - --persistent --by-path / >/dev/null 2>&1 ; then
|
||||||
|
- # Use persistent configuration
|
||||||
|
- chzdev --export "$_tempfile" --persistent --by-path / --quiet --type
|
||||||
|
- else
|
||||||
|
- # Use active configuration
|
||||||
|
- chzdev --export "$_tempfile" --active --by-path / --quiet --type
|
||||||
|
- sed -i -e 's/active/persistent/g' "$_tempfile"
|
||||||
|
- fi
|
||||||
|
+ chzdev --export "$_tempfile" --persistent --by-path / --quiet \
|
||||||
|
+ --type 2>/dev/null
|
||||||
|
+ chzdev --export - --persistent --by-attrib "zdev:early=1" --quiet \
|
||||||
|
+ --type 2>/dev/null >> "$_tempfile"
|
||||||
|
|
||||||
|
# Apply via --import to prevent other devices from being configured
|
||||||
|
chzdev --import "$_tempfile" --persistent --base "/etc=$initdir/etc" \
|
||||||
|
--- a/zdev/include/internal.h
|
||||||
|
+++ b/zdev/include/internal.h
|
||||||
|
@@ -12,7 +12,12 @@
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
+#include "attrib.h"
|
||||||
|
+
|
||||||
|
#define INTERNAL_ATTR_PREFIX "zdev:"
|
||||||
|
+#define INTERNAL_ATTR_EARLY INTERNAL_ATTR_PREFIX "early"
|
||||||
|
+
|
||||||
|
+extern struct attrib internal_attr_early;
|
||||||
|
|
||||||
|
const char *internal_get_name(const char *name);
|
||||||
|
bool internal_by_name(const char *name);
|
||||||
|
--- a/zdev/initramfs/hooks/zdev
|
||||||
|
+++ b/zdev/initramfs/hooks/zdev
|
||||||
|
@@ -10,7 +10,8 @@
|
||||||
|
# configuration data during boot.
|
||||||
|
#
|
||||||
|
|
||||||
|
-PREREQ=""
|
||||||
|
+# Needs to run after udev or resulting udev rules could be overwritten
|
||||||
|
+PREREQ="udev"
|
||||||
|
|
||||||
|
prereqs()
|
||||||
|
{
|
||||||
|
@@ -37,3 +38,19 @@ done
|
||||||
|
copy_exec /sbin/chzdev
|
||||||
|
copy_exec /sbin/lszdev
|
||||||
|
copy_exec /sbin/vmcp
|
||||||
|
+
|
||||||
|
+_tempfile=$(mktemp --tmpdir initramfs-zdev.XXXXXX)
|
||||||
|
+
|
||||||
|
+# Obtain early + root device configuration
|
||||||
|
+chzdev --export "$_tempfile" --persistent --by-path / \
|
||||||
|
+ --by-attrib "zdev:early=1" --quiet --type 2>/dev/null
|
||||||
|
+
|
||||||
|
+# Apply via --import to prevent other devices from being configured.
|
||||||
|
+# Rename the resulting cio-ignore rule to ensure that it does not override
|
||||||
|
+# the one copied by the initramfs udev hook to /lib/udev.
|
||||||
|
+chzdev --import "$_tempfile" --persistent \
|
||||||
|
+ --base "/etc/udev/rules.d/41-cio-ignore.rules=$DESTDIR/etc/udev/rules.d/41-cio-ignore-root.rules" \
|
||||||
|
+ --base "/etc=$DESTDIR/etc" --yes --quiet --no-root-update --force \
|
||||||
|
+ >/dev/null
|
||||||
|
+
|
||||||
|
+rm -f "$_tempfile"
|
||||||
|
--- a/zdev/man/chzdev.8
|
||||||
|
+++ b/zdev/man/chzdev.8
|
||||||
|
@@ -334,6 +334,35 @@ a specific attribute.
|
||||||
|
.PP
|
||||||
|
.
|
||||||
|
.
|
||||||
|
+.SS "Special settings"
|
||||||
|
+The following special settings affect how devices are handled by chzdev:
|
||||||
|
+.PP
|
||||||
|
+.
|
||||||
|
+.BR zdev:early =0|1
|
||||||
|
+.RS 4
|
||||||
|
+Control in which stage of the boot process a device is activated:
|
||||||
|
+.TP 4
|
||||||
|
+.B 0
|
||||||
|
+Device is activated normally during boot (default).
|
||||||
|
+.PP
|
||||||
|
+.TP 4
|
||||||
|
+.B 1
|
||||||
|
+Device is activated early in the boot process, by the initial RAM-disk.
|
||||||
|
+.PP
|
||||||
|
+Specify a value of 1 for this attribute in any of the following situations:
|
||||||
|
+.TP 4
|
||||||
|
+\(bu
|
||||||
|
+To ensure that your settings override auto-configuration settings.
|
||||||
|
+.PP
|
||||||
|
+.TP 4
|
||||||
|
+\(bu
|
||||||
|
+To ensure that a device required to access the root file system is correctly
|
||||||
|
+enabled during boot. An example would be a networking device, or a device that
|
||||||
|
+is intended to extend a logical volume that provides the root file system.
|
||||||
|
+.PP
|
||||||
|
+.RE
|
||||||
|
+.
|
||||||
|
+.
|
||||||
|
.SH ACTIONS
|
||||||
|
You can use one of the action options listed below to specify the
|
||||||
|
.B main tool action
|
||||||
|
--- a/zdev/src/chzdev.c
|
||||||
|
+++ b/zdev/src/chzdev.c
|
||||||
|
@@ -3025,8 +3025,8 @@ int main(int argc, char *argv[])
|
||||||
|
|
||||||
|
if ((pers_mod_devs || pers_mod_devtypes) && !opts.no_root_check &&
|
||||||
|
!dryrun) {
|
||||||
|
- /* If the root device/device type has been modified, additional
|
||||||
|
- * work might be necessary. */
|
||||||
|
+ /* If the root device/device type or early devices have been
|
||||||
|
+ * modified, additional work might be necessary. */
|
||||||
|
rc = root_check();
|
||||||
|
if (rc && !drc)
|
||||||
|
drc = rc;
|
||||||
|
--- a/zdev/src/ctc.c
|
||||||
|
+++ b/zdev/src/ctc.c
|
||||||
|
@@ -17,6 +17,7 @@
|
||||||
|
#include "ctc_auto.h"
|
||||||
|
#include "device.h"
|
||||||
|
#include "devtype.h"
|
||||||
|
+#include "internal.h"
|
||||||
|
#include "misc.h"
|
||||||
|
#include "namespace.h"
|
||||||
|
#include "path.h"
|
||||||
|
@@ -425,6 +426,7 @@ static struct subtype ctc_subtype = {
|
||||||
|
&ccw_attr_online,
|
||||||
|
&ctc_attr_buffer,
|
||||||
|
&ctc_attr_protocol,
|
||||||
|
+ &internal_attr_early,
|
||||||
|
),
|
||||||
|
.unknown_dev_attribs = 1,
|
||||||
|
.support_definable = 1,
|
||||||
|
--- a/zdev/src/dasd.c
|
||||||
|
+++ b/zdev/src/dasd.c
|
||||||
|
@@ -16,6 +16,7 @@
|
||||||
|
#include "dasd.h"
|
||||||
|
#include "device.h"
|
||||||
|
#include "devtype.h"
|
||||||
|
+#include "internal.h"
|
||||||
|
#include "misc.h"
|
||||||
|
#include "modprobe.h"
|
||||||
|
#include "module.h"
|
||||||
|
@@ -616,6 +617,7 @@ struct subtype dasd_subtype_eckd = {
|
||||||
|
&dasd_attr_reservation_policy,
|
||||||
|
&dasd_attr_last_known_reservation_state,
|
||||||
|
&dasd_attr_safe_offline,
|
||||||
|
+ &internal_attr_early,
|
||||||
|
),
|
||||||
|
.unknown_dev_attribs = 1,
|
||||||
|
|
||||||
|
@@ -651,6 +653,7 @@ struct subtype dasd_subtype_fba = {
|
||||||
|
&dasd_attr_reservation_policy,
|
||||||
|
&dasd_attr_last_known_reservation_state,
|
||||||
|
&dasd_attr_safe_offline,
|
||||||
|
+ &internal_attr_early,
|
||||||
|
),
|
||||||
|
.unknown_dev_attribs = 1,
|
||||||
|
|
||||||
|
--- a/zdev/src/generic_ccw.c
|
||||||
|
+++ b/zdev/src/generic_ccw.c
|
||||||
|
@@ -17,6 +17,7 @@
|
||||||
|
#include "devnode.h"
|
||||||
|
#include "devtype.h"
|
||||||
|
#include "generic_ccw.h"
|
||||||
|
+#include "internal.h"
|
||||||
|
#include "namespace.h"
|
||||||
|
#include "path.h"
|
||||||
|
#include "subtype.h"
|
||||||
|
@@ -182,6 +183,7 @@ static struct subtype generic_ccw_subtyp
|
||||||
|
.dev_attribs = ATTRIB_ARRAY(
|
||||||
|
&ccw_attr_online,
|
||||||
|
&ccw_attr_cmb_enable,
|
||||||
|
+ &internal_attr_early,
|
||||||
|
),
|
||||||
|
.unknown_dev_attribs = 1,
|
||||||
|
.generic = 1,
|
||||||
|
--- a/zdev/src/internal.c
|
||||||
|
+++ b/zdev/src/internal.c
|
||||||
|
@@ -9,9 +9,22 @@
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
+#include "attrib.h"
|
||||||
|
#include "internal.h"
|
||||||
|
#include "misc.h"
|
||||||
|
|
||||||
|
+struct attrib internal_attr_early = {
|
||||||
|
+ .name = INTERNAL_ATTR_EARLY,
|
||||||
|
+ .title = "Activate device early during boot",
|
||||||
|
+ .desc = "Control the time of activation of a device:\n"
|
||||||
|
+ " 0: Device is activated normally during boot\n"
|
||||||
|
+ " 1: Device is activated early in the boot process, by the\n"
|
||||||
|
+ " initial RAM-disk\n",
|
||||||
|
+ .defval = "0",
|
||||||
|
+ .accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
||||||
|
+ .internal = 1,
|
||||||
|
+};
|
||||||
|
+
|
||||||
|
/* Return identifier of internal attribute with specified @name. */
|
||||||
|
const char *internal_get_name(const char *name)
|
||||||
|
{
|
||||||
|
--- a/zdev/src/lcs.c
|
||||||
|
+++ b/zdev/src/lcs.c
|
||||||
|
@@ -15,6 +15,7 @@
|
||||||
|
#include "ccwgroup.h"
|
||||||
|
#include "device.h"
|
||||||
|
#include "devtype.h"
|
||||||
|
+#include "internal.h"
|
||||||
|
#include "lcs.h"
|
||||||
|
#include "lcs_auto.h"
|
||||||
|
#include "misc.h"
|
||||||
|
@@ -362,6 +363,7 @@ static struct subtype lcs_subtype = {
|
||||||
|
&ccw_attr_online,
|
||||||
|
&lcs_attr_lancmd_timeout,
|
||||||
|
&lcs_attr_recover,
|
||||||
|
+ &internal_attr_early,
|
||||||
|
),
|
||||||
|
.unknown_dev_attribs = 1,
|
||||||
|
.support_definable = 1,
|
||||||
|
--- a/zdev/src/qeth.c
|
||||||
|
+++ b/zdev/src/qeth.c
|
||||||
|
@@ -15,6 +15,7 @@
|
||||||
|
#include "ccwgroup.h"
|
||||||
|
#include "device.h"
|
||||||
|
#include "devtype.h"
|
||||||
|
+#include "internal.h"
|
||||||
|
#include "misc.h"
|
||||||
|
#include "namespace.h"
|
||||||
|
#include "nic.h"
|
||||||
|
@@ -1445,6 +1446,7 @@ struct subtype qeth_subtype_qeth = {
|
||||||
|
&qeth_attr_vnicc_takeover_learning,
|
||||||
|
&qeth_attr_vnicc_bridge_invisible,
|
||||||
|
&qeth_attr_vnicc_rx_bcast,
|
||||||
|
+ &internal_attr_early,
|
||||||
|
),
|
||||||
|
.unknown_dev_attribs = 1,
|
||||||
|
.support_definable = 1,
|
||||||
|
--- a/zdev/src/root.c
|
||||||
|
+++ b/zdev/src/root.c
|
||||||
|
@@ -8,11 +8,13 @@
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdlib.h>
|
||||||
|
+#include <string.h>
|
||||||
|
|
||||||
|
#include "lib/util_path.h"
|
||||||
|
|
||||||
|
#include "device.h"
|
||||||
|
#include "devtype.h"
|
||||||
|
+#include "internal.h"
|
||||||
|
#include "misc.h"
|
||||||
|
#include "path.h"
|
||||||
|
#include "root.h"
|
||||||
|
@@ -20,31 +22,78 @@
|
||||||
|
#include "setting.h"
|
||||||
|
#include "subtype.h"
|
||||||
|
|
||||||
|
-/* Determine if the root device was modified. If it was modified, run the
|
||||||
|
- * corresponding root-install scripts. */
|
||||||
|
+static bool is_early_removed(struct device *dev)
|
||||||
|
+{
|
||||||
|
+ struct setting *s;
|
||||||
|
+
|
||||||
|
+ s = setting_list_find(dev->persistent.settings,
|
||||||
|
+ internal_attr_early.name);
|
||||||
|
+ if (!s || !s->modified)
|
||||||
|
+ return false;
|
||||||
|
+ if (!s->actual_value || strcmp(s->actual_value, "1") != 0)
|
||||||
|
+ return false;
|
||||||
|
+ if (s->removed || strcmp(s->value, "0") == 0)
|
||||||
|
+ return true;
|
||||||
|
+ return false;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+static void add_early_removed(struct util_list *selected)
|
||||||
|
+{
|
||||||
|
+ int i, j;
|
||||||
|
+ struct devtype *dt;
|
||||||
|
+ struct subtype *st;
|
||||||
|
+ struct device *dev;
|
||||||
|
+
|
||||||
|
+ for (i = 0; devtypes[i]; i++) {
|
||||||
|
+ dt = devtypes[i];
|
||||||
|
+ for (j = 0; dt->subtypes[j]; j++) {
|
||||||
|
+ st = dt->subtypes[j];
|
||||||
|
+ util_list_iterate(&st->devices->hash.list, dev) {
|
||||||
|
+ if (is_early_removed(dev)) {
|
||||||
|
+ selected_dev_list_add(selected, dt, st,
|
||||||
|
+ dev->id, NULL, EXIT_OK);
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
+/* Determine if initial RAM-disk needs updating. If so, run the corresponding
|
||||||
|
+ * scripts if available. */
|
||||||
|
exit_code_t root_check(void)
|
||||||
|
{
|
||||||
|
struct util_list *selected, *params, *mod = NULL;
|
||||||
|
struct selected_dev_node *sel;
|
||||||
|
struct device *dev;
|
||||||
|
char *params_str;
|
||||||
|
- exit_code_t rc;
|
||||||
|
+ exit_code_t rc = EXIT_OK;
|
||||||
|
struct strlist_node *s;
|
||||||
|
struct devtype *dt;
|
||||||
|
+ struct select_opts *select;
|
||||||
|
|
||||||
|
- debug("Checking for modified root device configuration\n");
|
||||||
|
+ debug("Checking for required initial RAM-disk update\n");
|
||||||
|
|
||||||
|
- /* Get list of devices that provide the root device. */
|
||||||
|
+ /* Get list of devices that provide the root device or require
|
||||||
|
+ * early configuration. */
|
||||||
|
selected = selected_dev_list_new();
|
||||||
|
- rc = select_by_path(NULL, selected, config_active, scope_mandatory,
|
||||||
|
- NULL, NULL, PATH_ROOT, err_ignore);
|
||||||
|
- if (rc) {
|
||||||
|
+ /* First add devices that had zdev:early removed or changed to 0.
|
||||||
|
+ * The subsequent call to select_devices() will filter out any
|
||||||
|
+ * duplicates. */
|
||||||
|
+ add_early_removed(selected);
|
||||||
|
+ /* Now add devices required for root file system. */
|
||||||
|
+ if (select_by_path(NULL, selected, config_active, scope_mandatory,
|
||||||
|
+ NULL, NULL, PATH_ROOT, err_ignore)) {
|
||||||
|
/* Running from an unknown root device is not an error. */
|
||||||
|
verb("Note: Could not determine if root device configuration "
|
||||||
|
"needs to be updated\n");
|
||||||
|
- rc = 0;
|
||||||
|
- goto out;
|
||||||
|
}
|
||||||
|
+ /* Finally add devices with zdev:early=1. */
|
||||||
|
+ select = select_opts_new();
|
||||||
|
+ strlist_add(&select->by_attr, "%s=1", INTERNAL_ATTR_EARLY);
|
||||||
|
+ select_devices(select, selected, 1, 0, 0,
|
||||||
|
+ config_active | config_persistent, scope_mandatory,
|
||||||
|
+ err_ignore);
|
||||||
|
+ select_opts_free(select);
|
||||||
|
|
||||||
|
/* Determine if any of the devices or device types has been modified. */
|
||||||
|
mod = strlist_new();
|
||||||
|
@@ -68,19 +117,18 @@ exit_code_t root_check(void)
|
||||||
|
|
||||||
|
if (util_list_is_empty(mod))
|
||||||
|
goto out;
|
||||||
|
- info("Note: Some of the changes affect devices providing the root "
|
||||||
|
- "file system:\n");
|
||||||
|
+ info("Note: The initial RAM-disk must be updated for these changes to take effect:\n");
|
||||||
|
util_list_iterate(mod, s)
|
||||||
|
info(" - %s\n", s->str);
|
||||||
|
- info(" Additional steps such as rebuilding the RAM-disk might be "
|
||||||
|
- "required.\n");
|
||||||
|
|
||||||
|
/* Check if script is available. */
|
||||||
|
- if (!util_path_is_reg_file(PATH_ROOT_SCRIPT))
|
||||||
|
+ if (!util_path_is_reg_file(PATH_ROOT_SCRIPT)) {
|
||||||
|
+ warn("A manual update of the initial RAM-disk is required.\n");
|
||||||
|
goto out;
|
||||||
|
+ }
|
||||||
|
|
||||||
|
/* Ask for confirmation. */
|
||||||
|
- if (!confirm("Update persistent root device configuration now?")) {
|
||||||
|
+ if (!confirm("Update initial RAM-disk now?")) {
|
||||||
|
rc = EXIT_ABORTED;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
@@ -97,7 +145,7 @@ exit_code_t root_check(void)
|
||||||
|
/* Run update command. */
|
||||||
|
if (misc_system(err_delayed_print, "%s %s", PATH_ROOT_SCRIPT,
|
||||||
|
params_str) != 0) {
|
||||||
|
- error("Failure while updating root device configuration\n");
|
||||||
|
+ error("Failure while updating initial RAM-disk\n");
|
||||||
|
delayed_print(DELAY_INDENT);
|
||||||
|
rc = EXIT_RUNTIME_ERROR;
|
||||||
|
}
|
||||||
|
--- a/zdev/src/zfcp_host.c
|
||||||
|
+++ b/zdev/src/zfcp_host.c
|
||||||
|
@@ -17,6 +17,7 @@
|
||||||
|
#include "ccw.h"
|
||||||
|
#include "device.h"
|
||||||
|
#include "devtype.h"
|
||||||
|
+#include "internal.h"
|
||||||
|
#include "misc.h"
|
||||||
|
#include "path.h"
|
||||||
|
#include "setting.h"
|
||||||
|
@@ -247,6 +248,7 @@ struct subtype zfcp_host_subtype = {
|
||||||
|
&zfcp_host_attr_failed,
|
||||||
|
&zfcp_host_attr_port_remove,
|
||||||
|
&zfcp_host_attr_port_rescan,
|
||||||
|
+ &internal_attr_early,
|
||||||
|
),
|
||||||
|
.unknown_dev_attribs = 1,
|
||||||
|
|
||||||
|
--- a/zdev/src/zfcp_lun.c
|
||||||
|
+++ b/zdev/src/zfcp_lun.c
|
||||||
|
@@ -21,6 +21,7 @@
|
||||||
|
#include "devnode.h"
|
||||||
|
#include "devtype.h"
|
||||||
|
#include "misc.h"
|
||||||
|
+#include "internal.h"
|
||||||
|
#include "namespace.h"
|
||||||
|
#include "path.h"
|
||||||
|
#include "scsi.h"
|
||||||
|
@@ -1097,6 +1098,7 @@ struct subtype zfcp_lun_subtype = {
|
||||||
|
&zfcp_lun_attr_scsi_timeout,
|
||||||
|
&zfcp_lun_attr_scsi_state,
|
||||||
|
&zfcp_lun_attr_scsi_delete,
|
||||||
|
+ &internal_attr_early,
|
||||||
|
),
|
||||||
|
.prefixes = STRING_ARRAY(SCSI_ATTR_PREFIX),
|
||||||
|
.unknown_dev_attribs = 1,
|
@ -0,0 +1,50 @@
|
|||||||
|
Subject: zdev: Add support for handling I/O configuration data
|
||||||
|
From: Peter Oberparleiter <oberpar@linux.ibm.com>
|
||||||
|
|
||||||
|
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: -
|
||||||
|
Problem-ID: LS1604
|
||||||
|
|
||||||
|
Signed-off-by: Peter Oberparleiter <oberpar@linux.ibm.com>
|
||||||
|
---
|
||||||
|
zdev/src/zdev-root-update.dracut | 6 ------
|
||||||
|
1 file changed, 6 deletions(-)
|
||||||
|
|
||||||
|
--- a/zdev/src/zdev-root-update.dracut
|
||||||
|
+++ b/zdev/src/zdev-root-update.dracut
|
||||||
|
@@ -20,10 +20,4 @@ dracut -f || {
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
-echo "Installing IPL record"
|
||||||
|
-zipl --noninteractive || {
|
||||||
|
- echo "${TOOLNAME}: Error: Could not install IPL record" >&2
|
||||||
|
- exit 1
|
||||||
|
-}
|
||||||
|
-
|
||||||
|
exit 0
|
@ -21,7 +21,7 @@ Signed-off-by: Hans Wippel <hwippel@linux.ibm.com>
|
|||||||
|
|
||||||
--- a/zdev/src/qeth.c
|
--- a/zdev/src/qeth.c
|
||||||
+++ b/zdev/src/qeth.c
|
+++ b/zdev/src/qeth.c
|
||||||
@@ -1170,6 +1170,37 @@ static exit_code_t check_ineffective_set
|
@@ -1171,6 +1171,37 @@ static exit_code_t check_ineffective_set
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,7 +59,7 @@ Signed-off-by: Hans Wippel <hwippel@linux.ibm.com>
|
|||||||
/* Check if there are conflicting attribute settings */
|
/* Check if there are conflicting attribute settings */
|
||||||
static exit_code_t check_conflicting_settings(struct setting_list *list)
|
static exit_code_t check_conflicting_settings(struct setting_list *list)
|
||||||
{
|
{
|
||||||
@@ -1181,6 +1212,8 @@ static exit_code_t check_conflicting_set
|
@@ -1182,6 +1213,8 @@ static exit_code_t check_conflicting_set
|
||||||
util_list_iterate(&list->list, s) {
|
util_list_iterate(&list->list, s) {
|
||||||
if (s->removed)
|
if (s->removed)
|
||||||
continue;
|
continue;
|
@ -1,3 +1,24 @@
|
|||||||
|
-------------------------------------------------------------------
|
||||||
|
Thu Dec 6 21:03:08 UTC 2018 - mpost@suse.com
|
||||||
|
|
||||||
|
- Added the following patches for Fate#326825 (bsc#1113329)
|
||||||
|
I/O device pre-configuration
|
||||||
|
* s390-tools-sles15sp1-01-zdev-use-libutil-provided-path-functions.patch
|
||||||
|
* s390-tools-sles15sp1-02-zdev-Prepare-for-firmware-configuration-file-support.patch
|
||||||
|
* s390-tools-sles15sp1-03-zdev-Add-support-for-reading-firmware-configuration-.patch
|
||||||
|
* s390-tools-sles15sp1-04-zdev-Implement-no-settle.patch
|
||||||
|
* s390-tools-sles15sp1-05-zdev-Write-zfcp-lun-udev-rules-to-separate-files.patch
|
||||||
|
* s390-tools-sles15sp1-06-zdev-Add-support-for-handling-auto-configuration-dat.patch
|
||||||
|
* s390-tools-sles15sp1-07-zdev-Integrate-firmware-auto-configuration-with-drac.patch
|
||||||
|
* s390-tools-sles15sp1-08-zdev-Integrate-firmware-auto-configuration-with-init.patch
|
||||||
|
* s390-tools-sles15sp1-09-zdev-Implement-internal-device-attributes.patch
|
||||||
|
* s390-tools-sles15sp1-10-zdev-Implement-support-for-early-device-configuratio.patch
|
||||||
|
* s390-tools-sles15sp1-11-zdev-Do-not-call-zipl-on-initrd-update.patch
|
||||||
|
- Removed the obsolete customize-zdev-root-update-script.patch
|
||||||
|
- Replaced s390-tools-sles15-zdev-fix-qeth-BridgePort-and-VNICC-conflict-checking.patch
|
||||||
|
with s390-tools-sles15sp1-zdev-fix-qeth-BridgePort-and-VNICC-conflict-checking.patch
|
||||||
|
to fit the current version.
|
||||||
|
|
||||||
-------------------------------------------------------------------
|
-------------------------------------------------------------------
|
||||||
Thu Nov 29 00:03:01 UTC 2018 - mpost@suse.com
|
Thu Nov 29 00:03:01 UTC 2018 - mpost@suse.com
|
||||||
|
|
||||||
|
112
s390-tools.spec
112
s390-tools.spec
@ -152,51 +152,60 @@ Patch40: s390-tools-sles15-5-lstape-fix-to-prevent-error-messages-if-ther
|
|||||||
Patch41: s390-tools-sles15-6-lstape-fix-description-of-type-and-devbusid-filter-f.patch
|
Patch41: s390-tools-sles15-6-lstape-fix-description-of-type-and-devbusid-filter-f.patch
|
||||||
Patch42: s390-tools-sles15-7-lstape-fix-SCSI-output-description-in-man-page.patch
|
Patch42: s390-tools-sles15-7-lstape-fix-SCSI-output-description-in-man-page.patch
|
||||||
Patch43: s390-tools-sles15-8-lstape-fix-SCSI-HBA-CCW-device-bus-ID-e.g.-for-virti.patch
|
Patch43: s390-tools-sles15-8-lstape-fix-SCSI-HBA-CCW-device-bus-ID-e.g.-for-virti.patch
|
||||||
Patch44: s390-tools-sles15-zdev-fix-qeth-BridgePort-and-VNICC-conflict-checking.patch
|
Patch44: s390-tools-sles15sp1-0001-zkey-Add-properties-file-handling-routines.patch
|
||||||
Patch45: s390-tools-sles15sp1-0001-zkey-Add-properties-file-handling-routines.patch
|
Patch45: s390-tools-sles15sp1-0002-zkey-Add-build-dependency-to-OpenSSL-libcrypto.patch
|
||||||
Patch46: s390-tools-sles15sp1-0002-zkey-Add-build-dependency-to-OpenSSL-libcrypto.patch
|
Patch46: s390-tools-sles15sp1-0003-zkey-Add-helper-functions-for-comma-separated-string.patch
|
||||||
Patch47: s390-tools-sles15sp1-0003-zkey-Add-helper-functions-for-comma-separated-string.patch
|
Patch47: s390-tools-sles15sp1-0004-zkey-Externalize-secure-key-back-end-functions.patch
|
||||||
Patch48: s390-tools-sles15sp1-0004-zkey-Externalize-secure-key-back-end-functions.patch
|
Patch48: s390-tools-sles15sp1-0005-zkey-Add-keystore-implementation.patch
|
||||||
Patch49: s390-tools-sles15sp1-0005-zkey-Add-keystore-implementation.patch
|
Patch49: s390-tools-sles15sp1-0006-zkey-Add-keystore-related-commands.patch
|
||||||
Patch50: s390-tools-sles15sp1-0006-zkey-Add-keystore-related-commands.patch
|
Patch50: s390-tools-sles15sp1-0007-zkey-Create-key-repository-and-group-during-make-ins.patch
|
||||||
Patch51: s390-tools-sles15sp1-0007-zkey-Create-key-repository-and-group-during-make-ins.patch
|
Patch51: s390-tools-sles15sp1-0008-zkey-Man-page-updates.patch
|
||||||
Patch52: s390-tools-sles15sp1-0008-zkey-Man-page-updates.patch
|
Patch52: s390-tools-sles15sp1-0009-zkey-let-packaging-create-the-zkeyadm-group-and-perm.patch
|
||||||
Patch53: s390-tools-sles15sp1-0009-zkey-let-packaging-create-the-zkeyadm-group-and-perm.patch
|
Patch53: s390-tools-sles15sp1-0010-zkey-Update-README-to-add-info-about-packaging-requi.patch
|
||||||
Patch54: s390-tools-sles15sp1-0010-zkey-Update-README-to-add-info-about-packaging-requi.patch
|
Patch54: s390-tools-sles15sp1-0011-zkey-Typo-in-message.patch
|
||||||
Patch55: s390-tools-sles15sp1-0011-zkey-Typo-in-message.patch
|
Patch55: s390-tools-sles15sp1-0012-zkey-Fix-memory-leak.patch
|
||||||
Patch56: s390-tools-sles15sp1-0012-zkey-Fix-memory-leak.patch
|
Patch56: s390-tools-sles15sp1-0013-zkey-Fix-APQN-validation-routine.patch
|
||||||
Patch57: s390-tools-sles15sp1-0013-zkey-Fix-APQN-validation-routine.patch
|
Patch57: s390-tools-sles15sp1-0014-zkey-Fix-generate-and-import-leaving-key-in-an-incon.patch
|
||||||
Patch58: s390-tools-sles15sp1-0014-zkey-Fix-generate-and-import-leaving-key-in-an-incon.patch
|
Patch58: s390-tools-sles15sp1-0015-zkey-Add-zkey-cryptsetup-tool.patch
|
||||||
Patch59: s390-tools-sles15sp1-0015-zkey-Add-zkey-cryptsetup-tool.patch
|
Patch59: s390-tools-sles15sp1-0016-zkey-Add-man-page-for-zkey-cryptsetup.patch
|
||||||
Patch60: s390-tools-sles15sp1-0016-zkey-Add-man-page-for-zkey-cryptsetup.patch
|
Patch60: s390-tools-sles15sp1-0017-zkey-Add-build-dependency-for-libcryptsetup-and-json.patch
|
||||||
Patch61: s390-tools-sles15sp1-0017-zkey-Add-build-dependency-for-libcryptsetup-and-json.patch
|
Patch61: s390-tools-sles15sp1-0018-zkey-Add-key-verification-pattern-property.patch
|
||||||
Patch62: s390-tools-sles15sp1-0018-zkey-Add-key-verification-pattern-property.patch
|
Patch62: s390-tools-sles15sp1-0019-zkey-Add-volume-type-property-to-support-LUKS2-volum.patch
|
||||||
Patch63: s390-tools-sles15sp1-0019-zkey-Add-volume-type-property-to-support-LUKS2-volum.patch
|
Patch63: s390-tools-sles15sp1-01-lszcrypt-CEX6S-exploitation.patch
|
||||||
Patch64: s390-tools-sles15sp1-01-lszcrypt-CEX6S-exploitation.patch
|
Patch64: s390-tools-sles15sp1-02-lszcrypt-fix-date-and-wrong-indentation.patch
|
||||||
Patch65: s390-tools-sles15sp1-02-lszcrypt-fix-date-and-wrong-indentation.patch
|
Patch65: s390-tools-sles15sp1-01-chzcrypt-Corrections-at-the-chzcrypt-man-page.patch
|
||||||
Patch66: s390-tools-sles15sp1-01-chzcrypt-Corrections-at-the-chzcrypt-man-page.patch
|
Patch66: s390-tools-sles15sp1-02-lszcrypt-support-for-alternate-zcrypt-device-drivers.patch
|
||||||
Patch67: s390-tools-sles15sp1-02-lszcrypt-support-for-alternate-zcrypt-device-drivers.patch
|
Patch67: s390-tools-sles15sp1-01-zcryptctl-new-tool-zcryptctl-for-multiple-zcrypt-node.patch
|
||||||
Patch68: s390-tools-sles15sp1-01-zcryptctl-new-tool-zcryptctl-for-multiple-zcrypt-node.patch
|
Patch68: s390-tools-sles15sp1-01-cpumf-Add-extended-counter-defintion-files-for-IBM-z.patch
|
||||||
Patch69: s390-tools-sles15sp1-01-cpumf-Add-extended-counter-defintion-files-for-IBM-z.patch
|
Patch69: s390-tools-sles15sp1-02-cpumf-z14-split-counter-sets-according-to-CFVN-CSVN-.patch
|
||||||
Patch70: s390-tools-sles15sp1-02-cpumf-z14-split-counter-sets-according-to-CFVN-CSVN-.patch
|
Patch70: s390-tools-sles15sp1-03-cpumf-cpumf_helper-read-split-counter-sets-part-2-2.patch
|
||||||
Patch71: s390-tools-sles15sp1-03-cpumf-cpumf_helper-read-split-counter-sets-part-2-2.patch
|
Patch71: s390-tools-sles15sp1-04-cpumf-correct-z14-counter-number.patch
|
||||||
Patch72: s390-tools-sles15sp1-04-cpumf-correct-z14-counter-number.patch
|
Patch72: s390-tools-sles15sp1-05-cpumf-add-missing-Description-tag-for-z13-z14-ctr-12.patch
|
||||||
Patch73: s390-tools-sles15sp1-05-cpumf-add-missing-Description-tag-for-z13-z14-ctr-12.patch
|
Patch73: s390-tools-sles15sp1-06-cpumf-correct-counter-name-for-z13-and-z14.patch
|
||||||
Patch74: s390-tools-sles15sp1-06-cpumf-correct-counter-name-for-z13-and-z14.patch
|
Patch74: s390-tools-sles15sp1-07-cpumf-Add-IBM-z14-ZR1-to-the-CPU-Measurement-Facilit.patch
|
||||||
Patch75: s390-tools-sles15sp1-07-cpumf-Add-IBM-z14-ZR1-to-the-CPU-Measurement-Facilit.patch
|
Patch75: s390-tools-sles15sp1-01-util_path-add-function-to-check-if-a-path-exists.patch
|
||||||
Patch76: s390-tools-sles15sp1-01-util_path-add-function-to-check-if-a-path-exists.patch
|
Patch76: s390-tools-sles15sp1-02-util_path-Add-description-for-util_path_exists.patch
|
||||||
Patch77: s390-tools-sles15sp1-02-util_path-Add-description-for-util_path_exists.patch
|
Patch77: s390-tools-sles15sp1-03-util_path-Make-true-false-handling-consistent-with-o.patch
|
||||||
Patch78: s390-tools-sles15sp1-03-util_path-Make-true-false-handling-consistent-with-o.patch
|
Patch78: s390-tools-sles15sp1-04-zpcictl-Introduce-new-tool-zpcictl.patch
|
||||||
Patch79: s390-tools-sles15sp1-04-zpcictl-Introduce-new-tool-zpcictl.patch
|
Patch79: s390-tools-sles15sp1-05-zpcictl-include-sys-sysmacros.h-to-avoid-minor-major.patch
|
||||||
Patch80: s390-tools-sles15sp1-05-zpcictl-include-sys-sysmacros.h-to-avoid-minor-major.patch
|
Patch80: s390-tools-sles15sp1-06-zpcictl-Rephrase-man-page-entries-and-tool-output.patch
|
||||||
Patch81: s390-tools-sles15sp1-06-zpcictl-Rephrase-man-page-entries-and-tool-output.patch
|
Patch81: s390-tools-sles15sp1-07-zpcictl-Use-fopen-instead-of-open-for-writes.patch
|
||||||
Patch82: s390-tools-sles15sp1-07-zpcictl-Use-fopen-instead-of-open-for-writes.patch
|
Patch82: s390-tools-sles15sp1-08-zpcictl-Read-device-link-to-obtain-device-address.patch
|
||||||
Patch83: s390-tools-sles15sp1-08-zpcictl-Read-device-link-to-obtain-device-address.patch
|
Patch83: s390-tools-sles15sp1-09-zpcictl-Make-device-node-for-NVMe-optional.patch
|
||||||
Patch84: s390-tools-sles15sp1-09-zpcictl-Make-device-node-for-NVMe-optional.patch
|
Patch84: s390-tools-sles15sp1-10-zpcictl-Change-wording-of-man-page-and-help-output.patch
|
||||||
Patch85: s390-tools-sles15sp1-10-zpcictl-Change-wording-of-man-page-and-help-output.patch
|
Patch85: s390-tools-sles15sp1-dbginfo-gather-nvme-related-data.patch
|
||||||
Patch86: s390-tools-sles15sp1-dbginfo-gather-nvme-related-data.patch
|
Patch86: s390-tools-sles15sp1-01-zdev-use-libutil-provided-path-functions.patch
|
||||||
|
Patch87: s390-tools-sles15sp1-02-zdev-Prepare-for-firmware-configuration-file-support.patch
|
||||||
Patch999: customize-zdev-root-update-script.patch
|
Patch88: s390-tools-sles15sp1-03-zdev-Add-support-for-reading-firmware-configuration-.patch
|
||||||
|
Patch89: s390-tools-sles15sp1-04-zdev-Implement-no-settle.patch
|
||||||
|
Patch90: s390-tools-sles15sp1-05-zdev-Write-zfcp-lun-udev-rules-to-separate-files.patch
|
||||||
|
Patch91: s390-tools-sles15sp1-06-zdev-Add-support-for-handling-auto-configuration-dat.patch
|
||||||
|
Patch92: s390-tools-sles15sp1-07-zdev-Integrate-firmware-auto-configuration-with-drac.patch
|
||||||
|
Patch93: s390-tools-sles15sp1-08-zdev-Integrate-firmware-auto-configuration-with-init.patch
|
||||||
|
Patch94: s390-tools-sles15sp1-09-zdev-Implement-internal-device-attributes.patch
|
||||||
|
Patch95: s390-tools-sles15sp1-10-zdev-Implement-support-for-early-device-configuratio.patch
|
||||||
|
Patch96: s390-tools-sles15sp1-11-zdev-Do-not-call-zipl-on-initrd-update.patch
|
||||||
|
Patch97: s390-tools-sles15sp1-zdev-fix-qeth-BridgePort-and-VNICC-conflict-checking.patch
|
||||||
|
|
||||||
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||||
ExclusiveArch: s390x
|
ExclusiveArch: s390x
|
||||||
@ -339,8 +348,17 @@ to list files and directories.
|
|||||||
%patch84 -p1
|
%patch84 -p1
|
||||||
%patch85 -p1
|
%patch85 -p1
|
||||||
%patch86 -p1
|
%patch86 -p1
|
||||||
|
%patch87 -p1
|
||||||
%patch999 -p1
|
%patch88 -p1
|
||||||
|
%patch89 -p1
|
||||||
|
%patch90 -p1
|
||||||
|
%patch91 -p1
|
||||||
|
%patch92 -p1
|
||||||
|
%patch93 -p1
|
||||||
|
%patch94 -p1
|
||||||
|
%patch95 -p1
|
||||||
|
%patch96 -p1
|
||||||
|
%patch97 -p1
|
||||||
|
|
||||||
cp -vi %{S:22} CAUTION
|
cp -vi %{S:22} CAUTION
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user