Subject: [PATCH] [FEAT VS1822] libutil: Introduce util_udev
From: Matthew Rosato <mjrosato@linux.ibm.com>

Summary:     ap_tools: add ap-check and the ap device type to zdev   
Description: This feature adds multiple components in support of persistent
             configuration of vfio-ap mediated devices.

             The ap-check utility is added as a callout function for the
             mdevctl utility.  This allows for meaningful error messages to be
             presented to end-users when vfio-ap configuration errors are
             detected while using mdevctl to create/modify vfio-ap mediated
             devices.

             Additionally, the 'ap' device type is added to zdev, providing a
             command-line interface for managing the apmask and aqmask, which
             determine what AP resources are available for vfio-ap usage.
             'chzdev' is updated to allow for modifying the active masks as
             well as to specify persistent mask values via a udev rule.
             'lszdev' is updated to allow for querying of the active and
             persistent mask values.
Upstream-ID: 6f7982dae5499e9bf90ad80479f8303d85a6f157
Problem-ID:  VS1822

Upstream-Description:

             libutil: Introduce util_udev

             Move code to read udev files from zdev into a utility library for use by
             other tools.

             Acked-by: Jan Hoeppner <hoeppner@linux.ibm.com>
             Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
             Reviewed-by: Tony Krowiak <akrowiak@linux.ibm.com>
             Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com>
             Signed-off-by: Jan Hoeppner <hoeppner@linux.ibm.com>


Signed-off-by: Matthew Rosato <mjrosato@linux.ibm.com>
---
 include/lib/util_udev.h  |   44 +++++
 libutil/util_udev.c      |  362 +++++++++++++++++++++++++++++++++++++++++++++++
 zdev/include/udev.h      |   29 ---
 zdev/src/udev.c          |  327 ------------------------------------------
 zdev/src/udev_ccw.c      |   15 +
 zdev/src/udev_ccwgroup.c |   21 +-
 zdev/src/udev_zfcp_lun.c |   21 +-
 7 files changed, 443 insertions(+), 376 deletions(-)

