udevadm-info.c revision 17fcfb5972977b6a3aedca6ad2aa8d1fbfbc761d
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering * Copyright (C) 2004-2008 Kay Sievers <kay.sievers@vrfy.org>
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 * 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 * 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/>.
eb7bbee6cd182d5c4eb1e1180631c35158f59379Kay Sieversstatic void print_all_attributes(struct udev *udev, const char *devpath, const char *key)
d59d0a2b4b41a75eaf618b26b8f8bd1e17de7e2bcee util_strlcpy(path, udev_get_sys_path(udev), sizeof(path));
8666abb452db73d9a11ead61251eec42bc531cceKay Sievers for (dent = readdir(dir); dent != NULL; dent = readdir(dir)) {
f15515b5e6a9ebe95c938cc670df6e576fcf9176Filipe Brandenburger if (strcmp(dent->d_name, "uevent") == 0)
f15515b5e6a9ebe95c938cc670df6e576fcf9176Filipe Brandenburger util_strlcpy(filename, path, sizeof(filename));
f15515b5e6a9ebe95c938cc670df6e576fcf9176Filipe Brandenburger util_strlcat(filename, "/", sizeof(filename));
f15515b5e6a9ebe95c938cc670df6e576fcf9176Filipe Brandenburger util_strlcat(filename, dent->d_name, sizeof(filename));
2f96919bcdd0978164c801b21e053fb3b31e8bacFilipe Brandenburger attr_value = sysfs_attr_get_value(udev, devpath, dent->d_name);
2f96919bcdd0978164c801b21e053fb3b31e8bacFilipe Brandenburger len = util_strlcpy(value, attr_value, sizeof(value));
1c7dde3e475978c569a982d65fd86d4b4e3caad8Bastien Nocera dbg(udev, "attr '%s'='%s'(%zi)\n", dent->d_name, value, len);
1c7dde3e475978c569a982d65fd86d4b4e3caad8Bastien Nocera /* skip nonprintable attributes */
e9da3678fcfc774b325dc1eaa054d0e00028a1fcLennart Poettering dbg(udev, "attribute value of '%s' non-printable, skip\n", dent->d_name);
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering printf(" %s{%s}==\"%s\"\n", key, dent->d_name, value);
2d0efdf1af5ff77441228854343c61d42a89840cSamuli Suominenstatic int print_device_chain(struct udev *udev, const char *devpath)
446883528524429283626208928b51f49f28f810Lennart Poettering "Udevinfo starts with the device specified by the devpath and then\n"
4acbce79798347cddf1e1d42e9be571e0a041873Zbigniew Jędrzejewski-Szmek "walks up the chain of parent devices. It prints for every device\n"
4acbce79798347cddf1e1d42e9be571e0a041873Zbigniew Jędrzejewski-Szmek "found, all possible attributes in the udev rules key format.\n"
80a5cbace45a6adbf2f9119edc5a4b10db493064Kay Sievers "A rule to match, can be composed by the attributes of the device\n"
b37250d661ed67d07c734630617d73e64f6d7e49Zbigniew Jędrzejewski-Szmek "and the attributes from one single parent device.\n"
6581f00f7eabdaccf587a4b6af60ed4696dd2791Zbigniew Jędrzejewski-Szmek printf(" looking at device '%s':\n", dev->devpath);
fe1fed02c7637a2c18cd575f78be7fda27972148Zbigniew Jędrzejewski-Szmek printf(" SUBSYSTEM==\"%s\"\n", dev->subsystem);
fe1fed02c7637a2c18cd575f78be7fda27972148Zbigniew Jędrzejewski-Szmek printf(" DRIVER==\"%s\"\n", dev->driver);
fe1fed02c7637a2c18cd575f78be7fda27972148Zbigniew Jędrzejewski-Szmek print_all_attributes(udev, dev->devpath, "ATTR");
6e92b23f0d6dd398848376bbaf47e54a90ed3389Kay Sievers /* walk up the chain of devices */
d66ee73a3dd7b5433fc0da3125bbdff740de7745Zbigniew Jędrzejewski-Szmek dev = sysfs_device_get_parent(udev, dev);
3e2147858f21943d5f4a781c60f33ac22c6096edKay Sievers printf(" looking at parent device '%s':\n", dev->devpath);
ac714a78fdca481488d88f84b6332d28083a4511Martin Jansa printf(" SUBSYSTEMS==\"%s\"\n", dev->subsystem);
b62cfcea00862ccbf0e5e297f8a339f70987edefMichael Biebl print_all_attributes(udev, dev->devpath, "ATTRS");
732bfe09aeffc3cd78b80ee9e20c9c3babd944d6Zbigniew Jędrzejewski-Szmekstatic void print_record(struct udevice *udevice)
732bfe09aeffc3cd78b80ee9e20c9c3babd944d6Zbigniew Jędrzejewski-Szmek printf("P: %s\n", udevice->dev->devpath);
732bfe09aeffc3cd78b80ee9e20c9c3babd944d6Zbigniew Jędrzejewski-Szmek printf("N: %s\n", udevice->name);
732bfe09aeffc3cd78b80ee9e20c9c3babd944d6Zbigniew Jędrzejewski-Szmek list_for_each_entry(name_loop, &udevice->symlink_list, node)
732bfe09aeffc3cd78b80ee9e20c9c3babd944d6Zbigniew Jędrzejewski-Szmek printf("S: %s\n", name_loop->name);
732bfe09aeffc3cd78b80ee9e20c9c3babd944d6Zbigniew Jędrzejewski-Szmek if (udevice->link_priority != 0)
732bfe09aeffc3cd78b80ee9e20c9c3babd944d6Zbigniew Jędrzejewski-Szmek printf("L: %i\n", udevice->link_priority);
ae0ceefc2f432bc1068889fcff53d929eca8a3c4Zbigniew Jędrzejewski-Szmek printf("A:%u\n", udevice->partitions);
ae0ceefc2f432bc1068889fcff53d929eca8a3c4Zbigniew Jędrzejewski-Szmek printf("R:%u\n", udevice->ignore_remove);
ae0ceefc2f432bc1068889fcff53d929eca8a3c4Zbigniew Jędrzejewski-Szmek list_for_each_entry(name_loop, &udevice->env_list, node)
ae0ceefc2f432bc1068889fcff53d929eca8a3c4Zbigniew Jędrzejewski-Szmek printf("E: %s\n", name_loop->name);
ae0ceefc2f432bc1068889fcff53d929eca8a3c4Zbigniew Jędrzejewski-Szmekstatic void export_db(struct udev *udev)
ae0ceefc2f432bc1068889fcff53d929eca8a3c4Zbigniew Jędrzejewski-Szmek udev_db_get_all_entries(udev, &name_list);
ae0ceefc2f432bc1068889fcff53d929eca8a3c4Zbigniew Jędrzejewski-Szmek list_for_each_entry(name_loop, &name_list, node) {
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering if (udev_db_get_device(udevice_db, name_loop->name) == 0)
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poetteringstatic int lookup_device_by_name(struct udev *udev, struct udevice **udevice, const char *name)
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering count = udev_db_get_devices_by_name(udev, name, &name_list);
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering info(udev, "found %i devices for '%s'\n", count, name);
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering /* select the device that seems to match */
be1a67d9d63bfdd4a5f8ba9cfc804030f10f5833Lennart Poettering list_for_each_entry(device, &name_list, node) {
be1a67d9d63bfdd4a5f8ba9cfc804030f10f5833Lennart Poettering if (udev_db_get_device(udevice_loop, device->name) != 0)
d1ab0ca07372649dad70a0348d75e394f254e1b6Lennart Poettering info(udev, "found db entry '%s'\n", device->name);
9b85fc6a89386582bfe792dba881800b0a093839Gustavo Sverzut Barbieri /* make sure, we don't get a link of a different device */
9b85fc6a89386582bfe792dba881800b0a093839Gustavo Sverzut Barbieri util_strlcpy(filename, udev_get_dev_path(udev), sizeof(filename));
9b85fc6a89386582bfe792dba881800b0a093839Gustavo Sverzut Barbieri util_strlcat(filename, "/", sizeof(filename));
5a45a93627609451784a04366cfa1150d32611d1Lennart Poettering util_strlcat(filename, name, sizeof(filename));
2a4d1ec1520c926b0160efe14142634e164ddc30Cristian Rodríguez if (major(udevice_loop->devt) > 0 && udevice_loop->devt != statbuf.st_rdev) {
c1663b9daf5a43425e54bbe3daf6b10e64578f80Lennart Poettering info(udev, "skip '%s', dev_t doesn't match\n", udevice_loop->name);
a6c0b31d509f76023d8efbcd5e912863c8fb254cZbigniew Jędrzejewski-Szmek name_list_cleanup(udev, &name_list);
9b85fc6a89386582bfe792dba881800b0a093839Gustavo Sverzut Barbieristatic int stat_device(const char *name, int export, const char *prefix)
1c231f56482546725c4dbd3303f70300bd3c63e9Lennart Poettering "%sMINOR=%d\n",
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek printf("%d:%d\n", major(statbuf.st_dev), minor(statbuf.st_dev));
c937e0d5c579863677e0fcb5508517f7714c332dZbigniew Jędrzejewski-Szmekint udevadm_info(struct udev *udev, int argc, char *argv[])
32dcef3ab1eb91ee469c3246ef859578dccd8a45Zbigniew Jędrzejewski-Szmek const char *export_prefix = NULL;
c937e0d5c579863677e0fcb5508517f7714c332dZbigniew Jędrzejewski-Szmek static const struct option options[] = {
747cf8cdf61cdad068c727e42eac699f2505ae77Zbigniew Jędrzejewski-Szmek { "export-prefix", 1, NULL, 'P' },
747cf8cdf61cdad068c727e42eac699f2505ae77Zbigniew Jędrzejewski-Szmek { "version", 0, NULL, 1 }, /* -V outputs braindead format */
c937e0d5c579863677e0fcb5508517f7714c332dZbigniew Jędrzejewski-Szmek option = getopt_long(argc, argv, "aed:n:p:q:rxPVh", options, NULL);
7959ff9914a6f3a59dbff95c199bcc540b70ac94Kay Sievers /* remove /dev if given */
85f19d825e7504676f3a80c78c1d9a7ec35a3b3fMichael Biebl if (strncmp(optarg, udev_get_dev_path(udev), strlen(udev_get_dev_path(udev))) == 0)
85f19d825e7504676f3a80c78c1d9a7ec35a3b3fMichael Biebl util_strlcpy(name, &optarg[strlen(udev_get_dev_path(udev))+1], sizeof(name));
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering util_strlcpy(name, optarg, sizeof(name));
fba1ea06bb5b653e9eb0cc1b6004af8da273a4abShawn Landden /* remove /sys if given */
fba1ea06bb5b653e9eb0cc1b6004af8da273a4abShawn Landden if (strncmp(optarg, udev_get_sys_path(udev), strlen(udev_get_sys_path(udev))) == 0)
fba1ea06bb5b653e9eb0cc1b6004af8da273a4abShawn Landden util_strlcpy(path, &optarg[strlen(udev_get_sys_path(udev))], sizeof(path));
47be870bd83fb3719dffc3ee9348a409ab762a14Lennart Poettering util_strlcpy(path, optarg, sizeof(path));
81577dc22887debaf9b19bf1034a2887fb9069c7Zbigniew Jędrzejewski-Szmek /* possibly resolve to real devpath */
81577dc22887debaf9b19bf1034a2887fb9069c7Zbigniew Jędrzejewski-Szmek if (util_resolve_sys_link(udev, path, sizeof(path)) != 0) {
3b794314149e40afaf3c456285e1e529747b6560Holger Schurig /* also check if the parent is a link */
81577dc22887debaf9b19bf1034a2887fb9069c7Zbigniew Jędrzejewski-Szmek util_strlcpy(tail, pos, sizeof(tail));
81577dc22887debaf9b19bf1034a2887fb9069c7Zbigniew Jędrzejewski-Szmek if (util_resolve_sys_link(udev, temp, sizeof(temp)) == 0) {
81577dc22887debaf9b19bf1034a2887fb9069c7Zbigniew Jędrzejewski-Szmek util_strlcpy(path, temp, sizeof(path));
81577dc22887debaf9b19bf1034a2887fb9069c7Zbigniew Jędrzejewski-Szmek util_strlcat(path, tail, sizeof(path));
81577dc22887debaf9b19bf1034a2887fb9069c7Zbigniew Jędrzejewski-Szmek if (strcmp(optarg, "name") == 0) {
ac6b760ceedd4b21921b6a682cf1479af3d3024fZbigniew Jędrzejewski-Szmek if (strcmp(optarg, "env") == 0) {
ac6b760ceedd4b21921b6a682cf1479af3d3024fZbigniew Jędrzejewski-Szmek if (strcmp(optarg, "all") == 0) {
53e856e16ac37fe30b8bb59153ff69aad0fa9c27Zbigniew Jędrzejewski-Szmek fprintf(stderr, "unknown query type\n");
6aea6d10f460853111ca8744201ec8dade97de3cThomas H.P. Andersen util_strlcpy(name, optarg, sizeof(name));
6aea6d10f460853111ca8744201ec8dade97de3cThomas H.P. Andersen printf("udevinfo, version %s\n", VERSION);
6aea6d10f460853111ca8744201ec8dade97de3cThomas H.P. Andersen " --query=<type> query database for the specified value:\n"
e30431623a7d871da123cc37055ac49abf2c20eaTom Gundersen " name name of device node\n"
e30431623a7d871da123cc37055ac49abf2c20eaTom Gundersen " symlink pointing to node\n"
e30431623a7d871da123cc37055ac49abf2c20eaTom Gundersen " path sysfs device path\n"
e30431623a7d871da123cc37055ac49abf2c20eaTom Gundersen " env the device related imported environment\n"
e2ca86cf78f911a8be51f0224796e24883019139Dave Reisner " all all values\n"
e2ca86cf78f911a8be51f0224796e24883019139Dave Reisner " --path=<devpath> sysfs device path used for query or chain\n"
a18535d9e138c525d0443ec9f30a90b3e2184686Tom Gundersen " --name=<name> node or symlink name used for query\n"
e2ca86cf78f911a8be51f0224796e24883019139Dave Reisner " --root prepend to query result or print udev_root\n"
70d8320978dcbce022d9acbb953a10a7aca049abDavid Strauss " --attribute-walk print all key matches while walking along chain\n"
e2ca86cf78f911a8be51f0224796e24883019139Dave Reisner " of parent devices\n"
e30431623a7d871da123cc37055ac49abf2c20eaTom Gundersen " --device-id-of-file=<file> print major/minor of underlying device\n"
c4955740969d7ba8ba43b024bca1a0a5b56eb8e8Tom Gundersen " --export-db export the content of the udev database\n"
e30431623a7d871da123cc37055ac49abf2c20eaTom Gundersen " --help print this text\n"
f553b3b1074151200187df916427a1468186435eAnders Olofsson /* run action */
f553b3b1074151200187df916427a1468186435eAnders Olofsson /* needs devpath or node/symlink name for query */
c0467cf387548dc98c0254f63553d862b35a84e5Ronny Chevalier if (udev_db_get_device(udevice, path) != 0) {
c0467cf387548dc98c0254f63553d862b35a84e5Ronny Chevalier fprintf(stderr, "no record for '%s' in database\n", path);
c0467cf387548dc98c0254f63553d862b35a84e5Ronny Chevalier if (lookup_device_by_name(udev, &udevice, name) != 0) {
c0467cf387548dc98c0254f63553d862b35a84e5Ronny Chevalier fprintf(stderr, "query needs --path or node --name specified\n");
816115863962548a9a0d9fbfe429c7f8e685beacRoberto Sassu printf("%s/%s\n", udev_get_dev_path(udev), udevice->name);
816115863962548a9a0d9fbfe429c7f8e685beacRoberto Sassu list_for_each_entry(name_loop, &udevice->symlink_list, node) {
816115863962548a9a0d9fbfe429c7f8e685beacRoberto Sassu char c = name_loop->node.next != &udevice->symlink_list ? ' ' : '\n';
77e68fa2f0bd018bab2621a31919bfaa6a6b0a35Lennart Poettering printf("%s/%s%c", udev_get_dev_path(udev), name_loop->name, c);
77e68fa2f0bd018bab2621a31919bfaa6a6b0a35Lennart Poettering list_for_each_entry(name_loop, &udevice->env_list, node)
6a6751fe24bf456cf5c1efad785a4d11e78b42d0Lennart Poettering if (print_device_chain(udev, path) != 0) {
6a6751fe24bf456cf5c1efad785a4d11e78b42d0Lennart Poettering fprintf(stderr, "no valid sysfs device found\n");
591622d7efbc828f00f190d91b6608148b967ff5Lennart Poettering if (lookup_device_by_name(udev, &udevice, name) != 0) {
eef65bf3ee6f73afa4a5de23ae3a794a279f30c0Michael Scherer if (print_device_chain(udev, udevice->dev->devpath) != 0) {
eef65bf3ee6f73afa4a5de23ae3a794a279f30c0Michael Scherer fprintf(stderr, "no valid sysfs device found\n");
eef65bf3ee6f73afa4a5de23ae3a794a279f30c0Michael Scherer fprintf(stderr, "attribute walk needs --path or node --name specified\n");