zdev: Implement --no-settle

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 <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:53 +02:00
committed by Jan Höppner
parent 7d355b0fec
commit f32bff9688
5 changed files with 23 additions and 0 deletions

View File

@@ -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 {

View File

@@ -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.

View File

@@ -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)

View File

@@ -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

View File

@@ -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);
}