Is the PARTFLAGS option of lsblk broken or me?

I wanted lsblk to dump the partition flags of a disk, but I couldn’t figure out how to do it. I expected lsblk -o NAME,PARTFLAGS to do the trick, but it didn’t work. I couldn’t find another other option under lsblk -H that would provide me the flags of the partitions.

$ lsblk -o NAME,PARTFLAGS /dev/nvme0n1   
NAME                                          PARTFLAGS
nvme0n1                                       
├─nvme0n1p1                                   
├─nvme0n1p2                                   
├─nvme0n1p3                                   
└─nvme0n1p5   

$ rpm -qf /usr/bin/lsblk
util-linux-2.40.2-4.fc41.x86_64                           

lsblk’s option shows nothing, but parted returns the expected flags:

$ sudo parted /dev/nvme0n1 print      
Model: SHPP41-1000GM (nvme)
Disk /dev/nvme0n1: 1000GB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags: 

Number  Start   End     Size    File system  Name                  Flags
 1      1049kB  2149MB  2147MB  fat32        EFI System Partition  boot, esp
 2      2149MB  10.7GB  8590MB  ext4                               bls_boot
 3      10.7GB  333GB   322GB   btrfs
 5      334GB   1000GB  666GB

Is lsblk’s option not working or am I running the wrong option?

Possibly. What parted is called “flags” is mostly the partition type encoded as an UUID value. Try

lsblk -o NAME,PARTTYPENAME

I guess that PARTFLAGS should at least show the “boot” flag.

1 Like

Yes, PARTTYPENAMEshows the partition type names, not the partition flags.

The boot flag is primarily what I’m looking for. I played with a bunch of the -o flags trying to find out how to get it to tell me which partitions had the bootable flag. None I could find.

I started crawling through the lsblk source code. Something should be testing the attributes field of a GPT partition for bits 0-2 (libblkid/src/partitions/gpt.c), but as far as I can tell, nothing is doing that.

With an msdos partitioned disk, there is code that checks and tests for bootable (libblkid/src/partitions/dos.c:probe_dos_pt), but as far as I can tell, only for it being a valid partition.

I found an msdos partitioned USB stick laying about:

$ sudo parted /dev/sdb print                  
Model: SanDisk Ultra (scsi)
Disk /dev/sdb: 30.8GB
Sector size (logical/physical): 512B/512B
Partition Table: msdos
Disk Flags: 

Number  Start   End     Size    Type     File system  Flags
 1      1049kB  8011MB  8010MB  primary  fat32        boot, lba

$ lsblk -o NAME,PARTTYPE,PARTTYPENAME /dev/sdb    
NAME   PARTTYPE PARTTYPENAME
sdb             
└─sdb1 0xc      W95 FAT32 (LBA)

The bootable information/flag is also missing there too.

So I guess this is just a problem of missing functionality. Bug or (missing) feature?

If you are just looking for a tool to get the job done, it looks like sgdisk --attributes 1:show /dev/sdb should work (or maybe sgdisk --attributes 1:get:2 /dev/sdb if you are looking for a specific bit).

You might consider using gparted:

I’m looking for a single command that’ll do exactly what lsblk --fs does, but also adds which partitions are bootable.

I’m working with a Linux user that is not very fluent with Linux. I need to be able to give him shell commands that’ll dump out what lsblk --fs does, but I also need to determine which of the partitions on his system that are marked as bootable. It would be nice to give him a single shell command that requires no root privileges (safer) and no user interaction (safer) that’ll report everything I need (all disks with all their partitions, uuids, file system types and sizes, and mount points). That way he can just copy-and-paste the command right from my email and then send me back the output.

sudo parted /dev/<disk> print will tell me what I want for partition flags (which ones are bootable), but it requires him coming up with the disk device names and running commands with sudo. Or having to send me the lsblk --fs and wait for me to determine the drive and tell him the exact full parted commands to run.

