chiark
/
gitweb
/
~ianmdlvl
/
elogind.git
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
udevd: create /dev/.udev/rules.d/ before watching it wit inotify
[elogind.git]
/
udev
/
udevd.c
diff --git
a/udev/udevd.c
b/udev/udevd.c
index 2eb914a3f335f61952b355328ef9c8fae707b559..72f9b180d398d37294a8511ad6c9bd72ee045cd3 100644
(file)
--- a/
udev/udevd.c
+++ b/
udev/udevd.c
@@
-118,6
+118,8
@@
struct event {
const char *devpath;
size_t devpath_len;
const char *devpath_old;
const char *devpath;
size_t devpath_len;
const char *devpath_old;
+ dev_t devnum;
+ bool is_block;
};
static struct event *node_to_event(struct udev_list_node *node)
};
static struct event *node_to_event(struct udev_list_node *node)
@@
-221,7
+223,6
@@
static void worker_new(struct event *event)
/* allow the main daemon netlink address to send devices to the worker */
udev_monitor_allow_unicast_sender(worker_monitor, monitor);
udev_monitor_enable_receiving(worker_monitor);
/* allow the main daemon netlink address to send devices to the worker */
udev_monitor_allow_unicast_sender(worker_monitor, monitor);
udev_monitor_enable_receiving(worker_monitor);
- util_set_fd_cloexec(udev_monitor_get_fd(worker_monitor));
worker = calloc(1, sizeof(struct worker));
if (worker == NULL)
worker = calloc(1, sizeof(struct worker));
if (worker == NULL)
@@
-410,6
+411,8
@@
static void event_queue_insert(struct udev_device *dev)
event->devpath = udev_device_get_devpath(dev);
event->devpath_len = strlen(event->devpath);
event->devpath_old = udev_device_get_devpath_old(dev);
event->devpath = udev_device_get_devpath(dev);
event->devpath_len = strlen(event->devpath);
event->devpath_old = udev_device_get_devpath_old(dev);
+ event->devnum = udev_device_get_devnum(dev);
+ event->is_block = (strcmp("block", udev_device_get_subsystem(dev)) == 0);
udev_queue_export_device_queued(udev_queue_export, dev);
info(event->udev, "seq %llu queued, '%s' '%s'\n", udev_device_get_seqnum(dev),
udev_queue_export_device_queued(udev_queue_export, dev);
info(event->udev, "seq %llu queued, '%s' '%s'\n", udev_device_get_seqnum(dev),
@@
-473,7
+476,7
@@
static int mem_size_mb(void)
}
/* lookup event for identical, parent, child device */
}
/* lookup event for identical, parent, child device */
-static
int
devpath_busy(struct event *event)
+static
bool is_
devpath_busy(struct event *event)
{
struct udev_list_node *loop;
size_t common;
{
struct udev_list_node *loop;
size_t common;
@@
-488,18
+491,21
@@
static int devpath_busy(struct event *event)
/* event we checked earlier still exists, no need to check again */
if (loop_event->seqnum == event->delaying_seqnum)
/* event we checked earlier still exists, no need to check again */
if (loop_event->seqnum == event->delaying_seqnum)
- return
2
;
+ return
true
;
/* found ourself, no later event can block us */
if (loop_event->seqnum >= event->seqnum)
break;
/* found ourself, no later event can block us */
if (loop_event->seqnum >= event->seqnum)
break;
+ /* check major/minor */
+ if (major(event->devnum) != 0 && event->devnum == loop_event->devnum && event->is_block == loop_event->is_block)
+ return true;
+
/* check our old name */
/* check our old name */
- if (event->devpath_old != NULL)
- if (strcmp(loop_event->devpath, event->devpath_old) == 0) {
- event->delaying_seqnum = loop_event->seqnum;
- return 3;
- }
+ if (event->devpath_old != NULL && strcmp(loop_event->devpath, event->devpath_old) == 0) {
+ event->delaying_seqnum = loop_event->seqnum;
+ return true;
+ }
/* compare devpath */
common = MIN(loop_event->devpath_len, event->devpath_len);
/* compare devpath */
common = MIN(loop_event->devpath_len, event->devpath_len);
@@
-511,26
+517,26
@@
static int devpath_busy(struct event *event)
/* identical device event found */
if (loop_event->devpath_len == event->devpath_len) {
event->delaying_seqnum = loop_event->seqnum;
/* identical device event found */
if (loop_event->devpath_len == event->devpath_len) {
event->delaying_seqnum = loop_event->seqnum;
- return
4
;
+ return
true
;
}
/* parent device event found */
if (event->devpath[common] == '/') {
event->delaying_seqnum = loop_event->seqnum;
}
/* parent device event found */
if (event->devpath[common] == '/') {
event->delaying_seqnum = loop_event->seqnum;
- return
5
;
+ return
true
;
}
/* child device event found */
if (loop_event->devpath[common] == '/') {
event->delaying_seqnum = loop_event->seqnum;
}
/* child device event found */
if (loop_event->devpath[common] == '/') {
event->delaying_seqnum = loop_event->seqnum;
- return
6
;
+ return
true
;
}
/* no matching device */
continue;
}
}
/* no matching device */
continue;
}
- return
0
;
+ return
false
;
}
static void events_start(struct udev *udev)
}
static void events_start(struct udev *udev)
@@
-544,7
+550,7
@@
static void events_start(struct udev *udev)
continue;
/* do not start event if parent or child event is still running */
continue;
/* do not start event if parent or child event is still running */
- if (
devpath_busy(event) != 0
) {
+ if (
is_devpath_busy(event)
) {
dbg(udev, "delay seq %llu (%s)\n", event->seqnum, event->devpath);
continue;
}
dbg(udev, "delay seq %llu (%s)\n", event->seqnum, event->devpath);
continue;
}
@@
-662,7
+668,7
@@
static void handle_ctrl_msg(struct udev_ctrl *uctrl)
/* read inotify messages */
static int handle_inotify(struct udev *udev)
{
/* read inotify messages */
static int handle_inotify(struct udev *udev)
{
-
ssize_
t nbytes, pos;
+
in
t nbytes, pos;
char *buf;
struct inotify_event *ev;
char *buf;
struct inotify_event *ev;
@@
-913,6
+919,7
@@
int main(int argc, char *argv[])
IN_CREATE | IN_DELETE | IN_MOVE | IN_CLOSE_WRITE);
} else {
char filename[UTIL_PATH_SIZE];
IN_CREATE | IN_DELETE | IN_MOVE | IN_CLOSE_WRITE);
} else {
char filename[UTIL_PATH_SIZE];
+ struct stat statbuf;
inotify_add_watch(pfd[FD_INOTIFY].fd, LIBEXECDIR "/rules.d",
IN_CREATE | IN_DELETE | IN_MOVE | IN_CLOSE_WRITE);
inotify_add_watch(pfd[FD_INOTIFY].fd, LIBEXECDIR "/rules.d",
IN_CREATE | IN_DELETE | IN_MOVE | IN_CLOSE_WRITE);
@@
-921,6
+928,12
@@
int main(int argc, char *argv[])
/* watch dynamic rules directory */
util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev), "/.udev/rules.d", NULL);
/* watch dynamic rules directory */
util_strscpyl(filename, sizeof(filename), udev_get_dev_path(udev), "/.udev/rules.d", NULL);
+ if (stat(filename, &statbuf) != 0) {
+ util_create_path(udev, filename);
+ udev_selinux_setfscreatecon(udev, filename, S_IFDIR|0755);
+ mkdir(filename, 0755);
+ udev_selinux_resetfscreatecon(udev);
+ }
inotify_add_watch(pfd[FD_INOTIFY].fd, filename,
IN_CREATE | IN_DELETE | IN_MOVE | IN_CLOSE_WRITE);
}
inotify_add_watch(pfd[FD_INOTIFY].fd, filename,
IN_CREATE | IN_DELETE | IN_MOVE | IN_CLOSE_WRITE);
}
@@
-938,14
+951,13
@@
int main(int argc, char *argv[])
}
/* unnamed socket from workers to the main daemon */
}
/* unnamed socket from workers to the main daemon */
- if (socketpair(AF_LOCAL, SOCK_DGRAM, 0, worker_watch) < 0) {
+ if (socketpair(AF_LOCAL, SOCK_DGRAM
|SOCK_CLOEXEC
, 0, worker_watch) < 0) {
fprintf(stderr, "error getting socketpair\n");
err(udev, "error getting socketpair\n");
rc = 6;
goto exit;
}
pfd[FD_WORKER].fd = worker_watch[READ_END];
fprintf(stderr, "error getting socketpair\n");
err(udev, "error getting socketpair\n");
rc = 6;
goto exit;
}
pfd[FD_WORKER].fd = worker_watch[READ_END];
- util_set_fd_cloexec(worker_watch[WRITE_END]);
rules = udev_rules_new(udev, resolve_names);
if (rules == NULL) {
rules = udev_rules_new(udev, resolve_names);
if (rules == NULL) {