udevadm-monitor.c revision 116254097ad3c07d9f7ed06042dbec7ba4f0f4fd
fb0951b02ebf51a93acf12721d8857d31ce57ba3Lennart Poettering/*
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering * Copyright (C) 2004-2008 Kay Sievers <kay.sievers@vrfy.org>
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering *
3e2147858f21943d5f4a781c60f33ac22c6096edKay Sievers * This program is free software: you can redistribute it and/or modify
3e2147858f21943d5f4a781c60f33ac22c6096edKay Sievers * it under the terms of the GNU General Public License as published by
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering * the Free Software Foundation, either version 2 of the License, or
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering * (at your option) any later version.
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering *
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering * This program is distributed in the hope that it will be useful,
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering * but WITHOUT ANY WARRANTY; without even the implied warranty of
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering * GNU General Public License for more details.
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering *
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering * You should have received a copy of the GNU General Public License
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering * along with this program. If not, see <http://www.gnu.org/licenses/>.
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering */
5430f7f2bc7330f3088b894166bf3524a067e3d8Lennart Poettering
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering#include <unistd.h>
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering#include <stdio.h>
4e949c11a1df4547d5f102e4131e07b026369cd7Javier Jardón#include <stdlib.h>
4e949c11a1df4547d5f102e4131e07b026369cd7Javier Jardón#include <stddef.h>
4e949c11a1df4547d5f102e4131e07b026369cd7Javier Jardón#include <string.h>
139ee8cc316a861bcc8a8ebdf4a8449dffe16f79Lennart Poettering#include <fcntl.h>
4e949c11a1df4547d5f102e4131e07b026369cd7Javier Jardón#include <errno.h>
4e949c11a1df4547d5f102e4131e07b026369cd7Javier Jardón#include <signal.h>
4e949c11a1df4547d5f102e4131e07b026369cd7Javier Jardón#include <getopt.h>
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering#include <sys/time.h>
78a825f216d39ee0295b00647b059d45467e1d02Kay Sievers#include <sys/socket.h>
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering#include <sys/un.h>
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering#include <sys/select.h>
a80db8bd5f7f15859e8891aab9fc3694ce4cd0bdJavier Jardón#include <linux/types.h>
a80db8bd5f7f15859e8891aab9fc3694ce4cd0bdJavier Jardón#include <linux/netlink.h>
4db6d587c37c0357d20c79bf1a7c9afd4c7ced61Kay Sievers
907dd1953b7517534d646f5b2777780020c896e2Kay Sievers#include "udev.h"
eb7bbee6cd182d5c4eb1e1180631c35158f59379Kay Sievers
bbd9b8c2139a70005e4e83d198575e2a10fe1db2Lennart Poetteringstatic int udev_exit;
3e2147858f21943d5f4a781c60f33ac22c6096edKay Sievers
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poetteringstatic void asmlinkage sig_handler(int signum)
22be093ffb403a1c474037939ca9b88b1ee39f77Lennart Poettering{
d59d0a2b4b41a75eaf618b26b8f8bd1e17de7e2bcee if (signum == SIGINT || signum == SIGTERM)
d59d0a2b4b41a75eaf618b26b8f8bd1e17de7e2bcee udev_exit = 1;
d59d0a2b4b41a75eaf618b26b8f8bd1e17de7e2bcee}
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering
3e2147858f21943d5f4a781c60f33ac22c6096edKay Sieversstatic void print_device(struct udev_device *device, const char *source, int env)
3e2147858f21943d5f4a781c60f33ac22c6096edKay Sievers{
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering struct timeval tv;
1c7dde3e475978c569a982d65fd86d4b4e3caad8Bastien Nocera struct timezone tz;
1c7dde3e475978c569a982d65fd86d4b4e3caad8Bastien Nocera
1c7dde3e475978c569a982d65fd86d4b4e3caad8Bastien Nocera gettimeofday(&tv, &tz);
1c7dde3e475978c569a982d65fd86d4b4e3caad8Bastien Nocera printf("%-6s[%llu.%06u] %-8s %s (%s)\n",
1c7dde3e475978c569a982d65fd86d4b4e3caad8Bastien Nocera source,
1c7dde3e475978c569a982d65fd86d4b4e3caad8Bastien Nocera (unsigned long long) tv.tv_sec, (unsigned int) tv.tv_usec,
e9da3678fcfc774b325dc1eaa054d0e00028a1fcLennart Poettering udev_device_get_action(device),
e9da3678fcfc774b325dc1eaa054d0e00028a1fcLennart Poettering udev_device_get_devpath(device),
e9da3678fcfc774b325dc1eaa054d0e00028a1fcLennart Poettering udev_device_get_subsystem(device));
3ce4fad8f548db9edb19869ea540e3192d2123f4Kay Sievers if (env) {
f975e971accc4d50c73ae53167db3df7a7099cf2Lennart Poettering struct udev_list_entry *list_entry;
e9da3678fcfc774b325dc1eaa054d0e00028a1fcLennart Poettering
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(device))
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering printf("%s=%s\n",
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering udev_list_entry_get_name(list_entry),
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering udev_list_entry_get_value(list_entry));
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering printf("\n");
3e2147858f21943d5f4a781c60f33ac22c6096edKay Sievers }
fe1fed02c7637a2c18cd575f78be7fda27972148Zbigniew Jędrzejewski-Szmek}
92ec4495f76a7a2a6c31f5bb2a5240f78dcfe1d2Javier Jardón
86b2e20a5e5abf222fb81edcb5d58d012e35cbaaLennart Poetteringint udevadm_monitor(struct udev *udev, int argc, char *argv[])
86b2e20a5e5abf222fb81edcb5d58d012e35cbaaLennart Poettering{
b51fc639f01ee6194af3e7e944a79accce474fe1Dave Reisner struct sigaction act;
86b2e20a5e5abf222fb81edcb5d58d012e35cbaaLennart Poettering int option;
86b2e20a5e5abf222fb81edcb5d58d012e35cbaaLennart Poettering int env = 0;
c1c02e07ed87e027a6364c4f4aa2468796ca1c56Dave Reisner int print_kernel = 0;
96ede2601f27cd5fe52eed96b873bef55cd0ce23Lennart Poettering int print_udev = 0;
80a5cbace45a6adbf2f9119edc5a4b10db493064Kay Sievers struct udev_monitor *udev_monitor = NULL;
92ec4495f76a7a2a6c31f5bb2a5240f78dcfe1d2Javier Jardón struct udev_monitor *kernel_monitor = NULL;
9e45e7d8f0d8d3f31d790f85694585d0d4b368b8Javier Jardón fd_set readfds;
6e92b23f0d6dd398848376bbaf47e54a90ed3389Kay Sievers int rc = 0;
92ec4495f76a7a2a6c31f5bb2a5240f78dcfe1d2Javier Jardón
fe1fed02c7637a2c18cd575f78be7fda27972148Zbigniew Jędrzejewski-Szmek static const struct option options[] = {
fe1fed02c7637a2c18cd575f78be7fda27972148Zbigniew Jędrzejewski-Szmek { "environment", no_argument, NULL, 'e' },
fe1fed02c7637a2c18cd575f78be7fda27972148Zbigniew Jędrzejewski-Szmek { "kernel", no_argument, NULL, 'k' },
fe1fed02c7637a2c18cd575f78be7fda27972148Zbigniew Jędrzejewski-Szmek { "udev", no_argument, NULL, 'u' },
6e92b23f0d6dd398848376bbaf47e54a90ed3389Kay Sievers { "help", no_argument, NULL, 'h' },
0eaeca1f2373a323b98c86b47561d98e59c67b25Kay Sievers {}
6e92b23f0d6dd398848376bbaf47e54a90ed3389Kay Sievers };
3e2147858f21943d5f4a781c60f33ac22c6096edKay Sievers
8d7e170a5230753d8406276f8b5598e5bb6766e6Lennart Poettering while (1) {
8d7e170a5230753d8406276f8b5598e5bb6766e6Lennart Poettering option = getopt_long(argc, argv, "ekuh", options, NULL);
8d7e170a5230753d8406276f8b5598e5bb6766e6Lennart Poettering if (option == -1)
b62cfcea00862ccbf0e5e297f8a339f70987edefMichael Biebl break;
b62cfcea00862ccbf0e5e297f8a339f70987edefMichael Biebl
b62cfcea00862ccbf0e5e297f8a339f70987edefMichael Biebl switch (option) {
9a60da2834074d970ca063c210fe9d2f05c70532Thierry Reding case 'e':
8d7e170a5230753d8406276f8b5598e5bb6766e6Lennart Poettering env = 1;
8d7e170a5230753d8406276f8b5598e5bb6766e6Lennart Poettering break;
8d7e170a5230753d8406276f8b5598e5bb6766e6Lennart Poettering case 'k':
78fbaacac004f912ec84b6f57d0bc656c3c95439Wulf C. Krueger print_kernel = 1;
78fbaacac004f912ec84b6f57d0bc656c3c95439Wulf C. Krueger break;
78fbaacac004f912ec84b6f57d0bc656c3c95439Wulf C. Krueger case 'u':
78fbaacac004f912ec84b6f57d0bc656c3c95439Wulf C. Krueger print_udev = 1;
78fbaacac004f912ec84b6f57d0bc656c3c95439Wulf C. Krueger break;
78fbaacac004f912ec84b6f57d0bc656c3c95439Wulf C. Krueger case 'h':
568c7e02372ff7b8eb41172ad7c3a426723512f8Zbigniew Jędrzejewski-Szmek printf("Usage: udevadm monitor [--environment] [--kernel] [--udev] [--help]\n"
78fbaacac004f912ec84b6f57d0bc656c3c95439Wulf C. Krueger " --env print the whole event environment\n"
8d7e170a5230753d8406276f8b5598e5bb6766e6Lennart Poettering " --kernel print kernel uevents\n"
568c7e02372ff7b8eb41172ad7c3a426723512f8Zbigniew Jędrzejewski-Szmek " --udev print udev events\n"
568c7e02372ff7b8eb41172ad7c3a426723512f8Zbigniew Jędrzejewski-Szmek " --help\n\n");
568c7e02372ff7b8eb41172ad7c3a426723512f8Zbigniew Jędrzejewski-Szmek default:
568c7e02372ff7b8eb41172ad7c3a426723512f8Zbigniew Jędrzejewski-Szmek goto out;
568c7e02372ff7b8eb41172ad7c3a426723512f8Zbigniew Jędrzejewski-Szmek }
568c7e02372ff7b8eb41172ad7c3a426723512f8Zbigniew Jędrzejewski-Szmek }
568c7e02372ff7b8eb41172ad7c3a426723512f8Zbigniew Jędrzejewski-Szmek
568c7e02372ff7b8eb41172ad7c3a426723512f8Zbigniew Jędrzejewski-Szmek if (!print_kernel && !print_udev) {
568c7e02372ff7b8eb41172ad7c3a426723512f8Zbigniew Jędrzejewski-Szmek print_kernel = 1;
568c7e02372ff7b8eb41172ad7c3a426723512f8Zbigniew Jędrzejewski-Szmek print_udev =1;
568c7e02372ff7b8eb41172ad7c3a426723512f8Zbigniew Jędrzejewski-Szmek }
8d7e170a5230753d8406276f8b5598e5bb6766e6Lennart Poettering
9c4fa6ed1069e98db5f01a5d1056b443a04cc7d9Lennart Poettering /* set signal handlers */
eb2e280f9c59b66965c9316eadc4c113a13ca744Lucas De Marchi memset(&act, 0x00, sizeof(struct sigaction));
be1a67d9d63bfdd4a5f8ba9cfc804030f10f5833Lennart Poettering act.sa_handler = (void (*)(int)) sig_handler;
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering sigemptyset(&act.sa_mask);
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering act.sa_flags = SA_RESTART;
27765dfc7a32d790badb29e6498b34edb0b60c33Lennart Poettering sigaction(SIGINT, &act, NULL);
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering sigaction(SIGTERM, &act, NULL);
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering printf("monitor will print the received events for:\n");
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering if (print_udev) {
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering udev_monitor = udev_monitor_new_from_netlink(udev, UDEV_MONITOR_UDEV);
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering if (udev_monitor == NULL) {
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering rc = 1;
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering goto out;
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering }
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering if (udev_monitor_enable_receiving(udev_monitor) < 0) {
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering rc = 2;
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering goto out;
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering }
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering printf("UDEV - the event which udev sends out after rule processing\n");
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering }
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering if (print_kernel) {
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering kernel_monitor = udev_monitor_new_from_netlink(udev, UDEV_MONITOR_KERNEL);
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering if (kernel_monitor == NULL) {
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering fprintf(stderr, "unable to subscribe to kernel events\n");
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering rc = 3;
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering goto out;
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering }
be1a67d9d63bfdd4a5f8ba9cfc804030f10f5833Lennart Poettering if (udev_monitor_enable_receiving(kernel_monitor) < 0) {
be1a67d9d63bfdd4a5f8ba9cfc804030f10f5833Lennart Poettering rc = 4;
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering goto out;
be1a67d9d63bfdd4a5f8ba9cfc804030f10f5833Lennart Poettering }
8745297f9853c4a17bac69e1b7e652fe81bc1940Lennart Poettering printf("UEVENT - the kernel uevent\n");
d200735e13c52dcfe36c0e066f9f6c2fbfb85a9cMichal Schmidt }
be1a67d9d63bfdd4a5f8ba9cfc804030f10f5833Lennart Poettering printf("\n");
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering while (!udev_exit) {
9b85fc6a89386582bfe792dba881800b0a093839Gustavo Sverzut Barbieri int fdcount;
9b85fc6a89386582bfe792dba881800b0a093839Gustavo Sverzut Barbieri
9b85fc6a89386582bfe792dba881800b0a093839Gustavo Sverzut Barbieri FD_ZERO(&readfds);
5a45a93627609451784a04366cfa1150d32611d1Lennart Poettering if (kernel_monitor != NULL)
c1663b9daf5a43425e54bbe3daf6b10e64578f80Lennart Poettering FD_SET(udev_monitor_get_fd(kernel_monitor), &readfds);
c1663b9daf5a43425e54bbe3daf6b10e64578f80Lennart Poettering if (udev_monitor != NULL)
5a45a93627609451784a04366cfa1150d32611d1Lennart Poettering FD_SET(udev_monitor_get_fd(udev_monitor), &readfds);
5a45a93627609451784a04366cfa1150d32611d1Lennart Poettering
5a45a93627609451784a04366cfa1150d32611d1Lennart Poettering fdcount = select(UDEV_MAX(udev_monitor_get_fd(kernel_monitor), udev_monitor_get_fd(udev_monitor))+1,
5a45a93627609451784a04366cfa1150d32611d1Lennart Poettering &readfds, NULL, NULL, NULL);
5a45a93627609451784a04366cfa1150d32611d1Lennart Poettering if (fdcount < 0) {
9e7adc3ae1133fa08a468768a490812299fad030Lucas De Marchi if (errno != EINTR)
9e7adc3ae1133fa08a468768a490812299fad030Lucas De Marchi fprintf(stderr, "error receiving uevent message: %m\n");
9b85fc6a89386582bfe792dba881800b0a093839Gustavo Sverzut Barbieri continue;
5a45a93627609451784a04366cfa1150d32611d1Lennart Poettering }
5a45a93627609451784a04366cfa1150d32611d1Lennart Poettering
5a45a93627609451784a04366cfa1150d32611d1Lennart Poettering if ((kernel_monitor != NULL) && FD_ISSET(udev_monitor_get_fd(kernel_monitor), &readfds)) {
5a45a93627609451784a04366cfa1150d32611d1Lennart Poettering struct udev_device *device;
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering
e17187091d463ad008c0b74eb04de5078b2abb96Michal Schmidt device = udev_monitor_receive_device(kernel_monitor);
afea26ad7d406d8b6c95d2642cb5a1d807b87546Lennart Poettering if (device == NULL)
85f19d825e7504676f3a80c78c1d9a7ec35a3b3fMichael Biebl continue;
85f19d825e7504676f3a80c78c1d9a7ec35a3b3fMichael Biebl print_device(device, "UEVENT", env);
85f19d825e7504676f3a80c78c1d9a7ec35a3b3fMichael Biebl udev_device_unref(device);
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering }
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering
85f19d825e7504676f3a80c78c1d9a7ec35a3b3fMichael Biebl if ((udev_monitor != NULL) && FD_ISSET(udev_monitor_get_fd(udev_monitor), &readfds)) {
85f19d825e7504676f3a80c78c1d9a7ec35a3b3fMichael Biebl struct udev_device *device;
85f19d825e7504676f3a80c78c1d9a7ec35a3b3fMichael Biebl
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering device = udev_monitor_receive_device(udev_monitor);
9388e99e208a6487b26dcbda86005ee9eba8d93dMichael Olbrich if (device == NULL)
4db17f291c627c885de668200ff8cce2e57c933fZbigniew Jędrzejewski-Szmek continue;
9388e99e208a6487b26dcbda86005ee9eba8d93dMichael Olbrich print_device(device, "UDEV", env);
a8348796c0d39435b1c3d85ce6e95dad1ac85fecLennart Poettering udev_device_unref(device);
9388e99e208a6487b26dcbda86005ee9eba8d93dMichael Olbrich }
9388e99e208a6487b26dcbda86005ee9eba8d93dMichael Olbrich }
a8348796c0d39435b1c3d85ce6e95dad1ac85fecLennart Poettering
b237ef2cfac7ab0b33170809e8cb64628606207dTollef Fog Heenout:
a9b5b03212f9c854938483b8901e433c2ba6619bMichael Tremer udev_monitor_unref(udev_monitor);
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering udev_monitor_unref(kernel_monitor);
3e2147858f21943d5f4a781c60f33ac22c6096edKay Sievers return rc;
e30431623a7d871da123cc37055ac49abf2c20eaTom Gundersen}
e30431623a7d871da123cc37055ac49abf2c20eaTom Gundersen