LCOV - code coverage report
Current view: top level - udev - udevadm-monitor.c (source / functions) Hit Total Coverage
Test: systemd_full.info Lines: 0 137 0.0 %
Date: 2019-08-23 13:36:53 Functions: 0 5 0.0 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 0 103 0.0 %

           Branch data     Line data    Source code
       1                 :            : /* SPDX-License-Identifier: GPL-2.0+ */
       2                 :            : 
       3                 :            : #include <errno.h>
       4                 :            : #include <getopt.h>
       5                 :            : #include <signal.h>
       6                 :            : 
       7                 :            : #include "sd-device.h"
       8                 :            : #include "sd-event.h"
       9                 :            : 
      10                 :            : #include "alloc-util.h"
      11                 :            : #include "device-monitor-private.h"
      12                 :            : #include "device-private.h"
      13                 :            : #include "device-util.h"
      14                 :            : #include "fd-util.h"
      15                 :            : #include "format-util.h"
      16                 :            : #include "hashmap.h"
      17                 :            : #include "set.h"
      18                 :            : #include "signal-util.h"
      19                 :            : #include "string-util.h"
      20                 :            : #include "udevadm.h"
      21                 :            : #include "virt.h"
      22                 :            : #include "time-util.h"
      23                 :            : 
      24                 :            : static bool arg_show_property = false;
      25                 :            : static bool arg_print_kernel = false;
      26                 :            : static bool arg_print_udev = false;
      27                 :            : static Set *arg_tag_filter = NULL;
      28                 :            : static Hashmap *arg_subsystem_filter = NULL;
      29                 :            : 
      30                 :          0 : static int device_monitor_handler(sd_device_monitor *monitor, sd_device *device, void *userdata) {
      31                 :          0 :         DeviceAction action = _DEVICE_ACTION_INVALID;
      32                 :          0 :         const char *devpath = NULL, *subsystem = NULL;
      33                 :          0 :         MonitorNetlinkGroup group = PTR_TO_INT(userdata);
      34                 :            :         struct timespec ts;
      35                 :            : 
      36         [ #  # ]:          0 :         assert(device);
      37   [ #  #  #  # ]:          0 :         assert(IN_SET(group, MONITOR_GROUP_UDEV, MONITOR_GROUP_KERNEL));
      38                 :            : 
      39                 :          0 :         (void) device_get_action(device, &action);
      40                 :          0 :         (void) sd_device_get_devpath(device, &devpath);
      41                 :          0 :         (void) sd_device_get_subsystem(device, &subsystem);
      42                 :            : 
      43         [ #  # ]:          0 :         assert_se(clock_gettime(CLOCK_MONOTONIC, &ts) == 0);
      44                 :            : 
      45                 :          0 :         printf("%-6s[%"PRI_TIME".%06"PRI_NSEC"] %-8s %s (%s)\n",
      46                 :            :                group == MONITOR_GROUP_UDEV ? "UDEV" : "KERNEL",
      47         [ #  # ]:          0 :                ts.tv_sec, (nsec_t)ts.tv_nsec/1000,
      48                 :            :                strna(device_action_to_string(action)),
      49                 :            :                devpath, subsystem);
      50                 :            : 
      51         [ #  # ]:          0 :         if (arg_show_property) {
      52                 :            :                 const char *key, *value;
      53                 :            : 
      54         [ #  # ]:          0 :                 FOREACH_DEVICE_PROPERTY(device, key, value)
      55                 :          0 :                         printf("%s=%s\n", key, value);
      56                 :            : 
      57                 :          0 :                 printf("\n");
      58                 :            :         }
      59                 :            : 
      60                 :          0 :         return 0;
      61                 :            : }
      62                 :            : 
      63                 :          0 : static int setup_monitor(MonitorNetlinkGroup sender, sd_event *event, sd_device_monitor **ret) {
      64                 :          0 :         _cleanup_(sd_device_monitor_unrefp) sd_device_monitor *monitor = NULL;
      65                 :            :         const char *subsystem, *devtype, *tag;
      66                 :            :         Iterator i;
      67                 :            :         int r;
      68                 :            : 
      69                 :          0 :         r = device_monitor_new_full(&monitor, sender, -1);
      70         [ #  # ]:          0 :         if (r < 0)
      71         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to create netlink socket: %m");
      72                 :            : 
      73                 :          0 :         (void) sd_device_monitor_set_receive_buffer_size(monitor, 128*1024*1024);
      74                 :            : 
      75                 :          0 :         r = sd_device_monitor_attach_event(monitor, event);
      76         [ #  # ]:          0 :         if (r < 0)
      77         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to attach event: %m");
      78                 :            : 
      79         [ #  # ]:          0 :         HASHMAP_FOREACH_KEY(devtype, subsystem, arg_subsystem_filter, i) {
      80                 :          0 :                 r = sd_device_monitor_filter_add_match_subsystem_devtype(monitor, subsystem, devtype);
      81         [ #  # ]:          0 :                 if (r < 0)
      82   [ #  #  #  # ]:          0 :                         return log_error_errno(r, "Failed to apply subsystem filter '%s%s%s': %m",
      83                 :            :                                                subsystem, devtype ? "/" : "", strempty(devtype));
      84                 :            :         }
      85                 :            : 
      86         [ #  # ]:          0 :         SET_FOREACH(tag, arg_tag_filter, i) {
      87                 :          0 :                 r = sd_device_monitor_filter_add_match_tag(monitor, tag);
      88         [ #  # ]:          0 :                 if (r < 0)
      89         [ #  # ]:          0 :                         return log_error_errno(r, "Failed to apply tag filter '%s': %m", tag);
      90                 :            :         }
      91                 :            : 
      92                 :          0 :         r = sd_device_monitor_start(monitor, device_monitor_handler, INT_TO_PTR(sender));
      93         [ #  # ]:          0 :         if (r < 0)
      94         [ #  # ]:          0 :                 return log_error_errno(r, "Failed to start device monitor: %m");
      95                 :            : 
      96         [ #  # ]:          0 :         (void) sd_event_source_set_description(sd_device_monitor_get_event_source(monitor),
      97                 :            :                                                sender == MONITOR_GROUP_UDEV ? "device-monitor-udev" : "device-monitor-kernel");
      98                 :            : 
      99                 :          0 :         *ret = TAKE_PTR(monitor);
     100                 :          0 :         return 0;
     101                 :            : }
     102                 :            : 
     103                 :          0 : static int help(void) {
     104                 :          0 :         printf("%s monitor [OPTIONS]\n\n"
     105                 :            :                "Listen to kernel and udev events.\n\n"
     106                 :            :                "  -h --help                                Show this help\n"
     107                 :            :                "  -V --version                             Show package version\n"
     108                 :            :                "  -p --property                            Print the event properties\n"
     109                 :            :                "  -k --kernel                              Print kernel uevents\n"
     110                 :            :                "  -u --udev                                Print udev events\n"
     111                 :            :                "  -s --subsystem-match=SUBSYSTEM[/DEVTYPE] Filter events by subsystem\n"
     112                 :            :                "  -t --tag-match=TAG                       Filter events by tag\n"
     113                 :            :                , program_invocation_short_name);
     114                 :            : 
     115                 :          0 :         return 0;
     116                 :            : }
     117                 :            : 
     118                 :          0 : static int parse_argv(int argc, char *argv[]) {
     119                 :            :         static const struct option options[] = {
     120                 :            :                 { "property",        no_argument,       NULL, 'p' },
     121                 :            :                 { "environment",     no_argument,       NULL, 'e' }, /* alias for -p */
     122                 :            :                 { "kernel",          no_argument,       NULL, 'k' },
     123                 :            :                 { "udev",            no_argument,       NULL, 'u' },
     124                 :            :                 { "subsystem-match", required_argument, NULL, 's' },
     125                 :            :                 { "tag-match",       required_argument, NULL, 't' },
     126                 :            :                 { "version",         no_argument,       NULL, 'V' },
     127                 :            :                 { "help",            no_argument,       NULL, 'h' },
     128                 :            :                 {}
     129                 :            :         };
     130                 :            : 
     131                 :            :         int r, c;
     132                 :            : 
     133         [ #  # ]:          0 :         while ((c = getopt_long(argc, argv, "pekus:t:Vh", options, NULL)) >= 0)
     134   [ #  #  #  #  :          0 :                 switch (c) {
             #  #  #  #  
                      # ]
     135                 :          0 :                 case 'p':
     136                 :            :                 case 'e':
     137                 :          0 :                         arg_show_property = true;
     138                 :          0 :                         break;
     139                 :          0 :                 case 'k':
     140                 :          0 :                         arg_print_kernel = true;
     141                 :          0 :                         break;
     142                 :          0 :                 case 'u':
     143                 :          0 :                         arg_print_udev = true;
     144                 :          0 :                         break;
     145                 :          0 :                 case 's': {
     146   [ #  #  #  # ]:          0 :                         _cleanup_free_ char *subsystem = NULL, *devtype = NULL;
     147                 :            :                         const char *slash;
     148                 :            : 
     149                 :          0 :                         slash = strchr(optarg, '/');
     150         [ #  # ]:          0 :                         if (slash) {
     151                 :          0 :                                 devtype = strdup(slash + 1);
     152         [ #  # ]:          0 :                                 if (!devtype)
     153                 :          0 :                                         return -ENOMEM;
     154                 :            : 
     155                 :          0 :                                 subsystem = strndup(optarg, slash - optarg);
     156                 :            :                         } else
     157                 :          0 :                                 subsystem = strdup(optarg);
     158                 :            : 
     159         [ #  # ]:          0 :                         if (!subsystem)
     160                 :          0 :                                 return -ENOMEM;
     161                 :            : 
     162                 :          0 :                         r = hashmap_ensure_allocated(&arg_subsystem_filter, NULL);
     163         [ #  # ]:          0 :                         if (r < 0)
     164                 :          0 :                                 return r;
     165                 :            : 
     166                 :          0 :                         r = hashmap_put(arg_subsystem_filter, subsystem, devtype);
     167         [ #  # ]:          0 :                         if (r < 0)
     168                 :          0 :                                 return r;
     169                 :            : 
     170                 :          0 :                         subsystem = devtype = NULL;
     171                 :          0 :                         break;
     172                 :            :                 }
     173                 :          0 :                 case 't': {
     174         [ #  # ]:          0 :                         _cleanup_free_ char *tag = NULL;
     175                 :            : 
     176                 :          0 :                         r = set_ensure_allocated(&arg_tag_filter, &string_hash_ops);
     177         [ #  # ]:          0 :                         if (r < 0)
     178                 :          0 :                                 return r;
     179                 :            : 
     180                 :          0 :                         tag = strdup(optarg);
     181         [ #  # ]:          0 :                         if (!tag)
     182                 :          0 :                                 return -ENOMEM;
     183                 :            : 
     184                 :          0 :                         r = set_put(arg_tag_filter, tag);
     185         [ #  # ]:          0 :                         if (r < 0)
     186                 :          0 :                                 return r;
     187                 :            : 
     188                 :          0 :                         tag = NULL;
     189                 :          0 :                         break;
     190                 :            :                 }
     191                 :          0 :                 case 'V':
     192                 :          0 :                         return print_version();
     193                 :          0 :                 case 'h':
     194                 :          0 :                         return help();
     195                 :          0 :                 case '?':
     196                 :          0 :                         return -EINVAL;
     197                 :          0 :                 default:
     198                 :          0 :                         assert_not_reached("Unknown option.");
     199                 :            :                 }
     200                 :            : 
     201   [ #  #  #  # ]:          0 :         if (!arg_print_kernel && !arg_print_udev) {
     202                 :          0 :                 arg_print_kernel = true;
     203                 :          0 :                 arg_print_udev = true;
     204                 :            :         }
     205                 :            : 
     206                 :          0 :         return 1;
     207                 :            : }
     208                 :            : 
     209                 :          0 : int monitor_main(int argc, char *argv[], void *userdata) {
     210                 :          0 :         _cleanup_(sd_device_monitor_unrefp) sd_device_monitor *kernel_monitor = NULL, *udev_monitor = NULL;
     211                 :          0 :         _cleanup_(sd_event_unrefp) sd_event *event = NULL;
     212                 :            :         int r;
     213                 :            : 
     214                 :          0 :         r = parse_argv(argc, argv);
     215         [ #  # ]:          0 :         if (r <= 0)
     216                 :          0 :                 goto finalize;
     217                 :            : 
     218         [ #  # ]:          0 :         if (running_in_chroot() > 0) {
     219         [ #  # ]:          0 :                 log_info("Running in chroot, ignoring request.");
     220                 :          0 :                 return 0;
     221                 :            :         }
     222                 :            : 
     223                 :            :         /* Callers are expecting to see events as they happen: Line buffering */
     224                 :          0 :         setlinebuf(stdout);
     225                 :            : 
     226                 :          0 :         r = sd_event_default(&event);
     227         [ #  # ]:          0 :         if (r < 0) {
     228         [ #  # ]:          0 :                 log_error_errno(r, "Failed to initialize event: %m");
     229                 :          0 :                 goto finalize;
     230                 :            :         }
     231                 :            : 
     232         [ #  # ]:          0 :         assert_se(sigprocmask_many(SIG_UNBLOCK, NULL, SIGTERM, SIGINT, -1) >= 0);
     233                 :          0 :         (void) sd_event_add_signal(event, NULL, SIGTERM, NULL, NULL);
     234                 :          0 :         (void) sd_event_add_signal(event, NULL, SIGINT, NULL, NULL);
     235                 :            : 
     236                 :          0 :         printf("monitor will print the received events for:\n");
     237         [ #  # ]:          0 :         if (arg_print_udev) {
     238                 :          0 :                 r = setup_monitor(MONITOR_GROUP_UDEV, event, &udev_monitor);
     239         [ #  # ]:          0 :                 if (r < 0)
     240                 :          0 :                         goto finalize;
     241                 :            : 
     242                 :          0 :                 printf("UDEV - the event which udev sends out after rule processing\n");
     243                 :            :         }
     244                 :            : 
     245         [ #  # ]:          0 :         if (arg_print_kernel) {
     246                 :          0 :                 r = setup_monitor(MONITOR_GROUP_KERNEL, event, &kernel_monitor);
     247         [ #  # ]:          0 :                 if (r < 0)
     248                 :          0 :                         goto finalize;
     249                 :            : 
     250                 :          0 :                 printf("KERNEL - the kernel uevent\n");
     251                 :            :         }
     252                 :          0 :         printf("\n");
     253                 :            : 
     254                 :          0 :         r = sd_event_loop(event);
     255         [ #  # ]:          0 :         if (r < 0) {
     256         [ #  # ]:          0 :                 log_error_errno(r, "Failed to run event loop: %m");
     257                 :          0 :                 goto finalize;
     258                 :            :         }
     259                 :            : 
     260                 :          0 :         r = 0;
     261                 :            : 
     262                 :          0 : finalize:
     263                 :          0 :         hashmap_free_free_free(arg_subsystem_filter);
     264                 :          0 :         set_free_free(arg_tag_filter);
     265                 :            : 
     266                 :          0 :         return r;
     267                 :            : }

Generated by: LCOV version 1.14