On 02/14/2012 06:53 PM, Karel Zak wrote: > On Tue, Feb 14, 2012 at 08:56:12AM +0000, Richard W.M. Jones wrote: >> On Tue, Feb 14, 2012 at 03:30:26PM +0800, Wanlong Gao wrote: >> It's one of those things that might be an improvement, but it would >> have to be distinctly better than the existing approach of calling out >> to the 'blkid' binary. >> >> Is the libblkid library interface stable? Is it meant to be used by >> programs other than the blkid binary? > > Yes, for example the latest udevd is linked with libblkid. > >>> +#include <blkid/blkid.h> > > #include <blkid.h> if you want to use pkg-config > >>> static char * >>> get_blkid_tag (const char *device, const char *tag) >>> { >>> - char *out, *err; >>> - int r; >>> + int fd, rc; >>> + const char *data = NULL; >>> + blkid_probe blkprobe; >>> >>> - r = commandr (&out, &err, >>> - "blkid", >>> - /* Adding -c option kills all caching, even on RHEL 5. */ >>> - "-c", "/dev/null", >>> - "-o", "value", "-s", tag, device, NULL); >>> - if (r != 0 && r != 2) { >>> - if (r >= 0) >>> - reply_with_error ("%s: %s (blkid returned %d)", device, err, r); >>> - else >>> - reply_with_error ("%s: %s", device, err); >>> - free (out); >>> - free (err); >>> + if (!device || !tag) >>> return NULL; >>> - } >>> >>> - free (err); >>> + fd = open (device, O_RDONLY); >>> + if (fd < 0) >>> + return NULL; >>> >>> - if (r == 2) { /* means UUID etc not found */ >>> - free (out); >>> - out = strdup (""); >>> - if (out == NULL) >>> - reply_with_perror ("strdup"); >>> - return out; >>> - } >>> + blkprobe = blkid_new_probe (); >>> + if (!blkprobe) >>> + goto done; >>> + if (blkid_probe_set_device (blkprobe, fd, 0, 0)) >>> + goto done; >>> + >>> + blkid_probe_enable_superblocks(blkprobe, 1); > > You can also optionally enable > > blkid_probe_enable_partitions(pr, 1); > > to check for collisions between raids and partition tables (for example > RAID1 could be partitioned -- then PT could be at the begin of the device > and raid superblock at the end of the device, etc.) > >>> + blkid_probe_set_superblocks_flags (blkprobe, BLKID_SUBLKS_LABEL | >>> + BLKID_SUBLKS_UUID | >>> BLKID_SUBLKS_TYPE); >>> >>> - /* Trim trailing \n if present. */ >>> - size_t len = strlen (out); >>> - if (len > 0 && out[len-1] == '\n') >>> - out[len-1] = '\0'; >>> + rc = blkid_do_safeprobe (blkprobe); >>> + if (!rc) >>> + blkid_probe_lookup_value (blkprobe, tag, &data, NULL); >>> >>> - return out; /* caller frees */ >>> +done: >>> + close (fd); >>> + if (blkprobe) >>> + blkid_free_probe (blkprobe); >>> + return data ? strdup ((char *) data) : NULL; > > after blkid_free_probe() the "data" are deallocated, must be: > > done: > close (fd); > if (data) > data = strdup ((char *) data); > blkid_free_probe (blkprobe); > return data; > > Note that if-before-free is unnecessary for blkid_free_probe. > > Karel >
I did like this. Now get a problem like below: The *vfs_type* calls this *get_blkid_tag* function. I added a disk image to guestfish, this disk image contains a partition "/dev/vda1" with "ext4" filesystem. Then I ran *vfs_type /dev/vda1", I got the result, but with "vfs_type /dev/vda", it hang. It seems that the vfs_type can't get a type of /dev/vda, it's right that the type of /dev/vda is unknown, but why can't it go back with unknown result or NULL result? Maybe there's something wrong with the code of *get_blkid_tag* ? Can you give some advise? Karel? Rich? Thanks -Wanlong Gao _______________________________________________ Libguestfs mailing list Libguestfs@redhat.com https://www.redhat.com/mailman/listinfo/libguestfs