udevadm-settle.c revision 2ac23519d04835e8d8dfbce3d08d9ff76db58a68
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering/*
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering * Copyright (C) 2006-2009 Kay Sievers <kay@vrfy.org>
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering * Copyright (C) 2009 Canonical Ltd.
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering * Copyright (C) 2009 Scott James Remnant <scott@netsplit.com>
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering *
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering * This program is free software: you can redistribute it and/or modify
2f6a59070559786428d9eaf199ae3d61772b2225Kay Sievers * it under the terms of the GNU General Public License as published by
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering * the Free Software Foundation, either version 2 of the License, or
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering * (at your option) any later version.
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering *
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering * This program is distributed in the hope that it will be useful,
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering * but WITHOUT ANY WARRANTY; without even the implied warranty of
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering * GNU General Public License for more details.
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering *
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering * You should have received a copy of the GNU General Public License
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering * along with this program. If not, see <http://www.gnu.org/licenses/>.
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering */
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering#include <stdlib.h>
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering#include <stddef.h>
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering#include <string.h>
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering#include <stdio.h>
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering#include <unistd.h>
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering#include <errno.h>
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering#include <dirent.h>
a9cdc94f7ff40f22a3cf9472f612a80730a1b010Dave Reisner#include <fcntl.h>
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering#include <getopt.h>
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering#include <signal.h>
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering#include <time.h>
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen#include <sys/poll.h>
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen#include <sys/stat.h>
a281d9c7851b16c4c9195d042901540ee9ced799Thomas Hindoe Paaboel Andersen#include <sys/types.h>
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering#include "udev.h"
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering#include "udev-util.h"
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering#include "util.h"
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
f18ca9dcdeda247e208f7143e834fd2fb2070d80Kay Sieversstatic void help(void) {
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering printf("%s settle OPTIONS\n\n"
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering "Wait for pending udev events.\n\n"
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering " -h --help Show this help\n"
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering " --version Show package version\n"
7085053a437456ab87d726f3697002dd811fdf7aDaniel Wallace " -t --timeout=SECONDS Maximum time to wait for events\n"
e1636421f46db6d06fbd028ef20a3113fa3e11f8Lennart Poettering " -E --exit-if-exists=FILE Stop waiting if file exists\n"
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering , program_invocation_short_name);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering}
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poetteringstatic int adm_settle(struct udev *udev, int argc, char *argv[]) {
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering static const struct option options[] = {
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering { "timeout", required_argument, NULL, 't' },
1b12a7b5896f94bdf33b3a6661ebabd761ea6adcHarald Hoyer { "exit-if-exists", required_argument, NULL, 'E' },
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering { "help", no_argument, NULL, 'h' },
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering { "seq-start", required_argument, NULL, 's' }, /* removed */
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering { "seq-end", required_argument, NULL, 'e' }, /* removed */
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering { "quiet", no_argument, NULL, 'q' }, /* removed */
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering {}
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering };
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering const char *exists = NULL;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering unsigned int timeout = 120;
46e65dcc3a522b5e992e165b5e61d14254026859Lennart Poettering struct pollfd pfd[1] = { {.fd = -1}, };
46e65dcc3a522b5e992e165b5e61d14254026859Lennart Poettering int c;
46e65dcc3a522b5e992e165b5e61d14254026859Lennart Poettering struct udev_queue *queue;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering int rc = EXIT_FAILURE;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering while ((c = getopt_long(argc, argv, "t:E:hs:e:q", options, NULL)) >= 0) {
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering switch (c) {
2f6a59070559786428d9eaf199ae3d61772b2225Kay Sievers
ffc06c3513d9a0693c7f810d03b20705127ba55aKay Sievers case 't': {
2f6a59070559786428d9eaf199ae3d61772b2225Kay Sievers int r;
2f6a59070559786428d9eaf199ae3d61772b2225Kay Sievers
2f6a59070559786428d9eaf199ae3d61772b2225Kay Sievers r = safe_atou(optarg, &timeout);
2f6a59070559786428d9eaf199ae3d61772b2225Kay Sievers if (r < 0) {
2f6a59070559786428d9eaf199ae3d61772b2225Kay Sievers fprintf(stderr, "Invalid timeout value '%s': %s\n",
2f6a59070559786428d9eaf199ae3d61772b2225Kay Sievers optarg, strerror(-r));
2f6a59070559786428d9eaf199ae3d61772b2225Kay Sievers exit(EXIT_FAILURE);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering };
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering break;
2311eb2ff0c3ff80ec3645b02c97170c9a565454Kay Sievers }
2311eb2ff0c3ff80ec3645b02c97170c9a565454Kay Sievers
2311eb2ff0c3ff80ec3645b02c97170c9a565454Kay Sievers case 'E':
2311eb2ff0c3ff80ec3645b02c97170c9a565454Kay Sievers exists = optarg;
2311eb2ff0c3ff80ec3645b02c97170c9a565454Kay Sievers break;
2311eb2ff0c3ff80ec3645b02c97170c9a565454Kay Sievers
2311eb2ff0c3ff80ec3645b02c97170c9a565454Kay Sievers case 'h':
2311eb2ff0c3ff80ec3645b02c97170c9a565454Kay Sievers help();
2311eb2ff0c3ff80ec3645b02c97170c9a565454Kay Sievers return EXIT_SUCCESS;
2311eb2ff0c3ff80ec3645b02c97170c9a565454Kay Sievers
2311eb2ff0c3ff80ec3645b02c97170c9a565454Kay Sievers case 's':
2311eb2ff0c3ff80ec3645b02c97170c9a565454Kay Sievers case 'e':
2311eb2ff0c3ff80ec3645b02c97170c9a565454Kay Sievers case 'q':
2311eb2ff0c3ff80ec3645b02c97170c9a565454Kay Sievers log_info("Option -%c no longer supported.", c);
2311eb2ff0c3ff80ec3645b02c97170c9a565454Kay Sievers return EXIT_FAILURE;
2311eb2ff0c3ff80ec3645b02c97170c9a565454Kay Sievers
ffc06c3513d9a0693c7f810d03b20705127ba55aKay Sievers case '?':
f18ca9dcdeda247e208f7143e834fd2fb2070d80Kay Sievers return EXIT_FAILURE;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
2311eb2ff0c3ff80ec3645b02c97170c9a565454Kay Sievers default:
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering assert_not_reached("Unknown argument");
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering }
9ff09bcb86fb125768667aca9bc0b10b1745370aShawn Landden }
480a61ae742378a6a9a0eb84cf29c6c1e4ea22ffLennart Poettering
f18ca9dcdeda247e208f7143e834fd2fb2070d80Kay Sievers if (optind < argc) {
480a61ae742378a6a9a0eb84cf29c6c1e4ea22ffLennart Poettering fprintf(stderr, "Extraneous argument: '%s'\n", argv[optind]);
480a61ae742378a6a9a0eb84cf29c6c1e4ea22ffLennart Poettering return EXIT_FAILURE;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering }
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
599659860c770058f2eb04d578c521c16e0b1853Lennart Poettering /* guarantee that the udev daemon isn't pre-processing */
599659860c770058f2eb04d578c521c16e0b1853Lennart Poettering if (getuid() == 0) {
2f6a59070559786428d9eaf199ae3d61772b2225Kay Sievers struct udev_ctrl *uctrl;
2311eb2ff0c3ff80ec3645b02c97170c9a565454Kay Sievers
07a062a79374406e8f6b5a1e2f80c80baf031567Jason St. John uctrl = udev_ctrl_new(udev);
2311eb2ff0c3ff80ec3645b02c97170c9a565454Kay Sievers if (uctrl != NULL) {
2311eb2ff0c3ff80ec3645b02c97170c9a565454Kay Sievers if (udev_ctrl_send_ping(uctrl, timeout) < 0) {
2311eb2ff0c3ff80ec3645b02c97170c9a565454Kay Sievers log_debug("no connection to daemon");
9ff09bcb86fb125768667aca9bc0b10b1745370aShawn Landden udev_ctrl_unref(uctrl);
9ff09bcb86fb125768667aca9bc0b10b1745370aShawn Landden return EXIT_SUCCESS;
9ff09bcb86fb125768667aca9bc0b10b1745370aShawn Landden }
9ff09bcb86fb125768667aca9bc0b10b1745370aShawn Landden udev_ctrl_unref(uctrl);
9ff09bcb86fb125768667aca9bc0b10b1745370aShawn Landden }
9ff09bcb86fb125768667aca9bc0b10b1745370aShawn Landden }
9ff09bcb86fb125768667aca9bc0b10b1745370aShawn Landden
07a062a79374406e8f6b5a1e2f80c80baf031567Jason St. John queue = udev_queue_new(udev);
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering if (!queue) {
9ff09bcb86fb125768667aca9bc0b10b1745370aShawn Landden log_error("unable to get udev queue");
9ff09bcb86fb125768667aca9bc0b10b1745370aShawn Landden return EXIT_FAILURE;
9ff09bcb86fb125768667aca9bc0b10b1745370aShawn Landden }
9ff09bcb86fb125768667aca9bc0b10b1745370aShawn Landden
9ff09bcb86fb125768667aca9bc0b10b1745370aShawn Landden pfd[0].events = POLLIN;
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering pfd[0].fd = udev_queue_get_fd(queue);
9ff09bcb86fb125768667aca9bc0b10b1745370aShawn Landden if (pfd[0].fd < 0) {
9ff09bcb86fb125768667aca9bc0b10b1745370aShawn Landden log_debug("queue is empty, nothing to watch");
9ff09bcb86fb125768667aca9bc0b10b1745370aShawn Landden rc = EXIT_SUCCESS;
9ff09bcb86fb125768667aca9bc0b10b1745370aShawn Landden goto out;
9ff09bcb86fb125768667aca9bc0b10b1745370aShawn Landden }
9ff09bcb86fb125768667aca9bc0b10b1745370aShawn Landden
9ff09bcb86fb125768667aca9bc0b10b1745370aShawn Landden for (;;) {
9ff09bcb86fb125768667aca9bc0b10b1745370aShawn Landden if (exists && access(exists, F_OK) >= 0) {
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering rc = EXIT_SUCCESS;
2f6a59070559786428d9eaf199ae3d61772b2225Kay Sievers break;
2f6a59070559786428d9eaf199ae3d61772b2225Kay Sievers }
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
2f6a59070559786428d9eaf199ae3d61772b2225Kay Sievers /* exit if queue is empty */
2f6a59070559786428d9eaf199ae3d61772b2225Kay Sievers if (udev_queue_get_queue_is_empty(queue)) {
7f35b7bc4a241e9aa3b1512fd345cbf5b2e5a782Kay Sievers rc = EXIT_SUCCESS;
f18ca9dcdeda247e208f7143e834fd2fb2070d80Kay Sievers break;
f18ca9dcdeda247e208f7143e834fd2fb2070d80Kay Sievers }
2f6a59070559786428d9eaf199ae3d61772b2225Kay Sievers
9ff09bcb86fb125768667aca9bc0b10b1745370aShawn Landden /* wake up when queue is empty */
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering if (poll(pfd, 1, MSEC_PER_SEC) > 0 && pfd[0].revents & POLLIN)
2667cc25896a15f82f9f1583e80d416beb1316e1Thomas Hindoe Paaboel Andersen udev_queue_flush(queue);
2667cc25896a15f82f9f1583e80d416beb1316e1Thomas Hindoe Paaboel Andersen }
2667cc25896a15f82f9f1583e80d416beb1316e1Thomas Hindoe Paaboel Andersen
2667cc25896a15f82f9f1583e80d416beb1316e1Thomas Hindoe Paaboel Andersenout:
2667cc25896a15f82f9f1583e80d416beb1316e1Thomas Hindoe Paaboel Andersen udev_queue_unref(queue);
2667cc25896a15f82f9f1583e80d416beb1316e1Thomas Hindoe Paaboel Andersen return rc;
07a062a79374406e8f6b5a1e2f80c80baf031567Jason St. John}
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poetteringconst struct udevadm_cmd udevadm_settle = {
6d0274f11547a0f11200bb82bf598a5a253e12cfLennart Poettering .name = "settle",
2667cc25896a15f82f9f1583e80d416beb1316e1Thomas Hindoe Paaboel Andersen .cmd = adm_settle,
2f6a59070559786428d9eaf199ae3d61772b2225Kay Sievers .help = "Wait for pending udev events",
2f6a59070559786428d9eaf199ae3d61772b2225Kay Sievers};
2f6a59070559786428d9eaf199ae3d61772b2225Kay Sievers