move rules dirs to udev context; replace inotify with time-controlled stat()
This commit is contained in:
parent
d1aacc0fa9
commit
4f1795cca7
3
NEWS
3
NEWS
|
@ -1,5 +1,8 @@
|
|||
udev 175
|
||||
========
|
||||
A writable /run directory (tmpfs) is required now for a fully functional
|
||||
udev.
|
||||
|
||||
The default 'configure' install locations have changed. Packages for systems
|
||||
with the historic / vs. /usr split need to be adapted, otherwise udev will
|
||||
be installed in /usr and not work properly. Example configuration options are
|
||||
|
|
|
@ -62,9 +62,7 @@ void udev_log(struct udev *udev,
|
|||
int priority, const char *file, int line, const char *fn,
|
||||
const char *format, ...)
|
||||
__attribute__((format(printf, 6, 7)));
|
||||
const char *udev_get_rules_path(struct udev *udev);
|
||||
const char *udev_get_run_config_path(struct udev *udev);
|
||||
const char *udev_set_run_path(struct udev *udev, const char *path);
|
||||
int udev_get_rules_path(struct udev *udev, char **path[], unsigned long long *ts_usec[]);
|
||||
struct udev_list_entry *udev_add_property(struct udev *udev, const char *key, const char *value);
|
||||
struct udev_list_entry *udev_get_properties_list_entry(struct udev *udev);
|
||||
|
||||
|
@ -195,6 +193,7 @@ uid_t util_lookup_user(struct udev *udev, const char *user);
|
|||
gid_t util_lookup_group(struct udev *udev, const char *group);
|
||||
int util_resolve_subsys_kernel(struct udev *udev, const char *string,
|
||||
char *result, size_t maxsize, int read_value);
|
||||
unsigned long long ts_usec(const struct timespec *ts);
|
||||
unsigned long long now_usec(void);
|
||||
|
||||
/* libudev-selinux-private.c */
|
||||
|
|
|
@ -552,12 +552,17 @@ uint64_t util_string_bloom64(const char *str)
|
|||
|
||||
#define USEC_PER_SEC 1000000ULL
|
||||
#define NSEC_PER_USEC 1000ULL
|
||||
unsigned long long ts_usec(const struct timespec *ts)
|
||||
{
|
||||
return (unsigned long long) ts->tv_sec * USEC_PER_SEC +
|
||||
(unsigned long long) ts->tv_nsec / NSEC_PER_USEC;
|
||||
}
|
||||
|
||||
unsigned long long now_usec(void)
|
||||
{
|
||||
struct timespec ts;
|
||||
|
||||
if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0)
|
||||
return 0;
|
||||
return (unsigned long long) ts.tv_sec * USEC_PER_SEC +
|
||||
(unsigned long long) ts.tv_nsec / NSEC_PER_USEC;
|
||||
return ts_usec(&ts);
|
||||
}
|
||||
|
|
|
@ -17,6 +17,7 @@
|
|||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
#include <time.h>
|
||||
|
||||
#include "libudev.h"
|
||||
#include "libudev-private.h"
|
||||
|
@ -42,8 +43,9 @@ struct udev {
|
|||
void *userdata;
|
||||
char *sys_path;
|
||||
char *dev_path;
|
||||
char *rules_path;
|
||||
char *run_config_path;
|
||||
char *rules_path[4];
|
||||
unsigned long long rules_path_ts[4];
|
||||
int rules_path_count;
|
||||
char *run_path;
|
||||
struct udev_list properties_list;
|
||||
int log_priority;
|
||||
|
@ -218,11 +220,12 @@ UDEV_EXPORT struct udev *udev_new(void)
|
|||
continue;
|
||||
}
|
||||
if (strcmp(key, "udev_run") == 0) {
|
||||
set_value(&udev->run_config_path, val);
|
||||
set_value(&udev->run_path, val);
|
||||
continue;
|
||||
}
|
||||
if (strcmp(key, "udev_rules") == 0) {
|
||||
set_value(&udev->rules_path, val);
|
||||
set_value(&udev->rules_path[0], val);
|
||||
udev->rules_path_count = 1;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
@ -255,18 +258,35 @@ UDEV_EXPORT struct udev *udev_new(void)
|
|||
if (set_value(&udev->sys_path, "/sys") == NULL)
|
||||
goto err;
|
||||
|
||||
if (udev->run_config_path == NULL)
|
||||
if (set_value(&udev->run_config_path, "/run/udev") == NULL)
|
||||
if (udev->run_path == NULL)
|
||||
if (set_value(&udev->run_path, "/run/udev") == NULL)
|
||||
goto err;
|
||||
|
||||
if (udev->rules_path[0] == NULL) {
|
||||
/* /usr/lib/udev -- system rules */
|
||||
udev->rules_path[0] = strdup(LIBEXECDIR "/rules.d");
|
||||
if (!udev->rules_path[0])
|
||||
goto err;
|
||||
|
||||
/* /etc/udev -- local administration rules */
|
||||
udev->rules_path[1] = strdup(SYSCONFDIR "/udev/rules.d");
|
||||
if (!udev->rules_path[1])
|
||||
goto err;
|
||||
|
||||
/* /run/udev -- runtime rules */
|
||||
if (asprintf(&udev->rules_path[2], "%s/rules.d", udev->run_path) < 0)
|
||||
goto err;
|
||||
|
||||
udev->rules_path_count = 3;
|
||||
}
|
||||
|
||||
dbg(udev, "context %p created\n", udev);
|
||||
dbg(udev, "log_priority=%d\n", udev->log_priority);
|
||||
dbg(udev, "config_file='%s'\n", config_file);
|
||||
dbg(udev, "dev_path='%s'\n", udev->dev_path);
|
||||
dbg(udev, "sys_path='%s'\n", udev->sys_path);
|
||||
dbg(udev, "run_path='%s'\n", udev->run_config_path);
|
||||
if (udev->rules_path != NULL)
|
||||
dbg(udev, "rules_path='%s'\n", udev->rules_path);
|
||||
dbg(udev, "run_path='%s'\n", udev->run_path);
|
||||
dbg(udev, "rules_path='%s':'%s':'%s'\n", udev->rules_path[0], udev->rules_path[1], udev->rules_path[2]);
|
||||
free(config_file);
|
||||
return udev;
|
||||
err:
|
||||
|
@ -310,9 +330,10 @@ UDEV_EXPORT void udev_unref(struct udev *udev)
|
|||
udev_list_cleanup(&udev->properties_list);
|
||||
free(udev->dev_path);
|
||||
free(udev->sys_path);
|
||||
free(udev->rules_path);
|
||||
free(udev->rules_path[0]);
|
||||
free(udev->rules_path[1]);
|
||||
free(udev->rules_path[2]);
|
||||
free(udev->run_path);
|
||||
free(udev->run_config_path);
|
||||
dbg(udev, "context %p released\n", udev);
|
||||
free(udev);
|
||||
}
|
||||
|
@ -367,9 +388,12 @@ UDEV_EXPORT void udev_set_log_priority(struct udev *udev, int priority)
|
|||
udev_add_property(udev, "UDEV_LOG", num);
|
||||
}
|
||||
|
||||
const char *udev_get_rules_path(struct udev *udev)
|
||||
int udev_get_rules_path(struct udev *udev, char **path[], unsigned long long *stamp_usec[])
|
||||
{
|
||||
return udev->rules_path;
|
||||
*path = udev->rules_path;
|
||||
if (stamp_usec)
|
||||
*stamp_usec = udev->rules_path_ts;
|
||||
return udev->rules_path_count;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -406,11 +430,6 @@ UDEV_EXPORT const char *udev_get_dev_path(struct udev *udev)
|
|||
return udev->dev_path;
|
||||
}
|
||||
|
||||
const char *udev_get_run_config_path(struct udev *udev)
|
||||
{
|
||||
return udev->run_config_path;
|
||||
}
|
||||
|
||||
/**
|
||||
* udev_get_run_path:
|
||||
* @udev: udev library context
|
||||
|
@ -421,32 +440,11 @@ const char *udev_get_run_config_path(struct udev *udev)
|
|||
**/
|
||||
UDEV_EXPORT const char *udev_get_run_path(struct udev *udev)
|
||||
{
|
||||
if (udev->run_path != NULL)
|
||||
return udev->run_path;
|
||||
|
||||
/* check if configured path exists */
|
||||
if (access(udev->run_config_path, F_OK) < 0) {
|
||||
char filename[UTIL_PATH_SIZE];
|
||||
|
||||
/* fall back to /dev/.udev if that exists */
|
||||
util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev), "/.udev", NULL);
|
||||
if (access(filename, F_OK) >= 0)
|
||||
if (set_value(&udev->run_path, filename) != NULL)
|
||||
return udev->run_path;
|
||||
}
|
||||
|
||||
/* use default path */
|
||||
set_value(&udev->run_path, udev->run_config_path);
|
||||
if (udev->run_path == NULL)
|
||||
return udev->run_config_path;
|
||||
if (udev == NULL)
|
||||
return NULL;
|
||||
return udev->run_path;
|
||||
}
|
||||
|
||||
const char *udev_set_run_path(struct udev *udev, const char *path)
|
||||
{
|
||||
return set_value(&udev->run_path, path);
|
||||
}
|
||||
|
||||
struct udev_list_entry *udev_add_property(struct udev *udev, const char *key, const char *value)
|
||||
{
|
||||
if (value == NULL) {
|
||||
|
|
|
@ -322,6 +322,7 @@ static void udev_kmod_log(void *data, int priority, const char *file, int line,
|
|||
udev_main_log(data, priority, file, line, fn, format, args);
|
||||
}
|
||||
|
||||
/* needs to re-instantiate the context after a reload */
|
||||
static int builtin_kmod(struct udev_device *dev, int argc, char *argv[], bool test)
|
||||
{
|
||||
struct udev *udev = udev_device_get_udev(dev);
|
||||
|
@ -350,6 +351,7 @@ static int builtin_kmod(struct udev_device *dev, int argc, char *argv[], bool te
|
|||
return EXIT_SUCCESS;
|
||||
}
|
||||
|
||||
/* called at udev startup */
|
||||
static int builtin_kmod_init(struct udev *udev)
|
||||
{
|
||||
if (ctx)
|
||||
|
@ -365,11 +367,18 @@ static int builtin_kmod_init(struct udev *udev)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int builtin_kmod_exit(struct udev *udev)
|
||||
/* called on udev shutdown and reload request */
|
||||
static void builtin_kmod_exit(struct udev *udev)
|
||||
{
|
||||
ctx = kmod_unref(ctx);
|
||||
info(udev, "unload module index\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* called every couple of seconds during event activity; 'true' if config has changed */
|
||||
static bool builtin_kmod_validate(struct udev *udev)
|
||||
{
|
||||
info(udev, "validate module index\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
const struct udev_builtin udev_builtin_kmod = {
|
||||
|
@ -377,6 +386,7 @@ const struct udev_builtin udev_builtin_kmod = {
|
|||
.cmd = builtin_kmod,
|
||||
.init = builtin_kmod_init,
|
||||
.exit = builtin_kmod_exit,
|
||||
.validate = builtin_kmod_validate,
|
||||
.help = "kernel module loader",
|
||||
.run_once = false,
|
||||
};
|
||||
|
|
|
@ -37,30 +37,45 @@ static const struct udev_builtin *builtins[] = {
|
|||
int udev_builtin_init(struct udev *udev)
|
||||
{
|
||||
unsigned int i;
|
||||
int err;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(builtins); i++)
|
||||
if (builtins[i]->init)
|
||||
builtins[i]->init(udev);
|
||||
return 0;
|
||||
for (i = 0; i < ARRAY_SIZE(builtins); i++) {
|
||||
if (builtins[i]->init) {
|
||||
err = builtins[i]->init(udev);
|
||||
if (err < 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
return err;
|
||||
}
|
||||
|
||||
int udev_builtin_exit(struct udev *udev)
|
||||
void udev_builtin_exit(struct udev *udev)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(builtins); i++)
|
||||
if (builtins[i]->exit)
|
||||
builtins[i]->exit(udev);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int udev_builtin_list(struct udev *udev)
|
||||
bool udev_builtin_validate(struct udev *udev)
|
||||
{
|
||||
unsigned int i;
|
||||
bool change = false;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(builtins); i++)
|
||||
if (builtins[i]->validate)
|
||||
if (builtins[i]->validate(udev))
|
||||
change = true;
|
||||
return change;
|
||||
}
|
||||
|
||||
void udev_builtin_list(struct udev *udev)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(builtins); i++)
|
||||
fprintf(stderr, " %-12s %s\n", builtins[i]->name, builtins[i]->help);
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *udev_builtin_name(enum udev_builtin_cmd cmd)
|
||||
|
|
|
@ -1750,6 +1750,7 @@ struct udev_rules *udev_rules_new(struct udev *udev, int resolve_names)
|
|||
struct udev_list file_list;
|
||||
struct udev_list_entry *file_loop;
|
||||
struct token end_token;
|
||||
char **s;
|
||||
|
||||
rules = calloc(1, sizeof(struct udev_rules));
|
||||
if (rules == NULL)
|
||||
|
@ -1791,22 +1792,8 @@ struct udev_rules *udev_rules_new(struct udev *udev, int resolve_names)
|
|||
memset(rules->trie_nodes, 0x00, sizeof(struct trie_node));
|
||||
rules->trie_nodes_cur = 1;
|
||||
|
||||
if (udev_get_rules_path(udev) == NULL) {
|
||||
char filename[UTIL_PATH_SIZE];
|
||||
|
||||
/* /usr/lib/udev -- system rules */
|
||||
add_matching_files(udev, &file_list, LIBEXECDIR "/rules.d", ".rules");
|
||||
|
||||
/* /etc/udev -- local administration rules */
|
||||
add_matching_files(udev, &file_list, SYSCONFDIR "/udev/rules.d", ".rules");
|
||||
|
||||
/* /run/udev -- runtime rules */
|
||||
util_strscpyl(filename, sizeof(filename), udev_get_run_path(udev), "/rules.d", NULL);
|
||||
add_matching_files(udev, &file_list, filename, ".rules");
|
||||
} else {
|
||||
/* custom rules files location for testing */
|
||||
add_matching_files(udev, &file_list, udev_get_rules_path(udev), ".rules");
|
||||
}
|
||||
for (udev_get_rules_path(udev, &s, NULL); *s != NULL; s++)
|
||||
add_matching_files(udev, &file_list, *s, ".rules");
|
||||
|
||||
/* add all filenames to the string buffer */
|
||||
udev_list_entry_foreach(file_loop, udev_list_get_entry(&file_list)) {
|
||||
|
|
|
@ -146,7 +146,8 @@ struct udev_builtin {
|
|||
int (*cmd)(struct udev_device *dev, int argc, char *argv[], bool test);
|
||||
const char *help;
|
||||
int (*init)(struct udev *udev);
|
||||
int (*exit)(struct udev *udev);
|
||||
void (*exit)(struct udev *udev);
|
||||
bool (*validate)(struct udev *udev);
|
||||
bool run_once;
|
||||
};
|
||||
extern const struct udev_builtin udev_builtin_blkid;
|
||||
|
@ -155,13 +156,13 @@ extern const struct udev_builtin udev_builtin_input_id;
|
|||
extern const struct udev_builtin udev_builtin_kmod;
|
||||
extern const struct udev_builtin udev_builtin_path_id;
|
||||
extern const struct udev_builtin udev_builtin_usb_id;
|
||||
int udev_builtin_load(struct udev *udev);
|
||||
int udev_builtin_unload(struct udev *udev);
|
||||
int udev_builtin_init(struct udev *udev);
|
||||
void udev_builtin_exit(struct udev *udev);
|
||||
enum udev_builtin_cmd udev_builtin_lookup(const char *command);
|
||||
const char *udev_builtin_name(enum udev_builtin_cmd cmd);
|
||||
bool udev_builtin_run_once(enum udev_builtin_cmd cmd);
|
||||
int udev_builtin_run(struct udev_device *dev, enum udev_builtin_cmd cmd, const char *command, bool test);
|
||||
int udev_builtin_list(struct udev *udev);
|
||||
void udev_builtin_list(struct udev *udev);
|
||||
int udev_builtin_add_property(struct udev_device *dev, bool test, const char *key, const char *val);
|
||||
|
||||
/* udev logging */
|
||||
|
|
120
udev/udevd.c
120
udev/udevd.c
|
@ -736,19 +736,6 @@ static int handle_inotify(struct udev *udev)
|
|||
struct udev_device *dev;
|
||||
|
||||
ev = (struct inotify_event *)(buf + pos);
|
||||
if (ev->len) {
|
||||
const char *s;
|
||||
|
||||
info(udev, "inotify event: %x for %s\n", ev->mask, ev->name);
|
||||
s = strstr(ev->name, ".rules");
|
||||
if (s == NULL)
|
||||
continue;
|
||||
if (strlen(s) != strlen(".rules"))
|
||||
continue;
|
||||
reload = true;
|
||||
continue;
|
||||
}
|
||||
|
||||
dev = udev_watch_lookup(udev, ev->wd);
|
||||
if (dev != NULL) {
|
||||
info(udev, "inotify event: %x for %s\n", ev->mask, udev_device_get_devnode(dev));
|
||||
|
@ -1169,6 +1156,36 @@ static int systemd_fds(struct udev *udev, int *rctrl, int *rnetlink)
|
|||
return 0;
|
||||
}
|
||||
|
||||
static bool check_rules_timestamp(struct udev *udev)
|
||||
{
|
||||
char **p;
|
||||
unsigned long long *stamp_usec;
|
||||
int i, n;
|
||||
bool changed = false;
|
||||
|
||||
n = udev_get_rules_path(udev, &p, &stamp_usec);
|
||||
for (i = 0; i < n; i++) {
|
||||
struct stat stats;
|
||||
|
||||
if (stat(p[i], &stats) < 0)
|
||||
continue;
|
||||
|
||||
if (stamp_usec[i] == ts_usec(&stats.st_mtim))
|
||||
continue;
|
||||
|
||||
/* first check */
|
||||
if (stamp_usec[i] != 0) {
|
||||
info(udev, "reload - timestamp of '%s' changed\n", p[i]);
|
||||
changed = true;
|
||||
}
|
||||
|
||||
/* update timestamp */
|
||||
stamp_usec[i] = ts_usec(&stats.st_mtim);
|
||||
}
|
||||
|
||||
return changed;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
struct udev *udev;
|
||||
|
@ -1191,6 +1208,7 @@ int main(int argc, char *argv[])
|
|||
int fd_worker = -1;
|
||||
struct epoll_event ep_ctrl, ep_inotify, ep_signal, ep_netlink, ep_worker;
|
||||
struct udev_ctrl_connection *ctrl_conn = NULL;
|
||||
char **s;
|
||||
int rc = 1;
|
||||
|
||||
udev = udev_new();
|
||||
|
@ -1202,31 +1220,6 @@ int main(int argc, char *argv[])
|
|||
info(udev, "version %s\n", VERSION);
|
||||
udev_selinux_init(udev);
|
||||
|
||||
/* make sure, that our runtime dir exists and is writable */
|
||||
if (utimensat(AT_FDCWD, udev_get_run_config_path(udev), NULL, 0) < 0) {
|
||||
/* try to create our own subdirectory, do not create parent directories */
|
||||
mkdir(udev_get_run_config_path(udev), 0755);
|
||||
|
||||
if (utimensat(AT_FDCWD, udev_get_run_config_path(udev), NULL, 0) >= 0) {
|
||||
/* directory seems writable now */
|
||||
udev_set_run_path(udev, udev_get_run_config_path(udev));
|
||||
} else {
|
||||
/* fall back to /dev/.udev */
|
||||
char filename[UTIL_PATH_SIZE];
|
||||
|
||||
util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev), "/.udev", NULL);
|
||||
if (udev_set_run_path(udev, filename) == NULL)
|
||||
goto exit;
|
||||
mkdir(udev_get_run_path(udev), 0755);
|
||||
err(udev, "error: runtime directory '%s' not writable, for now falling back to '%s'",
|
||||
udev_get_run_config_path(udev), udev_get_run_path(udev));
|
||||
}
|
||||
}
|
||||
/* relabel runtime dir only if it resides below /dev */
|
||||
if (strncmp(udev_get_run_path(udev), udev_get_dev_path(udev), strlen(udev_get_dev_path(udev))) == 0)
|
||||
udev_selinux_lsetfilecon(udev, udev_get_run_path(udev), 0755);
|
||||
info(udev, "runtime dir '%s'\n", udev_get_run_path(udev));
|
||||
|
||||
for (;;) {
|
||||
int option;
|
||||
|
||||
|
@ -1469,28 +1462,6 @@ int main(int argc, char *argv[])
|
|||
rc = 4;
|
||||
goto exit;
|
||||
}
|
||||
|
||||
if (udev_get_rules_path(udev) != NULL) {
|
||||
inotify_add_watch(fd_inotify, udev_get_rules_path(udev),
|
||||
IN_DELETE | IN_MOVE | IN_CLOSE_WRITE);
|
||||
} else {
|
||||
char filename[UTIL_PATH_SIZE];
|
||||
struct stat statbuf;
|
||||
|
||||
inotify_add_watch(fd_inotify, LIBEXECDIR "/rules.d",
|
||||
IN_DELETE | IN_MOVE | IN_CLOSE_WRITE);
|
||||
inotify_add_watch(fd_inotify, SYSCONFDIR "/udev/rules.d",
|
||||
IN_DELETE | IN_MOVE | IN_CLOSE_WRITE);
|
||||
|
||||
/* watch dynamic rules directory */
|
||||
util_strscpyl(filename, sizeof(filename), udev_get_run_path(udev), "/rules.d", NULL);
|
||||
if (stat(filename, &statbuf) != 0) {
|
||||
util_create_path(udev, filename);
|
||||
mkdir(filename, 0755);
|
||||
}
|
||||
inotify_add_watch(fd_inotify, filename,
|
||||
IN_DELETE | IN_MOVE | IN_CLOSE_WRITE);
|
||||
}
|
||||
udev_watch_restore(udev);
|
||||
|
||||
/* block and listen to all signals on signalfd */
|
||||
|
@ -1575,6 +1546,7 @@ int main(int argc, char *argv[])
|
|||
udev_list_node_init(&worker_list);
|
||||
|
||||
for (;;) {
|
||||
static unsigned long long last_usec;
|
||||
struct epoll_event ev[8];
|
||||
int fdcount;
|
||||
int timeout;
|
||||
|
@ -1642,6 +1614,24 @@ int main(int argc, char *argv[])
|
|||
is_ctrl = true;
|
||||
}
|
||||
|
||||
/* check for changed config, every 3 seconds at most */
|
||||
if ((now_usec() - last_usec) > 3 * 1000 * 1000) {
|
||||
if (check_rules_timestamp(udev))
|
||||
reload = true;
|
||||
if (udev_builtin_validate(udev))
|
||||
reload = true;
|
||||
|
||||
last_usec = now_usec();
|
||||
}
|
||||
|
||||
/* reload requested, HUP signal received, rules changed, builtin changed */
|
||||
if (reload) {
|
||||
worker_kill(udev, 0);
|
||||
rules = udev_rules_unref(rules);
|
||||
udev_builtin_exit(udev);
|
||||
reload = 0;
|
||||
}
|
||||
|
||||
/* event has finished */
|
||||
if (is_worker)
|
||||
worker_returned(fd_worker);
|
||||
|
@ -1678,7 +1668,7 @@ int main(int argc, char *argv[])
|
|||
if (udev_exit)
|
||||
continue;
|
||||
|
||||
/* device node and rules directory inotify watch */
|
||||
/* device node watch */
|
||||
if (is_inotify)
|
||||
handle_inotify(udev);
|
||||
|
||||
|
@ -1693,14 +1683,6 @@ int main(int argc, char *argv[])
|
|||
*/
|
||||
if (is_ctrl)
|
||||
ctrl_conn = handle_ctrl_msg(udev_ctrl);
|
||||
|
||||
/* rules changed, set by inotify or a HUP signal */
|
||||
if (reload) {
|
||||
worker_kill(udev, 0);
|
||||
rules = udev_rules_unref(rules);
|
||||
udev_builtin_exit(udev);
|
||||
reload = 0;
|
||||
}
|
||||
}
|
||||
|
||||
rc = EXIT_SUCCESS;
|
||||
|
|
Loading…
Reference in a new issue