mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
zdev: onboard --site option on zdev commands
In some high-availability setups, root and boot disks of a Linux installation are copied to remote sites that can take over execution of a Linux workload in case of an outage of the original site. A site in this context is an execution environment such as an LPAR or z/VM guest. Each site may provide a different set of devices, or require different parameters to be applied per device. chzdev supports site-specific device configuration for up to 10 sites. Each site is identified by a number in the range 0 to 9. You can provide a separate set of persistent device configuration for each site. The IPL Load parameter value specified during boot determines the currently active site. Only the device configuration of the active site is applied during boot and when new devices become available. A common configuration can be provided that is applied when no site-specific configuration is available for a device in the active site. User can use the --site parameter to configure devices for a specific site only. Configuration actions without a site parameter apply to the common configuration. During the boot, the active site configuration is chosed based on the IPL LOADPARM variable. If the LOADPARM contains no valid site-id (0 to 9), the fallback-site id will be used. The fallback-site-id can also be configured with the zdev tools by not specifying the --site parameter. Some of the new chzdev/lszdev commands with site-parameter can be as follows 1. chzdev -ep f001 --site 3 This command is used to configure the device f001 for the site 3. During boot, if the LOADPARM value is S3, this device configuration will be used. 2. lszdev --site 3 This command lists all the devices which are configured for site 3. 3. chzdev -ep f001 Above command does not have a --site parameter. This device settings will be used for the following conditions 1. When the loadparm specifies a site, (e.g S3), and the device does not have an associated config-set, zdev uses fallback config set. 2. When the loadparm does not specify any site information, then the fallback config set will be used. When the loadparm specifies a site, and the device does not have an associated config set, nor a fallback site, nothing is configured for this device. 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
b3551f50a8
commit
198c9fc052
@@ -19,6 +19,20 @@
|
||||
struct subtype;
|
||||
struct setting_list;
|
||||
|
||||
/**
|
||||
* Currently zdev supports 10 sites. Which means, zdev support 10 different
|
||||
* set of attributes which are specific to each site. When the user does
|
||||
* not provide any site information, the common set will be used which is
|
||||
* not specific to any site. So, total we have 11 persistent attribute sets
|
||||
* Where,
|
||||
* 0- 9: Site specific attributes
|
||||
* 10: Common attributes which do not belong to any sites
|
||||
*/
|
||||
|
||||
#define NUM_SITES 11
|
||||
#define NUM_USER_SITES (NUM_SITES - 1)
|
||||
#define SITE_FALLBACK NUM_USER_SITES
|
||||
|
||||
/**
|
||||
* struct device_state - Represent the state of a device in a configuration
|
||||
* @settings: List of attribute settings
|
||||
|
||||
@@ -38,6 +38,7 @@ extern struct devtype *devtypes[];
|
||||
* devtypes with empty title will not be shown with --list-types.
|
||||
* @devname: Short name for devices of this device type
|
||||
* @modules: (Optional) Array of kernel modules required for this devtype
|
||||
* @site_support: Support for site-specific configuration for the device-type
|
||||
* @subtypes: Array of subtypes
|
||||
* @type_attribs: Array of device type attributes (may point to empty array)
|
||||
* @unknown_type_attribs: Allow specification of unknown device type attributes
|
||||
@@ -59,6 +60,7 @@ struct devtype {
|
||||
const char title[DEVTYPE_TITLE_LEN + 1];
|
||||
const char *devname;
|
||||
const char **modules;
|
||||
unsigned int site_support:1;
|
||||
|
||||
struct subtype **subtypes;
|
||||
struct attrib **type_attribs;
|
||||
|
||||
@@ -103,6 +103,8 @@ extern int delayed_warnings;
|
||||
extern unsigned long longrun_total;
|
||||
extern unsigned long longrun_current;
|
||||
|
||||
extern int global_site_id;
|
||||
|
||||
void misc_exit(void);
|
||||
void indent(unsigned int, const char *, ...);
|
||||
void error(const char *, ...);
|
||||
@@ -239,6 +241,7 @@ void longrun_stop(void);
|
||||
char *skip_comp(char *);
|
||||
void byte_swap(uint8_t *, unsigned int *, unsigned);
|
||||
bool valid_hex(const char *);
|
||||
bool is_valid_site(const char *);
|
||||
void debug_init(int, char **);
|
||||
|
||||
#endif /* MISC_H */
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "lib/util_path.h"
|
||||
#include "lib/zt_common.h"
|
||||
@@ -44,6 +45,12 @@
|
||||
#include "udev.h"
|
||||
#include "zfcp_lun.h"
|
||||
|
||||
/* current site-id in action. By default, operations are always on fallback
|
||||
* site; We need the current site-id as global variable to avoid excessive
|
||||
* diff of simple function parameter modifications to pass this value.
|
||||
*/
|
||||
int global_site_id = SITE_FALLBACK;
|
||||
|
||||
/* Main program action. */
|
||||
typedef enum {
|
||||
ACT_CONFIGURE,
|
||||
@@ -97,6 +104,7 @@ struct options {
|
||||
unsigned int verbose:1;
|
||||
unsigned int quiet:1;
|
||||
unsigned int no_settle:1;
|
||||
unsigned int site_id;
|
||||
};
|
||||
|
||||
/* Makefile converts chzdev_usage.txt into C file which we include here. */
|
||||
@@ -140,6 +148,7 @@ enum {
|
||||
OPT_QUIET = 'q',
|
||||
OPT_NO_SETTLE = (OPT_ANONYMOUS_BASE+__COUNTER__),
|
||||
OPT_AUTO_CONF = (OPT_ANONYMOUS_BASE+__COUNTER__),
|
||||
OPT_SITE = 's',
|
||||
};
|
||||
|
||||
static struct opts_conflict conflict_list[] = {
|
||||
@@ -177,6 +186,8 @@ static struct opts_conflict conflict_list[] = {
|
||||
OPT_REMOVE_ALL, OPT_ACTIVE, 0),
|
||||
OPTS_CONFLICT(OPT_ONLINE,
|
||||
OPT_OFFLINE),
|
||||
OPTS_CONFLICT(OPT_SITE,
|
||||
OPT_TYPE, OPT_EXPORT, OPT_IMPORT, 0),
|
||||
OPTS_CONFLICT(OPT_QUIET,
|
||||
OPT_VERBOSE),
|
||||
OPTS_CONFLICT(OPT_AUTO_CONF,
|
||||
@@ -225,11 +236,12 @@ static const struct option opt_list[] = {
|
||||
{ "verbose", no_argument, NULL, OPT_VERBOSE },
|
||||
{ "quiet", no_argument, NULL, OPT_QUIET },
|
||||
{ "no-settle", no_argument, NULL, OPT_NO_SETTLE },
|
||||
{ "site", required_argument, NULL, OPT_SITE },
|
||||
{ NULL, no_argument, NULL, 0 },
|
||||
};
|
||||
|
||||
/* Command line abbreviations. */
|
||||
static const char opt_str[] = ":edlHLapr:RfyhvVqt";
|
||||
static const char opt_str[] = ":edlHLapr:RfyhvVqts:";
|
||||
|
||||
/* Count of persistently modified devices. */
|
||||
static int pers_mod_devs;
|
||||
@@ -246,6 +258,8 @@ static void init_options(struct options *opts)
|
||||
opts->settings = strlist_new();
|
||||
opts->remove = strlist_new();
|
||||
opts->base = strlist_new();
|
||||
/* Default operations are on fallback site*/
|
||||
opts->site_id = SITE_FALLBACK;
|
||||
}
|
||||
|
||||
/* Release memory used in options data structure. */
|
||||
@@ -955,6 +969,28 @@ static exit_code_t parse_options(struct options *opts, int argc, char *argv[])
|
||||
opts->no_settle = 1;
|
||||
break;
|
||||
|
||||
case OPT_SITE:
|
||||
/* --site */
|
||||
/* 1. User can specify only site-ids from 0 to 9
|
||||
* 2. only one --site parameter is accepted
|
||||
*/
|
||||
|
||||
if (!is_valid_site(optarg)) {
|
||||
syntax("Unsupported site ID\n");
|
||||
return EXIT_USAGE_ERROR;
|
||||
}
|
||||
|
||||
if (opts->site_id != SITE_FALLBACK) {
|
||||
syntax("Cannot specify '--site' multiple "
|
||||
"times\n");
|
||||
return EXIT_USAGE_ERROR;
|
||||
}
|
||||
|
||||
opts->site_id = atoi(optarg);
|
||||
global_site_id = opts->site_id;
|
||||
opts->persistent = 1;
|
||||
break;
|
||||
|
||||
case ':':
|
||||
/* Missing option argument. */
|
||||
syntax("Option '%s' requires an argument\n",
|
||||
@@ -1794,6 +1830,24 @@ static void unblacklist_ranges(struct selected_dev_node *sel,
|
||||
*param_ptr = param;
|
||||
}
|
||||
|
||||
/* Currently the site-specific configurations are supported only
|
||||
* for some device types. Make sure that user get an error message when
|
||||
* try to configure other device-types with site parameter.
|
||||
*/
|
||||
static exit_code_t is_site_supported(struct util_list *selected)
|
||||
{
|
||||
struct selected_dev_node *sel;
|
||||
|
||||
util_list_iterate(selected, sel) {
|
||||
if (sel->dt && !sel->dt->site_support) {
|
||||
error("Site specific configuration is not supported"
|
||||
" for %s devices\n", sel->dt->devname);
|
||||
return EXIT_USAGE_ERROR;
|
||||
}
|
||||
}
|
||||
return EXIT_OK;
|
||||
}
|
||||
|
||||
/* Handle device configuration. */
|
||||
static exit_code_t configure_devices(struct options *opts, int specified,
|
||||
int *found_ptr)
|
||||
@@ -1827,6 +1881,9 @@ static exit_code_t configure_devices(struct options *opts, int specified,
|
||||
error("No device was selected!\n");
|
||||
rc = EXIT_EMPTY_SELECTION;
|
||||
goto out;
|
||||
} else if (opts->site_id != SITE_FALLBACK) {
|
||||
if (is_site_supported(selected))
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Work on selected devices. */
|
||||
@@ -2036,6 +2093,9 @@ static exit_code_t deconfigure_devices(struct options *opts)
|
||||
error("No device was selected!\n");
|
||||
rc = EXIT_EMPTY_SELECTION;
|
||||
goto out;
|
||||
} else if (opts->site_id != SITE_FALLBACK) {
|
||||
if (is_site_supported(selected))
|
||||
goto out;
|
||||
}
|
||||
|
||||
/* Work on selected devices. */
|
||||
@@ -2558,8 +2618,13 @@ static void action_note(const char *msg, config_t config)
|
||||
{
|
||||
if (config == config_active)
|
||||
info("%s the active configuration only\n", msg);
|
||||
else if (config == config_persistent)
|
||||
info("%s the persistent configuration only\n", msg);
|
||||
else if (config == config_persistent) {
|
||||
if (global_site_id == SITE_FALLBACK)
|
||||
info("%s the persistent configuration only\n", msg);
|
||||
else
|
||||
info("%s the site %d configuration only\n", msg,
|
||||
global_site_id);
|
||||
}
|
||||
else if (config == config_autoconf)
|
||||
info("%s the auto-configuration only\n", msg);
|
||||
}
|
||||
|
||||
@@ -56,5 +56,6 @@ OPTIONS
|
||||
--base PATH Use PATH as base for accessing files
|
||||
--no-settle Do not wait for udev to settle
|
||||
--auto-conf Apply changes to auto-configuration only
|
||||
-s, --site ID Apply changes to the specified site only
|
||||
-V, --verbose Print additional run-time information
|
||||
-q, --quiet Print only minimal run-time information
|
||||
|
||||
@@ -688,6 +688,7 @@ struct devtype dasd_devtype = {
|
||||
"(DASDs)",
|
||||
.devname = "DASD",
|
||||
.modules = STRING_ARRAY(DASD_MOD_NAME),
|
||||
.site_support = 1,
|
||||
|
||||
.subtypes = SUBTYPE_ARRAY(
|
||||
&dasd_subtype_eckd,
|
||||
|
||||
@@ -32,6 +32,12 @@
|
||||
#include "table.h"
|
||||
#include "table_types.h"
|
||||
|
||||
/* current site-id in action. By default, operations are always on fallback
|
||||
* site; We need the current site-id as global variable to avoid excessive
|
||||
* diff of simple function parameter modifications to pass this value.
|
||||
*/
|
||||
int global_site_id = SITE_FALLBACK;
|
||||
|
||||
/* Main program action. */
|
||||
typedef enum {
|
||||
ACT_LIST,
|
||||
@@ -66,6 +72,7 @@ struct options {
|
||||
unsigned int pairs:1;
|
||||
unsigned int verbose:1;
|
||||
unsigned int quiet:1;
|
||||
unsigned int site_id;
|
||||
};
|
||||
|
||||
/* Makefile converts lszdev_usage.txt into C file which we include here. */
|
||||
@@ -100,6 +107,7 @@ enum {
|
||||
OPT_QUIET = 'q',
|
||||
OPT_PAIRS = 'P',
|
||||
OPT_AUTO_CONF = (OPT_ANONYMOUS_BASE+__COUNTER__),
|
||||
OPT_SITE = 's',
|
||||
};
|
||||
|
||||
static struct opts_conflict conflict_list[] = {
|
||||
@@ -120,6 +128,8 @@ static struct opts_conflict conflict_list[] = {
|
||||
OPT_CONFIGURED, OPT_EXISTING, OPT_ONLINE, OPT_OFFLINE,
|
||||
OPT_BY_PATH, OPT_BY_NODE, OPT_BY_INTERFACE, OPT_FAILED,
|
||||
0),
|
||||
OPTS_CONFLICT(OPT_SITE,
|
||||
OPT_TYPE),
|
||||
OPTS_CONFLICT(OPT_ONLINE,
|
||||
OPT_OFFLINE),
|
||||
OPTS_CONFLICT(OPT_QUIET,
|
||||
@@ -159,11 +169,12 @@ static const struct option opt_list[] = {
|
||||
{ "pairs", no_argument, NULL, OPT_PAIRS },
|
||||
{ "verbose", no_argument, NULL, OPT_VERBOSE },
|
||||
{ "quiet", no_argument, NULL, OPT_QUIET },
|
||||
{ "site", required_argument, NULL, OPT_SITE },
|
||||
{ NULL, no_argument, NULL, 0 },
|
||||
};
|
||||
|
||||
/* Command line abbreviations. */
|
||||
static const char opt_str[] = ":tilLhvapPc:nVq";
|
||||
static const char opt_str[] = ":tilLhvapPc:nVqs:";
|
||||
|
||||
/* Initialize options data structure. */
|
||||
static void init_options(struct options *opts)
|
||||
@@ -172,6 +183,8 @@ static void init_options(struct options *opts)
|
||||
opts->select = select_opts_new();
|
||||
opts->columns = strlist_new();
|
||||
opts->base = strlist_new();
|
||||
/* Default operations are on fallback site*/
|
||||
opts->site_id = SITE_FALLBACK;
|
||||
}
|
||||
|
||||
/* Release memory used in options data structure. */
|
||||
@@ -661,6 +674,27 @@ static exit_code_t parse_options(struct options *opts, int argc, char *argv[])
|
||||
opts->quiet = 1;
|
||||
break;
|
||||
|
||||
case OPT_SITE:
|
||||
/* --site */
|
||||
/* User can specify only site-ids from 0 to 9 */
|
||||
if (!is_valid_site(optarg)) {
|
||||
syntax("Unsupported site ID\n");
|
||||
return EXIT_USAGE_ERROR;
|
||||
}
|
||||
|
||||
if (opts->site_id != SITE_FALLBACK) {
|
||||
syntax("Cannot specify '--site' multiple "
|
||||
"times\n");
|
||||
return EXIT_USAGE_ERROR;
|
||||
}
|
||||
|
||||
/* site information is a persistent configuration.
|
||||
* set opts->persistent here.
|
||||
*/
|
||||
opts->site_id = atoi(optarg);
|
||||
opts->persistent = 1;
|
||||
break;
|
||||
|
||||
case ':':
|
||||
/* Missing option argument. */
|
||||
syntax("Option '%s' requires an argument\n",
|
||||
@@ -718,7 +752,8 @@ static exit_code_t parse_options(struct options *opts, int argc, char *argv[])
|
||||
opts->select->all = 1;
|
||||
else if (opts->config == config_active)
|
||||
opts->select->existing = 1;
|
||||
else if (opts->config == config_persistent)
|
||||
else if (opts->config == config_persistent ||
|
||||
opts->site_id != SITE_FALLBACK)
|
||||
opts->select->configured = 1;
|
||||
}
|
||||
break;
|
||||
@@ -1558,6 +1593,7 @@ int main(int argc, char *argv[])
|
||||
/* Set globals. */
|
||||
verbose = opts.verbose;
|
||||
quiet = opts.quiet;
|
||||
global_site_id = opts.site_id;
|
||||
path_set_base(opts.base);
|
||||
if (opts.pairs)
|
||||
set_stdout_data();
|
||||
|
||||
@@ -42,5 +42,6 @@ OPTIONS
|
||||
--base PATH Use PATH as base for accessing files
|
||||
--pairs Produce output in KEY="VALUE" format
|
||||
--auto-conf Only show auto-configuration data
|
||||
-s, --site ID Only show data configured for the specified site
|
||||
-V, --verbose Print additional run-time information
|
||||
-q, --quiet Print only minimal run-time information
|
||||
|
||||
@@ -1695,3 +1695,20 @@ char *misc_strrstr(const char *haystack, const char *needle)
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* Check if the site mentioned is valid */
|
||||
bool is_valid_site(const char *str)
|
||||
{
|
||||
char *ptr = NULL;
|
||||
long site_id;
|
||||
|
||||
site_id = strtol(str, &ptr, 10);
|
||||
|
||||
if (*ptr)
|
||||
return false;
|
||||
|
||||
if (site_id < 0 || site_id >= NUM_USER_SITES)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user