mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
zdev: Implement internal device attributes
This change adds base infrastructure for implementing internal device
attributes. In the context of the zdev tools, an internal device
attribute is a new type of device attribute with the following
characteristics:
- Can be set and removed like normal device attributes
- Affects zdev-internal handling only
- Does not correspond to an actual device attribute, that is
it has no representation in SysFS
- Can not be set in the active configuration
- Name starts with "zdev:" to prevent conflicts with actual
device attributes
Values for internal device attributes are stored in udev rules alongside
the normal persistent configuration of a device. They are encoded as
udev environment variables. Note that they have no further effect on
udev processing.
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:
committed by
Jan Höppner
parent
3c5644ccfd
commit
c0392efa39
@@ -18,6 +18,7 @@
|
||||
|
||||
#include "attrib.h"
|
||||
#include "device.h"
|
||||
#include "internal.h"
|
||||
#include "misc.h"
|
||||
#include "path.h"
|
||||
#include "scsi.h"
|
||||
@@ -128,7 +129,7 @@ static bool zfcp_lun_devid_from_entry(struct zfcp_lun_devid *id_ptr,
|
||||
struct udev_entry_node *entry)
|
||||
{
|
||||
struct zfcp_lun_devid id;
|
||||
char *copy = NULL, *s;
|
||||
char *copy = NULL, *s, *e, *u;
|
||||
int i;
|
||||
bool rc = false;
|
||||
|
||||
@@ -182,6 +183,28 @@ static bool zfcp_lun_devid_from_entry(struct zfcp_lun_devid *id_ptr,
|
||||
goto out;
|
||||
}
|
||||
|
||||
/*ENV{zdev_var__0_0_1941_0x500507630510c1ae_0x402340d400000000}="1"*/
|
||||
if (starts_with(entry->key, "ENV{zdev_")) {
|
||||
copy = misc_strdup(entry->key);
|
||||
|
||||
/* Find ID start (last __) and end (last }). */
|
||||
s = misc_strrstr(copy, "__");
|
||||
e = strrchr(copy, '}');
|
||||
if (!s || !e)
|
||||
goto out;
|
||||
*e = 0;
|
||||
s += 2;
|
||||
/* Convert variable name to ID format. */
|
||||
for (i = 0, u = s; (u = strchr(u, '_')); i++, u++) {
|
||||
if (i < 2)
|
||||
*u = '.';
|
||||
else
|
||||
*u = ':';
|
||||
}
|
||||
rc = zfcp_lun_parse_devid(&id, s, err_ignore) == EXIT_OK ?
|
||||
true : false;
|
||||
}
|
||||
|
||||
out:
|
||||
free(copy);
|
||||
if (rc)
|
||||
@@ -211,11 +234,46 @@ static struct zfcp_lun_node *zfcp_lun_node_from_entry(
|
||||
return node;
|
||||
}
|
||||
|
||||
static void add_internal_setting_from_entry(struct udev_entry_node *entry,
|
||||
struct zfcp_lun_node *node)
|
||||
{
|
||||
char *copy, *name, *end, *u;
|
||||
struct attrib *a;
|
||||
|
||||
/*ENV{zdev_var__0_0_1941_0x500507630510c1ae_0x402340d400000000}="1"*/
|
||||
copy = misc_strdup(entry->key);
|
||||
|
||||
/* Find attribute name start and end. */
|
||||
name = strchr(copy, '{');
|
||||
end = misc_strrstr(copy, "__");
|
||||
if (!name || !end)
|
||||
goto out;
|
||||
*end = 0;
|
||||
name++;
|
||||
|
||||
/* zdev_ => zdev: */
|
||||
u = strchr(name, '_');
|
||||
if (u)
|
||||
*u = ':';
|
||||
|
||||
a = attrib_find(zfcp_lun_subtype.dev_attribs, name);
|
||||
setting_list_apply_actual(node->fc_settings, a, name, entry->value);
|
||||
|
||||
out:
|
||||
free(copy);
|
||||
}
|
||||
|
||||
static void add_fc_setting_from_entry(struct udev_entry_node *entry,
|
||||
struct zfcp_lun_node *node)
|
||||
{
|
||||
char *copy, *s, *e;
|
||||
|
||||
/*ENV{zdev_var__0_0_1941_0x500507630510c1ae_0x402340d400000000}="1"*/
|
||||
if (starts_with(entry->key, "ENV{zdev_") &&
|
||||
strcmp(entry->op, "=") == 0) {
|
||||
add_internal_setting_from_entry(entry, node);
|
||||
return;
|
||||
}
|
||||
/*ATTR{[ccw/0.0.1941]0x500507630510c1ae/0x402340d400000000/failed}="0"*/
|
||||
if (!starts_with(entry->key, "ATTR{[ccw/"))
|
||||
return;
|
||||
@@ -490,7 +548,7 @@ static struct zfcp_lun_node *state_to_zfcp_lun_node(struct zfcp_lun_devid *id,
|
||||
s->value);
|
||||
setting_list_add(node->scsi_settings, n);
|
||||
} else {
|
||||
n = setting_new(NULL, s->name, s->value);
|
||||
n = setting_new(s->attrib, s->name, s->value);
|
||||
setting_list_add(node->fc_settings, n);
|
||||
}
|
||||
}
|
||||
@@ -580,9 +638,21 @@ static exit_code_t write_luns_rule(const char *path, struct util_list *list)
|
||||
node->id.lun);
|
||||
|
||||
util_list_iterate(&node->fc_settings->list, s) {
|
||||
fprintf(fd, "ATTR{[ccw/%s]0x%016" PRIx64 "/0x%016"
|
||||
PRIx64 "/%s}=\"%s\"\n", hba_id, node->id.wwpn,
|
||||
node->id.lun, s->name, s->value);
|
||||
if ((s->attrib && s->attrib->internal) ||
|
||||
internal_by_name(s->name)) {
|
||||
fprintf(fd, "ENV{zdev_%s__%x_%x_%04x_0x%016"
|
||||
PRIx64 "_0x%016" PRIx64 "}=\"%s\"\n",
|
||||
internal_get_name(s->name),
|
||||
node->id.fcp_dev.cssid,
|
||||
node->id.fcp_dev.ssid,
|
||||
node->id.fcp_dev.devno, node->id.wwpn,
|
||||
node->id.lun, s->value);
|
||||
} else {
|
||||
fprintf(fd, "ATTR{[ccw/%s]0x%016" PRIx64
|
||||
"/0x%016" PRIx64 "/%s}=\"%s\"\n",
|
||||
hba_id, node->id.wwpn, node->id.lun,
|
||||
s->name, s->value);
|
||||
}
|
||||
}
|
||||
last_node = node;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user