[lvm-devel] [PATCH 1/2] Add vg_get_attr_list() libLVM API to return a list of VG attribute names.
Dave Wysochanski
dwysocha at redhat.com
Wed Jan 21 21:52:47 UTC 2009
This API returns a list of attribute names for a VG. A later API will
allow the values of the attributes to be queried. The API implementation
relies on adding an exported call to libdevmapper, dm_report_get_field_ids(),
which is the interface into dm's reporting infrastructure to retrieve the
attribute/field names/ids.
Main code is in libdm/libdevmapper.h, libdm/libdm-report.c, and
lib/report/report.c. Other supporting code was added just to get it to
compile and is not the primary focus of this patch. The test/api/test.c
file allows for a simple test as follows:
./test
lvm> vg_read vg1
Success reading vg vg1
lvm> vg_get_attr_list
VG attribute names:
vg_fmt
vg_uuid
vg_name
vg_attr
vg_size
vg_free
vg_sysid
vg_extent_size
vg_extent_count
vg_free_count
...
Signed-off-by: Dave Wysochanski <dwysocha at redhat.com>
---
lib/lvm2.h | 16 ++++++++++++++
lib/metadata/metadata-exported.h | 2 +-
lib/metadata/metadata.c | 6 +++++
lib/misc/lib.h | 1 +
lib/report/report.c | 28 ++++++++++++++++++++++++
libdm/.exported_symbols | 1 +
libdm/libdevmapper.h | 12 ++++++++++
libdm/libdm-report.c | 27 +++++++++++++++++++++++
test/api/test.c | 43 ++++++++++++++++++++++++++++++++-----
9 files changed, 129 insertions(+), 7 deletions(-)
diff --git a/lib/lvm2.h b/lib/lvm2.h
index b18cead..6689b37 100644
--- a/lib/lvm2.h
+++ b/lib/lvm2.h
@@ -16,6 +16,7 @@
#define _LIB_LVM2_H
#include <stdint.h>
+#include "libdevmapper.h"
/*
* Library Initialisation
@@ -50,4 +51,19 @@ void lvm2_destroy(lvm_handle_t h);
*/
#define lvm2_destroy(X) destroy_toolcontext(X)
+/* FIXME: this should be in the create/init routine(s) */
+int init_locking(int type, struct cmd_context *cmd);
+
+struct volume_group;
+typedef struct volume_group vg_t;
+
+/* FIXME: temporary simplistic vg_read interface */
+vg_t *vg_open_for_read(struct cmd_context *cmd, const char *vg_name);
+
+/*
+ * Get a list of VG attributes we can query.
+ * Returns a list of struct dm_report_field_ids_type
+ */
+int vg_get_attr_list(vg_t *vg, struct dm_list *list);
+
#endif
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index 40ece6f..bf8555f 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -22,11 +22,11 @@
#define _LVM_METADATA_EXPORTED_H
#include "uuid.h"
+#include "lvm2.h"
struct physical_volume;
typedef struct physical_volume pv_t;
struct volume_group;
-typedef struct volume_group vg_t;
struct logical_volume;
diff --git a/lib/metadata/metadata.c b/lib/metadata/metadata.c
index a49c4d8..19ba8f3 100644
--- a/lib/metadata/metadata.c
+++ b/lib/metadata/metadata.c
@@ -2461,6 +2461,12 @@ vg_t *vg_lock_and_read(struct cmd_context *cmd, const char *vg_name,
return vg;
}
+vg_t *vg_open_for_read(struct cmd_context *cmd, const char *vg_name)
+{
+ return vg_lock_and_read(cmd, vg_name, NULL, LCK_VG_READ,
+ CLUSTERED, 0);
+}
+
/*
* Gets/Sets for external LVM library
*/
diff --git a/lib/misc/lib.h b/lib/misc/lib.h
index 100827d..188f79e 100644
--- a/lib/misc/lib.h
+++ b/lib/misc/lib.h
@@ -31,6 +31,7 @@
#include "lvm-wrappers.h"
#include "lvm-types.h"
#include "util.h"
+#include "lvm2.h"
#ifdef DM
# include "dm-logging.h"
diff --git a/lib/report/report.c b/lib/report/report.c
index 8439b2b..edd3453 100644
--- a/lib/report/report.c
+++ b/lib/report/report.c
@@ -1191,3 +1191,31 @@ int report_object(void *handle, struct volume_group *vg,
return dm_report_object(handle, &obj);
}
+
+/*
+ * Get a list of attributes for a vg
+ */
+int vg_get_attr_list(vg_t *vg, struct dm_list *list)
+{
+ void *rh;
+ report_type_t report_type = VGS;
+
+ dm_list_init(list);
+
+ /*
+ * Create a report so we can return the headings.
+ */
+ if (!(rh = report_init(vg->cmd, "all", "", &report_type,
+ " ", 1, 1, 1, 0, 0, 0))) {
+ stack;
+ return 0;
+ }
+
+ if (!dm_report_get_field_ids(rh, report_type, list)) {
+ dm_report_free(rh);
+ return 0;
+ }
+
+ dm_report_free(rh);
+ return 1;
+}
diff --git a/libdm/.exported_symbols b/libdm/.exported_symbols
index a6e04f8..aa70f29 100644
--- a/libdm/.exported_symbols
+++ b/libdm/.exported_symbols
@@ -132,6 +132,7 @@ dm_report_field_int32
dm_report_field_uint32
dm_report_field_uint64
dm_report_field_set_value
+dm_report_get_field_ids
dm_report_set_output_field_name_prefix
dm_regex_create
dm_regex_match
diff --git a/libdm/libdevmapper.h b/libdm/libdevmapper.h
index 93aecbb..cc8302a 100644
--- a/libdm/libdevmapper.h
+++ b/libdm/libdevmapper.h
@@ -924,6 +924,17 @@ struct dm_report_field_type {
const char *desc; /* description of the field */
};
+struct dm_report_field_ids_type {
+ struct dm_list list;
+ const char *id;
+};
+
+/*
+ * Returns a list of all field ids for a specific report type.
+ */
+int dm_report_get_field_ids(struct dm_report *rh, uint32_t type,
+ struct dm_list *list);
+
/*
* dm_report_init output_flags
*/
@@ -947,6 +958,7 @@ int dm_report_object(struct dm_report *rh, void *object);
int dm_report_output(struct dm_report *rh);
void dm_report_free(struct dm_report *rh);
+
/*
* Prefix added to each field name with DM_REPORT_OUTPUT_FIELD_NAME_PREFIX
*/
diff --git a/libdm/libdm-report.c b/libdm/libdm-report.c
index 0c5ee6d..a9db211 100644
--- a/libdm/libdm-report.c
+++ b/libdm/libdm-report.c
@@ -1076,3 +1076,30 @@ int dm_report_output(struct dm_report *rh)
else
return _output_as_columns(rh);
}
+
+/*
+ * Return a list of field IDs (names) for a specified report type.
+ */
+int dm_report_get_field_ids(struct dm_report *rh, uint32_t type,
+ struct dm_list *list)
+{
+ uint32_t f;
+ struct dm_report_field_ids_type *field_id;
+
+ for (f = 0; rh->fields[f].report_fn; f++) {
+ if (rh->fields[f].type != type)
+ continue;
+
+ if (!(field_id = dm_pool_zalloc(rh->mem, sizeof(*field_id)))) {
+ log_error("dm_report_get_field_ids: struct "
+ "dm_report_field_ids_type allocation failed");
+ return 0;
+ }
+ if (!(field_id->id = dm_pool_strdup(rh->mem, rh->fields[f].id))) {
+ log_error("dm_report_get_field_ids: dm_pool_strdup failed");
+ return 0;
+ }
+ dm_list_add(list, &field_id->list);
+ }
+ return 1;
+}
diff --git a/test/api/test.c b/test/api/test.c
index de53c46..04177d7 100644
--- a/test/api/test.c
+++ b/test/api/test.c
@@ -48,10 +48,18 @@ static int lvm_split(char *str, int *argc, char **argv, int max)
return *argc;
}
-static int lvmapi_test_shell(void *h)
+static void _show_help(void)
{
- int argc, i;
+ printf("'vg_read vgname': Issue a vg_read() API call on VG 'vgname'\n");
+ printf("'vg_get_attr_list': Issue vg_get_attr_list() API; must follow vg_read\n");
+ printf("'quit': exit the program\n");
+}
+
+int lvmapi_test_shell(void *h)
+{
+ int argc;
char *input = NULL, *args[MAX_ARGS], **argv;
+ vg_t *vg = NULL;
while (1) {
free(input);
@@ -86,10 +94,27 @@ static int lvmapi_test_shell(void *h)
printf("Exiting.\n");
break;
} else if (!strcmp(argv[0], "?") || !strcmp(argv[0], "help")) {
- printf("No commands defined\n");
- } else if (!strcmp(argv[0], "scan")) {
- for (i=1; i < argc; i++)
- printf("Scan a path!\n");
+ _show_help();
+ } else if (!strcmp(argv[0], "vg_read")) {
+ if (!(vg = vg_open_for_read(h, argv[1])))
+ printf("Error reading vg %s\n", argv[1]);
+ else
+ printf("Success reading vg %s\n", argv[1]);
+ } else if (!strcmp(argv[0], "vg_get_attr_list")) {
+ struct dm_list list;
+ struct dm_report_field_ids_type *field_id;
+ if (!vg) {
+ printf("Run vg_read first\n");
+ continue;
+ }
+ if (!vg_get_attr_list(vg, &list)) {
+ printf("Error reading vg attribute list\n");
+ continue;
+ }
+ printf("VG attribute names:\n");
+ dm_list_iterate_items(field_id, &list) {
+ printf("%s\n", field_id->id);
+ }
}
}
@@ -107,6 +132,12 @@ int main (int argc, char *argv[])
return 1;
}
+ /* FIXME: this needs to go into the create / init routine */
+ if (!init_locking(1, h)) {
+ printf("Locking error\n");
+ return 1;
+ }
+
lvmapi_test_shell(h);
if (h)
--
1.5.5.1
More information about the lvm-devel
mailing list