--- /dev/null
+++ b/include/lib/util_udev.h
@@ -0,0 +1,44 @@
+/*
+ * @defgroup util_udev_h  util_udev: UDEV interface
+ * @{
+ * @brief Work with UDEV files
+ *
+ * Copyright IBM Corp. 2022
+ *
+ * s390-tools is free software; you can redistribute it and/or modify
+ * it under the terms of the MIT license. See LICENSE for details.
+ */
+
+#ifndef LIB_UTIL_UDEV_H
+#define LIB_UTIL_UDEV_H
+
+#include <stdbool.h>
+#include "lib/util_exit_code.h"
+#include "lib/util_list.h"
+
+/* Single key-operator-value entry in a udev rule line.*/
+struct util_udev_entry_node {
+	struct util_list_node node;
+	char *key;
+	char *op;
+	char *value;
+};
+
+/* Single udev line in a udev rule file. */
+struct util_udev_line_node {
+	struct util_list_node node;
+	struct util_list entries;
+	char *line;
+};
+
+/* Udev rule file. */
+struct util_udev_file {
+	struct util_list lines;
+};
+
+util_exit_code_t util_udev_read_file(const char *path,
+				     struct util_udev_file **file_ptr);
+void util_udev_free_file(struct util_udev_file *file);
+void util_udev_file_print(struct util_udev_file *file);
+
+#endif /** LIB_UTIL_UDEV_H @} */
--- /dev/null
+++ b/libutil/util_udev.c
@@ -0,0 +1,362 @@
+/*
+ * util - Utility function library
+ *
+ * UDEV helper functions
+ *
+ * Copyright IBM Corp. 2022
+ *
+ * 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 <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "lib/util_exit_code.h"
+#include "lib/util_file.h"
+#include "lib/util_libc.h"
+#include "lib/util_list.h"
+#include "lib/util_path.h"
+#include "lib/util_udev.h"
+
+/* Create a newly allocated udev entry. */
+static struct util_udev_entry_node *util_udev_entry_node_new(const char *key,
+							     const char *op,
+							     const char *value)
+{
+	struct util_udev_entry_node *entry;
+
+	entry = util_zalloc(sizeof(struct util_udev_entry_node));
+	entry->key = util_strdup(key);
+	entry->op = util_strdup(op);
+	entry->value = util_strdup(value);
+
+	return entry;
+}
+
+/* Release resources associated with udev entry. */
+static void util_udev_entry_node_free(struct util_udev_entry_node *entry)
+{
+	if (!entry)
+		return;
+	free(entry->key);
+	free(entry->op);
+	free(entry->value);
+	free(entry);
+}
+
+/* Create a newly allocated udev line. */
+static struct util_udev_line_node *util_udev_line_node_new(void)
+{
+	struct util_udev_line_node *line;
+
+	line = util_zalloc(sizeof(struct util_udev_line_node));
+	util_list_init(&line->entries, struct util_udev_entry_node, node);
+
+	return line;
+}
+
+/* Release resources associated with udev line. */
+static void util_udev_line_node_free(struct util_udev_line_node *line)
+{
+	struct util_udev_entry_node *e, *n;
+
+	if (!line)
+		return;
+	util_list_iterate_safe(&line->entries, e, n) {
+		util_list_remove(&line->entries, e);
+		util_udev_entry_node_free(e);
+	}
+	free(line->line);
+	free(line);
+}
+
+/* Create a newly allocated udev file. */
+static struct util_udev_file *util_udev_file_new(void)
+{
+	struct util_udev_file *file;
+
+	file = util_zalloc(sizeof(struct util_udev_file));
+	util_list_init(&file->lines, struct util_udev_line_node, node);
+
+	return file;
+}
+
+/**
+ * Release resources associated with udev file.
+ *
+ * @param[in, out] file       Udev file structure to be freed
+ */
+void util_udev_free_file(struct util_udev_file *file)
+{
+	struct util_udev_line_node *l, *n;
+
+	if (!file)
+		return;
+	util_list_iterate_safe(&file->lines, l, n) {
+		util_list_remove(&file->lines, l);
+		util_udev_line_node_free(l);
+	}
+	free(file);
+}
+
+/**
+ * Print the contents of a udev file to stdout. Used for debugging.
+ *
+ * @param[in]      file       Udev file structure to print
+ */
+void util_udev_file_print(struct util_udev_file *file)
+{
+	struct util_udev_line_node *l;
+	struct util_udev_entry_node *e;
+
+	printf("util_udev_file at %p\n", (void *) file);
+	if (!file)
+		return;
+	util_list_iterate(&file->lines, l) {
+		printf("  util_udev_line_node at %p\n", (void *) l);
+		printf("    line='%s'\n", l->line);
+		util_list_iterate(&l->entries, e) {
+			printf("    util_udev_entry at %p\n", (void *) e);
+			printf("      '%s' '%s' '%s'\n", e->key, e->op,
+			       e->value);
+		}
+	}
+}
+
+static void skip_whitespace(const char **s_ptr)
+{
+	const char *s = *s_ptr;
+
+	while (*s && isspace(*s))
+		s++;
+
+	*s_ptr = s;
+}
+
+static char *parse_key(const char **s_ptr)
+{
+	const char *s, *e;
+	char *key;
+
+	s = *s_ptr;
+	/* Parse \w+(\{[^\}]*\})? */
+	e = s;
+	while (*e && (isalnum(*e) || *e == '_'))
+		e++;
+	if (*e == '{') {
+		while (*e && *e != '}')
+			e++;
+		if (*e == '}')
+			e++;
+	}
+
+	if (e == s)
+		return NULL;
+
+	/* s points to key start, e to character after key end. */
+	key = util_zalloc(e - s + 1);
+	memcpy(key, s, e - s);
+
+	*s_ptr = e;
+
+	return key;
+}
+
+static char *parse_op(const char **s_ptr)
+{
+	const char *ops[] = { "==", "!=", "=", "+=", ":=", NULL };
+	const char *entry;
+	size_t len;
+	int i;
+
+	entry = *s_ptr;
+	for (i = 0; ops[i]; i++) {
+		len = strlen(ops[i]);
+		if (strncmp(entry, ops[i], len) == 0) {
+			*s_ptr += len;
+			return util_strdup(ops[i]);
+		}
+	}
+
+	return NULL;
+}
+
+static char *parse_value(const char **s_ptr)
+{
+	const char *s, *e;
+	char *value;
+
+	/* Parse: ^\s*(.*)\s*$ */
+	s = *s_ptr;
+	skip_whitespace(&s);
+	e = s;
+	while (*e)
+		e++;
+	e--;
+	while (e > s && isspace(*e))
+		e--;
+	e++;
+
+	*s_ptr = e;
+
+	/* Remove quotes. */
+	if ((*s == '"' && *(e - 1) == '"') ||
+	    (*s == '\'' && *(e - 1) == '\'')) {
+		s++;
+		e--;
+	}
+
+	/* s points to value start, e to character after value end. */
+	value = util_zalloc(e - s + 1);
+	memcpy(value, s, e - s);
+
+	return value;
+}
+
+static bool parse_util_udev_entry(struct util_udev_line_node *line,
+				  const char *entry)
+{
+	char *key = NULL, *op = NULL, *value = NULL;
+	struct util_udev_entry_node *e;
+	bool rc = false;
+
+	/* Parse: ^\s*(\w+)\s*(==|!=|=|\+=|:=)\s*"?([^"]*)"\s*$ */
+
+	/* Parse key. */
+	skip_whitespace(&entry);
+	key = parse_key(&entry);
+	if (!key)
+		goto out;
+
+	/* Parse operator. */
+	skip_whitespace(&entry);
+	op = parse_op(&entry);
+	if (!op)
+		goto out;
+
+	/* Parse value. */
+	skip_whitespace(&entry);
+	value = parse_value(&entry);
+	if (!value)
+		goto out;
+	skip_whitespace(&entry);
+
+	/* Check for unrecognized characters at end of entry. */
+	if (*entry != 0)
+		goto out;
+
+	/* Add entry to list. */
+	e = util_udev_entry_node_new(key, op, value);
+	util_list_add_tail(&line->entries, e);
+	rc = true;
+
+out:
+	free(key);
+	free(op);
+	free(value);
+
+	return rc;
+}
+
+static void replace_unquoted(char *s, char from, char to)
+{
+	char quoted = 0;
+
+	for (; *s; s++) {
+		if (quoted) {
+			/* Skip until quote end is found. */
+			if (*s == quoted)
+				quoted = 0;
+			continue;
+		}
+		if (*s == '"' || *s == '\'') {
+			quoted = *s;
+			continue;
+		}
+		if (*s == from)
+			*s = to;
+	}
+}
+
+static bool parse_util_udev_line(struct util_udev_file *file, const char *line)
+{
+	char *copy, *curr, *next;
+	struct util_udev_line_node *l;
+	int i;
+	bool result = true;
+
+	l = util_udev_line_node_new();
+	l->line = util_strdup(line);
+
+	/* Check for empty lines and comment lines. */
+	for (i = 0; line[i] && isspace(line[i]); i++);
+	if (line[i] == 0 || line[i] == '#')
+		goto ok;
+
+	/* Parse each comma-separated entry. */
+	copy = util_strdup(line);
+
+	/* A hack to differentiate between quoted and unquoted commas. */
+	replace_unquoted(copy, ',', 1);
+
+	next = copy;
+	while ((curr = strsep(&next, "\1"))) {
+		if (!parse_util_udev_entry(l, curr)) {
+			result = false;
+			break;
+		}
+	}
+	free(copy);
+
+ok:
+	if (result)
+		util_list_add_tail(&file->lines, l);
+	else
+		util_udev_line_node_free(l);
+
+	return result;
+}
+
+/**
+ * Create a new util_udev_file structure and read the contents of a specified
+ * udev file into that structure.
+ *
+ * @param[in]      path       Path to the udev file that will be read in
+ * @param[in, out] file_ptr   A buffer to store resulting udev file structure
+ *
+ * @retval         0                       Udev file read successfully
+ * @retval         UTIL_EXIT_RUNTIME_ERROR Error reading the udev file
+ */
+util_exit_code_t util_udev_read_file(const char *path,
+				     struct util_udev_file **file_ptr)
+{
+	char *text, *curr, *next;
+	struct util_udev_file *file;
+	int once = 0;
+
+	text = util_file_read_text_file(path, 0);
+	if (!text)
+		return UTIL_EXIT_RUNTIME_ERROR;
+	file = util_udev_file_new();
+
+	/* Iterate over each line. */
+	next = text;
+	while ((curr = strsep(&next, "\n"))) {
+		if (parse_util_udev_line(file, curr))
+			continue;
+		if (!once) {
+			once = 1;
+			fprintf(stderr, "Unrecognized udev rule in %s:\n",
+				path);
+		}
+		fprintf(stderr, "%s\n", curr);
+	}
+
+	free(text);
+	*file_ptr = file;
+
+	return UTIL_EXIT_OK;
+}
--- a/zdev/include/udev.h
+++ b/zdev/include/udev.h
@@ -11,7 +11,7 @@
 #define UDEV_H
 
 #include "lib/util_list.h"
