From f32bff96881a04bb68b895c23b13ae50daa9e7b4 Mon Sep 17 00:00:00 2001 From: Peter Oberparleiter Date: Fri, 1 Sep 2017 11:05:53 +0200 Subject: [PATCH] zdev: Implement --no-settle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There are some situations where running "udevadm settle" can result in a deadlock, such as in the early stages of initial RAM-disk processing. Introduce a new command-line option --no-settle that can be used to suppress calling "udevadm settle" to allow chzdev to be run in such situations. Signed-off-by: Peter Oberparleiter Signed-off-by: Jan Höppner --- zdev/include/udev.h | 1 + zdev/man/chzdev.8 | 9 +++++++++ zdev/src/chzdev.c | 9 +++++++++ zdev/src/chzdev_usage.txt | 1 + zdev/src/udev.c | 3 +++ 5 files changed, 23 insertions(+) diff --git a/zdev/include/udev.h b/zdev/include/udev.h index 03e5b215..cfcb8407 100644 --- a/zdev/include/udev.h +++ b/zdev/include/udev.h @@ -14,6 +14,7 @@ #include "exit_code.h" extern int udev_need_settle; +extern int udev_no_settle; /* Single key-operator-value entry in a udev rule line.*/ struct udev_entry_node { diff --git a/zdev/man/chzdev.8 b/zdev/man/chzdev.8 index ae99600c..1c0e6bcd 100644 --- a/zdev/man/chzdev.8 +++ b/zdev/man/chzdev.8 @@ -528,6 +528,15 @@ device configuration persistent. Typically such steps include rebuilding the initial RAM disk, or modifying the kernel command line. .PP . +.OD no-settle "" "" +Do not wait for udev processing to complete. + +Skips all calls to the udevadm tool that are intended to wait for udev to +finish processing before continuing. There is typically no need to use this +option unless chzdev is run in an environment where udev is not fully +functional (such as in the early phase of an initial RAM disk). +.PP +. .OD persistent "p" "" Apply changes to persistent configuration only. diff --git a/zdev/src/chzdev.c b/zdev/src/chzdev.c index 561de66d..7c7e9f11 100644 --- a/zdev/src/chzdev.c +++ b/zdev/src/chzdev.c @@ -95,6 +95,7 @@ struct options { struct util_list *base; /* List of struct strlist_node */ unsigned int verbose:1; unsigned int quiet:1; + unsigned int no_settle:1; }; /* Makefile converts chzdev_usage.txt into C file which we include here. */ @@ -136,6 +137,7 @@ enum { OPT_VERSION = 'v', OPT_VERBOSE = 'V', OPT_QUIET = 'q', + OPT_NO_SETTLE = (OPT_ANONYMOUS_BASE+__COUNTER__), }; static struct opts_conflict conflict_list[] = { @@ -217,6 +219,7 @@ static const struct option opt_list[] = { { "base", required_argument, NULL, OPT_BASE }, { "verbose", no_argument, NULL, OPT_VERBOSE }, { "quiet", no_argument, NULL, OPT_QUIET }, + { "no-settle", no_argument, NULL, OPT_NO_SETTLE }, { NULL, no_argument, NULL, 0 }, }; @@ -937,6 +940,11 @@ static exit_code_t parse_options(struct options *opts, int argc, char *argv[]) opts->quiet = 1; break; + case OPT_NO_SETTLE: + /* --no-settle */ + opts->no_settle = 1; + break; + case ':': /* Missing option argument. */ syntax("Option '%s' requires an argument\n", @@ -2904,6 +2912,7 @@ int main(int argc, char *argv[]) force = opts.force; yes = opts.yes; dryrun = opts.dryrun; + udev_no_settle = opts.no_settle; path_set_base(opts.base); if (dryrun) diff --git a/zdev/src/chzdev_usage.txt b/zdev/src/chzdev_usage.txt index f05b9c8b..12d71a29 100644 --- a/zdev/src/chzdev_usage.txt +++ b/zdev/src/chzdev_usage.txt @@ -54,5 +54,6 @@ OPTIONS --no-root-update Skip root device update --dry-run Display changes without applying --base PATH Use PATH as base for accessing files + --no-settle Do not wait for udev to settle -V, --verbose Print additional run-time information -q, --quiet Print only minimal run-time information diff --git a/zdev/src/udev.c b/zdev/src/udev.c index b58717e6..8733ee45 100644 --- a/zdev/src/udev.c +++ b/zdev/src/udev.c @@ -24,6 +24,7 @@ #include "udev.h" 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, @@ -403,5 +404,7 @@ exit_code_t udev_remove_rule(const char *type, const char *id) /* 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); }