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>
This commit is contained in:
Peter Oberparleiter
2017-09-01 11:05:59 +02:00
committed by Jan Höppner
parent c0392efa39
commit 156450f359
14 changed files with 152 additions and 36 deletions

View File

@@ -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;

View File

@@ -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,

View File

@@ -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,

View File

@@ -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_subtype = {
.dev_attribs = ATTRIB_ARRAY(
&ccw_attr_online,
&ccw_attr_cmb_enable,
&internal_attr_early,
),
.unknown_dev_attribs = 1,
.generic = 1,

View File

@@ -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)
{

View File

@@ -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,

View File

@@ -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,

View File

@@ -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;
}

View File

@@ -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,

View File

@@ -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,