I was hoping to come up with an lsblk -o ... command for him that’ll do everything for me in one simple step. When I found the PARTFLAGS option, it looked like it’d do exactly what I wanted (dump partitions’ flags), but it seems not to be helpful and I can’t find another option that’ll do it. Providing the bootable status of a msdos and GPT partitioned drives seem out of lsblk’s current feature set.

1 Like

The boot flags isn’t really used in linux. For UEFI, the first stages boot loader is loaded according to the entries seen when running efibootmgr. Usually, this loader is located in the esp (EFI System Partition) which has this special partition type to identify it. Usually this partition will also have the boot flag set, whether needed or not.

In linux the first stage is shim.efi or shimx86.efi which will load the next stage grubx64.efi which will find the file grub.cfg in the same directory. The grub.cfg then determines what happens next, including locating the initial ram disk and the root file system. For classic BIOS boot, the first part of grub2 is loacated in the MBR, and the rest is found somewhere else on the disk using a list of absolute sector numbers. It doesn’t use the boot flag for that.

The boot flag was used in the old ms-dos master boot loader located in the Master Boot Record on the first sector of the selected disk unit. The code in the Master Boot Record will go through the partition table and find the bootable partition table and load the Partition Boot Record and run this code. This then loades MSDOS or for WIndows the Windows Boot manager.

In UEFI mode, this is all replaced by files found the the ESP, so no Master Boot Record and no Partition Boot Record.

2 Likes

Thank you for providing a lot of good background on the boot processes for MBR/msdos and UEFI/GPT. I’m sure some of that will come in handy helping me to resolve his current mess. I used to know some of that stuff fairly well 10-20 years ago, but those neurons have unfortunately long decayed. Looks like I need a refresher.

In my descriptions here, I did get some things blurred in trying to help this guy out with info co-mingled between his MBR/msdos hard drive, his live booting a distro from a USB stick on his affected system with UEFI/GPT, and then researching on my systems UEFI/GPT.

The system of his with the problem is an MS-DOS (yes, genuine, original, true MS-DOS) with MBR that he had configured to dual boot Linux on (with grub). He attempted to install another Linux distro on it to replace the distro he had, ended up in the weeds, and tried to dig himself out mangling his system. From 2000 miles away, I’m trying to figure out what state he’s got it all in dumping info from lsblk ... and sudo parted ... from the Linux live boot USB stick and see if it’s fixable.

I had been hoping he could get all the information I needed with the right options to lsblk and found PARTFLAGS. When testing the option on my UEFI/GPT systems, it didn’t do as I thought it should (which you have since corrected my understanding!).

However, it turns out that when run on an MBR/msdos disk, PARTFLAGS actually works. (I messed up in my post yesterday using the wrong option swapping PARTFLAGS for PARTTYPE.) Here’s showing it works when rerunning it with using PARTFLAGS:

NAME   PARTFLAGS PARTTYPE PARTTYPENAME
sdb                       
└─sdb1 0x80      0xc      W95 FAT32 (LBA)

The 0x80 shows that that partition 1 is bootable, as expected.

Before asking for help, he was trying to get back and undo the Linux install he stopped in the middle of and just get back to a single-boot MS-DOS system with fdisk /mbr and start over. I think the a boot flag on the partially installed and now abandoned Linux partitions is what got him stuck.

I’m trying to get him to leave the MS-DOS installed hard drive alone and just put another physical drive in the system to install Linux on.

To give the curious the background, he has some ancient equipment and the software for it is in MS-DOS, never released for MS Windows. The MS-DOS application has hard real-time requirements for the equipment it controls, so it has to run native. The machine is located in an outbuilding with no networking. After gathering the data he needs for a given run, he reboots into Linux, mounts the MS-DOS partition, processes and then copies the data to a USB stick (remember, no USB support in MS-DOS!), and then sneakernets the stick back to his main building.

In linux you can install the package dosemu which allows you to run old dos programs in a virtual environment.

Thank you, but as I mentioned, this MS-DOS program controls external equipment with hard real-time requirements (timing must be precise with no uncontrolled latency from interrupts or task switching) that only native execution on bare hardware can meet.