mirror of
https://github.com/systemd/systemd.git
synced 2024-11-27 12:13:33 +08:00
Merge pull request #22963 from poettering/udevadm-diskseq-fix
sd-device diskseq fix + udevadm info improvements
This commit is contained in:
commit
f379362157
@ -502,6 +502,19 @@ manpages = [
|
||||
'sd_bus_track_unrefp'],
|
||||
''],
|
||||
['sd_bus_wait', '3', [], ''],
|
||||
['sd_device_get_syspath',
|
||||
'3',
|
||||
['sd_device_get_devname',
|
||||
'sd_device_get_devnum',
|
||||
'sd_device_get_devpath',
|
||||
'sd_device_get_devtype',
|
||||
'sd_device_get_diskseq',
|
||||
'sd_device_get_driver',
|
||||
'sd_device_get_ifindex',
|
||||
'sd_device_get_subsystem',
|
||||
'sd_device_get_sysname',
|
||||
'sd_device_get_sysnum'],
|
||||
''],
|
||||
['sd_event_add_child',
|
||||
'3',
|
||||
['sd_event_add_child_pidfd',
|
||||
|
200
man/sd_device_get_syspath.xml
Normal file
200
man/sd_device_get_syspath.xml
Normal file
@ -0,0 +1,200 @@
|
||||
<?xml version='1.0'?> <!--*-nxml-*-->
|
||||
<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
|
||||
"http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd">
|
||||
<!-- SPDX-License-Identifier: LGPL-2.1-or-later -->
|
||||
|
||||
<refentry id="sd_device_get_syspath"
|
||||
xmlns:xi="http://www.w3.org/2001/XInclude">
|
||||
|
||||
<refentryinfo>
|
||||
<title>sd_device_get_syspath</title>
|
||||
<productname>systemd</productname>
|
||||
</refentryinfo>
|
||||
|
||||
<refmeta>
|
||||
<refentrytitle>sd_device_get_syspath</refentrytitle>
|
||||
<manvolnum>3</manvolnum>
|
||||
</refmeta>
|
||||
|
||||
<refnamediv>
|
||||
<refname>sd_device_get_syspath</refname>
|
||||
<refname>sd_device_get_devpath</refname>
|
||||
<refname>sd_device_get_sysname</refname>
|
||||
<refname>sd_device_get_sysnum</refname>
|
||||
<refname>sd_device_get_subsystem</refname>
|
||||
<refname>sd_device_get_devtype</refname>
|
||||
<refname>sd_device_get_devname</refname>
|
||||
<refname>sd_device_get_devnum</refname>
|
||||
<refname>sd_device_get_ifindex</refname>
|
||||
<refname>sd_device_get_driver</refname>
|
||||
<refname>sd_device_get_diskseq</refname>
|
||||
|
||||
<refpurpose>Returns various fields of device objects</refpurpose>
|
||||
</refnamediv>
|
||||
|
||||
<refsynopsisdiv>
|
||||
<funcsynopsis>
|
||||
<funcsynopsisinfo>#include <systemd/sd-device.h></funcsynopsisinfo>
|
||||
|
||||
<funcprototype>
|
||||
<funcdef>int <function>sd_device_get_syspath</function></funcdef>
|
||||
<paramdef>sd_device *<parameter>device</parameter></paramdef>
|
||||
<paramdef>const char **<parameter>ret</parameter></paramdef>
|
||||
</funcprototype>
|
||||
|
||||
<funcprototype>
|
||||
<funcdef>int <function>sd_device_get_devpath</function></funcdef>
|
||||
<paramdef>sd_device *<parameter>device</parameter></paramdef>
|
||||
<paramdef>const char **<parameter>ret</parameter></paramdef>
|
||||
</funcprototype>
|
||||
|
||||
<funcprototype>
|
||||
<funcdef>int <function>sd_device_get_sysname</function></funcdef>
|
||||
<paramdef>sd_device *<parameter>device</parameter></paramdef>
|
||||
<paramdef>const char **<parameter>ret</parameter></paramdef>
|
||||
</funcprototype>
|
||||
|
||||
<funcprototype>
|
||||
<funcdef>int <function>sd_device_get_sysnum</function></funcdef>
|
||||
<paramdef>sd_device *<parameter>device</parameter></paramdef>
|
||||
<paramdef>const char **<parameter>ret</parameter></paramdef>
|
||||
</funcprototype>
|
||||
|
||||
<funcprototype>
|
||||
<funcdef>int <function>sd_device_get_subsystem</function></funcdef>
|
||||
<paramdef>sd_device *<parameter>device</parameter></paramdef>
|
||||
<paramdef>const char **<parameter>ret</parameter></paramdef>
|
||||
</funcprototype>
|
||||
|
||||
<funcprototype>
|
||||
<funcdef>int <function>sd_device_get_devtype</function></funcdef>
|
||||
<paramdef>sd_device *<parameter>device</parameter></paramdef>
|
||||
<paramdef>const char **<parameter>ret</parameter></paramdef>
|
||||
</funcprototype>
|
||||
|
||||
<funcprototype>
|
||||
<funcdef>int <function>sd_device_get_devname</function></funcdef>
|
||||
<paramdef>sd_device *<parameter>device</parameter></paramdef>
|
||||
<paramdef>const char **<parameter>ret</parameter></paramdef>
|
||||
</funcprototype>
|
||||
|
||||
<funcprototype>
|
||||
<funcdef>int <function>sd_device_get_devnum</function></funcdef>
|
||||
<paramdef>sd_device *<parameter>device</parameter></paramdef>
|
||||
<paramdef>dev_t *<parameter>ret</parameter></paramdef>
|
||||
</funcprototype>
|
||||
|
||||
<funcprototype>
|
||||
<funcdef>int <function>sd_device_get_ifindex</function></funcdef>
|
||||
<paramdef>sd_device *<parameter>device</parameter></paramdef>
|
||||
<paramdef>int *<parameter>ret</parameter></paramdef>
|
||||
</funcprototype>
|
||||
|
||||
<funcprototype>
|
||||
<funcdef>int <function>sd_device_get_driver</function></funcdef>
|
||||
<paramdef>sd_device *<parameter>device</parameter></paramdef>
|
||||
<paramdef>const char **<parameter>ret</parameter></paramdef>
|
||||
</funcprototype>
|
||||
|
||||
<funcprototype>
|
||||
<funcdef>int <function>sd_device_get_diskseq</function></funcdef>
|
||||
<paramdef>sd_device *<parameter>device</parameter></paramdef>
|
||||
<paramdef>uint64_t *<parameter>ret</parameter></paramdef>
|
||||
</funcprototype>
|
||||
|
||||
</funcsynopsis>
|
||||
</refsynopsisdiv>
|
||||
|
||||
<refsect1>
|
||||
<title>Description</title>
|
||||
|
||||
<para><function>sd_device_get_syspath()</function> returns the sysfs path of the specified device record,
|
||||
including the <filename>/sys</filename> prefix. Example: <filename>/sys/devices/virtual/tty/tty7</filename></para>
|
||||
|
||||
<para><function>sd_device_get_devpath()</function> returns the sysfs path of the specified device record,
|
||||
excluding the <filename>/sys</filename> prefix. Example: <filename>/devices/virtual/tty/tty7</filename></para>
|
||||
|
||||
<para><function>sd_device_get_sysname()</function> returns the sysfs name of the specified device record,
|
||||
i.e. the last component of the sysfs path. Example: <literal>tty7</literal> for the device
|
||||
<filename>/sys/devices/virtual/tty/tty7</filename></para>
|
||||
|
||||
<para><function>sd_device_get_sysnum()</function> returns the sysfs device number of the specified device
|
||||
record, i.e. the numeric suffix of the last component of the sysfs path. Example: <literal>7</literal>
|
||||
for the device <filename>/sys/devices/virtual/tty/tty7</filename></para>
|
||||
|
||||
<para><function>sd_device_get_subsystem()</function> returns the kernel subsystem of the specified device
|
||||
record. This is a short string fitting into a filename, and thus does not contain a slash and cannot be
|
||||
empty. Example: <literal>tty</literal>, <literal>block</literal> or <literal>net</literal>.</para>
|
||||
|
||||
<para><function>sd_device_get_devtype()</function> returns the device type of the specified device
|
||||
record, if the subsystem manages multiple types of devices. Example: for devices of the
|
||||
<literal>block</literal> subsystem this can be <literal>disk</literal> or <literal>partition</literal>
|
||||
</para>
|
||||
|
||||
<para><function>sd_device_get_devname()</function> returns the device node path of the specified device
|
||||
record if the device has a device node. Example: for <filename>/sys/devices/virtual/tty/tty7</filename>
|
||||
the string <filename>/dev/tty7</filename> is typically returned.</para>
|
||||
|
||||
<para><function>sd_device_get_devnum()</function> returns the device node major/minor
|
||||
(i.e. <type>dev_t</type>) of the specified device record if the device has a device node (i.e. the one
|
||||
returned by <function>sd_device_get_devname()</function>). For devices belonging to the
|
||||
<literal>block</literal> subsystem this refers to a block device node, in all other cases to a character
|
||||
device node. Example: for the <filename>/sys/devices/virtual/tty/tty7</filename> device this typically
|
||||
returns the device number with major/minor <literal>4:7</literal>.</para>
|
||||
|
||||
<para><function>sd_device_get_ifindex()</function> returns the network interface index of the specified
|
||||
device record, if the device encapsulates a network interface device, i.e. belongs to the
|
||||
<literal>net</literal> subsystem. Example: the <literal>lo</literal> interface typically has interface
|
||||
index 1.</para>
|
||||
|
||||
<para><function>sd_device_get_driver()</function> returns the kernel driver name attached to the
|
||||
device. Note that the driver field is set on the devices consumed by the driver, not on the device
|
||||
created by it. Example: a PCI device <filename>/sys/bus/pci/devices/0000:00:1f.6</filename> might be
|
||||
attached to a driver <literal>e1000e</literal>.</para>
|
||||
|
||||
<para><function>sd_device_get_diskseq()</function> returns the kernel disk sequence number of the block
|
||||
device. This number monotonically increases whenever a backing medium of a block device changes without
|
||||
the device name changing, and is relevant for block devices encapsulating devices with changing media
|
||||
(e.g. floppy or CD-ROM), or loopback block devices. Only defined for block devices, i.e. those of
|
||||
subsystem <literal>block</literal>.</para>
|
||||
</refsect1>
|
||||
|
||||
<refsect1>
|
||||
<title>Return Value</title>
|
||||
|
||||
<para>On success, these calls return 0 or a positive integer. On failure, they return a negative
|
||||
errno-style error code.</para>
|
||||
|
||||
<refsect2>
|
||||
<title>Errors</title>
|
||||
|
||||
<para>Returned errors may indicate the following problems:</para>
|
||||
|
||||
<variablelist>
|
||||
<varlistentry>
|
||||
<term><constant>-EINVAL</constant></term>
|
||||
|
||||
<listitem><para>A specified parameter is invalid.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
<varlistentry>
|
||||
<term><constant>-ENOENT</constant></term>
|
||||
|
||||
<listitem><para>The requested field is not present in the device record.</para></listitem>
|
||||
</varlistentry>
|
||||
|
||||
</variablelist>
|
||||
</refsect2>
|
||||
</refsect1>
|
||||
|
||||
<xi:include href="libsystemd-pkgconfig.xml" />
|
||||
|
||||
<refsect1>
|
||||
<title>See Also</title>
|
||||
|
||||
<para>
|
||||
<citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>
|
||||
</para>
|
||||
</refsect1>
|
||||
|
||||
</refentry>
|
@ -230,6 +230,30 @@
|
||||
<entry><literal>P:</literal></entry>
|
||||
<entry>Device path in <filename>/sys/</filename></entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>M:</literal></entry>
|
||||
<entry>Device name in <filename>/sys/</filename> (i.e. the last component of <literal>P:</literal>)</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>R:</literal></entry>
|
||||
<entry>Device number in <filename>/sys/</filename> (i.e. the numeric suffix of the last component of <literal>P:</literal>)</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>U:</literal></entry>
|
||||
<entry>Kernel subsystem</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>T:</literal></entry>
|
||||
<entry>Kernel device type within subsystem</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>D:</literal></entry>
|
||||
<entry>Kernel device node major/minor</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>I:</literal></entry>
|
||||
<entry>Network interface index</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>N:</literal></entry>
|
||||
<entry>Kernel device node name</entry>
|
||||
@ -242,6 +266,14 @@
|
||||
<entry><literal>S:</literal></entry>
|
||||
<entry>Device node symlink</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>Q:</literal></entry>
|
||||
<entry>Block device sequence number (DISKSEQ)</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>V:</literal></entry>
|
||||
<entry>Attached driver</entry>
|
||||
</row>
|
||||
<row>
|
||||
<entry><literal>E:</literal></entry>
|
||||
<entry>Device property</entry>
|
||||
|
@ -109,6 +109,7 @@ int device_set_devname(sd_device *device, const char *devname);
|
||||
int device_set_devtype(sd_device *device, const char *devtype);
|
||||
int device_set_devnum(sd_device *device, const char *major, const char *minor);
|
||||
int device_set_subsystem(sd_device *device, const char *subsystem);
|
||||
int device_set_diskseq(sd_device *device, const char *str);
|
||||
int device_set_drivers_subsystem(sd_device *device);
|
||||
int device_set_driver(sd_device *device, const char *driver);
|
||||
int device_set_usec_initialized(sd_device *device, usec_t when);
|
||||
|
@ -255,28 +255,6 @@ static int device_set_seqnum(sd_device *device, const char *str) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int device_set_diskseq(sd_device *device, const char *str) {
|
||||
uint64_t diskseq;
|
||||
int r;
|
||||
|
||||
assert(device);
|
||||
assert(str);
|
||||
|
||||
r = safe_atou64(str, &diskseq);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (diskseq == 0)
|
||||
return -EINVAL;
|
||||
|
||||
r = device_add_property_internal(device, "DISKSEQ", str);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
device->diskseq = diskseq;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int device_amend(sd_device *device, const char *key, const char *value) {
|
||||
int r;
|
||||
|
||||
|
@ -570,7 +570,34 @@ int device_set_devnum(sd_device *device, const char *major, const char *minor) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int handle_uevent_line(sd_device *device, const char *key, const char *value, const char **major, const char **minor) {
|
||||
int device_set_diskseq(sd_device *device, const char *str) {
|
||||
uint64_t diskseq;
|
||||
int r;
|
||||
|
||||
assert(device);
|
||||
assert(str);
|
||||
|
||||
r = safe_atou64(str, &diskseq);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (diskseq == 0)
|
||||
return -EINVAL;
|
||||
|
||||
r = device_add_property_internal(device, "DISKSEQ", str);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
device->diskseq = diskseq;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int handle_uevent_line(
|
||||
sd_device *device,
|
||||
const char *key,
|
||||
const char *value,
|
||||
const char **major,
|
||||
const char **minor) {
|
||||
int r;
|
||||
|
||||
assert(device);
|
||||
@ -595,6 +622,10 @@ static int handle_uevent_line(sd_device *device, const char *key, const char *va
|
||||
r = device_set_devmode(device, value);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else if (streq(key, "DISKSEQ")) {
|
||||
r = device_set_diskseq(device, value);
|
||||
if (r < 0)
|
||||
return r;
|
||||
} else if (streq(key, "MAJOR"))
|
||||
*major = value;
|
||||
else if (streq(key, "MINOR"))
|
||||
@ -1047,14 +1078,15 @@ _public_ int sd_device_get_driver(sd_device *device, const char **ret) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
_public_ int sd_device_get_devpath(sd_device *device, const char **devpath) {
|
||||
_public_ int sd_device_get_devpath(sd_device *device, const char **ret) {
|
||||
assert_return(device, -EINVAL);
|
||||
|
||||
assert(device->devpath);
|
||||
assert(device->devpath[0] == '/');
|
||||
|
||||
if (devpath)
|
||||
*devpath = device->devpath;
|
||||
if (ret)
|
||||
*ret = device->devpath;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -22,9 +22,10 @@
|
||||
#include "static-destruct.h"
|
||||
#include "string-table.h"
|
||||
#include "string-util.h"
|
||||
#include "terminal-util.h"
|
||||
#include "udev-util.h"
|
||||
#include "udevadm-util.h"
|
||||
#include "udevadm.h"
|
||||
#include "udevadm-util.h"
|
||||
|
||||
typedef enum ActionType {
|
||||
ACTION_QUERY,
|
||||
@ -171,26 +172,72 @@ static int print_device_chain(sd_device *device) {
|
||||
}
|
||||
|
||||
static int print_record(sd_device *device) {
|
||||
const char *str, *val;
|
||||
int i;
|
||||
const char *str, *val, *subsys;
|
||||
dev_t devnum;
|
||||
uint64_t q;
|
||||
int i, ifi;
|
||||
|
||||
assert(device);
|
||||
|
||||
(void) sd_device_get_devpath(device, &str);
|
||||
printf("P: %s\n", str);
|
||||
/* We don't show syspath here, because it's identical to devpath (modulo the "/sys" prefix).
|
||||
*
|
||||
* We don't show action/seqnum here because that only makes sense for records synthesized from
|
||||
* uevents, not for those synthesized from database entries.
|
||||
*
|
||||
* We don't show sysattrs here, because they can be expensive and potentially issue expensive driver
|
||||
* IO.
|
||||
*
|
||||
* Coloring: let's be conservative with coloring. Let's use it to group related fields. Right now:
|
||||
*
|
||||
* • white for fields that give the device a name
|
||||
* • green for fields that categorize the device into subsystem/devtype and similar
|
||||
* • cyan for fields about associated device nodes/symlinks/network interfaces and such
|
||||
* • magenta for block device diskseq
|
||||
* • yellow for driver info
|
||||
* • no color for regular properties */
|
||||
|
||||
assert_se(sd_device_get_devpath(device, &str) >= 0);
|
||||
printf("P: %s%s%s\n", ansi_highlight_white(), str, ansi_normal());
|
||||
|
||||
if (sd_device_get_sysname(device, &str) >= 0)
|
||||
printf("M: %s%s%s\n", ansi_highlight_white(), str, ansi_normal());
|
||||
|
||||
if (sd_device_get_sysnum(device, &str) >= 0)
|
||||
printf("R: %s%s%s\n", ansi_highlight_white(), str, ansi_normal());
|
||||
|
||||
if (sd_device_get_subsystem(device, &subsys) >= 0)
|
||||
printf("U: %s%s%s\n", ansi_highlight_green(), subsys, ansi_normal());
|
||||
|
||||
if (sd_device_get_devtype(device, &str) >= 0)
|
||||
printf("T: %s%s%s\n", ansi_highlight_green(), str, ansi_normal());
|
||||
|
||||
if (sd_device_get_devnum(device, &devnum) >= 0)
|
||||
printf("D: %s%c %u:%u%s\n",
|
||||
ansi_highlight_cyan(),
|
||||
streq_ptr(subsys, "block") ? 'b' : 'c', major(devnum), minor(devnum),
|
||||
ansi_normal());
|
||||
|
||||
if (sd_device_get_ifindex(device, &ifi) >= 0)
|
||||
printf("I: %s%i%s\n", ansi_highlight_cyan(), ifi, ansi_normal());
|
||||
|
||||
if (sd_device_get_devname(device, &str) >= 0) {
|
||||
assert_se(val = path_startswith(str, "/dev/"));
|
||||
printf("N: %s\n", val);
|
||||
printf("N: %s%s%s\n", ansi_highlight_cyan(), val, ansi_normal());
|
||||
|
||||
if (device_get_devlink_priority(device, &i) >= 0)
|
||||
printf("L: %s%i%s\n", ansi_highlight_cyan(), i, ansi_normal());
|
||||
|
||||
FOREACH_DEVICE_DEVLINK(device, str) {
|
||||
assert_se(val = path_startswith(str, "/dev/"));
|
||||
printf("S: %s%s%s\n", ansi_highlight_cyan(), val, ansi_normal());
|
||||
}
|
||||
}
|
||||
|
||||
if (device_get_devlink_priority(device, &i) >= 0)
|
||||
printf("L: %i\n", i);
|
||||
if (sd_device_get_diskseq(device, &q) >= 0)
|
||||
printf("Q: %s%" PRIu64 "%s\n", ansi_highlight_magenta(), q, ansi_normal());
|
||||
|
||||
FOREACH_DEVICE_DEVLINK(device, str) {
|
||||
assert_se(val = path_startswith(str, "/dev/"));
|
||||
printf("S: %s\n", val);
|
||||
}
|
||||
if (sd_device_get_driver(device, &str) >= 0)
|
||||
printf("V: %s%s%s\n", ansi_highlight_yellow4(), str, ansi_normal());
|
||||
|
||||
FOREACH_DEVICE_PROPERTY(device, str, val)
|
||||
printf("E: %s=%s\n", str, val);
|
||||
@ -442,7 +489,7 @@ static int help(void) {
|
||||
int info_main(int argc, char *argv[], void *userdata) {
|
||||
_cleanup_strv_free_ char **devices = NULL;
|
||||
_cleanup_free_ char *name = NULL;
|
||||
int c, r;
|
||||
int c, r, ret;
|
||||
|
||||
enum {
|
||||
ARG_PROPERTY = 0x100,
|
||||
@ -584,14 +631,21 @@ int info_main(int argc, char *argv[], void *userdata) {
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"-x/--export or -P/--export-prefix cannot be used with --value");
|
||||
|
||||
ret = 0;
|
||||
STRV_FOREACH(p, devices) {
|
||||
_cleanup_(sd_device_unrefp) sd_device *device = NULL;
|
||||
|
||||
r = find_device(*p, NULL, &device);
|
||||
if (r == -EINVAL)
|
||||
return log_error_errno(r, "Bad argument \"%s\", expected an absolute path in /dev/ or /sys or a unit name: %m", *p);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Unknown device \"%s\": %m", *p);
|
||||
if (r < 0) {
|
||||
if (r == -EINVAL)
|
||||
log_error_errno(r, "Bad argument \"%s\", expected an absolute path in /dev/ or /sys/ or a unit name: %m", *p);
|
||||
else
|
||||
log_error_errno(r, "Unknown device \"%s\": %m", *p);
|
||||
|
||||
if (ret == 0)
|
||||
ret = r;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (arg_wait_for_initialization_timeout > 0) {
|
||||
sd_device *d;
|
||||
@ -618,5 +672,5 @@ int info_main(int argc, char *argv[], void *userdata) {
|
||||
return r;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return ret;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user