UDEV_CTRL_SET_ENV,
UDEV_CTRL_SET_MAX_CHILDS,
UDEV_CTRL_SET_MAX_CHILDS_RUNNING,
+ UDEV_CTRL_SETTLE,
};
struct udev_ctrl_msg_wire {
int refcount;
struct udev_ctrl *uctrl;
struct udev_ctrl_msg_wire ctrl_msg_wire;
+ pid_t pid;
};
struct udev_ctrl {
return ctrl_send(uctrl, UDEV_CTRL_SET_MAX_CHILDS, count, NULL);
}
+int udev_ctrl_send_settle(struct udev_ctrl *uctrl)
+{
+ return ctrl_send(uctrl, UDEV_CTRL_SETTLE, 0, NULL);
+}
+
struct udev_ctrl_msg *udev_ctrl_receive_msg(struct udev_ctrl *uctrl)
{
struct udev_ctrl_msg *uctrl_msg;
goto err;
}
+ uctrl_msg->pid = cred->pid;
+
if (uctrl_msg->ctrl_msg_wire.magic != UDEV_CTRL_MAGIC) {
err(uctrl->udev, "message magic 0x%08x doesn't match, ignore it\n", uctrl_msg->ctrl_msg_wire.magic);
goto err;
return ctrl_msg->ctrl_msg_wire.intval;
return -1;
}
+
+pid_t udev_ctrl_get_settle(struct udev_ctrl_msg *ctrl_msg)
+{
+ if (ctrl_msg->ctrl_msg_wire.type == UDEV_CTRL_SETTLE)
+ return ctrl_msg->pid;
+ return -1;
+}
extern int udev_ctrl_send_stop_exec_queue(struct udev_ctrl *uctrl);
extern int udev_ctrl_send_start_exec_queue(struct udev_ctrl *uctrl);
extern int udev_ctrl_send_reload_rules(struct udev_ctrl *uctrl);
+extern int udev_ctrl_send_settle(struct udev_ctrl *uctrl);
extern int udev_ctrl_send_set_env(struct udev_ctrl *uctrl, const char *key);
extern int udev_ctrl_send_set_max_childs(struct udev_ctrl *uctrl, int count);
struct udev_ctrl_msg;
extern int udev_ctrl_get_stop_exec_queue(struct udev_ctrl_msg *ctrl_msg);
extern int udev_ctrl_get_start_exec_queue(struct udev_ctrl_msg *ctrl_msg);
extern int udev_ctrl_get_reload_rules(struct udev_ctrl_msg *ctrl_msg);
+extern pid_t udev_ctrl_get_settle(struct udev_ctrl_msg *ctrl_msg);
extern const char *udev_ctrl_get_set_env(struct udev_ctrl_msg *ctrl_msg);
extern int udev_ctrl_get_set_max_childs(struct udev_ctrl_msg *ctrl_msg);
/*
* Copyright (C) 2006-2008 Kay Sievers <kay@vrfy.org>
+ * Copyright (C) 2009 Canonical Ltd.
+ * Copyright (C) 2009 Scott James Remnant <scott@netsplit.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
switch (signum) {
case SIGALRM:
is_timeout = 1;
+ case SIGUSR1:
+ ;
}
}
sigemptyset (&act.sa_mask);
act.sa_flags = 0;
sigaction(SIGALRM, &act, NULL);
+ sigaction(SIGUSR1, &act, NULL);
while (1) {
int option;
}
}
+ /* guarantee that the udev daemon isn't pre-processing */
+ if (getuid() == 0) {
+ struct udev_ctrl *uctrl;
+
+ uctrl = udev_ctrl_new_from_socket(udev, UDEV_CTRL_SOCK_PATH);
+ if (uctrl != NULL) {
+ sigset_t mask, oldmask;
+
+ sigemptyset(&mask);
+ sigaddset(&mask, SIGUSR1);
+ sigaddset(&mask, SIGALRM);
+ sigprocmask(SIG_BLOCK, &mask, &oldmask);
+ if (udev_ctrl_send_settle(uctrl) > 0)
+ sigsuspend(&oldmask);
+ udev_ctrl_unref(uctrl);
+ }
+ }
+
while (!is_timeout) {
/* exit if queue is empty */
if (udev_queue_get_queue_is_empty(udev_queue))
/*
* Copyright (C) 2004-2008 Kay Sievers <kay.sievers@vrfy.org>
* Copyright (C) 2004 Chris Friesen <chris_friesen@sympatico.ca>
+ * Copyright (C) 2009 Canonical Ltd.
+ * Copyright (C) 2009 Scott James Remnant <scott@netsplit.com>
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
static volatile int udev_exit;
static volatile int reload_config;
static volatile int signal_received;
+static volatile pid_t settle_pid;
static int run_exec_q;
static int stop_exec_q;
static int max_childs;
info(udev, "udevd message (SET_MAX_CHILDS) received, max_childs=%i\n", i);
max_childs = i;
}
+
+ settle_pid = udev_ctrl_get_settle(ctrl_msg);
+ if (settle_pid > 0) {
+ info(udev, "udevd message (SETTLE) received\n");
+ }
udev_ctrl_msg_unref(ctrl_msg);
}
if (!stop_exec_q)
event_queue_manager(udev);
}
+
+ if (settle_pid > 0) {
+ kill(settle_pid, SIGUSR1);
+ settle_pid = 0;
+ }
}
cleanup_queue_dir(udev);
rc = 0;