diff --git a/src/report/report-basic.c b/src/report/report-basic.c index 4b8d9ce024..eb2fe6a498 100644 --- a/src/report/report-basic.c +++ b/src/report/report-basic.c @@ -384,7 +384,7 @@ static int disk_io_generate(const MetricFamily mf[static 2], sd_varlink *link, v size_t n_devices = 0; CLEANUP_ARRAY(devices, n_devices, block_device_array_free); - r = blockdev_list(BLOCKDEV_LIST_IGNORE_VIRTUAL | BLOCKDEV_LIST_IGNORE_PARTITIONS | BLOCKDEV_LIST_RW_STATS, + r = blockdev_list(BLOCKDEV_LIST_IGNORE_VIRTUAL | BLOCKDEV_LIST_IGNORE_LOOP | BLOCKDEV_LIST_IGNORE_PARTITIONS | BLOCKDEV_LIST_RW_STATS, &devices, &n_devices); if (r < 0) return r; diff --git a/src/shared/blockdev-list.c b/src/shared/blockdev-list.c index fe71bd4ccc..e44332dc60 100644 --- a/src/shared/blockdev-list.c +++ b/src/shared/blockdev-list.c @@ -167,7 +167,22 @@ int blockdev_list_one( goto no_match; } - if (FLAGS_SET(flags, BLOCKDEV_LIST_IGNORE_VIRTUAL)) { + bool is_loop = false; + if (flags & (BLOCKDEV_LIST_IGNORE_LOOP|BLOCKDEV_LIST_IGNORE_VIRTUAL)) { + r = device_sysname_startswith(dev, "loop"); + if (r < 0) { + log_device_warning_errno(dev, r, "Failed to check device name of discovered block device '%s', ignoring: %m", node); + goto skipped; + } + + is_loop = r > 0; + if (is_loop && FLAGS_SET(flags, BLOCKDEV_LIST_IGNORE_LOOP)) + goto no_match; + } + + /* Loopback devices are virtual devices too, but they are covered by BLOCKDEV_LIST_IGNORE_LOOP above, + * hence exclude them here. */ + if (FLAGS_SET(flags, BLOCKDEV_LIST_IGNORE_VIRTUAL) && !is_loop) { const char *devpath; r = sd_device_get_devpath(dev, &devpath); diff --git a/src/shared/blockdev-list.h b/src/shared/blockdev-list.h index e79ad74a76..c50745abbb 100644 --- a/src/shared/blockdev-list.h +++ b/src/shared/blockdev-list.h @@ -6,16 +6,17 @@ typedef enum BlockDevListFlags { BLOCKDEV_LIST_SHOW_SYMLINKS = 1 << 0, /* Pick up symlinks to block devices too */ BLOCKDEV_LIST_REQUIRE_PARTITION_SCANNING = 1 << 1, /* Only consider block devices with partition scanning */ - BLOCKDEV_LIST_IGNORE_VIRTUAL = 1 << 2, /* Ignore virtual devices (devices under /sys/devices/virtual/) */ - BLOCKDEV_LIST_IGNORE_PARTITIONS = 1 << 3, /* Ignore partitions */ - BLOCKDEV_LIST_IGNORE_ZRAM = 1 << 4, /* Ignore ZRAM */ - BLOCKDEV_LIST_IGNORE_ROOT = 1 << 5, /* Ignore the block device we are currently booted from */ - BLOCKDEV_LIST_IGNORE_EMPTY = 1 << 6, /* Ignore disks of zero size (usually drives without a medium) */ - BLOCKDEV_LIST_IGNORE_READ_ONLY = 1 << 7, /* Ignore read-only block devices */ - BLOCKDEV_LIST_REQUIRE_LUKS = 1 << 8, /* Only consider block devices with LUKS superblocks */ - BLOCKDEV_LIST_METADATA = 1 << 9, /* Fill in model, vendor, subsystem, read_only */ - BLOCKDEV_LIST_DISKSEQ = 1 << 10, /* Fill in the diskseq field */ - BLOCKDEV_LIST_RW_STATS = 1 << 11, /* Fill in read and write measurements */ + BLOCKDEV_LIST_IGNORE_VIRTUAL = 1 << 2, /* Ignore virtual devices (devices under /sys/devices/virtual/), except loopback devices */ + BLOCKDEV_LIST_IGNORE_LOOP = 1 << 3, /* Ignore loopback devices */ + BLOCKDEV_LIST_IGNORE_PARTITIONS = 1 << 4, /* Ignore partitions */ + BLOCKDEV_LIST_IGNORE_ZRAM = 1 << 5, /* Ignore ZRAM */ + BLOCKDEV_LIST_IGNORE_ROOT = 1 << 6, /* Ignore the block device we are currently booted from */ + BLOCKDEV_LIST_IGNORE_EMPTY = 1 << 7, /* Ignore disks of zero size (usually drives without a medium) */ + BLOCKDEV_LIST_IGNORE_READ_ONLY = 1 << 8, /* Ignore read-only block devices */ + BLOCKDEV_LIST_REQUIRE_LUKS = 1 << 9, /* Only consider block devices with LUKS superblocks */ + BLOCKDEV_LIST_METADATA = 1 << 10, /* Fill in model, vendor, subsystem, read_only */ + BLOCKDEV_LIST_DISKSEQ = 1 << 11, /* Fill in the diskseq field */ + BLOCKDEV_LIST_RW_STATS = 1 << 12, /* Fill in read and write measurements */ } BlockDevListFlags; /* The "dynamic" filters – ones the kernel can flip at runtime via sysattrs on a live device.