[Libguestfs] [PATCH RFC] blkid: start using libblkid directly instead

Wanlong Gao gaowanlong at cn.fujitsu.com
Wed Feb 15 08:42:45 UTC 2012


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




More information about the Libguestfs mailing list