lsblk: move udev and blkid stuff to lsblk-properties.c

Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
Karel Zak 2018-09-19 11:25:08 +02:00
parent baad6dcc6e
commit ccafadb7c5
4 changed files with 210 additions and 193 deletions

View file

@ -80,6 +80,7 @@ dist_man_MANS += misc-utils/lsblk.8
lsblk_SOURCES = \
misc-utils/lsblk.c \
misc-utils/lsblk-mnt.c \
misc-utils/lsblk-properties.c \
misc-utils/lsblk.h
lsblk_LDADD = $(LDADD) libblkid.la libmount.la libcommon.la libsmartcols.la
lsblk_CFLAGS = $(AM_CFLAGS) -I$(ul_libblkid_incdir) -I$(ul_libmount_incdir) -I$(ul_libsmartcols_incdir)

View file

@ -0,0 +1,188 @@
#include <blkid.h>
#ifdef HAVE_LIBUDEV
# include <libudev.h>
#endif
#include "c.h"
#include "xalloc.h"
#include "mangle.h"
#include "lsblk.h"
#ifdef HAVE_LIBUDEV
static struct udev *udev;
#endif
void lsblk_device_free_properties(struct lsblk_devprop *p)
{
if (!p)
return;
free(p->fstype);
free(p->uuid);
free(p->ptuuid);
free(p->pttype);
free(p->label);
free(p->parttype);
free(p->partuuid);
free(p->partlabel);
free(p->wwn);
free(p->serial);
free(p->model);
free(p);
}
#ifndef HAVE_LIBUDEV
static struct lsblk_devprop *get_properties_by_udev(struct blkdev_cxt *cxt
__attribute__((__unused__)))
{
return NULL;
}
#else
static struct lsblk_devprop *get_properties_by_udev(struct blkdev_cxt *cxt)
{
struct udev_device *dev;
if (cxt->udev_requested)
return cxt->properties;
if (lsblk->sysroot)
goto done;
if (!udev)
udev = udev_new(); /* global handler */
if (!udev)
goto done;
dev = udev_device_new_from_subsystem_sysname(udev, "block", cxt->name);
if (dev) {
const char *data;
struct lsblk_devprop *prop;
if (cxt->properties)
lsblk_device_free_properties(cxt->properties);
prop = cxt->properties = xcalloc(1, sizeof(*cxt->properties));
if ((data = udev_device_get_property_value(dev, "ID_FS_LABEL_ENC"))) {
prop->label = xstrdup(data);
unhexmangle_string(prop->label);
}
if ((data = udev_device_get_property_value(dev, "ID_FS_UUID_ENC"))) {
prop->uuid = xstrdup(data);
unhexmangle_string(prop->uuid);
}
if ((data = udev_device_get_property_value(dev, "ID_PART_TABLE_UUID")))
prop->ptuuid = xstrdup(data);
if ((data = udev_device_get_property_value(dev, "ID_PART_TABLE_TYPE")))
prop->pttype = xstrdup(data);
if ((data = udev_device_get_property_value(dev, "ID_PART_ENTRY_NAME"))) {
prop->partlabel = xstrdup(data);
unhexmangle_string(prop->partlabel);
}
if ((data = udev_device_get_property_value(dev, "ID_FS_TYPE")))
prop->fstype = xstrdup(data);
if ((data = udev_device_get_property_value(dev, "ID_PART_ENTRY_TYPE")))
prop->parttype = xstrdup(data);
if ((data = udev_device_get_property_value(dev, "ID_PART_ENTRY_UUID")))
prop->partuuid = xstrdup(data);
if ((data = udev_device_get_property_value(dev, "ID_PART_ENTRY_FLAGS")))
prop->partflags = xstrdup(data);
data = udev_device_get_property_value(dev, "ID_WWN_WITH_EXTENSION");
if (!data)
data = udev_device_get_property_value(dev, "ID_WWN");
if (data)
prop->wwn = xstrdup(data);
if ((data = udev_device_get_property_value(dev, "ID_SERIAL_SHORT")))
prop->serial = xstrdup(data);
if ((data = udev_device_get_property_value(dev, "ID_MODEL")))
prop->model = xstrdup(data);
udev_device_unref(dev);
DBG(DEV, ul_debugobj(cxt, "%s: found udev properties", cxt->name));
}
done:
cxt->udev_requested = 1;
return cxt->properties;
}
#endif /* HAVE_LIBUDEV */
static struct lsblk_devprop *get_properties_by_blkid(struct blkdev_cxt *cxt)
{
blkid_probe pr = NULL;
if (cxt->blkid_requested)
return cxt->properties;
if (!cxt->size)
goto done;
if (getuid() != 0)
goto done;; /* no permissions to read from the device */
pr = blkid_new_probe_from_filename(cxt->filename);
if (!pr)
goto done;
blkid_probe_enable_superblocks(pr, 1);
blkid_probe_set_superblocks_flags(pr, BLKID_SUBLKS_LABEL |
BLKID_SUBLKS_UUID |
BLKID_SUBLKS_TYPE);
blkid_probe_enable_partitions(pr, 1);
blkid_probe_set_partitions_flags(pr, BLKID_PARTS_ENTRY_DETAILS);
if (!blkid_do_safeprobe(pr)) {
const char *data = NULL;
struct lsblk_devprop *prop;
if (cxt->properties)
lsblk_device_free_properties(cxt->properties);
prop = cxt->properties = xcalloc(1, sizeof(*cxt->properties));
if (!blkid_probe_lookup_value(pr, "TYPE", &data, NULL))
prop->fstype = xstrdup(data);
if (!blkid_probe_lookup_value(pr, "UUID", &data, NULL))
prop->uuid = xstrdup(data);
if (!blkid_probe_lookup_value(pr, "PTUUID", &data, NULL))
prop->ptuuid = xstrdup(data);
if (!blkid_probe_lookup_value(pr, "PTTYPE", &data, NULL))
prop->pttype = xstrdup(data);
if (!blkid_probe_lookup_value(pr, "LABEL", &data, NULL))
prop->label = xstrdup(data);
if (!blkid_probe_lookup_value(pr, "PART_ENTRY_TYPE", &data, NULL))
prop->parttype = xstrdup(data);
if (!blkid_probe_lookup_value(pr, "PART_ENTRY_UUID", &data, NULL))
prop->partuuid = xstrdup(data);
if (!blkid_probe_lookup_value(pr, "PART_ENTRY_NAME", &data, NULL))
prop->partlabel = xstrdup(data);
if (!blkid_probe_lookup_value(pr, "PART_ENTRY_FLAGS", &data, NULL))
prop->partflags = xstrdup(data);
DBG(DEV, ul_debugobj(cxt, "%s: found blkid properties", cxt->name));
}
done:
blkid_free_probe(pr);
cxt->blkid_requested = 1;
return cxt->properties;
}
struct lsblk_devprop *lsblk_device_get_properties(struct blkdev_cxt *cxt)
{
struct lsblk_devprop *p = get_properties_by_udev(cxt);
if (!p)
p = get_properties_by_blkid(cxt);
return p;
}
void lsblk_properties_deinit(void)
{
#ifdef HAVE_LIBUDEV
udev_unref(udev);
#endif
}

