From c8c2aa3df24542a729129753d4b58e9e5027a288 Mon Sep 17 00:00:00 2001 From: Jo-Philipp Wich Date: Mon, 17 Oct 2016 00:05:15 +0200 Subject: [PATCH] probe: add full libblkid support Attempt to dlopen() libblkid.so at runtime and use it for proping filesystems if available. Signed-off-by: Jo-Philipp Wich --- CMakeLists.txt | 6 +-- probe-libblkid.c | 117 +++++++++++++++++++++++++++++++++++++++++++++++ probe.c | 13 ++++-- probe.h | 1 + 4 files changed, 131 insertions(+), 6 deletions(-) create mode 100644 probe-libblkid.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 0d4c763..e7a97db 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,12 +56,12 @@ INSTALL(TARGETS mount_root RUNTIME DESTINATION sbin) find_library(json NAMES json-c json) -ADD_EXECUTABLE(block block.c probe.c) +ADD_EXECUTABLE(block block.c probe.c probe-libblkid.c) IF(DEFINED CMAKE_UBIFS_EXTROOT) ADD_DEFINITIONS(-DUBIFS_EXTROOT) - TARGET_LINK_LIBRARIES(block blkid-tiny uci ubox blobmsg_json ubi-utils ${json}) + TARGET_LINK_LIBRARIES(block blkid-tiny dl uci ubox blobmsg_json ubi-utils ${json}) ELSE(DEFINED CMAKE_UBIFS_EXTROOT) - TARGET_LINK_LIBRARIES(block blkid-tiny uci ubox blobmsg_json ${json}) + TARGET_LINK_LIBRARIES(block blkid-tiny dl uci ubox blobmsg_json ${json}) ENDIF(DEFINED CMAKE_UBIFS_EXTROOT) INSTALL(TARGETS block RUNTIME DESTINATION sbin) diff --git a/probe-libblkid.c b/probe-libblkid.c new file mode 100644 index 0000000..c448888 --- /dev/null +++ b/probe-libblkid.c @@ -0,0 +1,117 @@ +/* + * Copyright (C) 2016 Jo-Philipp Wich + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 2.1 + * as published by the Free Software Foundation + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include + +#include "probe.h" + + +static struct { + bool loaded; + blkid_probe (*alloc)(const char *); + int (*probe)(blkid_probe); + int (*lookup)(blkid_probe, const char *, const char **, size_t *); + void (*free)(blkid_probe); +} libblkid = { }; + + +static bool +load_libblkid(void) +{ + void *lib; + + if (!libblkid.loaded) { + lib = dlopen("libblkid.so", RTLD_GLOBAL); + + if (lib) { + libblkid.alloc = dlsym(lib, "blkid_new_probe_from_filename"); + libblkid.probe = dlsym(lib, "blkid_do_probe"); + libblkid.lookup = dlsym(lib, "blkid_probe_lookup_value"); + libblkid.free = dlsym(lib, "blkid_free_probe"); + } + + libblkid.loaded = true; + } + + return (libblkid.alloc && libblkid.probe && libblkid.lookup && libblkid.free); +} + +struct probe_info * +probe_path_libblkid(const char *path) +{ + blkid_probe pr; + struct probe_info *info = NULL; + size_t type_len, uuid_len, label_len, name_len, version_len; + char *dev_ptr, *type_ptr, *uuid_ptr, *label_ptr, *name_ptr, *version_ptr; + const char *type_val, *uuid_val, *label_val, *name_val, *version_val; + + if (!load_libblkid()) + return NULL; + + pr = libblkid.alloc(path); + + if (!pr) + return NULL; + + if (libblkid.probe(pr) == 0) { + if (libblkid.lookup(pr, "TYPE", &type_val, &type_len)) + type_len = 0; + + if (libblkid.lookup(pr, "UUID", &uuid_val, &uuid_len)) + uuid_len = 0; + + if (libblkid.lookup(pr, "LABEL", &label_val, &label_len)) + label_len = 0; + + if (libblkid.lookup(pr, "NAME", &name_val, &name_len)) + name_len = 0; + + if (libblkid.lookup(pr, "VERSION", &version_val, &version_len)) + version_len = 0; + + if (type_len) { + info = calloc_a(sizeof(*info), + &dev_ptr, strlen(path) + 1, + &type_ptr, type_len, + &uuid_ptr, uuid_len, + &label_ptr, label_len, + &name_ptr, name_len, + &version_ptr, version_len); + + if (info) { + info->dev = strcpy(dev_ptr, path); + info->type = strcpy(type_ptr, type_val); + + if (uuid_len) + info->uuid = strcpy(uuid_ptr, uuid_val); + + if (label_len) + info->label = strcpy(label_ptr, label_val); + + if (name_len) + info->name = strcpy(name_ptr, name_val); + + if (version_len) + info->version = strcpy(version_ptr, version_val); + } + } + } + + libblkid.free(pr); + + return info; +} diff --git a/probe.c b/probe.c index 9983a72..1117044 100644 --- a/probe.c +++ b/probe.c @@ -35,7 +35,7 @@ probe_path_tiny(const char *path) if (info) { info->type = strcpy(type, pr.id->name); - + if (pr.dev[0]) info->dev = strcpy(dev, pr.dev); @@ -56,10 +56,17 @@ probe_path_tiny(const char *path) return info; } -struct probe_info * +struct probe_info * probe_path(const char *path) { - return probe_path_tiny(path); + struct probe_info *info; + + info = probe_path_tiny(path); + + if (!info) + info = probe_path_libblkid(path); + + return info; } int diff --git a/probe.h b/probe.h index bcee3a8..b8557a4 100644 --- a/probe.h +++ b/probe.h @@ -28,6 +28,7 @@ struct probe_info { }; struct probe_info * probe_path(const char *path); +struct probe_info * probe_path_libblkid(const char *path); int make_devs(void); -- 2.30.2