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

Karel Zak kzak at redhat.com
Tue Feb 14 10:53:22 UTC 2012


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

-- 
 Karel Zak  <kzak at redhat.com>
 http://karelzak.blogspot.com




More information about the Libguestfs mailing list