udevd.c revision d315bba6f6c9d929acdbf3c37cbcf6c9a72365ac
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen * Copyright (C) 2004-2012 Kay Sievers <kay.sievers@vrfy.org>
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen * Copyright (C) 2004 Chris Friesen <chris_friesen@sympatico.ca>
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen * Copyright (C) 2009 Canonical Ltd.
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen * Copyright (C) 2009 Scott James Remnant <scott@netsplit.com>
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen * This program is free software: you can redistribute it and/or modify
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen * it under the terms of the GNU General Public License as published by
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen * the Free Software Foundation, either version 2 of the License, or
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen * (at your option) any later version.
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen * This program is distributed in the hope that it will be useful,
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen * but WITHOUT ANY WARRANTY; without even the implied warranty of
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen * GNU General Public License for more details.
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen * You should have received a copy of the GNU General Public License
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen * along with this program. If not, see <http://www.gnu.org/licenses/>.
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersenvoid udev_main_log(struct udev *udev, int priority,
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen log_metav(priority, file, line, fn, format, args);
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersenstatic struct udev_queue_export *udev_queue_export;
cfb5b3805759e63dc5e0cae6e92e1df885b5c5b6Tom Gundersen unsigned long long int delaying_seqnum;
9ee18af3a036074c4021c82ae2e67f5ccaa9ea9dTom Gundersen unsigned long long int seqnum;
bool is_block;
int ifindex;
enum worker_state {
struct worker {
int refcount;
unsigned long long event_start_usec;
struct worker_message {
int exitcode;
if (export) {
return worker;
children--;
switch (pid) {
int fd_monitor;
if (fd_signal < 0) {
goto out;
if (fd_ep < 0) {
goto out;
goto out;
int err;
goto out;
if (exec_delay > 0)
if (err == 0)
if (err != 0)
goto out;
int fdcount;
if (fdcount < 0) {
goto out;
for (i = 0; i < fdcount; i++) {
case SIGTERM:
goto out;
out:
if (fd_signal >= 0)
if (fd_ep >= 0)
log_close();
children++;
if (count < 0) {
if (major(event->devnum) != 0 && event->devnum == loop_event->devnum && event->is_block == loop_event->is_block)
if (major(event->devnum) != 0 && (event->devnum != loop_event->devnum || event->is_block != loop_event->is_block))
const char *str;
goto out;
goto out;
stop_exec_queue = true;
stop_exec_queue = false;
reload = true;
char *key;
char *val;
children_max = i;
udev_exit = true;
out:
char *buf;
int fd;
if (fd >= 0) {
switch (signo) {
case SIGINT:
case SIGTERM:
udev_exit = true;
case SIGCHLD:
int status;
if (pid <= 0)
case SIGHUP:
reload = true;
FILE *f;
if (f == NULL)
const char *modname;
const char *devname;
const char *devno;
char type;
if (s == NULL)
if (s == NULL)
if (s == NULL)
if (s != NULL)
fclose(f);
static int mem_size_mb(void)
FILE *f;
if (f == NULL)
long int value;
fclose(f);
return memsize;
FILE *f;
if (f != NULL) {
fclose(f);
bool have_db;
const char *id;
have_db = false;
if (!have_db) {
have_db = true;
if (!have_db) {
have_db = true;
if (!have_db) {
have_db = true;
if (have_db)
int fd, n;
n = sd_listen_fds(true);
if (ctrl >= 0)
if (netlink >= 0)
FILE *f;
int daemonize = false;
goto exit;
log_open();
int option;
switch (option) {
daemonize = true;
debug = true;
resolve_names = 0;
goto exit;
goto exit;
goto exit;
goto exit;
* udev.children-max=<number of workers> events are fully serialized if set to 1
if (f != NULL) {
char *pos;
fclose(f);
if (getuid() != 0) {
goto exit;
dev_setup();
if (daemonize) {
int fd;
if (fd >= 0) {
goto exit;
goto exit;
goto exit;
goto exit;
goto exit;
goto exit;
goto exit;
if (daemonize) {
int fd;
switch (pid) {
goto exit;
goto exit_daemonize;
setsid();
if (fd >= 0) {
if (f != NULL) {
fclose(f);
if (!debug) {
int fd;
if (fd >= 0) {
if (fd_inotify < 0) {
goto exit;
if (fd_signal < 0) {
goto exit;
goto exit;
goto exit;
if (fd_ep < 0) {
goto exit;
goto exit;
if (children_max <= 0) {
if (memsize > 0)
static unsigned long long last_usec;
int fdcount;
int timeout;
if (udev_exit) {
if (fd_ctrl >= 0) {
if (fd_inotify >= 0) {
if (udev_cgroup)
if (fdcount < 0)
if (fdcount == 0) {
if (udev_exit) {
for (i = 0; i < fdcount; i++) {
is_worker = true;
is_netlink = true;
is_signal = true;
is_inotify = true;
is_ctrl = true;
reload = true;
reload = true;
if (reload) {
reload = 0;
if (is_worker)
if (is_netlink) {
if (is_signal) {
if (udev_exit)
if (is_inotify)
if (is_ctrl)
exit:
if (fd_ep >= 0)
if (fd_signal >= 0)
label_finish();
log_close();
return rc;