DarkElvenAngel
Posts: 197
Joined: Tue Mar 20, 2018 9:53 pm

How to get PARTUUID

Sun Aug 18, 2019 5:55 pm

Hello everyone,

I'm working on a program to auto-mount USB drives when connected to the system. For the most part I have this working.

My plan is to add a file /etc/xfstab it will be formatted exactly like fstab with the exception that it's sole function is for how to mount external USB media. The sticking point are PARTUUIDs I can't seem to find them.

I'm currently using libblkid and I get most of what I needed, from the documentation I have found I should be able to do what I want. However nothing I have found works.

This is my sample code I use this to test be aware if you try this code it needs libblkid-dev to be installed and it doesn't do error checking when trying to read the data. So it may print out garbage also it must be run with root privileges.

Code: Select all

#include <stdio.h>
#include <string.h>
#include <err.h>
#include <blkid/blkid.h>

int main (int argc, char *argv[])
{
	blkid_probe pr = blkid_new_probe_from_filename(argv[1]);
	if (!pr) { err(1, "Failed to open");}

	blkid_partlist ls;
	int nparts, i;

	ls = blkid_probe_get_partitions(pr);
	nparts = blkid_partlist_numof_partitions(ls);
	printf("Number of Partitions : %d\n", nparts);

	if (nparts <= 0) { err(0, "Need the root block device [eg /dev/sda]"); }

	const char *uuid;
        const char *partuuid;
	const char *label;
	const char *type;

	for ( i=0; i<nparts; i++ )
	{
		char dev_name[30];
		printf("DEVICE NAME: %s%d\n", argv[1], (i+1));
		sprintf(dev_name, "%s%d", argv[1], (i+1));

		pr = blkid_new_probe_from_filename(dev_name);
		blkid_do_probe(pr);

		blkid_probe_lookup_value(pr, "PTUUID", &partuuid, NULL);
		blkid_probe_lookup_value(pr, "UUID", &uuid, NULL);
		blkid_probe_lookup_value(pr, "LABEL", &label, NULL);
		blkid_probe_lookup_value(pr, "TYPE", &type, NULL);

		 printf("UUID: %s, LABEL: %s, TYPE: %s PARTUUID: %s\n", uuid, label, type, partuuid);
	}

	blkid_free_probe(pr);

	return 0;
}
//PART_ENTRY_UUID no
//PTUUID no
To compile use

Code: Select all

gcc <filename.c> -lblkid
Then run with a USB stick installed

Code: Select all

sudo ./a.out /dev/sda
Sample output

Code: Select all

Number of Partitions : 1
DEVICE NAME: /dev/sda1
UUID: 1234-ABCD, LABEL: KINGSTON, TYPE: vfat PARTUUID: (NULL)
Any help would be great thanks.

User avatar
DougieLawson
Posts: 36578
Joined: Sun Jun 16, 2013 11:19 pm
Location: Basingstoke, UK
Contact: Website Twitter

Re: How to get PARTUUID

Sun Aug 18, 2019 6:19 pm

What's wrong with the built-in blkid command? What does your new version do better?
Note: Having anything humorous in your signature is completely banned on this forum. Wear a tin-foil hat and you'll get a ban.

Any DMs sent on Twitter will be answered next month.

This is a doctor free zone.

User avatar
HawaiianPi
Posts: 4879
Joined: Mon Apr 08, 2013 4:53 am
Location: Aloha, Oregon USA

Re: How to get PARTUUID

Sun Aug 18, 2019 6:25 pm

Or how about, ls -l /dev/disk/by-partuuid, which also works fine.

~ $ ls -l /dev/disk/by-partuuid
total 0
lrwxrwxrwx 1 root root 10 Aug 3 18:45 1a2b3c4d-01 -> ../../sdb1
lrwxrwxrwx 1 root root 15 Aug 3 18:45 a4b3c2d1-01 -> ../../mmcblk0p1
lrwxrwxrwx 1 root root 10 Aug 3 18:45 d1c2b3a4-01 -> ../../sda1
lrwxrwxrwx 1 root root 10 Aug 3 18:45 d1c2b3a4-02 -> ../../sda2
My mind is like a browser. 27 tabs are open, 9 aren't responding,
lots of pop-ups...and where is that annoying music coming from?

DarkElvenAngel
Posts: 197
Joined: Tue Mar 20, 2018 9:53 pm

Re: How to get PARTUUID

Sun Aug 18, 2019 8:01 pm

DougieLawson wrote:
Sun Aug 18, 2019 6:19 pm
What's wrong with the built-in blkid command? What does your new version do better?
That's a good question, I'm not trying to reinvent that particular wheel. My goal is to be able to read each partitions filesystem type, label, UUID and PARTUUID. And with that information I can then generate the appropriate mount point and use the mount system call to mount the drive. The target environment's blkid command is too simple and doesn't give the required information.
HawaiianPi wrote: Or how about, ls -l /dev/disk/by-partuuid, which also works fine.

~ $ ls -l /dev/disk/by-partuuid
total 0
lrwxrwxrwx 1 root root 10 Aug 3 18:45 1a2b3c4d-01 -> ../../sdb1
lrwxrwxrwx 1 root root 15 Aug 3 18:45 a4b3c2d1-01 -> ../../mmcblk0p1
lrwxrwxrwx 1 root root 10 Aug 3 18:45 d1c2b3a4-01 -> ../../sda1
lrwxrwxrwx 1 root root 10 Aug 3 18:45 d1c2b3a4-02 -> ../../sda2
Simply that will not work my target environment is very simple and doesn't generate those symlinks for new devices.

These ideas both work perfectly in Raspbian where I can do all I need with one bash script.

User avatar
Roken
Posts: 309
Joined: Sun Dec 31, 2017 4:35 pm
Location: UK

Re: How to get PARTUUID

Mon Aug 19, 2019 5:19 am

Headless PI. OMG, someone cut it's head off. Oh, hang on. it didn't have one to start with.

DarkElvenAngel
Posts: 197
Joined: Tue Mar 20, 2018 9:53 pm

Re: How to get PARTUUID

Mon Aug 19, 2019 8:08 pm

Roken wrote:
Mon Aug 19, 2019 5:19 am
https://wiki.debian.org/udev does that.
Thank you Roken, I'm aware that udev can do that I'm using it to trigger my program

Code: Select all

ACTION=="add", KERNEL=="sd?", SUBSYSTEM=="block", RUN+="/usr/bin/usb add %k auto"
ACTION=="remove", KERNEL=="sd?", SUBSYSTEM=="block", RUN+="/usr/bin/usb remove %k"
I wanted to avoid passing a bunch of command-line arguments. However it's one way to do things that is much simpler.

I see there is a libudev I'm actively looking into this library now, I'm hoping someone knows how to do this programmatically.

Return to “C/C++”