Skip to content

Commit

Permalink
udev-builtin-blkid: add support for --hint offsets
Browse files Browse the repository at this point in the history
The next libblkid v2.37 is going to support session offsets for
multi-session CD/DVDs. This feature is implemented by "hint offsets".

These offsets are optional and prober specific (e.g., iso, udf, ...).
For this purpose, the library provides a new function
blkid_probe_set_hint(), and blkid(8) provides a new command-line
option --hint <name>=<offset>. For CD/DVD, the offset name is
"session_offset".

The difference between classic --offset and the new --hint is that
--offset is very restrictive and defines the probing area and the rest
of the device is invisible to the library. The new --hint works
like a suggestion, it provides a hint where the user assumes the
filesystem, but the rest of the device is still readable for the
library (for example, to get some additional superblock information
etc.).

If the --hint is without a value then it defaults to zero.

The option --hint implementation in udev-builtin-blkid.c is backwardly
compatible. If compiled against old libblkid, then the option is used in
the same way as --offset.

Addresses: util-linux/util-linux#1161
Addresses: #17424
  • Loading branch information
karelzak authored and yuwata committed Jan 12, 2021
1 parent 885598f commit 4fcc033
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 10 deletions.
3 changes: 3 additions & 0 deletions meson.build
Expand Up @@ -1003,6 +1003,9 @@ want_blkid = get_option('blkid')
if want_blkid != 'false' and not skip_deps
libblkid = dependency('blkid', required : want_blkid == 'true')
have = libblkid.found()

conf.set10('HAVE_BLKID_PROBE_SET_HINT',
have and cc.has_function('blkid_probe_set_hint', dependencies : libblkid))
else
have = false
libblkid = []
Expand Down
2 changes: 1 addition & 1 deletion rules.d/60-persistent-storage.rules
Expand Up @@ -104,7 +104,7 @@ KERNEL=="vd*[0-9]", ENV{ID_PATH}=="pci-*", SYMLINK+="disk/by-path/virtio-$env{ID

