zdev: Add support for handling auto-configuration data

Auto-configuration is the name of a new configuration target that is
supported by chzdev and lszdev besides the existing active and
persistent configuration targets. Directives created in this new
configuration are stored as udev rules in the /run/udev/rules.d
directory.

Auto-configuration directives are only in effect if there are no
directives for the same device in the user-provided persistent
configuration. This allows users to override auto-configuration
directives if necessary.

Due to the volatile nature of the /run directory, auto-configuration
directives are cleared on reboot. Therefore mechanisms that generate
auto-configuration directives must recreate them on every boot.

The lszdev tool displays auto-configuration data both in list view
as well as in detail view. Users can specify the new option --auto-conf
to only show data from this configuration target.

Mechanisms that generate automated configuration directives can use
chzdev together with the --auto-conf option to create the corresponding
udev rules.

Note: This change does not include a mechanism that generates
      auto-configuration directives.

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:
Peter Oberparleiter
2017-09-01 11:05:55 +02:00
committed by Jan Höppner
parent a86fb8b091
commit fe68ec513d
32 changed files with 911 additions and 286 deletions

View File

@@ -45,6 +45,7 @@ struct device_state {
* @node: Node for adding this device to a list
* @active: Device state in the active configuration
* @persistent: Device state in the persistent configuration
* @autoconf: Auto-configured device state
* @errors: A strlist of error and warning messages issued for the device
* @processed: Device has been processed
*/
@@ -59,6 +60,7 @@ struct device {
struct device_state active;
struct device_state persistent;
struct device_state autoconf;
unsigned int processed:1;
};
@@ -97,4 +99,6 @@ void device_list_print(struct device_list *, int);
struct setting_list *device_get_setting_list(struct device *dev,
config_t config);
config_t device_get_config(struct device *dev);
#endif /* DEVICE_H */

View File

@@ -19,9 +19,14 @@
#include "exit_code.h"
#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
#define SCOPE_ACTIVE(x) (((x) == config_active) || ((x) == config_all))
#define SCOPE_PERSISTENT(x) (((x) == config_persistent) || \
((x) == config_all))
#define SCOPE_ACTIVE(x) ((x) & config_active ? 1 : 0)
#define SCOPE_PERSISTENT(x) ((x) & config_persistent ? 1 : 0)
#define SCOPE_AUTOCONF(x) ((x) & config_autoconf ? 1 : 0)
#define SCOPE_ALL(x) ((x) == (config_active | config_persistent |\
config_autoconf))
#define SCOPE_SINGLE(x) ((x) == config_active || \
(x) == config_persistent || \
(x) == config_autoconf)
#define DELAY_INDENT 4
@@ -34,12 +39,15 @@
#define EVEN(x) (((x) & 1) == 0)
/* Enumeration of configuration sets. */
typedef enum {
config_active,
config_persistent,
config_all,
} config_t;
/* Enumeration of configuration sets. Multiple configuration sets can be
* combined using bit-wise or. */
enum {
config_active = 1,
config_persistent = 2,
config_autoconf = 4,
config_all = 7,
};
typedef int config_t;
typedef enum {
err_ignore,
@@ -167,7 +175,7 @@ exit_code_t misc_write_text_file(const char *, const char *, err_t);
exit_code_t misc_write_text_file_retry(const char *, const char *, err_t);
exit_code_t misc_mktemp(char **, int *);
char *misc_readlink(const char *path);
config_t get_config(int, int);
config_t get_config(int act, int pers, int ac);
bool is_zvm(void);
bool is_terminal(void);
const char *config_to_str(config_t);

View File

@@ -24,6 +24,7 @@
#define PATH_CCW_BUS "/sys/bus/ccw"
#define PATH_CCWGROUP_BUS "/sys/bus/ccwgroup"
#define PATH_UDEV_RULES "/etc/udev/rules.d"
#define PATH_UDEV_RULES_VOLATILE "/run/udev/rules.d"
#define PATH_PROC "/proc"
#define PATH_UDEVADM "udevadm"
@@ -55,8 +56,8 @@ char *path_get_ccw_device(const char *, const char *);
char *path_get_ccw_devices(const char *);
char *path_get_ccwgroup_device(const char *, const char *);
char *path_get_ccwgroup_devices(const char *);
char *path_get_udev_rule(const char *, const char *);
char *path_get_udev_rules(void);
char *path_get_udev_rule(const char *type, const char *id, bool vol);
char *path_get_udev_rules(bool vol);
char *path_get_proc(const char *);
char *path_get_sys_bus_dev(const char *, const char *);
char *path_get_sys_bus_drv(const char *, const char *);

View File

@@ -94,7 +94,8 @@ void setting_list_map_values(struct setting_list *);
void setting_list_mark_default_derived(struct setting_list *);
int setting_list_count_set(struct setting_list *);
void setting_list_remove_derived(struct setting_list *);
char *setting_get_changes(struct setting_list *, struct setting_list *);
char *setting_get_changes(struct setting_list *act, struct setting_list *pers,
struct setting_list *ac);
bool setting_match_value(struct setting *, const char *);
#endif /* SETTING_H */

View File

@@ -67,17 +67,22 @@ typedef exit_code_t (*subtype_cb_t)(struct subtype *st, const char *id,
*
* @exists_active: Check if device exists in active configuration
* @exists_persistent: Check if device exists in persistent configuration
* @exists_autoconf: Check if device exists in autoconf configuration
*
* @add_active_ids: Add IDs of all devices existing in active configuration to
* specified strlist
* @add_persistent_ids: Add IDs of all devices existing in persistent
* configuration to specified strlist
* @add_autoconf_ids: Add IDs of all devices existing in autoconf
* configuration to specified strlist
*
* @read_active: Read device configuration from active configuration
* @read_persistent: Read device configuration from persistent configuration
* @read_autoconf: Read device configuration from autoconf configuration
*
* @configure_active: Apply configuration to active configuration
* @configure_persistent: Apply configuration to persistent configuration
* @configure_autoconf: Apply configuration to autoconf configuration
*
* @check_pre_write: Optional: Determine if the given configuration is valid
* for the specified device. If not, emit warning messages
@@ -150,24 +155,33 @@ struct subtype {
bool (*exists_active)(struct subtype *, const char *);
bool (*exists_persistent)(struct subtype *, const char *);
bool (*exists_autoconf)(struct subtype *, const char *);
void (*add_active_ids)(struct subtype *, struct util_list *);
void (*add_persistent_ids)(struct subtype *,
struct util_list *);
void (*add_autoconf_ids)(struct subtype *,
struct util_list *);
exit_code_t (*read_active)(struct subtype *, struct device *,
read_scope_t);
exit_code_t (*read_persistent)(struct subtype *, struct device *,
read_scope_t);
exit_code_t (*read_autoconf)(struct subtype *, struct device *,
read_scope_t);
exit_code_t (*configure_active)(struct subtype *, struct device *);
exit_code_t (*configure_persistent)(struct subtype *,
struct device *);
exit_code_t (*configure_autoconf)(struct subtype *,
struct device *);
exit_code_t (*deconfigure_active)(struct subtype *,
struct device *);
exit_code_t (*deconfigure_persistent)(struct subtype *,
struct device *);
exit_code_t (*deconfigure_autoconf)(struct subtype *,
struct device *);
exit_code_t (*check_pre_configure)(struct subtype *,
struct device *, int, config_t);
@@ -217,23 +231,31 @@ void subtype_exit(struct subtype *);
bool subtype_device_exists_active(struct subtype *, const char *);
bool subtype_device_exists_persistent(struct subtype *, const char *);
bool subtype_device_exists_autoconf(struct subtype *st, const char *id);
void subtype_add_active_ids(struct subtype *, struct util_list *);
void subtype_add_persistent_ids(struct subtype *, struct util_list *);
void subtype_add_autoconf_ids(struct subtype *st, struct util_list *ids);
exit_code_t subtype_device_read_active(struct subtype *, struct device *,
read_scope_t);
exit_code_t subtype_device_read_persistent(struct subtype *, struct device *,
read_scope_t);
exit_code_t subtype_device_read_autoconf(struct subtype *st, struct device *dev,
read_scope_t scope);
exit_code_t subtype_device_configure_active(struct subtype *, struct device *);
exit_code_t subtype_device_configure_persistent(struct subtype *,
struct device *);
exit_code_t subtype_device_configure_autoconf(struct subtype *st,
struct device *dev);
exit_code_t subtype_device_deconfigure_active(struct subtype *,
struct device *);
exit_code_t subtype_device_deconfigure_persistent(struct subtype *st,
struct device *);
exit_code_t subtype_device_deconfigure_autoconf(struct subtype *st,
struct device *dev);
exit_code_t subtype_check_pre_configure(struct subtype *, struct device *, int,
config_t);

View File

@@ -40,8 +40,9 @@ exit_code_t udev_read_file(const char *, struct udev_file **);
void udev_free_file(struct udev_file *);
void udev_file_print(struct udev_file *);
void udev_get_device_ids(const char *, struct util_list *);
exit_code_t udev_remove_rule(const char *, const char *);
void udev_get_device_ids(const char *type, struct util_list *list,
bool autoconf);
exit_code_t udev_remove_rule(const char *type, const char *id, bool autoconf);
void udev_settle(void);

View File

@@ -15,9 +15,9 @@
struct device;
bool udev_ccw_exists(const char *, const char *);
exit_code_t udev_ccw_read_device(struct device *);
exit_code_t udev_ccw_write_device(struct device *);
exit_code_t udev_ccw_write_cio_ignore(const char *);
bool udev_ccw_exists(const char *type, const char *id, bool autoconf);
exit_code_t udev_ccw_read_device(struct device *dev, bool autoconf);
exit_code_t udev_ccw_write_device(struct device *dev, bool autoconf);
exit_code_t udev_ccw_write_cio_ignore(const char *id_list, bool autoconf);
#endif /* UDEV_CCW_H */

View File

@@ -16,10 +16,12 @@
struct device;
struct util_list;
bool udev_ccwgroup_exists(const char *, const char *);
exit_code_t udev_ccwgroup_read_device(struct device *);
exit_code_t udev_ccwgroup_write_device(struct device *);
void udev_ccwgroup_add_device_ids(const char *, struct util_list *);
exit_code_t udev_ccwgroup_remove_rule(const char *, const char *);
bool udev_ccwgroup_exists(const char *type, const char *id, bool autoconf);
exit_code_t udev_ccwgroup_read_device(struct device *dev, bool autoconf);
exit_code_t udev_ccwgroup_write_device(struct device *dev, bool autoconf);
void udev_ccwgroup_add_device_ids(const char *type, struct util_list *list,
bool autoconf);
exit_code_t udev_ccwgroup_remove_rule(const char *type, const char *id,
bool autoconf);
#endif /* UDEV_CCWGROUP_H */

View File

@@ -15,10 +15,10 @@
struct device;
void udev_zfcp_lun_add_device_ids(struct util_list *);
bool udev_zfcp_lun_exists(const char *);
exit_code_t udev_zfcp_lun_read_device(struct device *);
exit_code_t udev_zfcp_lun_write_device(struct device *);
exit_code_t udev_zfcp_lun_remove_rule(const char *);
void udev_zfcp_lun_add_device_ids(struct util_list *list, bool autoconf);
bool udev_zfcp_lun_exists(const char *id, bool autoconf);
exit_code_t udev_zfcp_lun_read_device(struct device *dev, bool autoconf);
exit_code_t udev_zfcp_lun_write_device(struct device *dev, bool autoconf);
exit_code_t udev_zfcp_lun_remove_rule(const char *id, bool autoconf);
#endif /* UDEV_ZFCP_LUN_H */