udev/sd: add support for DISKSEQ

DISKSEQ is a monotonic per-use unique sequence number, incremented
on each block device create/attach. For example, the same loop device
will have different diskseq each time an object is attached to it.
Add sd/udev helpers to parse/expose it.
This commit is contained in:
Luca Boccassi
2021-07-20 15:22:16 +01:00
parent 463aef23a7
commit 122adcb294
5 changed files with 46 additions and 0 deletions

View File

@@ -762,3 +762,8 @@ global:
sd_device_new_from_ifname;
sd_device_new_from_ifindex;
} LIBSYSTEMD_248;
LIBSYSTEMD_250 {
global:
sd_device_get_diskseq;
} LIBSYSTEMD_249;

View File

@@ -75,6 +75,8 @@ struct sd_device {
uid_t devuid;
gid_t devgid;
uint64_t diskseq; /* Block device sequence number, monothonically incremented by the kernel on create/attach */
/* only set when device is passed through netlink */
sd_device_action_t action;
uint64_t seqnum;

View File

@@ -226,6 +226,28 @@ 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;
@@ -292,6 +314,10 @@ static int device_amend(sd_device *device, const char *key, const char *value) {
r = device_set_seqnum(device, value);
if (r < 0)
return log_device_debug_errno(device, r, "sd-device: Failed to set SEQNUM to '%s': %m", value);
} else if (streq(key, "DISKSEQ")) {
r = device_set_diskseq(device, value);
if (r < 0)
return log_device_debug_errno(device, r, "sd-device: Failed to set DISKSEQ to '%s': %m", value);
} else if (streq(key, "DEVLINKS")) {
for (const char *p = value;;) {
_cleanup_free_ char *word = NULL;

View File

@@ -1140,6 +1140,18 @@ _public_ int sd_device_get_seqnum(sd_device *device, uint64_t *ret) {
return 0;
}
_public_ int sd_device_get_diskseq(sd_device *device, uint64_t *ret) {
assert_return(device, -EINVAL);
if (device->diskseq == 0)
return -ENOENT;
if (ret)
*ret = device->diskseq;
return 0;
}
static bool is_valid_tag(const char *tag) {
assert(tag);

View File

@@ -80,6 +80,7 @@ int sd_device_get_sysname(sd_device *device, const char **ret);
int sd_device_get_sysnum(sd_device *device, const char **ret);
int sd_device_get_action(sd_device *device, sd_device_action_t *ret);
int sd_device_get_seqnum(sd_device *device, uint64_t *ret);
int sd_device_get_diskseq(sd_device *device, uint64_t *ret);
int sd_device_get_is_initialized(sd_device *device);
int sd_device_get_usec_initialized(sd_device *device, uint64_t *usec);