diff --git a/README.md b/README.md index 5a2153c9..44a90d72 100644 --- a/README.md +++ b/README.md @@ -284,10 +284,11 @@ build options: This table lists additional build or install options: -| __COMPONENT__ | __OPTION__ | __TOOLS__ | -|----------------|:----------------:|:-------------------------------:| -| dracut | `HAVE_DRACUT` | zdev | -| initramfs-tools| `HAVE_INITRAMFS` | zdev | +| __COMPONENT__ | __OPTION__ | __TOOLS__ | +|------------------|:----------------------------:|:--------------:| +| dracut | `HAVE_DRACUT` | zdev | +| initramfs-tools | `HAVE_INITRAMFS` | zdev | +| | `ZDEV_ALWAYS_UPDATE_INITRD` | zdev | The s390-tools build process uses "pkg-config" if available and hard-coded compiler and linker options otherwise. @@ -378,6 +379,17 @@ the different tools are provided: Distributors with different boot or RAM-disk mechanisms should provide a custom zdev-root-update helper script. + - `ZDEV_ALWAYS_UPDATE_INITRD=1` upon modification of any persistent device + configuration, chzdev updates the initial RAM-disk by default, without any + additional user interaction. + + For some distributions, all the configuration attributes must be copied to + the initial RAM-disk. Because the device configuration directives applied + in the initial RAM-disk takes precedence over those stored in the root file- + system. This copying is done usually by explicitly invoking a command. This + build option makes it user-friendly and does this copying without any manual + intervention. + Some functions of zdev require that the following programs are available: - modprobe (kmod) diff --git a/zdev/include/root.h b/zdev/include/root.h index 6fd78e7e..d15d3934 100644 --- a/zdev/include/root.h +++ b/zdev/include/root.h @@ -12,6 +12,6 @@ #include "exit_code.h" -exit_code_t root_check(void); +exit_code_t initrd_check(bool all_pers); #endif /* ROOT_H */ diff --git a/zdev/src/Makefile b/zdev/src/Makefile index e9be1e2e..40a18792 100644 --- a/zdev/src/Makefile +++ b/zdev/src/Makefile @@ -4,6 +4,16 @@ include ../../common.mak ALL_CPPFLAGS += -I ../include -std=gnu99 -Wno-unused-parameter \ -Wno-missing-field-initializers +# Adding ZDEV_ALWAYS_UPDATE_INITRD=1 option will update the initial RAM-disk +# without the user interaction upon the modification of a persistent device +# configuration. + +ifeq ($(ZDEV_ALWAYS_UPDATE_INITRD),1) +ALL_CPPFLAGS += -DZDEV_ALWAYS_UPDATE_INITRD=true +else +ALL_CPPFLAGS += -DZDEV_ALWAYS_UPDATE_INITRD=false +endif + # Core 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 \ diff --git a/zdev/src/chzdev.c b/zdev/src/chzdev.c index 4e453335..76f7309d 100644 --- a/zdev/src/chzdev.c +++ b/zdev/src/chzdev.c @@ -3027,7 +3027,7 @@ int main(int argc, char *argv[]) !dryrun) { /* If the root device/device type or early devices have been * modified, additional work might be necessary. */ - rc = root_check(); + rc = initrd_check(ZDEV_ALWAYS_UPDATE_INITRD); if (rc && !drc) drc = rc; } diff --git a/zdev/src/root.c b/zdev/src/root.c index a6d9e0cc..385b7787 100644 --- a/zdev/src/root.c +++ b/zdev/src/root.c @@ -58,11 +58,50 @@ static void add_early_removed(struct util_list *selected) } } +static void add_pers_removed(struct util_list *strlist) +{ + 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 (dev->persistent.deconfigured) { + strlist_add(strlist, "%s %s", + dev->subtype->devname, dev->id); + } + } + } + } +} + +static bool is_zdev_early_0(struct selected_dev_node *sel) +{ + struct setting *s; + struct device *dev; + + dev = device_list_find(sel->st->devices, sel->id, NULL); + if (!dev) + return false; + s = setting_list_find(dev->persistent.settings, + internal_attr_early.name); + if (!s) + return false; + if (s->specified && strcmp(s->value, "0") == 0) + return true; + + return false; +} + /* Determine if initial RAM-disk needs updating. If so, run the corresponding * scripts if available. */ -exit_code_t root_check(void) +exit_code_t initrd_check(bool all_pers) { - struct util_list *selected, *params, *mod = NULL; + struct util_list *selected, *params, *mod = strlist_new(); struct selected_dev_node *sel; struct device *dev; char *params_str; @@ -76,6 +115,20 @@ exit_code_t root_check(void) /* Get list of devices that provide the root device or require * early configuration. */ selected = selected_dev_list_new(); + + if (all_pers) { + /* Add all persistently configured devices. */ + select = select_opts_new(); + select->configured = 1; + select_devices(select, selected, 1, 0, 0, config_persistent, + scope_mandatory, err_ignore); + select_opts_free(select); + + /* Ensure that removed devices are considered. */ + add_pers_removed(mod); + goto check_mod; + } + /* First add devices that had zdev:early removed or changed to 0. * The subsequent call to select_devices() will filter out any * duplicates. */ @@ -95,8 +148,8 @@ exit_code_t root_check(void) err_ignore); select_opts_free(select); +check_mod: /* Determine if any of the devices or device types has been modified. */ - mod = strlist_new(); util_list_iterate(selected, sel) { dt = sel->st->devtype; @@ -127,17 +180,22 @@ exit_code_t root_check(void) goto out; } - /* Ask for confirmation. */ - if (!confirm("Update initial RAM-disk now?")) { - rc = EXIT_ABORTED; - goto out; + if (!all_pers) { + /* Ask for confirmation. */ + if (!confirm("Update initial RAM-disk now?")) { + rc = EXIT_ABORTED; + goto out; + } } /* Build the command line. */ params = strlist_new(); util_list_iterate(selected, sel) { - strlist_add(params, "%s", sel->st->name); - strlist_add(params, "%s", sel->id); + /* From the selected list, remove the devices with zdev:early=0 */ + if (!is_zdev_early_0(sel)) { + strlist_add(params, "%s", sel->st->name); + strlist_add(params, "%s", sel->id); + } } params_str = strlist_flatten(params, " "); strlist_free(params);