mirror of
https://github.com/ibm-s390-linux/s390-tools.git
synced 2026-08-05 02:14:52 +00:00
Currently ZDEV_SITE_ID is derived with the help of an additional udev-rule, 40-zdev-id.rules. The sole purpose of this rule is to determine the ZDEV_SITE_ID environment value with the help of zdev_id binary. This solution is minimal, but this has some unwanted side- effects. The zdev_id logic get executed for all the events, even those completely unrelated to zdev/or site, and imports the unneeded envionment values to the udev-db. Instead of having an additional rule file, add this logic as part of the udev-rule of those devices which are configured with site-support. The logic will then be available on all those rules with the site-supported devices only. Signed-off-by: Vineeth Vijayan <vneethv@linux.ibm.com> Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com> Signed-off-by: Jan Höppner <hoeppner@linux.ibm.com>
152 lines
3.1 KiB
C
152 lines
3.1 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 <ctype.h>
|
|
#include <errno.h>
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include "lib/util_path.h"
|
|
#include "lib/util_udev.h"
|
|
|
|
#include "attrib.h"
|
|
#include "ccw.h"
|
|
#include "device.h"
|
|
#include "misc.h"
|
|
#include "path.h"
|
|
#include "setting.h"
|
|
#include "udev.h"
|
|
#include "zdev_id.h"
|
|
|
|
int udev_need_settle = 0;
|
|
int udev_no_settle;
|
|
|
|
/* Check if a udev file does not contain any statements. */
|
|
bool udev_file_is_empty(struct util_udev_file *file)
|
|
{
|
|
struct util_udev_line_node *l;
|
|
|
|
if (!file)
|
|
return true;
|
|
util_list_iterate(&file->lines, l) {
|
|
if (l->line[0])
|
|
return false;
|
|
}
|
|
|
|
return true;
|
|
}
|
|
|
|
static bool get_ids_cb(const char *filename, void *data)
|
|
{
|
|
char *prefix = data;
|
|
|
|
if (strncmp(filename, prefix, strlen(prefix)) != 0)
|
|
return false;
|
|
if (!ends_with(filename, UDEV_SUFFIX))
|
|
return false;
|
|
|
|
return true;
|
|
}
|
|
|
|
/* Add the IDs for all devices of the specified subtype name for which a
|
|
* udev rule exists to strlist LIST. */
|
|
void udev_get_device_ids(const char *type, struct util_list *list,
|
|
bool autoconf)
|
|
{
|
|
char *path, *prefix;
|
|
struct util_list *files;
|
|
struct strlist_node *s;
|
|
size_t plen, len;
|
|
|
|
prefix = misc_asprintf("%s-%s-", UDEV_PREFIX, type);
|
|
plen = strlen(prefix);
|
|
path = path_get_udev_rules(autoconf);
|
|
files = strlist_new();
|
|
if (!misc_read_dir(path, files, get_ids_cb, prefix))
|
|
goto out;
|
|
|
|
util_list_iterate(files, s) {
|
|
/* 41-dasd-eckd-0.0.1234.rules */
|
|
len = strlen(s->str);
|
|
s->str[len - sizeof(UDEV_SUFFIX) + 1] = 0;
|
|
strlist_add(list, &s->str[plen]);
|
|
}
|
|
|
|
out:
|
|
strlist_free(files);
|
|
free(path);
|
|
free(prefix);
|
|
}
|
|
|
|
/* Remove UDEV rule for device. */
|
|
exit_code_t udev_remove_rule(const char *type, const char *id, bool autoconf)
|
|
{
|
|
char *path;
|
|
exit_code_t rc = EXIT_OK;
|
|
|
|
path = path_get_udev_rule(type, id, autoconf);
|
|
if (util_path_is_reg_file(path))
|
|
rc = remove_file(path);
|
|
free(path);
|
|
|
|
return rc;
|
|
}
|
|
|
|
/* Wait for all current udev events to finish. */
|
|
void udev_settle(void)
|
|
{
|
|
if (udev_no_settle)
|
|
return;
|
|
misc_system(err_ignore, "%s settle", PATH_UDEVADM);
|
|
}
|
|
|
|
/* Extract internal attribute settings from @entry and add to @list.
|
|
* Associate corresponding attribute if found in @attribs. */
|
|
void udev_add_internal_from_entry(struct setting_list *list,
|
|
struct util_udev_entry_node *entry,
|
|
struct attrib **attribs)
|
|
{
|
|
char *copy, *name, *end, *u;
|
|
struct attrib *a;
|
|
|
|
/* ENV{zdev_var}="1" */
|
|
copy = misc_strdup(entry->key);
|
|
|
|
/* Find attribute name start. */
|
|
name = strchr(copy, '{');
|
|
end = strrchr(copy, '}');
|
|
if (!name || !end)
|
|
goto out;
|
|
*end = 0;
|
|
name++;
|
|
|
|
/* zdev_ => zdev: */
|
|
u = strchr(name, '_');
|
|
if (u)
|
|
*u = ':';
|
|
|
|
a = attrib_find(attribs, name);
|
|
setting_list_apply_actual(list, a, name, entry->value);
|
|
|
|
out:
|
|
free(copy);
|
|
}
|
|
|
|
bool is_legacy_rule(struct util_udev_file *file)
|
|
{
|
|
struct util_udev_line_node *line;
|
|
|
|
util_list_iterate(&file->lines, line)
|
|
if (starts_with(line->line, SITE_BLOCK_START))
|
|
return false;
|
|
|
|
return true;
|
|
}
|