Re: Finding a block device quickly with libblkid

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Mar 01, 2024 at 06:30:15PM +0000, Eric Curtin wrote:
> We are looking into optimizing the boot sequence of a device with many
> partitions.

Nice topic :-)

> On boot in the default systemd implementation, all the block devices
> are queried via libblkid and the various symlinks are set up in
> /dev/disk/* from the results of those queries. The problem is on a
> device with many partitions this can delay the boot by hundreds of
> milliseconds, which is not ideal, especially when in many cases all
> you really care about is mounting the block device that represents the
> rootfs partition.

It's a little bit more complex. It's not just about rootfs. The reason
why udevd scans all the devices is to create a udev database and fill
it with data usable for running the system. For example, when you type
'lsblk --fs', it reads the data from the database (findmnt, mount,
etc.), which is also used by udev rules and for dependency evaluations
in systemd, etc. This is the reason why the system gathers all the
data about a new device when it's detected.

If you want to avoid all of this, you need to customize udev rules
where you can filter out what and how to scan.

> We can sort of guess "/dev/sde38" is the correct
> one, but that's not deterministic.
> 
> So we started digging and came across blkid_find_dev_with_tag and
> blkid_dev_devname, which you can call like this:
> 
> blkid_dev_devname(blkid_find_dev_with_tag(cache, "PARTLABEL", "system_a")))
> 
> blkid_dev_devname(blkid_find_dev_with_tag(cache, "PARTLABEL", "system_b")))

You're on the right track. PARTLABEL and PARTUUID are stored in the
partition table, so it's unnecessary to scan partitions for their
content (filesystems).

> On first glance this looks useful as you don't have to loop through
> all the devices to use.
> 
> But this function only seems to work if the data is already cached, so
> it's not so useful on boot.

Yes, using blkid_dev_devname() is not advisable. It's part of the old
high-level libblkid API from the pre-udev era.

If you truly need to read data from the device, then utilizing the
low-level probing API is recommended. This can be done from the
command line with 'blkid -p', but you'll need to disable scanning for
all unwanted data (using '--usage no*'). For instance:

    blkid -o udev -p --usages nofilesystem,raid,crypto,others /dev/sda1

This command will only return ID_PART_ENTRY_* data from the partition
table.

You can use the LIBBLKID_DEBUG=all environment variable to see
the library's operations.

The question arises whether using blkid is the ideal solution if you
only require PARTLABELs and PARTUUIDs. For example, sfdisk could be a
more efficient approach:

    sfdisk -l /dev/sda -o+NAME,UUID

However, a potential issue is that sfdisk only provides the guessed
partition names (paths); the name used by the kernel might be different.

> Has anyone any ideas on how we can optimize the identification of a
> block device via UUID, LABEL, PARTUUID, PARTLABEL, etc.? Because the
> current implementations don't scale well when you have many block
> devices.

It depends on your goal. You can heavily customize your system to
speed up boot (all the necessary tools are available for this
purpose). However, the problem I see is the issue of portability and
the maintenance overhead.

    Karel

-- 
 Karel Zak  <kzak@xxxxxxxxxx>
 http://karelzak.blogspot.com




[Index of Archives]     [LARTC]     [Bugtraq]     [Yosemite Forum]     [Photo]

  Powered by Linux