udevadm-info,trigger: replace udev_device by sd_device

This commit is contained in:
Yu Watanabe 2018-08-29 17:28:05 +09:00
parent a46556f77d
commit 13aca84769
4 changed files with 203 additions and 194 deletions

View file

@ -10,10 +10,15 @@
#include <sys/stat.h>
#include <unistd.h>
#include "sd-device.h"
#include "device-enumerator-private.h"
#include "device-private.h"
#include "device-util.h"
#include "dirent-util.h"
#include "fd-util.h"
#include "libudev-private.h"
#include "string-util.h"
#include "udev.h"
#include "udevadm.h"
#include "udevadm-util.h"
@ -35,22 +40,15 @@ static bool skip_attribute(const char *name) {
return false;
}
static void print_all_attributes(struct udev_device *device, const char *key) {
struct udev_list_entry *sysattr;
static void print_all_attributes(sd_device *device, const char *key) {
const char *name, *value;
udev_list_entry_foreach(sysattr, udev_device_get_sysattr_list_entry(device)) {
const char *name;
const char *value;
FOREACH_DEVICE_PROPERTY(device, name, value) {
size_t len;
name = udev_list_entry_get_name(sysattr);
if (skip_attribute(name))
continue;
value = udev_device_get_sysattr_value(device, name);
if (value == NULL)
continue;
/* skip any values that look like a path */
if (value[0] == '/')
continue;
@ -67,8 +65,8 @@ static void print_all_attributes(struct udev_device *device, const char *key) {
printf("\n");
}
static int print_device_chain(struct udev_device *device) {
struct udev_device *device_parent;
static int print_device_chain(sd_device *device) {
sd_device *child, *parent;
const char *str;
printf("\n"
@ -79,62 +77,54 @@ static int print_device_chain(struct udev_device *device) {
"and the attributes from one single parent device.\n"
"\n");
printf(" looking at device '%s':\n", udev_device_get_devpath(device));
printf(" KERNEL==\"%s\"\n", udev_device_get_sysname(device));
str = udev_device_get_subsystem(device);
if (str == NULL)
(void) sd_device_get_devpath(device, &str);
printf(" looking at device '%s':\n", str);
(void) sd_device_get_sysname(device, &str);
printf(" KERNEL==\"%s\"\n", str);
if (sd_device_get_subsystem(device, &str) < 0)
str = "";
printf(" SUBSYSTEM==\"%s\"\n", str);
str = udev_device_get_driver(device);
if (str == NULL)
if (sd_device_get_driver(device, &str) < 0)
str = "";
printf(" DRIVER==\"%s\"\n", str);
print_all_attributes(device, "ATTR");
device_parent = device;
do {
device_parent = udev_device_get_parent(device_parent);
if (device_parent == NULL)
break;
printf(" looking at parent device '%s':\n", udev_device_get_devpath(device_parent));
printf(" KERNELS==\"%s\"\n", udev_device_get_sysname(device_parent));
str = udev_device_get_subsystem(device_parent);
if (str == NULL)
for (child = device; sd_device_get_parent(child, &parent) >= 0; child = parent) {
(void) sd_device_get_devpath(parent, &str);
printf(" looking at parent device '%s':\n", str);
(void) sd_device_get_sysname(parent, &str);
printf(" KERNELS==\"%s\"\n", str);
if (sd_device_get_subsystem(parent, &str) < 0)
str = "";
printf(" SUBSYSTEMS==\"%s\"\n", str);
str = udev_device_get_driver(device_parent);
if (str == NULL)
if (sd_device_get_driver(parent, &str) < 0)
str = "";
printf(" DRIVERS==\"%s\"\n", str);
print_all_attributes(device_parent, "ATTRS");
} while (device_parent != NULL);
print_all_attributes(parent, "ATTRS");
}
return 0;
}
static void print_record(struct udev_device *device) {
const char *str;
static void print_record(sd_device *device) {
const char *str, *val;
int i;
struct udev_list_entry *list_entry;
printf("P: %s\n", udev_device_get_devpath(device));
(void) sd_device_get_devpath(device, &str);
printf("P: %s\n", str);
str = udev_device_get_devnode(device);
if (str != NULL)
if (sd_device_get_devname(device, &str) >= 0)
printf("N: %s\n", str + STRLEN("/dev/"));
i = udev_device_get_devlink_priority(device);
if (i != 0)
if (device_get_devlink_priority(device, &i) >= 0)
printf("L: %i\n", i);
udev_list_entry_foreach(list_entry, udev_device_get_devlinks_list_entry(device))
printf("S: %s\n",
udev_list_entry_get_name(list_entry) + STRLEN("/dev/"));
FOREACH_DEVICE_DEVLINK(device, str)
printf("S: %s\n", str + STRLEN("/dev/"));
FOREACH_DEVICE_PROPERTY(device, str, val)
printf("E: %s=%s\n", str, val);
udev_list_entry_foreach(list_entry, udev_device_get_properties_list_entry(device))
printf("E: %s=%s\n",
udev_list_entry_get_name(list_entry),
udev_list_entry_get_value(list_entry));
printf("\n");
}
@ -145,7 +135,7 @@ static int stat_device(const char *name, bool export, const char *prefix) {
return -errno;
if (export) {
if (prefix == NULL)
if (!prefix)
prefix = "INFO_";
printf("%sMAJOR=%u\n"
"%sMINOR=%u\n",
@ -157,21 +147,24 @@ static int stat_device(const char *name, bool export, const char *prefix) {
}
static int export_devices(void) {
_cleanup_(udev_enumerate_unrefp) struct udev_enumerate *udev_enumerate;
struct udev_list_entry *list_entry;
_cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
sd_device *d;
int r;
udev_enumerate = udev_enumerate_new(NULL);
if (udev_enumerate == NULL)
return -ENOMEM;
r = sd_device_enumerator_new(&e);
if (r < 0)
return r;
udev_enumerate_scan_devices(udev_enumerate);
udev_list_entry_foreach(list_entry, udev_enumerate_get_list_entry(udev_enumerate)) {
_cleanup_(udev_device_unrefp) struct udev_device *device;
r = sd_device_enumerator_allow_uninitialized(e);
if (r < 0)
return r;
device = udev_device_new_from_syspath(NULL, udev_list_entry_get_name(list_entry));
if (device != NULL)
print_record(device);
}
r = device_enumerator_scan_devices(e);
if (r < 0)
return r;
FOREACH_DEVICE_AND_SUBSYSTEM(e, d)
print_record(d);
return 0;
}
@ -192,10 +185,10 @@ static void cleanup_dir(DIR *dir, mode_t mask, int depth) {
if ((stats.st_mode & mask) != 0)
continue;
if (S_ISDIR(stats.st_mode)) {
_cleanup_closedir_ DIR *dir2;
_cleanup_closedir_ DIR *dir2 = NULL;
dir2 = fdopendir(openat(dirfd(dir), dent->d_name, O_RDONLY|O_NONBLOCK|O_DIRECTORY|O_CLOEXEC));
if (dir2 != NULL)
if (dir2)
cleanup_dir(dir2, mask, depth-1);
(void) unlinkat(dirfd(dir), dent->d_name, AT_REMOVEDIR);
@ -210,23 +203,23 @@ static void cleanup_db(void) {
(void) unlink("/run/udev/queue.bin");
dir1 = opendir("/run/udev/data");
if (dir1 != NULL)
if (dir1)
cleanup_dir(dir1, S_ISVTX, 1);
dir2 = opendir("/run/udev/links");
if (dir2 != NULL)
if (dir2)
cleanup_dir(dir2, 0, 2);
dir3 = opendir("/run/udev/tags");
if (dir3 != NULL)
if (dir3)
cleanup_dir(dir3, 0, 2);
dir4 = opendir("/run/udev/static_node-tags");
if (dir4 != NULL)
if (dir4)
cleanup_dir(dir4, 0, 2);
dir5 = opendir("/run/udev/watch");
if (dir5 != NULL)
if (dir5)
cleanup_dir(dir5, 0, 1);
}
@ -258,12 +251,11 @@ static int help(void) {
}
int info_main(int argc, char *argv[], void *userdata) {
_cleanup_(udev_device_unrefp) struct udev_device *device = NULL;
_cleanup_(sd_device_unrefp) sd_device *device = NULL;
bool root = 0;
bool export = 0;
const char *export_prefix = NULL;
char name[UTIL_PATH_SIZE];
struct udev_list_entry *list_entry;
int c, r;
static const struct option options[] = {
@ -304,9 +296,9 @@ int info_main(int argc, char *argv[], void *userdata) {
return -EINVAL;
}
device = find_device(optarg, "/dev/");
if (!device)
return log_error_errno(errno, "device node not found: %m");
r = find_device(optarg, "/dev/", &device);
if (r < 0)
return log_error_errno(r, "device node not found: %m");
break;
case 'p':
if (device) {
@ -314,9 +306,9 @@ int info_main(int argc, char *argv[], void *userdata) {
return -EINVAL;
}
device = find_device(optarg, "/sys");
if (!device)
return log_error_errno(errno, "syspath not found: %m");
r = find_device(optarg, "/sys", &device);
if (r < 0)
return log_error_errno(r, "syspath not found: %m");
break;
case 'q':
action = ACTION_QUERY;
@ -373,57 +365,63 @@ int info_main(int argc, char *argv[], void *userdata) {
help();
return -EINVAL;
}
device = find_device(argv[optind], NULL);
if (!device) {
log_error("Unknown device, --name=, --path=, or absolute path in /dev/ or /sys expected.");
return -EINVAL;
}
r = find_device(argv[optind], NULL, &device);
if (r < 0)
return log_error_errno(r, "Unknown device, --name=, --path=, or absolute path in /dev/ or /sys expected: %m");
}
switch(query) {
case QUERY_NAME: {
const char *node = udev_device_get_devnode(device);
const char *node;
if (!node)
return log_error_errno(errno, "no device node found");
r = sd_device_get_devname(device, &node);
if (r < 0)
return log_error_errno(r, "no device node found: %m");
if (root)
printf("%s\n", udev_device_get_devnode(device));
printf("%s\n", node);
else
printf("%s\n",
udev_device_get_devnode(device) + STRLEN("/dev/"));
printf("%s\n", node + STRLEN("/dev/"));
break;
}
case QUERY_SYMLINK:
list_entry = udev_device_get_devlinks_list_entry(device);
while (list_entry) {
if (root)
printf("%s", udev_list_entry_get_name(list_entry));
else
printf("%s",
udev_list_entry_get_name(list_entry) + STRLEN("/dev/"));
list_entry = udev_list_entry_get_next(list_entry);
if (list_entry)
case QUERY_SYMLINK: {
const char *devlink;
bool first = true;
FOREACH_DEVICE_DEVLINK(device, devlink) {
if (!first)
printf(" ");
if (root)
printf("%s", devlink);
else
printf("%s", devlink + STRLEN("/dev/"));
first = false;
}
printf("\n");
break;
case QUERY_PATH:
printf("%s\n", udev_device_get_devpath(device));
return 0;
case QUERY_PROPERTY:
list_entry = udev_device_get_properties_list_entry(device);
while (list_entry) {
if (export)
printf("%s%s='%s'\n", strempty(export_prefix),
udev_list_entry_get_name(list_entry),
udev_list_entry_get_value(list_entry));
else
printf("%s=%s\n", udev_list_entry_get_name(list_entry), udev_list_entry_get_value(list_entry));
}
case QUERY_PATH: {
const char *devpath;
r = sd_device_get_devpath(device, &devpath);
if (r < 0)
return log_error_errno(r, "Failed to get device path: %m");
printf("%s\n", devpath);
return 0;
}
case QUERY_PROPERTY: {
const char *key, *value;
FOREACH_DEVICE_PROPERTY(device, key, value)
if (export)
printf("%s%s='%s'\n", strempty(export_prefix), key, value);
else
printf("%s=%s\n", key, value);
list_entry = udev_list_entry_get_next(list_entry);
}
break;
}
case QUERY_ALL:
print_record(device);
break;
@ -433,11 +431,9 @@ int info_main(int argc, char *argv[], void *userdata) {
break;
case ACTION_ATTRIBUTE_WALK:
if (!device && argv[optind]) {
device = find_device(argv[optind], NULL);
if (!device) {
log_error("Unknown device, absolute path in /dev/ or /sys expected.");
return -EINVAL;
}
r = find_device(argv[optind], NULL, &device);
if (r < 0)
return log_error_errno(r, "Unknown device, absolute path in /dev/ or /sys expected: %m");
}
if (!device) {
log_error("Unknown device, --name=, --path=, or absolute path in /dev/ or /sys expected.");

View file

@ -6,32 +6,36 @@
#include <stddef.h>
#include <stdio.h>
#include <string.h>
#include <sys/epoll.h>
#include <unistd.h>
#include "device-enumerator-private.h"
#include "fd-util.h"
#include "libudev-private.h"
#include "set.h"
#include "string-util.h"
#include "udev.h"
#include "strv.h"
#include "udevadm.h"
#include "udevadm-util.h"
#include "util.h"
static int verbose;
static int dry_run;
static bool arg_verbose = false;
static bool arg_dry_run = false;
static int exec_list(struct udev_enumerate *udev_enumerate, const char *action, Set *settle_set) {
struct udev_list_entry *entry;
static int exec_list(sd_device_enumerator *e, const char *action, Set *settle_set) {
sd_device *d;
int r;
udev_list_entry_foreach(entry, udev_enumerate_get_list_entry(udev_enumerate)) {
FOREACH_DEVICE_AND_SUBSYSTEM(e, d) {
char filename[UTIL_PATH_SIZE];
const char *syspath;
_cleanup_close_ int fd = -1;
syspath = udev_list_entry_get_name(entry);
if (verbose)
if (sd_device_get_syspath(d, &syspath) < 0)
continue;
if (arg_verbose)
printf("%s\n", syspath);
if (dry_run)
if (arg_dry_run)
continue;
strscpyl(filename, sizeof(filename), syspath, "/uevent", NULL);
@ -120,7 +124,7 @@ int trigger_main(int argc, char *argv[], void *userdata) {
TYPE_SUBSYSTEMS,
} device_type = TYPE_DEVICES;
const char *action = "change";
_cleanup_(udev_enumerate_unrefp) struct udev_enumerate *udev_enumerate = NULL;
_cleanup_(sd_device_enumerator_unrefp) sd_device_enumerator *e = NULL;
_cleanup_(udev_monitor_unrefp) struct udev_monitor *udev_monitor = NULL;
_cleanup_close_ int fd_ep = -1;
int fd_udev = -1;
@ -129,9 +133,13 @@ int trigger_main(int argc, char *argv[], void *userdata) {
_cleanup_set_free_free_ Set *settle_set = NULL;
int c, r;
udev_enumerate = udev_enumerate_new(NULL);
if (!udev_enumerate)
return -errno;
r = sd_device_enumerator_new(&e);
if (r < 0)
return r;
r = sd_device_enumerator_allow_uninitialized(e);
if (r < 0)
return r;
while ((c = getopt_long(argc, argv, "vnt:c:s:S:a:A:p:g:y:b:wVh", options, NULL)) >= 0) {
const char *key;
@ -140,10 +148,10 @@ int trigger_main(int argc, char *argv[], void *userdata) {
switch (c) {
case 'v':
verbose = 1;
arg_verbose = true;
break;
case 'n':
dry_run = 1;
arg_dry_run = true;
break;
case 't':
if (streq(optarg, "devices"))
@ -165,51 +173,51 @@ int trigger_main(int argc, char *argv[], void *userdata) {
break;
case 's':
r = udev_enumerate_add_match_subsystem(udev_enumerate, optarg);
r = sd_device_enumerator_add_match_subsystem(e, optarg, true);
if (r < 0)
return log_error_errno(r, "could not add subsystem match '%s': %m", optarg);
break;
case 'S':
r = udev_enumerate_add_nomatch_subsystem(udev_enumerate, optarg);
r = sd_device_enumerator_add_match_subsystem(e, optarg, false);
if (r < 0)
return log_error_errno(r, "could not add negative subsystem match '%s': %m", optarg);
break;
case 'a':
key = keyval(optarg, &val, buf, sizeof(buf));
r = udev_enumerate_add_match_sysattr(udev_enumerate, key, val);
r = sd_device_enumerator_add_match_sysattr(e, key, val, true);
if (r < 0)
return log_error_errno(r, "could not add sysattr match '%s=%s': %m", key, val);
break;
case 'A':
key = keyval(optarg, &val, buf, sizeof(buf));
r = udev_enumerate_add_nomatch_sysattr(udev_enumerate, key, val);
r = sd_device_enumerator_add_match_sysattr(e, key, val, false);
if (r < 0)
return log_error_errno(r, "could not add negative sysattr match '%s=%s': %m", key, val);
break;
case 'p':
key = keyval(optarg, &val, buf, sizeof(buf));
r = udev_enumerate_add_match_property(udev_enumerate, key, val);
r = sd_device_enumerator_add_match_property(e, key, val);
if (r < 0)
return log_error_errno(r, "could not add property match '%s=%s': %m", key, val);
break;
case 'g':
r = udev_enumerate_add_match_tag(udev_enumerate, optarg);
r = sd_device_enumerator_add_match_tag(e, optarg);
if (r < 0)
return log_error_errno(r, "could not add tag match '%s': %m", optarg);
break;
case 'y':
r = udev_enumerate_add_match_sysname(udev_enumerate, optarg);
r = sd_device_enumerator_add_match_sysname(e, optarg);
if (r < 0)
return log_error_errno(r, "could not add sysname match '%s': %m", optarg);
break;
case 'b': {
_cleanup_(udev_device_unrefp) struct udev_device *dev;
_cleanup_(sd_device_unrefp) sd_device *dev = NULL;
dev = find_device(optarg, "/sys");
if (!dev)
return log_error_errno(errno, "unable to open the device '%s'", optarg);
r = find_device(optarg, "/sys", &dev);
if (r < 0)
return log_error_errno(r, "unable to open the device '%s'", optarg);
r = udev_enumerate_add_match_parent(udev_enumerate, dev);
r = sd_device_enumerator_add_match_parent(e, dev);
if (r < 0)
return log_error_errno(r, "could not add parent match '%s': %m", optarg);
break;
@ -219,13 +227,13 @@ int trigger_main(int argc, char *argv[], void *userdata) {
break;
case ARG_NAME: {
_cleanup_(udev_device_unrefp) struct udev_device *dev;
_cleanup_(sd_device_unrefp) sd_device *dev = NULL;
dev = find_device(optarg, "/dev/");
if (!dev)
return log_error_errno(errno, "unable to open the device '%s'", optarg);
r = find_device(optarg, "/dev/", &dev);
if (r < 0)
return log_error_errno(r, "unable to open the device '%s'", optarg);
r = udev_enumerate_add_match_parent(udev_enumerate, dev);
r = sd_device_enumerator_add_match_parent(e, dev);
if (r < 0)
return log_error_errno(r, "could not add parent match '%s': %m", optarg);
break;
@ -243,17 +251,15 @@ int trigger_main(int argc, char *argv[], void *userdata) {
}
for (; optind < argc; optind++) {
_cleanup_(udev_device_unrefp) struct udev_device *dev;
_cleanup_(sd_device_unrefp) sd_device *dev = NULL;
dev = find_device(argv[optind], NULL);
if (!dev) {
log_error("unable to open the device '%s'", argv[optind]);
return -EINVAL;
}
r = udev_enumerate_add_match_parent(udev_enumerate, dev);
r = find_device(argv[optind], NULL, &dev);
if (r < 0)
return log_error_errno(r, "could not add tag match '%s': %m", optarg);
return log_error_errno(r, "unable to open the device '%s'", argv[optind]);
r = sd_device_enumerator_add_match_parent(e, dev);
if (r < 0)
return log_error_errno(r, "could not add parent match '%s': %m", argv[optind]);
}
if (settle) {
@ -266,12 +272,17 @@ int trigger_main(int argc, char *argv[], void *userdata) {
return log_error_errno(errno, "error: unable to create netlink socket: %m");
fd_udev = udev_monitor_get_fd(udev_monitor);
if (fd_udev < 0)
return log_error_errno(fd_udev, "Failed to get udev_monitor fd: %m");
r = udev_monitor_enable_receiving(udev_monitor);
if (r < 0)
return log_error_errno(r, "error: unable to subscribe to udev events: %m");
ep_udev = (struct epoll_event) { .events = EPOLLIN, .data.fd = fd_udev };
ep_udev = (struct epoll_event) {
.events = EPOLLIN,
.data.fd = fd_udev,
};
if (epoll_ctl(fd_ep, EPOLL_CTL_ADD, fd_udev, &ep_udev) < 0)
return log_error_errno(errno, "fail to add fd to epoll: %m");
@ -282,15 +293,19 @@ int trigger_main(int argc, char *argv[], void *userdata) {
switch (device_type) {
case TYPE_SUBSYSTEMS:
udev_enumerate_scan_subsystems(udev_enumerate);
r = device_enumerator_scan_subsystems(e);
if (r < 0)
return log_error_errno(r, "Failed to scan subsystems: %m");
break;
case TYPE_DEVICES:
udev_enumerate_scan_devices(udev_enumerate);
r = device_enumerator_scan_devices(e);
if (r < 0)
return log_error_errno(r, "Failed to scan devices: %m");
break;
default:
assert_not_reached("device_type");
}
r = exec_list(udev_enumerate, action, settle_set);
r = exec_list(e, action, settle_set);
if (r < 0)
return r;
@ -307,20 +322,23 @@ int trigger_main(int argc, char *argv[], void *userdata) {
}
for (i = 0; i < fdcount; i++) {
if (ev[i].data.fd == fd_udev && ev[i].events & EPOLLIN) {
_cleanup_(udev_device_unrefp) struct udev_device *device;
const char *syspath = NULL;
_cleanup_(sd_device_unrefp) sd_device *dev = NULL;
const char *syspath = NULL;
device = udev_monitor_receive_device(udev_monitor);
if (!device)
continue;
if (!(ev[i].data.fd == fd_udev && ev[i].events & EPOLLIN))
continue;
syspath = udev_device_get_syspath(device);
if (verbose)
printf("settle %s\n", syspath);
if (!set_remove(settle_set, syspath))
log_debug("Got epoll event on syspath %s not present in syspath set", syspath);
}
if (udev_monitor_receive_sd_device(udev_monitor, &dev) < 0)
continue;
if (sd_device_get_syspath(dev, &syspath) < 0)
continue;
if (arg_verbose)
printf("settle %s\n", syspath);
if (!set_remove(settle_set, syspath))
log_debug("Got epoll event on syspath %s not present in syspath set", syspath);
}
}

View file

@ -1,34 +1,30 @@
/* SPDX-License-Identifier: GPL-2.0+ */
#include <errno.h>
#include "device-private.h"
#include "path-util.h"
#include "string-util.h"
#include "udevadm-util.h"
struct udev_device *find_device(const char *id,
const char *prefix) {
int find_device(const char *id, const char *prefix, sd_device **ret) {
assert(id);
assert(ret);
if (prefix && !startswith(id, prefix))
id = strjoina(prefix, id);
if (path_startswith(id, "/sys/"))
return sd_device_new_from_syspath(ret, id);
if (path_startswith(id, "/dev/")) {
struct stat statbuf;
char type;
struct stat st;
if (stat(id, &statbuf) < 0)
return NULL;
if (stat(id, &st) < 0)
return -errno;
if (S_ISBLK(statbuf.st_mode))
type = 'b';
else if (S_ISCHR(statbuf.st_mode))
type = 'c';
else
return NULL;
return device_new_from_stat_rdev(ret, &st);
}
return udev_device_new_from_devnum(NULL, type, statbuf.st_rdev);
} else if (path_startswith(id, "/sys/"))
return udev_device_new_from_syspath(NULL, id);
else
return NULL;
return -EINVAL;
}

View file

@ -1,7 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0+ */
#pragma once
#include "udev.h"
#include "sd-device.h"
struct udev_device *find_device(const char *id,
const char *prefix);
int find_device(const char *id, const char *prefix, sd_device **ret);