mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
zdev: add --deconfigure-all function for chzdev
Introduce --deconfigure-all feature, which will remove all available settings from the mentioned device. A typical device can have 10 different site-specific settings, active settings, persistent settings and sometimes auto-configured settings configured in it. --deconfigure-all can be used to remove all of them with a single command. usage: chzdev -D <device-id> chzdev --deconfigure-all <device-id> Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com> Signed-off-by: Vineeth Vijayan <vneethv@linux.ibm.com> Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
This commit is contained in:
committed by
Jan Höppner
parent
34146c3f92
commit
fa3dd0ec20
@@ -80,6 +80,7 @@ struct options {
|
||||
/* Actions */
|
||||
unsigned int enable:1;
|
||||
unsigned int deconfigure:1;
|
||||
unsigned int deconfigure_all:1;
|
||||
unsigned int list_attribs:1;
|
||||
unsigned int list_types:1;
|
||||
unsigned int help_attribs:1;
|
||||
@@ -127,6 +128,7 @@ enum {
|
||||
OPT_TYPE = 't',
|
||||
OPT_ENABLE = 'e',
|
||||
OPT_DECONFIGURE = 'd',
|
||||
OPT_DECONFIGURE_ALL = 'D',
|
||||
OPT_LIST_ATTRIBS = 'l',
|
||||
OPT_HELP_ATTRIBS = 'H',
|
||||
OPT_LIST_TYPES = 'L',
|
||||
@@ -154,36 +156,42 @@ enum {
|
||||
static struct opts_conflict conflict_list[] = {
|
||||
OPTS_CONFLICT(OPT_ENABLE,
|
||||
OPT_DECONFIGURE, OPT_LIST_ATTRIBS, OPT_LIST_TYPES,
|
||||
OPT_EXPORT, OPT_IMPORT, OPT_APPLY, OPT_TYPE, 0),
|
||||
OPT_EXPORT, OPT_IMPORT, OPT_APPLY, OPT_TYPE,
|
||||
OPT_DECONFIGURE_ALL, 0),
|
||||
OPTS_CONFLICT(OPT_DECONFIGURE,
|
||||
OPT_LIST_ATTRIBS, OPT_HELP_ATTRIBS, OPT_LIST_TYPES,
|
||||
OPT_EXPORT, OPT_IMPORT, OPT_APPLY, OPT_REMOVE,
|
||||
OPT_REMOVE_ALL, OPT_TYPE, 0),
|
||||
OPT_REMOVE_ALL, OPT_TYPE,
|
||||
OPT_DECONFIGURE_ALL, 0),
|
||||
OPTS_CONFLICT(OPT_LIST_ATTRIBS,
|
||||
OPT_DECONFIGURE, OPT_HELP_ATTRIBS, OPT_LIST_TYPES,
|
||||
OPT_EXPORT, OPT_IMPORT, OPT_APPLY, OPT_REMOVE,
|
||||
OPT_REMOVE_ALL, OPT_CONFIGURED, OPT_EXISTING, OPT_ONLINE,
|
||||
OPT_OFFLINE, OPT_BY_PATH, OPT_BY_NODE, OPT_BY_INTERFACE,
|
||||
OPT_BY_ATTRIB, OPT_ACTIVE, OPT_PERSISTENT, OPT_FAILED, 0),
|
||||
OPT_BY_ATTRIB, OPT_ACTIVE, OPT_PERSISTENT, OPT_FAILED,
|
||||
OPT_DECONFIGURE_ALL, 0),
|
||||
OPTS_CONFLICT(OPT_LIST_TYPES,
|
||||
OPT_DECONFIGURE, OPT_LIST_ATTRIBS, OPT_HELP_ATTRIBS,
|
||||
OPT_EXPORT, OPT_IMPORT, OPT_APPLY, OPT_REMOVE,
|
||||
OPT_REMOVE_ALL, OPT_CONFIGURED, OPT_EXISTING, OPT_ONLINE,
|
||||
OPT_OFFLINE, OPT_BY_PATH, OPT_BY_NODE, OPT_BY_INTERFACE,
|
||||
OPT_BY_ATTRIB, OPT_ACTIVE, OPT_PERSISTENT, OPT_FAILED, 0),
|
||||
OPT_BY_ATTRIB, OPT_ACTIVE, OPT_PERSISTENT, OPT_FAILED,
|
||||
OPT_DECONFIGURE_ALL, 0),
|
||||
OPTS_CONFLICT(OPT_EXPORT,
|
||||
OPT_DECONFIGURE, OPT_LIST_ATTRIBS, OPT_HELP_ATTRIBS,
|
||||
OPT_LIST_TYPES, OPT_IMPORT, OPT_APPLY, OPT_REMOVE,
|
||||
OPT_REMOVE_ALL, 0),
|
||||
OPT_REMOVE_ALL, OPT_DECONFIGURE_ALL, 0),
|
||||
OPTS_CONFLICT(OPT_IMPORT,
|
||||
OPT_DECONFIGURE, OPT_LIST_ATTRIBS, OPT_HELP_ATTRIBS,
|
||||
OPT_LIST_TYPES, OPT_EXPORT, OPT_APPLY, OPT_REMOVE,
|
||||
OPT_REMOVE_ALL, OPT_CONFIGURED, OPT_EXISTING, OPT_BY_PATH,
|
||||
OPT_BY_ATTRIB, OPT_BY_NODE, OPT_BY_INTERFACE, 0),
|
||||
OPT_BY_ATTRIB, OPT_BY_NODE, OPT_BY_INTERFACE,
|
||||
OPT_DECONFIGURE_ALL, 0),
|
||||
OPTS_CONFLICT(OPT_APPLY,
|
||||
OPT_DECONFIGURE, OPT_LIST_ATTRIBS, OPT_HELP_ATTRIBS,
|
||||
OPT_LIST_TYPES, OPT_EXPORT, OPT_IMPORT, OPT_REMOVE,
|
||||
OPT_REMOVE_ALL, OPT_ACTIVE, 0),
|
||||
OPT_REMOVE_ALL, OPT_ACTIVE,
|
||||
OPT_DECONFIGURE_ALL, 0),
|
||||
OPTS_CONFLICT(OPT_ONLINE,
|
||||
OPT_OFFLINE),
|
||||
OPTS_CONFLICT(OPT_SITE,
|
||||
@@ -213,6 +221,7 @@ static const struct option opt_list[] = {
|
||||
/* Actions. */
|
||||
{ "enable", no_argument, NULL, OPT_ENABLE },
|
||||
{ "disable", no_argument, NULL, OPT_DECONFIGURE },
|
||||
{ "disable-all", no_argument, NULL, OPT_DECONFIGURE_ALL },
|
||||
{ "list-attributes", no_argument, NULL, OPT_LIST_ATTRIBS },
|
||||
{ "help-attribute", no_argument, NULL, OPT_HELP_ATTRIBS },
|
||||
{ "list-types", no_argument, NULL, OPT_LIST_TYPES },
|
||||
@@ -241,7 +250,7 @@ static const struct option opt_list[] = {
|
||||
};
|
||||
|
||||
/* Command line abbreviations. */
|
||||
static const char opt_str[] = ":edlHLapr:RfyhvVqts:";
|
||||
static const char opt_str[] = ":edlHLapr:RfyhvVqts:D";
|
||||
|
||||
/* Count of persistently modified devices. */
|
||||
static int pers_mod_devs;
|
||||
@@ -852,6 +861,12 @@ static exit_code_t parse_options(struct options *opts, int argc, char *argv[])
|
||||
opts->deconfigure = 1;
|
||||
break;
|
||||
|
||||
case OPT_DECONFIGURE_ALL:
|
||||
/* --disable all the settings*/
|
||||
opts->deconfigure = 1;
|
||||
opts->deconfigure_all = 1;
|
||||
break;
|
||||
|
||||
case OPT_LIST_ATTRIBS:
|
||||
/* --list-attributes */
|
||||
opts->list_attribs = 1;
|
||||
@@ -1023,7 +1038,9 @@ static exit_code_t parse_options(struct options *opts, int argc, char *argv[])
|
||||
goto out;
|
||||
|
||||
/* Determine configuration set. */
|
||||
if (!opts->active && !opts->persistent && !opts->auto_conf) {
|
||||
if (opts->deconfigure_all) {
|
||||
opts->config = config_all;
|
||||
} else if (!opts->active && !opts->persistent && !opts->auto_conf) {
|
||||
/* Default configuration targets are active + persistent */
|
||||
opts->config = config_active | config_persistent;
|
||||
} else {
|
||||
@@ -1970,6 +1987,18 @@ static exit_code_t check_in_use(struct device *dev)
|
||||
return EXIT_OK;
|
||||
}
|
||||
|
||||
static bool is_site_modified(struct device *dev)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NUM_USER_SITES; i++) {
|
||||
if (dev->site_specific[i].modified)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Deconfigure specified device. */
|
||||
static exit_code_t deconfigure_one_device(struct subtype *st, const char *id,
|
||||
struct options *opts, int try,
|
||||
@@ -1979,6 +2008,7 @@ static exit_code_t deconfigure_one_device(struct subtype *st, const char *id,
|
||||
exit_code_t rc;
|
||||
struct device *dev;
|
||||
config_t config, read_config;
|
||||
int i, site_available = 0;
|
||||
|
||||
/* Reset processed flag. */
|
||||
if (proc_ptr)
|
||||
@@ -2011,7 +2041,7 @@ static exit_code_t deconfigure_one_device(struct subtype *st, const char *id,
|
||||
dev->processed = 1;
|
||||
|
||||
if (try && !(dev->active.exists || dev->active.definable ||
|
||||
dev->persistent.exists || dev->autoconf.exists)) {
|
||||
is_dev_pers(dev) || dev->autoconf.exists)) {
|
||||
/* Attempt to deconfigure this device will fail. */
|
||||
return EXIT_DEVICE_NOT_FOUND;
|
||||
}
|
||||
@@ -2021,7 +2051,7 @@ static exit_code_t deconfigure_one_device(struct subtype *st, const char *id,
|
||||
* dev. */
|
||||
if (SCOPE_ACTIVE(config) &&
|
||||
!(dev->active.exists || dev->active.definable)) {
|
||||
if (!((SCOPE_PERSISTENT(config) && dev->persistent.exists) ||
|
||||
if (!((SCOPE_PERSISTENT(config) && is_dev_pers(dev)) ||
|
||||
(SCOPE_AUTOCONF(config) && dev->autoconf.exists)))
|
||||
return EXIT_DEVICE_NOT_FOUND;
|
||||
}
|
||||
@@ -2042,16 +2072,48 @@ static exit_code_t deconfigure_one_device(struct subtype *st, const char *id,
|
||||
} else if (subtype_online_get(st, dev, config_active) == 1)
|
||||
dev->active.modified = 1;
|
||||
}
|
||||
if (SCOPE_PERSISTENT(config) && dev->persistent.exists) {
|
||||
dev->persistent.deconfigured = 1;
|
||||
dev->persistent.modified = 1;
|
||||
if (SCOPE_PERSISTENT(config)) {
|
||||
if (dev->persistent.exists) {
|
||||
dev->persistent.deconfigured = 1;
|
||||
dev->persistent.modified = 1;
|
||||
} else if (is_dev_pers(dev) && global_site_id != SITE_FALLBACK) {
|
||||
dev->persistent.deconfigured = 1;
|
||||
dev->persistent.modified = 1;
|
||||
}
|
||||
}
|
||||
if (SCOPE_AUTOCONF(config) && dev->autoconf.exists) {
|
||||
dev->autoconf.deconfigured = 1;
|
||||
dev->autoconf.modified = 1;
|
||||
}
|
||||
|
||||
/* In case of deconfigure_all command, make sure that site specific
|
||||
* settings are also removed.
|
||||
*/
|
||||
if (opts->deconfigure_all) {
|
||||
for (i = 0; i < NUM_USER_SITES; i++) {
|
||||
if (dev->site_specific[i].exists) {
|
||||
site_available++;
|
||||
/* To remove site-specific settings, simply
|
||||
* make the deconfigured = 1
|
||||
*/
|
||||
dev->site_specific[i].deconfigured = 1;
|
||||
dev->site_specific[i].modified = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (site_available) {
|
||||
/* set persistent.exists = 1 to let the
|
||||
* drivers know that we need to modify the
|
||||
* udev-rule
|
||||
*/
|
||||
dev->persistent.exists = 1;
|
||||
dev->persistent.modified = 1;
|
||||
dev->persistent.deconfigured = 1;
|
||||
}
|
||||
|
||||
if (!dev->active.modified && !dev->persistent.modified &&
|
||||
!dev->autoconf.modified)
|
||||
!dev->autoconf.modified && !is_site_modified(dev))
|
||||
return EXIT_OK;
|
||||
|
||||
/* Pre-write check. */
|
||||
@@ -3099,7 +3161,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 = initrd_check(ZDEV_ALWAYS_UPDATE_INITRD);
|
||||
rc = initrd_check(ZDEV_ALWAYS_UPDATE_INITRD, opts.deconfigure_all);
|
||||
if (rc && !drc)
|
||||
drc = rc;
|
||||
}
|
||||
|
||||
@@ -33,7 +33,8 @@ SETTINGS
|
||||
|
||||
ACTIONS
|
||||
-e, --enable Enable device
|
||||
-d, --disable Disable device
|
||||
-d, --disable Disable specified setting of the device
|
||||
-D, --disable-all Disable all the settings of the device
|
||||
-l, --list-attributes List attributes
|
||||
-L, --list-types List supported device types
|
||||
-H, --help-attribute Show detailed help on specified attribute
|
||||
|
||||
@@ -83,23 +83,58 @@ static bool is_zdev_early_0(struct selected_dev_node *sel)
|
||||
{
|
||||
struct setting *s;
|
||||
struct device *dev;
|
||||
int i;
|
||||
|
||||
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)
|
||||
|
||||
for (i = 0; i < NUM_SITES; i++) {
|
||||
s = setting_list_find(dev->site_specific[i].settings,
|
||||
internal_attr_early.name);
|
||||
if (!s)
|
||||
return false;
|
||||
if (s->specified && strcmp(s->value, "0") == 0)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* When site-specific settings has zdev:early configured, it is not
|
||||
* detected with the --by-attr functionality of select_devices. Instead
|
||||
* we will have to iterate through each configuration and check if there
|
||||
* is a zdev:early set in the device. This is usually applicable only in
|
||||
* the case of deconfigure-all command, because, for all other commands
|
||||
* we copy the settings-in-action to the persistent settings and do the
|
||||
* processing there.
|
||||
*/
|
||||
static bool is_zdev_early_site(struct selected_dev_node *sel)
|
||||
{
|
||||
struct setting *s;
|
||||
struct device *dev;
|
||||
int i;
|
||||
|
||||
if (global_site_id != SITE_FALLBACK)
|
||||
return false;
|
||||
if (s->specified && strcmp(s->value, "0") == 0)
|
||||
return true;
|
||||
|
||||
dev = device_list_find(sel->st->devices, sel->id, NULL);
|
||||
if (!dev)
|
||||
return false;
|
||||
|
||||
for (i = 0; i < NUM_SITES; i++) {
|
||||
s = setting_list_find(dev->site_specific[i].settings,
|
||||
internal_attr_early.name);
|
||||
if (s)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Determine if initial RAM-disk needs updating. If so, run the corresponding
|
||||
* scripts if available. */
|
||||
exit_code_t initrd_check(bool all_pers)
|
||||
exit_code_t initrd_check(bool all_pers, int site_validate)
|
||||
{
|
||||
struct util_list *selected, *params, *mod = strlist_new();
|
||||
struct selected_dev_node *sel;
|
||||
@@ -142,7 +177,12 @@ exit_code_t initrd_check(bool all_pers)
|
||||
}
|
||||
/* Finally add devices with zdev:early=1. */
|
||||
select = select_opts_new();
|
||||
strlist_add(&select->by_attr, "%s=1", INTERNAL_ATTR_EARLY);
|
||||
/* If we need information from multiple site, we cannot use the by-attr
|
||||
* functionality of select_devices function. Instead we have to iterate
|
||||
* through individual devices and site settings to find the key.
|
||||
*/
|
||||
if (!site_validate)
|
||||
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);
|
||||
@@ -162,7 +202,12 @@ check_mod:
|
||||
/* Check devices. */
|
||||
dev = device_list_find(sel->st->devices, sel->id, NULL);
|
||||
if (dev && dev->persistent.exists &&
|
||||
(device_needs_writing(dev, config_persistent) || force)) {
|
||||
(device_needs_writing(dev, config_persistent) || force) &&
|
||||
!site_validate) {
|
||||
strlist_add(mod, "%s %s", dev->subtype->devname,
|
||||
dev->id);
|
||||
} else if (site_validate && is_zdev_early_site(sel) &&
|
||||
device_needs_writing(dev, config_persistent)) {
|
||||
strlist_add(mod, "%s %s", dev->subtype->devname,
|
||||
dev->id);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user