mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
Provide information for the DASD device attribute 'fc_security'. The help output for this attribute can be queried like this: chzdev dasd --help-attribute The lszdev tool can be used to display the current state of the FC Endpoint Security information: lszdev dasd -a -c TYPE,ID,ATTR:fc_security,ATTRPATH:fc_security Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com> Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
710 lines
19 KiB
C
710 lines
19 KiB
C
/*
|
|
* zdev - Modify and display the persistent configuration of devices
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "attrib.h"
|
|
#include "ccw.h"
|
|
#include "dasd.h"
|
|
#include "device.h"
|
|
#include "devtype.h"
|
|
#include "internal.h"
|
|
#include "misc.h"
|
|
#include "modprobe.h"
|
|
#include "module.h"
|
|
#include "path.h"
|
|
#include "setting.h"
|
|
#include "udev.h"
|
|
|
|
#define DASD_MOD_NAME "dasd_mod"
|
|
#define DASD_ECKD_MOD_NAME "dasd_eckd_mod"
|
|
#define DASD_FBA_MOD_NAME "dasd_fba_mod"
|
|
#define DASD_DIAG_MOD_NAME "dasd_diag_mod"
|
|
|
|
/* Subtype specific data. */
|
|
struct dasd_subtype_data {
|
|
const char *ccwdrv;
|
|
const char *module;
|
|
};
|
|
|
|
/* List of dependent modules. */
|
|
static const char *dasd_mods[] = {
|
|
DASD_ECKD_MOD_NAME,
|
|
DASD_FBA_MOD_NAME,
|
|
DASD_DIAG_MOD_NAME,
|
|
NULL,
|
|
};
|
|
|
|
/*
|
|
* DASD type attributes.
|
|
*/
|
|
|
|
static struct attrib dasd_tattr_autodetect = {
|
|
.name = "autodetect",
|
|
.title = "Enable automatic DASD activation",
|
|
.desc =
|
|
"Control whether the DASD driver automatically enables all detected\n"
|
|
"DASDs:\n"
|
|
" 0: Only configured DASDs are enabled\n"
|
|
" 1: All detected DASDs are automatically enabled\n",
|
|
.defval = "0",
|
|
.activerem = 1,
|
|
.defunset = 1,
|
|
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
|
};
|
|
|
|
static struct attrib dasd_tattr_probeonly = {
|
|
.name = "probeonly",
|
|
.title = "Inhibit access to DASD device nodes",
|
|
.desc =
|
|
"Control whether the DASD driver allows access to DASD devices:\n"
|
|
" 0: All enabled DASDs can be accessed normally\n"
|
|
" 1: Reject any attempt to open DASD devices\n",
|
|
.defval = "0",
|
|
.activerem = 1,
|
|
.defunset = 1,
|
|
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
|
};
|
|
|
|
static struct attrib dasd_tattr_nopav = {
|
|
.name = "nopav",
|
|
.title = "Deactivate the Parallel Access Volume feature",
|
|
.desc = "Control the use of the Parallel Access Volume (PAV) feature:\n"
|
|
" 0: PAV is used when supported by the storage system\n"
|
|
" 1: The use of PAV is suppressed when running in LPAR\n",
|
|
.defval = "0",
|
|
.activerem = 1,
|
|
.defunset = 1,
|
|
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
|
};
|
|
|
|
static struct attrib dasd_tattr_nofcx = {
|
|
.name = "nofcx",
|
|
.title = "Deactivate the High Performance FICON feature",
|
|
.desc = "Control the use of the High Performance FICON (HPF) feature:\n"
|
|
" 0: HPF is used when supported by the storage hardware\n"
|
|
" 1: HPF is not used\n",
|
|
.defval = "0",
|
|
.activerem = 1,
|
|
.defunset = 1,
|
|
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
|
};
|
|
|
|
static struct attrib dasd_tattr_eer_pages = {
|
|
.name = "eer_pages",
|
|
.title = "Modify buffer size for error records",
|
|
.desc =
|
|
"Control the number of 4 KB pages that are used for internal "
|
|
"buffering\n"
|
|
"of error records generated by the Extended Error Reporting (EER)\n"
|
|
"feature.\n",
|
|
.defval = "5",
|
|
.activerem = 1,
|
|
.nounload = 1,
|
|
.accept = ACCEPT_ARRAY(ACCEPT_NUM_GE(1)),
|
|
};
|
|
|
|
/*
|
|
* DASD device attributes.
|
|
*/
|
|
|
|
static struct attrib dasd_attr_failfast = {
|
|
.name = "failfast",
|
|
.title = "Modify error recovery in no-path scenario",
|
|
.desc =
|
|
"Control I/O handling when all paths to a DASD have been lost:\n"
|
|
" 0: Queue I/O until path becomes available\n"
|
|
" 1: Fail I/O request immediately\n",
|
|
.defval = "0",
|
|
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
|
};
|
|
|
|
static struct attrib dasd_attr_readonly = {
|
|
.name = "readonly",
|
|
.title = "Inhibit write access to DASD",
|
|
.desc = "Control the DASD driver read-only setting for a DASD:\n"
|
|
" 0: Allow writing to the device\n"
|
|
" 1: Deny writing to the device\n",
|
|
.defval = "0",
|
|
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
|
};
|
|
|
|
static struct attrib dasd_attr_erplog = {
|
|
.name = "erplog",
|
|
.title = "Enable logging of Error Recovery Processing",
|
|
.desc = "Control logging of Error Recovery Processing (ERP), such as\n"
|
|
"failing channel programs:\n"
|
|
" 0: ERP logging is disabled\n"
|
|
" 1: ERP logging is enabled\n",
|
|
.defval = "0",
|
|
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
|
};
|
|
|
|
static int dasd_raw_diag_order_cmp(struct setting *, struct setting *);
|
|
static bool dasd_raw_diag_check(struct setting *, struct setting *, config_t);
|
|
|
|
static struct attrib dasd_attr_use_diag = {
|
|
.name = "use_diag",
|
|
.title = "Activate z/VM hypervisor assisted I/O processing",
|
|
.desc =
|
|
"Control I/O access mode for a DASD:\n"
|
|
" 0: I/O is performed using standard channel programs\n"
|
|
" 1: I/O is performed using the z/VM DIAGNOSE X'250' interface\n"
|
|
"\n"
|
|
"The DIAGNOSE X'250' access mode works only when:\n"
|
|
" - Running Linux as z/VM guest\n"
|
|
" - Using devices formatted with consistent block sizes, such as\n"
|
|
" ECKD DASDs with LDL or CMS format, or FBA devices\n",
|
|
.order_cmp = dasd_raw_diag_order_cmp,
|
|
.check = dasd_raw_diag_check,
|
|
.defval = "0",
|
|
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
|
};
|
|
|
|
static struct attrib dasd_attr_raw_track_access = {
|
|
.name = "raw_track_access",
|
|
.title = "Enable access to ECKD track metadata",
|
|
.desc =
|
|
"Control whether the DASD driver provides access to full ECKD tracks,\n"
|
|
"including ECKD-specific meta-data:\n"
|
|
" 0: Only access the data portion of ECKD tracks\n"
|
|
" 1: Access the full track\n",
|
|
.order_cmp = dasd_raw_diag_order_cmp,
|
|
.check = dasd_raw_diag_check,
|
|
.defval = "0",
|
|
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
|
};
|
|
|
|
/* Ensure ordering if both use_diag and raw_track_access are modified. */
|
|
static int dasd_raw_diag_order_cmp(struct setting *a, struct setting *b)
|
|
{
|
|
int a_val, b_val;
|
|
|
|
if ((a->attrib == &dasd_attr_use_diag &&
|
|
b->attrib == &dasd_attr_raw_track_access) ||
|
|
(a->attrib == &dasd_attr_raw_track_access &&
|
|
b->attrib == &dasd_attr_use_diag)) {
|
|
/* Define order to ensure that =0 is done before =1. */
|
|
a_val = atoi(a->value);
|
|
b_val = atoi(b->value);
|
|
|
|
if (a_val == 1 && b_val == 0)
|
|
return 1;
|
|
if (a_val == 0 && b_val == 1)
|
|
return -1;
|
|
}
|
|
|
|
return ccw_offline_only_order_cmp(a, b);
|
|
}
|
|
|
|
/* Conflict if both use_diag and raw_track_access are set. */
|
|
static bool dasd_raw_diag_check(struct setting *a, struct setting *b,
|
|
config_t config)
|
|
{
|
|
if ((a->attrib == &dasd_attr_use_diag &&
|
|
b->attrib == &dasd_attr_raw_track_access) ||
|
|
(a->attrib == &dasd_attr_raw_track_access &&
|
|
b->attrib == &dasd_attr_use_diag)) {
|
|
if (atoi(a->value) == 1 && atoi(b->value) == 1)
|
|
return false;
|
|
}
|
|
|
|
return ccw_offline_only_check(a, b, config);
|
|
}
|
|
|
|
static struct attrib dasd_attr_eer_enabled = {
|
|
.name = "eer_enabled",
|
|
.title = "Enable Extended Error Reporting",
|
|
.desc =
|
|
"Control the Extended Error Reporting (EER) feature for a DASD:\n"
|
|
" 0: EER is disabled\n"
|
|
" 1: EER is enabled\n",
|
|
.order_cmp = ccw_online_only_order_cmp,
|
|
.check = ccw_online_only_check,
|
|
.defval = "0",
|
|
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
|
};
|
|
|
|
static struct attrib dasd_attr_expires = {
|
|
.name = "expires",
|
|
.title = "Modify I/O operation timeout",
|
|
.desc =
|
|
"Specify the time in seconds that the DASD driver waits for the\n"
|
|
"completion of a single I/O operation before considering that I/O\n"
|
|
"operation to have failed.\n"
|
|
"\n"
|
|
"The default value depends on the DASD type.\n",
|
|
.order_cmp = ccw_online_only_order_cmp,
|
|
.check = ccw_online_only_check,
|
|
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(1, 40000000)),
|
|
};
|
|
|
|
static struct attrib dasd_attr_retries = {
|
|
.name = "retries",
|
|
.title = "Modify I/O operation retry counter",
|
|
.desc =
|
|
"Specify the number of times that a failed I/O should be retried\n"
|
|
"before reporting it as failed.\n"
|
|
"\n"
|
|
"The default value is dependent on the DASD type.\n",
|
|
.order_cmp = ccw_online_only_order_cmp,
|
|
.check = ccw_online_only_check,
|
|
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 32768)),
|
|
};
|
|
|
|
static struct attrib dasd_attr_timeout = {
|
|
.name = "timeout",
|
|
.title = "Modify I/O request timeout",
|
|
.desc =
|
|
"Specify the total time in seconds that the Linux block device layer\n"
|
|
"waits for the completion of an I/O request issued to the DASD driver\n"
|
|
"before considering that I/O to have failed. Specify 0 to deactivate\n"
|
|
"timeout handling.\n",
|
|
.order_cmp = ccw_online_only_order_cmp,
|
|
.check = ccw_online_only_check,
|
|
.defval = "0",
|
|
.accept = ACCEPT_ARRAY(ACCEPT_NUM_GE(0)),
|
|
};
|
|
|
|
static struct attrib dasd_attr_reservation_policy = {
|
|
.name = "reservation_policy",
|
|
.title = "Modify lost device reservation behavior",
|
|
.desc =
|
|
"Control the DASD driver behavior if an existing DASD reservation of\n"
|
|
"this system for a DASD is lost:\n"
|
|
" ignore: I/O operations are blocked until the external reservation\n"
|
|
" is released (default)\n"
|
|
" fail: All I/O operations are considered to have failed\n",
|
|
.defval = "ignore",
|
|
.accept = ACCEPT_ARRAY(ACCEPT_STR("ignore"), ACCEPT_STR("fail")),
|
|
};
|
|
|
|
static struct attrib dasd_attr_last_known_reservation_state = {
|
|
.name = "last_known_reservation_state",
|
|
.title = "Display and reset driver device reservation view",
|
|
.desc =
|
|
"Display the DASD driver's view of device reservations held by this\n"
|
|
"system:\n"
|
|
" none: No reservation held or no information available\n"
|
|
" reserved: Device is assumed to be reserved by this system\n"
|
|
" lost: A reservation held by this system was lost\n"
|
|
"\n"
|
|
"To reset the reservation state from 'lost' to 'none', set this\n"
|
|
"attribute to 'reset'.\n",
|
|
.unstable = 1,
|
|
.accept = ACCEPT_ARRAY(ACCEPT_RANGE(0, 1)),
|
|
};
|
|
|
|
static struct attrib dasd_attr_safe_offline = {
|
|
.name = "safe_offline",
|
|
.title = "Deactivate DASD after processing pending I/Os",
|
|
.desc = "Write an arbitrary value to this attribute to attempt to set\n"
|
|
"the DASD offline after all outstanding I/O requests have\n"
|
|
"been processed.\n",
|
|
.activeonly = 1,
|
|
.writeonly = 1,
|
|
};
|
|
|
|
static struct attrib dasd_attr_fc_security = {
|
|
.name = "fc_security",
|
|
.title = "Show FC Endpoint Security state of DASD device",
|
|
.desc =
|
|
"This read-only attribute shows the Fibre Channel Endpoint Security\n"
|
|
"status of the connection to the DASD device:\n"
|
|
" Unsupported : The DASD device does not support Fibre Channel\n"
|
|
" Endpoint Security\n"
|
|
" Inconsistent : The operational channel paths of the DASD device\n"
|
|
" report inconsistent Fibre Channel Endpoint\n"
|
|
" Security status\n"
|
|
" Authentication: The connection has been authenticated\n"
|
|
" Encryption : The connection is encrypted\n",
|
|
.readonly = 1,
|
|
};
|
|
|
|
/*
|
|
* DASD subtype methods.
|
|
*/
|
|
|
|
static bool _check_use_diag(struct setting_list *list)
|
|
{
|
|
struct setting *u;
|
|
|
|
u = setting_list_find(list, dasd_attr_use_diag.name);
|
|
if (u && u->modified) {
|
|
if (u->value && atoi(u->value) == 1) {
|
|
delayed_warn("Cannot set 'use_diag=1' on non-z/VM system\n");
|
|
return false;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
/* Check if use_diag setting can be correctly applied. */
|
|
static exit_code_t check_use_diag(struct device *dev, config_t config)
|
|
{
|
|
if (is_zvm())
|
|
return EXIT_OK;
|
|
|
|
if (SCOPE_ACTIVE(config) && !_check_use_diag(dev->active.settings))
|
|
return EXIT_INVALID_CONFIG;
|
|
if (SCOPE_PERSISTENT(config) &&
|
|
!_check_use_diag(dev->persistent.settings))
|
|
return EXIT_INVALID_CONFIG;
|
|
if (SCOPE_AUTOCONF(config) &&
|
|
!_check_use_diag(dev->autoconf.settings))
|
|
return EXIT_INVALID_CONFIG;
|
|
|
|
return EXIT_OK;
|
|
}
|
|
|
|
static exit_code_t dasd_st_check_pre_configure(struct subtype *st,
|
|
struct device *dev,
|
|
int prereq, config_t config)
|
|
{
|
|
exit_code_t rc;
|
|
|
|
if (dev->active.deconfigured)
|
|
return EXIT_OK;
|
|
rc = check_use_diag(dev, config);
|
|
if (rc)
|
|
return rc;
|
|
|
|
return EXIT_OK;
|
|
}
|
|
|
|
static void dasd_st_add_modules(struct subtype *st, struct device *dev,
|
|
struct util_list *modules)
|
|
{
|
|
int changed, aset, pset;
|
|
|
|
/* Add main module. */
|
|
st->super->add_modules(st, dev, modules);
|
|
|
|
/* Add dasd_diag_mod if use_diag is set. */
|
|
setting_list_get_bool_state(dev->active.settings,
|
|
dasd_attr_use_diag.name, &changed, &aset);
|
|
setting_list_get_bool_state(dev->persistent.settings,
|
|
dasd_attr_use_diag.name, &changed, &pset);
|
|
setting_list_get_bool_state(dev->autoconf.settings,
|
|
dasd_attr_use_diag.name, &changed, &pset);
|
|
|
|
if (aset || pset)
|
|
strlist_add_unique(modules, DASD_DIAG_MOD_NAME);
|
|
}
|
|
|
|
/*
|
|
* DASD methods.
|
|
*/
|
|
|
|
/* Clean up all resources used by devtype object. */
|
|
static void dasd_devtype_exit(struct devtype *dt)
|
|
{
|
|
setting_list_free(dt->active_settings);
|
|
setting_list_free(dt->persistent_settings);
|
|
}
|
|
|
|
/* Split a dasd= module parameter string into a setting_list, based on
|
|
* known attributes encoded in dasd= parameters. */
|
|
static void split_dasd(struct devtype *dt, const char *str,
|
|
struct setting_list *list)
|
|
{
|
|
char *copy, *curr, *next, *dasd_str;
|
|
struct attrib *a;
|
|
struct util_list *dasd;
|
|
|
|
dasd = strlist_new();
|
|
copy = misc_strdup(str);
|
|
next = copy;
|
|
while ((curr = strsep(&next, ","))) {
|
|
if (strcmp(curr, "(null)") == 0)
|
|
continue;
|
|
if (*curr == 0) {
|
|
/* Handle dasd="" */
|
|
continue;
|
|
}
|
|
/* Check for known attributes. */
|
|
a = attrib_find(dt->type_attribs, curr);
|
|
if (a) {
|
|
/* Currently only boolean attributes implemented. */
|
|
setting_list_apply_actual(list, a, curr, "1");
|
|
continue;
|
|
}
|
|
/* An unknown setting or device spec - leave in dasd=. */
|
|
strlist_add(dasd, "%s", curr);
|
|
}
|
|
free(copy);
|
|
|
|
/* Add dasd= setting if necessary. */
|
|
if (!util_list_is_empty(dasd)) {
|
|
dasd_str = strlist_flatten(dasd, ",");
|
|
setting_list_apply_actual(list, NULL, "dasd", dasd_str);
|
|
free(dasd_str);
|
|
}
|
|
strlist_free(dasd);
|
|
}
|
|
|
|
/* Convert a module parameter list into a devtype settings list. */
|
|
static void convert_params_to_settings(struct devtype *dt,
|
|
struct setting_list *from,
|
|
struct setting_list *to)
|
|
{
|
|
struct setting *s;
|
|
|
|
util_list_iterate(&from->list, s) {
|
|
if (strcmp(s->name, "dasd") == 0) {
|
|
/* Special handling: split known attribs out. */
|
|
split_dasd(dt, s->value, to);
|
|
continue;
|
|
}
|
|
/* Just copy remaining attributes. */
|
|
setting_list_apply_actual(to, s->attrib, s->name, s->value);
|
|
}
|
|
}
|
|
|
|
/* Convert a devtype settings list to a module parameter list. */
|
|
static void convert_settings_to_params(struct devtype *dt,
|
|
struct setting_list *from,
|
|
struct setting_list **to)
|
|
{
|
|
struct setting *s_from, *s_to;
|
|
struct util_list *dasd;
|
|
int dasd_mod;
|
|
char *flat;
|
|
|
|
*to = setting_list_new();
|
|
dasd = strlist_new();
|
|
dasd_mod = 0;
|
|
|
|
util_list_iterate(&from->list, s_from) {
|
|
if (s_from->removed)
|
|
continue;
|
|
if (s_from->derived && !s_from->modified)
|
|
continue;
|
|
if (strcmp(s_from->name, "eer_pages") == 0) {
|
|
/* Copy stand-alone parameter. */
|
|
setting_list_add(*to, setting_copy(s_from));
|
|
continue;
|
|
}
|
|
/* All other settings need to go into dasd=. */
|
|
if (strcmp(s_from->name, "dasd") == 0) {
|
|
/* Just add explicit dasd= content. */
|
|
strlist_add(dasd, "%s", s_from->value);
|
|
} else if (strcmp(s_from->value, "0") == 0) {
|
|
/* A flag in dasd= counts as set, so skip the unset
|
|
* ones. */
|
|
continue;
|
|
} else {
|
|
/* Just add the name for set attributes. */
|
|
strlist_add(dasd, "%s", s_from->name);
|
|
dasd_mod += s_from->modified;
|
|
}
|
|
}
|
|
|
|
flat = strlist_flatten(dasd, ",");
|
|
s_to = setting_new(NULL, "dasd", flat);
|
|
free(flat);
|
|
if (dasd_mod > 0)
|
|
s_to->modified = 1;
|
|
if (util_list_is_empty(dasd))
|
|
s_to->removed = 1;
|
|
setting_list_add(*to, s_to);
|
|
strlist_free(dasd);
|
|
}
|
|
|
|
static exit_code_t dasd_devtype_read_settings(struct devtype *dt,
|
|
config_t config)
|
|
{
|
|
struct setting_list *list;
|
|
char *path;
|
|
exit_code_t rc = EXIT_OK;
|
|
|
|
if (SCOPE_ACTIVE(config) && !dt->active_settings) {
|
|
dt->active_exists = 0;
|
|
rc = module_get_params(DASD_MOD_NAME, dt->type_attribs, &list);
|
|
if (rc)
|
|
return rc;
|
|
dt->active_settings = setting_list_new();
|
|
if (list) {
|
|
convert_params_to_settings(dt, list,
|
|
dt->active_settings);
|
|
setting_list_mark_default_derived(dt->active_settings);
|
|
setting_list_apply_defaults(dt->active_settings,
|
|
dt->type_attribs, false);
|
|
setting_list_free(list);
|
|
dt->active_exists = 1;
|
|
}
|
|
}
|
|
|
|
if (SCOPE_PERSISTENT(config) && !dt->persistent_settings) {
|
|
dt->persistent_exists = 0;
|
|
path = path_get_modprobe_conf(dt);
|
|
rc = modprobe_read_settings(path, DASD_MOD_NAME,
|
|
dt->type_attribs, &list);
|
|
free(path);
|
|
if (rc)
|
|
return rc;
|
|
dt->persistent_settings = setting_list_new();
|
|
if (list) {
|
|
convert_params_to_settings(dt, list,
|
|
dt->persistent_settings);
|
|
setting_list_apply_defaults(dt->persistent_settings,
|
|
dt->type_attribs, false);
|
|
setting_list_free(list);
|
|
dt->persistent_exists = 1;
|
|
}
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
static exit_code_t dasd_devtype_write_settings(struct devtype *dt,
|
|
config_t config)
|
|
{
|
|
struct setting_list *list;
|
|
char *path;
|
|
exit_code_t rc = EXIT_OK;
|
|
|
|
if (SCOPE_ACTIVE(config) && dt->active_settings) {
|
|
/* Try setting parameters directly via Sysfs. */
|
|
if (module_set_params(DASD_MOD_NAME, dt->active_settings))
|
|
goto persistent;
|
|
|
|
convert_settings_to_params(dt, dt->active_settings, &list);
|
|
rc = module_load(DASD_MOD_NAME, dasd_mods, list,
|
|
err_delayed_print);
|
|
setting_list_free(list);
|
|
if (rc)
|
|
return rc;
|
|
}
|
|
|
|
persistent:
|
|
if (SCOPE_PERSISTENT(config) && dt->persistent_settings) {
|
|
path = path_get_modprobe_conf(dt);
|
|
if (!rc) {
|
|
convert_settings_to_params(dt, dt->persistent_settings,
|
|
&list);
|
|
rc = modprobe_write_settings(path, DASD_MOD_NAME, list);
|
|
setting_list_free(list);
|
|
}
|
|
free(path);
|
|
}
|
|
|
|
return rc;
|
|
}
|
|
|
|
/*
|
|
* DASD device sub-types.
|
|
*/
|
|
static struct ccw_subtype_data dasd_eckd_data = {
|
|
.ccwdrv = "dasd-eckd",
|
|
.mod = "dasd_eckd_mod",
|
|
};
|
|
|
|
struct subtype dasd_subtype_eckd = {
|
|
.super = &ccw_subtype,
|
|
.devtype = &dasd_devtype,
|
|
.name = "dasd-eckd",
|
|
.title = "Enhanced Count Key Data (ECKD) DASDs",
|
|
.devname = "ECKD DASD",
|
|
.modules = STRING_ARRAY(DASD_ECKD_MOD_NAME),
|
|
.namespace = &ccw_namespace,
|
|
.data = &dasd_eckd_data,
|
|
|
|
.dev_attribs = ATTRIB_ARRAY(
|
|
&ccw_attr_online_force,
|
|
&ccw_attr_cmb_enable,
|
|
&dasd_attr_failfast,
|
|
&dasd_attr_readonly,
|
|
&dasd_attr_erplog,
|
|
&dasd_attr_use_diag,
|
|
&dasd_attr_raw_track_access,
|
|
&dasd_attr_eer_enabled,
|
|
&dasd_attr_expires,
|
|
&dasd_attr_retries,
|
|
&dasd_attr_timeout,
|
|
&dasd_attr_reservation_policy,
|
|
&dasd_attr_last_known_reservation_state,
|
|
&dasd_attr_safe_offline,
|
|
&dasd_attr_fc_security,
|
|
&internal_attr_early,
|
|
),
|
|
.unknown_dev_attribs = 1,
|
|
|
|
.check_pre_configure = &dasd_st_check_pre_configure,
|
|
.add_modules = &dasd_st_add_modules,
|
|
};
|
|
|
|
static struct ccw_subtype_data dasd_fba_data = {
|
|
.ccwdrv = "dasd-fba",
|
|
.mod = "dasd_fba_mod",
|
|
};
|
|
|
|
struct subtype dasd_subtype_fba = {
|
|
.super = &ccw_subtype,
|
|
.devtype = &dasd_devtype,
|
|
.name = "dasd-fba",
|
|
.title = "Fixed Block Architecture (FBA) DASDs",
|
|
.devname = "FBA DASD",
|
|
.modules = STRING_ARRAY(DASD_FBA_MOD_NAME),
|
|
.namespace = &ccw_namespace,
|
|
.data = &dasd_fba_data,
|
|
|
|
.dev_attribs = ATTRIB_ARRAY(
|
|
&ccw_attr_online_force,
|
|
&ccw_attr_cmb_enable,
|
|
&dasd_attr_failfast,
|
|
&dasd_attr_readonly,
|
|
&dasd_attr_erplog,
|
|
&dasd_attr_use_diag,
|
|
&dasd_attr_expires,
|
|
&dasd_attr_retries,
|
|
&dasd_attr_timeout,
|
|
&dasd_attr_reservation_policy,
|
|
&dasd_attr_last_known_reservation_state,
|
|
&dasd_attr_safe_offline,
|
|
&internal_attr_early,
|
|
),
|
|
.unknown_dev_attribs = 1,
|
|
|
|
.check_pre_configure = &dasd_st_check_pre_configure,
|
|
.add_modules = &dasd_st_add_modules,
|
|
};
|
|
|
|
/*
|
|
* DASD device type.
|
|
*/
|
|
|
|
struct devtype dasd_devtype = {
|
|
.name = "dasd",
|
|
.title = "FICON-attached Direct Access Storage Devices "
|
|
"(DASDs)",
|
|
.devname = "DASD",
|
|
.modules = STRING_ARRAY(DASD_MOD_NAME),
|
|
|
|
.subtypes = SUBTYPE_ARRAY(
|
|
&dasd_subtype_eckd,
|
|
&dasd_subtype_fba,
|
|
),
|
|
|
|
.type_attribs = ATTRIB_ARRAY(
|
|
&dasd_tattr_autodetect,
|
|
&dasd_tattr_probeonly,
|
|
&dasd_tattr_nopav,
|
|
&dasd_tattr_nofcx,
|
|
&dasd_tattr_eer_pages,
|
|
),
|
|
|
|
.exit = &dasd_devtype_exit,
|
|
|
|
.read_settings = &dasd_devtype_read_settings,
|
|
.write_settings = &dasd_devtype_write_settings,
|
|
};
|