-#include "exit_code.h"
+#include "lib/util_udev.h"
 
 struct attrib;
 struct setting_list;
@@ -19,30 +19,7 @@ struct setting_list;
 extern int udev_need_settle;
 extern int udev_no_settle;
 
-/* Single key-operator-value entry in a udev rule line.*/
-struct udev_entry_node {
-	struct util_list_node node;
-	char *key;
-	char *op;
-	char *value;
-};
-
-/* Single udev line in a udev rule file. */
-struct udev_line_node {
-	struct util_list_node node;
-	struct util_list entries;
-	char *line;
-};
-
-/* Udev rule file. */
-struct udev_file {
-	struct util_list lines;
-};
-
-exit_code_t udev_read_file(const char *, struct udev_file **);
-bool udev_file_is_empty(struct udev_file *file);
-void udev_free_file(struct udev_file *);
-void udev_file_print(struct udev_file *);
+bool udev_file_is_empty(struct util_udev_file *file);
 
 void udev_get_device_ids(const char *type, struct util_list *list,
 			 bool autoconf);
@@ -51,7 +28,7 @@ exit_code_t udev_remove_rule(const char
 void udev_settle(void);
 
 void udev_add_internal_from_entry(struct setting_list *list,
-				  struct udev_entry_node *entry,
+				  struct util_udev_entry_node *entry,
 				  struct attrib **attribs);
 
 #endif /* UDEV_H */
--- a/zdev/src/udev.c
+++ b/zdev/src/udev.c
@@ -14,6 +14,7 @@
 #include <string.h>
 
 #include "lib/util_path.h"
+#include "lib/util_udev.h"
 
 #include "attrib.h"
 #include "ccw.h"
@@ -26,330 +27,10 @@
 int udev_need_settle = 0;
 int udev_no_settle;
 
-/* Create a newly allocated udev entry. */
-static struct udev_entry_node *udev_entry_node_new(const char *key,
-						   const char *op,
-						   const char *value)
-{
-	struct udev_entry_node *entry;
-
-	entry = misc_malloc(sizeof(struct udev_entry_node));
-	entry->key = misc_strdup(key);
-	entry->op = misc_strdup(op);
-	entry->value = misc_strdup(value);
-
-	return entry;
-}
-
-/* Release resources associated with udev entry. */
-static void udev_entry_node_free(struct udev_entry_node *entry)
-{
-	if (!entry)
-		return;
-	free(entry->key);
-	free(entry->op);
-	free(entry->value);
-	free(entry);
-}
-
-/* Create a newly allocated udev line. */
-static struct udev_line_node *udev_line_node_new(void)
-{
-	struct udev_line_node *line;
-
-	line = misc_malloc(sizeof(struct udev_line_node));
-	util_list_init(&line->entries, struct udev_entry_node, node);
-
-	return line;
-}
-
-/* Release resources associated with udev line. */
-static void udev_line_node_free(struct udev_line_node *line)
-{
-	struct udev_entry_node *e, *n;
-
-	if (!line)
-		return;
-	util_list_iterate_safe(&line->entries, e, n) {
-		util_list_remove(&line->entries, e);
-		udev_entry_node_free(e);
-	}
-	free(line->line);
-	free(line);
-}
-
-/* Create a newly allocated udev file. */
-static struct udev_file *udev_file_new(void)
-{
-	struct udev_file *file;
-
-	file = misc_malloc(sizeof(struct udev_file));
-	util_list_init(&file->lines, struct udev_line_node, node);
-
-	return file;
-}
-
-/* Release resources associated with udev file. */
-void udev_free_file(struct udev_file *file)
-{
-	struct udev_line_node *l, *n;
-
-	if (!file)
-		return;
-	util_list_iterate_safe(&file->lines, l, n) {
-		util_list_remove(&file->lines, l);
-		udev_line_node_free(l);
-	}
-	free(file);
-}
-
-/* Used for debugging. */
-void udev_file_print(struct udev_file *file)
-{
-	struct udev_line_node *l;
-	struct udev_entry_node *e;
-
-	printf("udev_file at %p\n", (void *) file);
-	if (!file)
-		return;
-	util_list_iterate(&file->lines, l) {
-		printf("  udev_line_node at %p\n", (void *) l);
-		printf("    line='%s'\n", l->line);
-		util_list_iterate(&l->entries, e) {
-			printf("    udev_entry at %p\n", (void *) e);
-			printf("      '%s' '%s' '%s'\n", e->key, e->op,
-			       e->value);
-		}
-	}
-}
-
-static void skip_whitespace(const char **s_ptr)
-{
-	const char *s = *s_ptr;
-
-	while (*s && isspace(*s))
-		s++;
-
-	*s_ptr = s;
-}
-
-static char *parse_key(const char **s_ptr)
-{
-	const char *s, *e;
-	char *key;
-
-	s = *s_ptr;
-	/* Parse \w+(\{[^\}]*\})? */
-	e = s;
-	while (*e && (isalnum(*e) || *e == '_'))
-		e++;
-	if (*e == '{') {
-		while (*e && *e != '}')
-			e++;
-		if (*e == '}')
-			e++;
-	}
-
-	if (e == s)
-		return NULL;
-
-	/* s points to key start, e to character after key end. */
-	key = misc_malloc(e - s + 1);
-	memcpy(key, s, e - s);
-
-	*s_ptr = e;
-
-	return key;
-}
-
-static char *parse_op(const char **s_ptr)
-{
-	const char *ops[] = { "==", "!=", "=", "+=", ":=", NULL };
-	const char *entry;
-	size_t len;
-	int i;
-
-	entry = *s_ptr;
-	for (i = 0; ops[i]; i++) {
-		len = strlen(ops[i]);
-		if (strncmp(entry, ops[i], len) == 0) {
-			*s_ptr += len;
-			return misc_strdup(ops[i]);
-		}
-	}
-
-	return NULL;
-}
-
-static char *parse_value(const char **s_ptr)
-{
-	const char *s, *e;
-	char *value;
-
-	/* Parse: ^\s*(.*)\s*$ */
-	s = *s_ptr;
-	skip_whitespace(&s);
-	e = s;
-	while (*e)
-		e++;
-	e--;
-	while (e > s && isspace(*e))
-		e--;
-	e++;
-
-	*s_ptr = e;
-
-	/* Remove quotes. */
-	if ((*s == '"' && *(e - 1) == '"') ||
-	    (*s == '\'' && *(e - 1) == '\'')) {
-		s++;
-		e--;
-	}
-
-	/* s points to value start, e to character after value end. */
-	value = misc_malloc(e - s + 1);
-	memcpy(value, s, e - s);
-
-	return value;
-}
-
-static bool parse_udev_entry(struct udev_line_node *line, const char *entry)
-{
-	char *key = NULL, *op = NULL, *value = NULL;
-	struct udev_entry_node *e;
-	bool rc = false;
-
-	/* Parse: ^\s*(\w+)\s*(==|!=|=|\+=|:=)\s*"?([^"]*)"\s*$ */
-
-	/* Parse key. */
-	skip_whitespace(&entry);
-	key = parse_key(&entry);
-	if (!key)
-		goto out;
-
-	/* Parse operator. */
-	skip_whitespace(&entry);
-	op = parse_op(&entry);
-	if (!op)
-		goto out;
-
-	/* Parse value. */
-	skip_whitespace(&entry);
-	value = parse_value(&entry);
-	if (!value)
-		goto out;
-	skip_whitespace(&entry);
-
-	/* Check for unrecognized characters at end of entry. */
-	if (*entry != 0)
-		goto out;
-
-	/* Add entry to list. */
-	e = udev_entry_node_new(key, op, value);
-	util_list_add_tail(&line->entries, e);
-	rc = true;
-
-out:
-	free(key);
-	free(op);
-	free(value);
-
-	return rc;
-}
-
-static void replace_unquoted(char *s, char from, char to)
-{
-	char quoted = 0;
-
-	for (; *s; s++) {
-		if (quoted) {
-			/* Skip until quote end is found. */
-			if (*s == quoted)
-				quoted = 0;
-			continue;
-		}
-		if (*s == '"' || *s == '\'') {
-			quoted = *s;
-			continue;
-		}
-		if (*s == from)
-			*s = to;
-	}
-}
-
-static bool parse_udev_line(struct udev_file *file, const char *line)
-{
-	char *copy, *curr, *next;
-	struct udev_line_node *l;
-	int i;
-	bool result = true;
-
-	l = udev_line_node_new();
-	l->line = misc_strdup(line);
-
-	/* Check for empty lines and comment lines. */
-	for (i = 0; line[i] && isspace(line[i]); i++);
-	if (line[i] == 0 || line[i] == '#')
-		goto ok;
-
-	/* Parse each comma-separated entry. */
-	copy = misc_strdup(line);
-
-	/* A hack to differentiate between quoted and unquoted commas. */
-	replace_unquoted(copy, ',', 1);
-
-	next = copy;
-	while ((curr = strsep(&next, "\1"))) {
-		if (!parse_udev_entry(l, curr)) {
-			result = false;
-			break;
-		}
-	}
-	free(copy);
-
-ok:
-	if (result)
-		util_list_add_tail(&file->lines, l);
-	else
-		udev_line_node_free(l);
-
-	return result;
-}
-
-/* Read the contents of a udev rule file. */
-exit_code_t udev_read_file(const char *path, struct udev_file **file_ptr)
-{
-	char *text, *curr, *next;
-	struct udev_file *file;
-	int once = 0;
-
-	text = misc_read_text_file(path, 0, err_print);
-	if (!text)
-		return EXIT_RUNTIME_ERROR;
-	file = udev_file_new();
-
-	/* Iterate over each line. */
-	next = text;
-	while ((curr = strsep(&next, "\n"))) {
-		if (parse_udev_line(file, curr))
-			continue;
-		if (!once) {
-			once = 1;
-			verb("Unrecognized udev rule format in %s:\n", path);
-		}
-		verb("%s\n", curr);
-	}
-
-	free(text);
-	*file_ptr = file;
-
-	return EXIT_OK;
-}
-
 /* Check if a udev file does not contain any statements. */
-bool udev_file_is_empty(struct udev_file *file)
+bool udev_file_is_empty(struct util_udev_file *file)
 {
-	struct udev_line_node *l;
+	struct util_udev_line_node *l;
 
 	if (!file)
 		return true;
@@ -428,7 +109,7 @@ void udev_settle(void)
 /* 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 udev_entry_node *entry,
+				  struct util_udev_entry_node *entry,
 				  struct attrib **attribs)
 {
 	char *copy, *name, *end, *u;
--- a/zdev/src/udev_ccw.c
+++ b/zdev/src/udev_ccw.c
@@ -14,6 +14,7 @@
 #include <string.h>
 
 #include "lib/util_path.h"
+#include "lib/util_udev.h"
 
 #include "attrib.h"
 #include "ccw.h"
@@ -44,7 +45,7 @@ bool udev_ccw_exists(const char *type, c
 }
 
 static void add_setting_from_entry(struct setting_list *list,
-				   struct udev_entry_node *entry,
+				   struct util_udev_entry_node *entry,
 				   struct attrib **attribs)
 {
 	char *copy, *name, *end;
@@ -79,12 +80,12 @@ out:
 }
 
 /* Extract CCW device settings from a CCW device udev rule file. */
-static void udev_file_get_settings(struct udev_file *file,
+static void udev_file_get_settings(struct util_udev_file *file,
 				   struct attrib **attribs,
 				   struct setting_list *list)
 {
-	struct udev_line_node *line;
-	struct udev_entry_node *entry;
+	struct util_udev_line_node *line;
+	struct util_udev_entry_node *entry;
 
 	util_list_iterate(&file->lines, line) {
 		entry = util_list_start(&line->entries);
@@ -100,12 +101,12 @@ exit_code_t udev_ccw_read_device(struct
 	struct subtype *st = dev->subtype;
 	struct device_state *state = autoconf ? &dev->autoconf :
 						&dev->persistent;
-	struct udev_file *file = NULL;
+	struct util_udev_file *file = NULL;
 	exit_code_t rc;
 	char *path;
 
 	path = path_get_udev_rule(st->name, dev->id, autoconf);
-	rc = udev_read_file(path, &file);
+	rc = (exit_code_t) util_udev_read_file(path, &file);
 	if (rc)
 		goto out;
 	if (udev_file_is_empty(file)) {
@@ -115,7 +116,7 @@ exit_code_t udev_ccw_read_device(struct
 		udev_file_get_settings(file, st->dev_attribs, state->settings);
 		state->exists = 1;
 	}
-	udev_free_file(file);
+	util_udev_free_file(file);
 
 out:
 	free(path);
--- a/zdev/src/udev_ccwgroup.c
+++ b/zdev/src/udev_ccwgroup.c
@@ -14,6 +14,7 @@
 #include <string.h>
 
 #include "lib/util_path.h"
+#include "lib/util_udev.h"
 
 #include "attrib.h"
 #include "ccwgroup.h"
@@ -63,7 +64,7 @@ bool udev_ccwgroup_exists(const char *ty
 }
 
 static void add_setting_from_entry(struct setting_list *list,
-				   struct udev_entry_node *entry,
+				   struct util_udev_entry_node *entry,
 				   struct attrib **attribs)
 {
 	char *copy, *name, *end;
@@ -98,12 +99,12 @@ out:
 }
 
 /* Extract CCWGROUP device settings from a CCWGROUP device udev rule file. */
-static void udev_file_get_settings(struct udev_file *file,
+static void udev_file_get_settings(struct util_udev_file *file,
 				   struct attrib **attribs,
 				   struct setting_list *list)
 {
-	struct udev_line_node *line;
-	struct udev_entry_node *entry;
+	struct util_udev_line_node *line;
+	struct util_udev_entry_node *entry;
 
 	util_list_iterate(&file->lines, line) {
 		entry = util_list_start(&line->entries);
@@ -114,12 +115,12 @@ static void udev_file_get_settings(struc
 }
 
 /* Determine full CCWGROUP from data in udev rule file. */
-static void expand_id(struct device *dev, struct udev_file *file)
+static void expand_id(struct device *dev, struct util_udev_file *file)
 {
 	struct ccwgroup_devid devid;
 	struct ccwgroup_devid *devid_ptr = dev->devid;
-	struct udev_line_node *line;
-	struct udev_entry_node *entry;
+	struct util_udev_line_node *line;
+	struct util_udev_entry_node *entry;
 	char *id;
 	int i;
 
@@ -155,12 +156,12 @@ exit_code_t udev_ccwgroup_read_device(st
 	struct subtype *st = dev->subtype;
 	struct device_state *state = autoconf ? &dev->autoconf :
 						&dev->persistent;
-	struct udev_file *file = NULL;
+	struct util_udev_file *file = NULL;
 	exit_code_t rc;
 	char *path;
 
 	path = get_rule_path_by_devid(st->name, dev->devid, autoconf);
-	rc = udev_read_file(path, &file);
+	rc = (exit_code_t) util_udev_read_file(path, &file);
 	if (rc)
 		goto out;
 	if (udev_file_is_empty(file)) {
@@ -171,7 +172,7 @@ exit_code_t udev_ccwgroup_read_device(st
 		expand_id(dev, file);
 		state->exists = 1;
 	}
-	udev_free_file(file);
+	util_udev_free_file(file);
 
 out:
 	free(path);
--- a/zdev/src/udev_zfcp_lun.c
+++ b/zdev/src/udev_zfcp_lun.c
@@ -15,6 +15,7 @@
 #include <string.h>
 
 #include "lib/util_path.h"
+#include "lib/util_udev.h"
 
 #include "attrib.h"
 #include "device.h"
@@ -126,7 +127,7 @@ void zfcp_lun_node_list_print(struct uti
 }
 
 static bool zfcp_lun_devid_from_entry(struct zfcp_lun_devid *id_ptr,
-				      struct udev_entry_node *entry)
+				      struct util_udev_entry_node *entry)
 {
 	struct zfcp_lun_devid id;
 	char *copy = NULL, *s, *e, *u;
@@ -214,7 +215,7 @@ out:
 }
 
 static struct zfcp_lun_node *zfcp_lun_node_from_entry(
-					struct udev_entry_node *entry,
+					struct util_udev_entry_node *entry,
 					struct zfcp_lun_node *old,
 					struct util_list *list)
 {
@@ -234,7 +235,7 @@ static struct zfcp_lun_node *zfcp_lun_no
 	return node;
 }
 
-static void add_internal_setting_from_entry(struct udev_entry_node *entry,
+static void add_internal_setting_from_entry(struct util_udev_entry_node *entry,
 					    struct zfcp_lun_node *node)
 {
 	char *copy, *name, *end, *u;
@@ -263,7 +264,7 @@ out:
 	free(copy);
 }
 
-static void add_fc_setting_from_entry(struct udev_entry_node *entry,
+static void add_fc_setting_from_entry(struct util_udev_entry_node *entry,
 				      struct zfcp_lun_node *node)
 {
 	char *copy, *s, *e;
@@ -294,7 +295,7 @@ out:
 	free(copy);
 }
 
-static void add_scsi_setting_from_entry(struct udev_entry_node *entry,
+static void add_scsi_setting_from_entry(struct util_udev_entry_node *entry,
 					struct zfcp_lun_node *node)
 {
 	char *copy, *s, *e;
@@ -336,9 +337,9 @@ static exit_code_t udev_read_zfcp_lun_ru
 					   struct util_list *list)
 {
 	exit_code_t rc;
-	struct udev_file *file = NULL;
-	struct udev_line_node *line;
-	struct udev_entry_node *entry;
+	struct util_udev_file *file = NULL;
+	struct util_udev_line_node *line;
+	struct util_udev_entry_node *entry;
 	struct zfcp_lun_node *node = NULL;
 	enum {
 		none,
@@ -347,7 +348,7 @@ static exit_code_t udev_read_zfcp_lun_ru
 	} state = none;
 	bool empty_rule = true;
 
-	rc = udev_read_file(filename, &file);
+	rc = (exit_code_t) util_udev_read_file(filename, &file);
 	if (rc)
 		goto out;
 
@@ -398,7 +399,7 @@ static exit_code_t udev_read_zfcp_lun_ru
 	sort_zfcp_lun_list(list);
 
 out:
-	udev_free_file(file);
+	util_udev_free_file(file);
 
 	if (empty_rule)
 		warn_once("Warning: Invalid udev rule: %s\n", filename);