View file

@ -36,15 +36,9 @@
#include <pwd.h>
#include <grp.h>
#include <ctype.h>
#include <assert.h>
#include <blkid.h>
#include <libmount.h>
#ifdef HAVE_LIBUDEV
#include <libudev.h>
#endif
#include <assert.h>
#include "c.h"
#include "pathnames.h"
@ -55,7 +49,6 @@
#include "strutils.h"
#include "sysfs.h"
#include "closestream.h"
#include "mangle.h"
#include "optutils.h"
#include "lsblk.h"
@ -245,10 +238,6 @@ static size_t nexcludes;
static int includes[256];
static size_t nincludes;
#ifdef HAVE_LIBUDEV
static struct udev *udev;
#endif
static void lsblk_init_debug(void)
{
__UL_INIT_DEBUG_FROM_ENV(lsblk, LSBLK_DEBUG_, 0, LSBLK_DEBUG);
@ -328,26 +317,6 @@ static int column_id_to_number(int id)
return -1;
}
static void free_device_properties(struct lsblk_devprop *p)
{
if (!p)
return;
free(p->fstype);
free(p->uuid);
free(p->ptuuid);
free(p->pttype);
free(p->label);
free(p->parttype);
free(p->partuuid);
free(p->partlabel);
free(p->wwn);
free(p->serial);
free(p->model);
free(p);
}
static void reset_blkdev_cxt(struct blkdev_cxt *cxt)
{
if (!cxt)
@ -360,7 +329,7 @@ static void reset_blkdev_cxt(struct blkdev_cxt *cxt)
free(cxt->filename);
free(cxt->mountpoint);
free_device_properties(cxt->properties);
lsblk_device_free_properties(cxt->properties);
ul_unref_path(cxt->sysfs);
memset(cxt, 0, sizeof(*cxt));
@ -403,151 +372,6 @@ static char *get_device_path(struct blkdev_cxt *cxt)
return xstrdup(path);
}
#ifndef HAVE_LIBUDEV
static struct lsblk_devprop *get_properties_by_udev(struct blkdev_cxt *cxt
__attribute__((__unused__)))
{
return NULL;
}
#else
static struct lsblk_devprop *get_properties_by_udev(struct blkdev_cxt *cxt)
{
struct udev_device *dev;
if (cxt->udev_requested)
return cxt->properties;
if (lsblk->sysroot)
goto done;
if (!udev)
udev = udev_new(); /* global handler */
if (!udev)
goto done;
dev = udev_device_new_from_subsystem_sysname(udev, "block", cxt->name);
if (dev) {
const char *data;
struct lsblk_devprop *prop;
if (cxt->properties)
free_device_properties(cxt->properties);
prop = cxt->properties = xcalloc(1, sizeof(*cxt->properties));
if ((data = udev_device_get_property_value(dev, "ID_FS_LABEL_ENC"))) {
prop->label = xstrdup(data);
unhexmangle_string(prop->label);
}
if ((data = udev_device_get_property_value(dev, "ID_FS_UUID_ENC"))) {
prop->uuid = xstrdup(data);
unhexmangle_string(prop->uuid);
}
if ((data = udev_device_get_property_value(dev, "ID_PART_TABLE_UUID")))
prop->ptuuid = xstrdup(data);
if ((data = udev_device_get_property_value(dev, "ID_PART_TABLE_TYPE")))
prop->pttype = xstrdup(data);
if ((data = udev_device_get_property_value(dev, "ID_PART_ENTRY_NAME"))) {
prop->partlabel = xstrdup(data);
unhexmangle_string(prop->partlabel);
}
if ((data = udev_device_get_property_value(dev, "ID_FS_TYPE")))
prop->fstype = xstrdup(data);
if ((data = udev_device_get_property_value(dev, "ID_PART_ENTRY_TYPE")))
prop->parttype = xstrdup(data);
if ((data = udev_device_get_property_value(dev, "ID_PART_ENTRY_UUID")))
prop->partuuid = xstrdup(data);
if ((data = udev_device_get_property_value(dev, "ID_PART_ENTRY_FLAGS")))
prop->partflags = xstrdup(data);
data = udev_device_get_property_value(dev, "ID_WWN_WITH_EXTENSION");
if (!data)
data = udev_device_get_property_value(dev, "ID_WWN");
if (data)
prop->wwn = xstrdup(data);
if ((data = udev_device_get_property_value(dev, "ID_SERIAL_SHORT")))
prop->serial = xstrdup(data);
if ((data = udev_device_get_property_value(dev, "ID_MODEL")))
prop->model = xstrdup(data);
udev_device_unref(dev);
DBG(DEV, ul_debugobj(cxt, "%s: found udev properties", cxt->name));
}
done:
cxt->udev_requested = 1;
return cxt->properties;
}
#endif /* HAVE_LIBUDEV */
static struct lsblk_devprop *get_properties_by_blkid(struct blkdev_cxt *cxt)
{
blkid_probe pr = NULL;
if (cxt->blkid_requested)
return cxt->properties;
if (!cxt->size)
goto done;
if (getuid() != 0)
goto done;; /* no permissions to read from the device */
pr = blkid_new_probe_from_filename(cxt->filename);
if (!pr)
goto done;
blkid_probe_enable_superblocks(pr, 1);
blkid_probe_set_superblocks_flags(pr, BLKID_SUBLKS_LABEL |
BLKID_SUBLKS_UUID |
BLKID_SUBLKS_TYPE);
blkid_probe_enable_partitions(pr, 1);
blkid_probe_set_partitions_flags(pr, BLKID_PARTS_ENTRY_DETAILS);
if (!blkid_do_safeprobe(pr)) {
const char *data = NULL;
struct lsblk_devprop *prop;
if (cxt->properties)
free_device_properties(cxt->properties);
prop = cxt->properties = xcalloc(1, sizeof(*cxt->properties));
if (!blkid_probe_lookup_value(pr, "TYPE", &data, NULL))
prop->fstype = xstrdup(data);
if (!blkid_probe_lookup_value(pr, "UUID", &data, NULL))
prop->uuid = xstrdup(data);
if (!blkid_probe_lookup_value(pr, "PTUUID", &data, NULL))
prop->ptuuid = xstrdup(data);
if (!blkid_probe_lookup_value(pr, "PTTYPE", &data, NULL))
prop->pttype = xstrdup(data);
if (!blkid_probe_lookup_value(pr, "LABEL", &data, NULL))
prop->label = xstrdup(data);
if (!blkid_probe_lookup_value(pr, "PART_ENTRY_TYPE", &data, NULL))
prop->parttype = xstrdup(data);
if (!blkid_probe_lookup_value(pr, "PART_ENTRY_UUID", &data, NULL))
prop->partuuid = xstrdup(data);
if (!blkid_probe_lookup_value(pr, "PART_ENTRY_NAME", &data, NULL))
prop->partlabel = xstrdup(data);
if (!blkid_probe_lookup_value(pr, "PART_ENTRY_FLAGS", &data, NULL))
prop->partflags = xstrdup(data);
DBG(DEV, ul_debugobj(cxt, "%s: found blkid properties", cxt->name));
}
done:
blkid_free_probe(pr);
cxt->blkid_requested = 1;
return cxt->properties;
}
static struct lsblk_devprop *get_device_properties(struct blkdev_cxt *cxt)
{
struct lsblk_devprop *p = get_properties_by_udev(cxt);
if (!p)
p = get_properties_by_blkid(cxt);
return p;
}
static int is_readonly_device(struct blkdev_cxt *cxt)
{
int fd, ro = 0;
@ -913,7 +737,7 @@ static void set_scols_data(struct blkdev_cxt *cxt, int col, int id, struct libsc
set_sortdata_u64(ln, col, makedev(cxt->maj, cxt->min));
break;
case COL_FSTYPE:
prop = get_device_properties(cxt);
prop = lsblk_device_get_properties(cxt);
if (prop && prop->fstype)
str = xstrdup(prop->fstype);
break;
@ -927,47 +751,47 @@ static void set_scols_data(struct blkdev_cxt *cxt, int col, int id, struct libsc
str = xstrdup(lsblk_device_get_mountpoint(cxt));
break;
case COL_LABEL:
prop = get_device_properties(cxt);
prop = lsblk_device_get_properties(cxt);
if (prop && prop->label)
str = xstrdup(prop->label);
break;
case COL_UUID:
prop = get_device_properties(cxt);
prop = lsblk_device_get_properties(cxt);
if (prop && prop->uuid)
str = xstrdup(prop->uuid);
break;
case COL_PTUUID:
prop = get_device_properties(cxt);
prop = lsblk_device_get_properties(cxt);
if (prop && prop->ptuuid)
str = xstrdup(prop->ptuuid);
break;
case COL_PTTYPE:
prop = get_device_properties(cxt);
prop = lsblk_device_get_properties(cxt);
if (prop && prop->pttype)
str = xstrdup(prop->pttype);
break;
case COL_PARTTYPE:
prop = get_device_properties(cxt);
prop = lsblk_device_get_properties(cxt);
if (prop && prop->parttype)
str = xstrdup(prop->parttype);
break;
case COL_PARTLABEL:
prop = get_device_properties(cxt);
prop = lsblk_device_get_properties(cxt);
if (prop && prop->partlabel)
str = xstrdup(prop->partlabel);
break;
case COL_PARTUUID:
prop = get_device_properties(cxt);
prop = lsblk_device_get_properties(cxt);
if (prop && prop->partuuid)
str = xstrdup(prop->partuuid);
break;
case COL_PARTFLAGS:
prop = get_device_properties(cxt);
prop = lsblk_device_get_properties(cxt);
if (prop && prop->partflags)
str = xstrdup(prop->partflags);
break;
case COL_WWN:
prop = get_properties_by_udev(cxt);
prop = lsblk_device_get_properties(cxt);
if (prop && prop->wwn)
str = xstrdup(prop->wwn);
break;
@ -997,7 +821,7 @@ static void set_scols_data(struct blkdev_cxt *cxt, int col, int id, struct libsc
break;
case COL_MODEL:
if (!cxt->partition && cxt->nslaves == 0) {
prop = get_properties_by_udev(cxt);
prop = lsblk_device_get_properties(cxt);
if (prop && prop->model)
str = xstrdup(prop->model);
else
@ -1006,7 +830,7 @@ static void set_scols_data(struct blkdev_cxt *cxt, int col, int id, struct libsc
break;
case COL_SERIAL:
if (!cxt->partition && cxt->nslaves == 0) {
prop = get_properties_by_udev(cxt);
prop = lsblk_device_get_properties(cxt);
if (prop && prop->serial)
str = xstrdup(prop->serial);
else
@ -1986,9 +1810,8 @@ leave:
scols_unref_table(lsblk->table);
#ifdef HAVE_LIBUDEV
udev_unref(udev);
#endif
lsblk_mnt_deinit();
lsblk_properties_deinit();
return status;
}

View file

@ -103,4 +103,9 @@ extern void lsblk_mnt_deinit(void);
extern char *lsblk_device_get_mountpoint(struct blkdev_cxt *cxt);
/* lsblk-properties.c */
extern void lsblk_device_free_properties(struct lsblk_devprop *p);
extern struct lsblk_devprop *lsblk_device_get_properties(struct blkdev_cxt *cxt);
extern void lsblk_properties_deinit(void);
#endif /* UTIL_LINUX_LSBLK_H */