# probe filesystem metadata of optical drives which have a media inserted
KERNEL=="sr*", ENV{DISK_EJECT_REQUEST}!="?*", ENV{ID_CDROM_MEDIA_TRACK_COUNT_DATA}=="?*", ENV{ID_CDROM_MEDIA_SESSION_LAST_OFFSET}=="?*", \
IMPORT{builtin}="blkid --offset=$env{ID_CDROM_MEDIA_SESSION_LAST_OFFSET}"
IMPORT{builtin}="blkid --hint=session_offset=$env{ID_CDROM_MEDIA_SESSION_LAST_OFFSET}"
# single-session CDs do not have ID_CDROM_MEDIA_SESSION_LAST_OFFSET
KERNEL=="sr*", ENV{DISK_EJECT_REQUEST}!="?*", ENV{ID_CDROM_MEDIA_TRACK_COUNT_DATA}=="?*", ENV{ID_CDROM_MEDIA_SESSION_LAST_OFFSET}=="", \
IMPORT{builtin}="blkid --noraid"
Expand Down
33 changes: 25 additions & 8 deletions src/udev/udev-builtin-blkid.c
Expand Up @@ -238,10 +238,16 @@ static int builtin_blkid(sd_device *dev, int argc, char *argv[], bool test) {

static const struct option options[] = {
{ "offset", required_argument, NULL, 'o' },
{ "hint", required_argument, NULL, 'H' },
{ "noraid", no_argument, NULL, 'R' },
{}
};

errno = 0;
pr = blkid_new_probe();
if (!pr)
return log_device_debug_errno(dev, errno_or_else(ENOMEM), "Failed to create blkid prober: %m");

for (;;) {
int option;

Expand All @@ -250,24 +256,35 @@ static int builtin_blkid(sd_device *dev, int argc, char *argv[], bool test) {
break;

switch (option) {
case 'H':
#if HAVE_BLKID_PROBE_SET_HINT
errno = 0;
r = blkid_probe_set_hint(pr, optarg, 0);
if (r < 0)
return log_device_error_errno(dev, errno_or_else(ENOMEM), "Failed to use '%s' probing hint: %m", optarg);
break;
#else
/* Use the hint <name>=<offset> as probing offset for old versions */
optarg = strchr(optarg, '=');
if (!optarg)
/* no value means 0, do nothing for old versions */
break;
++optarg;
_fallthrough_;
#endif
case 'o':
r = safe_atoi64(optarg, &offset);
if (r < 0)
return log_device_error_errno(dev, r, "Failed to parse '%s' as an integer: %m", optarg);
if (offset < 0)
return log_device_error_errno(dev, SYNTHETIC_ERRNO(ERANGE), "Invalid offset %"PRIi64": %m", offset);
return log_device_error_errno(dev, SYNTHETIC_ERRNO(EINVAL), "Invalid offset %"PRIi64": %m", offset);
break;
case 'R':
noraid = true;
break;
}
}

errno = 0;
pr = blkid_new_probe();
if (!pr)
return log_device_debug_errno(dev, errno > 0 ? errno : ENOMEM, "Failed to create blkid prober: %m");

blkid_probe_set_superblocks_flags(pr,
BLKID_SUBLKS_LABEL | BLKID_SUBLKS_UUID |
BLKID_SUBLKS_TYPE | BLKID_SUBLKS_SECTYPE |
Expand All @@ -287,7 +304,7 @@ static int builtin_blkid(sd_device *dev, int argc, char *argv[], bool test) {
errno = 0;
r = blkid_probe_set_device(pr, fd, offset, 0);
if (r < 0)
return log_device_debug_errno(dev, errno > 0 ? errno : ENOMEM, "Failed to set device to blkid prober: %m");
return log_device_debug_errno(dev, errno_or_else(ENOMEM), "Failed to set device to blkid prober: %m");

log_device_debug(dev, "Probe %s with %sraid and offset=%"PRIi64, devnode, noraid ? "no" : "", offset);

Expand All @@ -301,7 +318,7 @@ static int builtin_blkid(sd_device *dev, int argc, char *argv[], bool test) {
errno = 0;
nvals = blkid_probe_numof_values(pr);
if (nvals < 0)
return log_device_debug_errno(dev, errno > 0 ? errno : ENOMEM, "Failed to get number of probed values: %m");
return log_device_debug_errno(dev, errno_or_else(ENOMEM), "Failed to get number of probed values: %m");

for (i = 0; i < nvals; i++) {
if (blkid_probe_get_value(pr, i, &name, &data, NULL) < 0)
Expand Down
2 changes: 1 addition & 1 deletion test/fuzz/fuzz-udev-rules/60-persistent-storage.rules
Expand Up @@ -86,7 +86,7 @@ KERNEL=="vd*[0-9]", ENV{ID_PATH}=="pci-*", SYMLINK+="disk/by-path/virtio-$env{ID

# probe filesystem metadata of optical drives which have a media inserted
KERNEL=="sr*", ENV{DISK_EJECT_REQUEST}!="?*", ENV{ID_CDROM_MEDIA_TRACK_COUNT_DATA}=="?*", ENV{ID_CDROM_MEDIA_SESSION_LAST_OFFSET}=="?*", \
IMPORT{builtin}="blkid --offset=$env{ID_CDROM_MEDIA_SESSION_LAST_OFFSET}"
IMPORT{builtin}="blkid --hint=session_offset=$env{ID_CDROM_MEDIA_SESSION_LAST_OFFSET}"
# single-session CDs do not have ID_CDROM_MEDIA_SESSION_LAST_OFFSET
KERNEL=="sr*", ENV{DISK_EJECT_REQUEST}!="?*", ENV{ID_CDROM_MEDIA_TRACK_COUNT_DATA}=="?*", ENV{ID_CDROM_MEDIA_SESSION_LAST_OFFSET}=="", \
IMPORT{builtin}="blkid --noraid"
Expand Down

0 comments on commit 4fcc033

Please sign in to comment.