summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoe Thornber <ejt@redhat.com>2018-04-30 16:16:58 +0100
committerJoe Thornber <ejt@redhat.com>2018-04-30 16:16:58 +0100
commit52ebad31bae64edd92244a244c8928fb2171c209 (patch)
tree05a33fbdf512a0b8e58e2425b8c7152d2c9604f8
parent9384b2b5c59e9bca8c2054f76b62155a64c51c38 (diff)
downloadlvm2-52ebad31bae64edd92244a244c8928fb2171c209.tar.gz
vdo: Code drop for status parsing.
Doesn't even compile yet. Squash this patch.
-rw-r--r--Makefile.in2
-rw-r--r--device-mapper/Makefile20
-rw-r--r--device-mapper/vdo/status.c207
-rw-r--r--device-mapper/vdo/target.h69
4 files changed, 298 insertions, 0 deletions
diff --git a/Makefile.in b/Makefile.in
index 916f54d4a..1b169457b 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -214,6 +214,8 @@ ifeq ("$(TESTING)", "yes")
include test/unit/Makefile
endif
+include device-mapper/Makefile
+
ifneq ($(shell which ctags),)
.PHONY: tags
tags:
diff --git a/device-mapper/Makefile b/device-mapper/Makefile
new file mode 100644
index 000000000..76e19f020
--- /dev/null
+++ b/device-mapper/Makefile
@@ -0,0 +1,20 @@
+# Copyright (C) 2018 Red Hat, Inc. All rights reserved.
+#
+# This file is part of LVM2.
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions
+# of the GNU General Public License v.2.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+
+DM_SOURCE=\
+ device-mapper/vdo/status.c
+
+DM_DEPENDS=$(subst .c,.d,$(DM_SOURCE))
+DM_OBJECTS=$(DM_SOURCE:%.c=%.o)
+CLEAN_TARGETS+=$(DM_DEPENDS) $(DM_OBJECTS)
+
+-include $(DM_DEPENDS)
diff --git a/device-mapper/vdo/status.c b/device-mapper/vdo/status.c
new file mode 100644
index 000000000..ccebc83f1
--- /dev/null
+++ b/device-mapper/vdo/status.c
@@ -0,0 +1,207 @@
+#include "target.h"
+
+// For DM_ARRAY_SIZE!
+#include "libdevmapper.h"
+
+#include <stdlib.h>
+
+//----------------------------------------------------------------
+
+static const char *_tok_cpy(const char *b, const char *e, const char *str)
+{
+ char *new = malloc((e - b) + 1);
+ char *ptr = new;
+
+ if (new)
+ while (b != e)
+ *ptr++ = *b++;
+
+ return new;
+}
+
+static bool _tok_eq(const char *b, const char *e, const char *str)
+{
+ while (b != e) {
+ if (!*str || *b != *str)
+ return false;
+
+ b++;
+ str++;
+ }
+
+ return !*str;
+}
+
+static bool _parse_operating_mode(const char *b, const char *e,
+ enum vdo_operating_mode *r)
+{
+ static struct {
+ const char *str;
+ enum vdo_operating_mode mode;
+ } _table[] = {
+ {"recovering", VDO_MODE_RECOVERING},
+ {"read-only", VDO_MODE_READ_ONLY},
+ {"normal", VDO_MODE_NORMAL}
+ };
+
+ unsigned i;
+ for (i = 0; i < DM_ARRAY_SIZE(_table); i++) {
+ if (_tok_eq(b, e, _table[i].str)) {
+ *r = _table[i].mode;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static bool _parse_compression_state(const char *b, const char *e,
+ enum vdo_compression_state *r)
+{
+ static struct {
+ const char *str;
+ enum vdo_compression_state state;
+ } _table[] = {
+ {"online", VDO_COMPRESSION_ONLINE},
+ {"offline", VDO_COMPRESSION_OFFLINE}
+ };
+
+ unsigned i;
+ for (i = 0; i < DM_ARRAY_SIZE(_table); i++) {
+ if (_tok_eq(b, e, _table[i].str)) {
+ *r = _table[i].state;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static bool _parse_recovering(const char *b, const char *e, bool *r)
+{
+ if (_tok_eq(b, e, "recovering"))
+ *r = true;
+
+ else if (_tok_eq(b, e, "-"))
+ *r = false;
+
+ else
+ return false;
+
+ return true;
+}
+
+static bool _parse_index_state(const char *b, const char *e,
+ enum vdo_index_state *r)
+{
+ static struct {
+ const char *str;
+ enum vdo_index_state state;
+ } _table[] = {
+ {"error", VDO_INDEX_ERROR},
+ {"closed", VDO_INDEX_CLOSED},
+ {"opening", VDO_INDEX_OPENING},
+ {"closing", VDO_INDEX_CLOSING},
+ {"offline", VDO_INDEX_OFFLINE},
+ {"online", VDO_INDEX_ONLINE},
+ {"unknown", VDO_INDEX_UNKNOWN}
+ };
+
+ unsigned i;
+ for (i = 0; i < DM_ARRAY_SIZE(_table); i++) {
+ if (_tok_eq(b, e, _table[i].str)) {
+ *r = _table[i].state;
+ return true;
+ }
+ }
+
+ return false;
+}
+
+static const char *_eat_space(const char *b, const char *e)
+{
+ while (b != e && isspace(*b))
+ b++;
+
+ return b;
+}
+
+static const char *_next_tok(const char *b, const char *e)
+{
+ while (b != e && !isspace(*b))
+ b++;
+
+ return b == e ? NULL : b;
+}
+
+static bool _parse_field(const char **b, const char *e,
+ bool (*p_fn)(const char *, const char *, void *)
+ void *field, const char *field_name,
+ struct parse_result *result)
+{
+ const char *te;
+
+ te = _next_tok(*b, e);
+ if (!te) {
+ snprintf(result->error, sizeof(result->error),
+ "couldn't get token for '%s'", field_name);
+ return false;
+ }
+
+ if (!p_fn(*b, te, field) {
+ snprintf(result->error, sizeof(result->error),
+ "couldn't parse '%s'", field_name);
+ return false;
+ }
+
+ *b = _eat_space(te);
+ return true;
+
+}
+
+bool parse_vdo_status(const char *input, struct parse_result *result)
+{
+ const char *b = _eat_space(input);
+ const char *e = input + strlen(input);
+ const char *te;
+ struct vdo_status *s = malloc(sizeof(*s));
+
+ if (!s) {
+ result->error = "out of memory";
+ return false;
+ }
+
+ te = _next_tok(b, e);
+ if (!te) {
+ result->error = "couldn't get token for device";
+ free(s);
+ return false;
+ }
+
+ s->device = _tok_cpy(b, te);
+ if (!s->device) {
+ result->error = "out of memory";
+ free(s);
+ return false;
+ }
+
+ b = _eat_space(te);
+
+#define XX(p, f, fn) if (!_parse_field(&b, e, p, f, fn, result)) goto bad;
+ XX(_parse_recovering, &s->recovering, "recovering");
+ XX(_parse_index, &s->index_state, "index state");
+ XX(_parse_compression_state, &s->compression_state, "compression state");
+ XX(_parse_uint64, &s->used_blocks, "used blocks");
+ XX(_parse_uint64, &s->total_blocks, "total blocks");
+#undef XX
+
+ result->result = s;
+ return true;
+
+bad:
+ free(s->device);
+ free(s);
+ return false;
+}
+
+//----------------------------------------------------------------
diff --git a/device-mapper/vdo/target.h b/device-mapper/vdo/target.h
new file mode 100644
index 000000000..e3c6788e7
--- /dev/null
+++ b/device-mapper/vdo/target.h
@@ -0,0 +1,69 @@
+/*
+ * Copyright (C) 2018 Red Hat, Inc. All rights reserved.
+ *
+ * This file is part of the device-mapper userspace tools.
+ *
+ * This copyrighted material is made available to anyone wishing to use,
+ * modify, copy, or redistribute it subject to the terms and conditions
+ * of the GNU Lesser General Public License v.2.1.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ */
+
+#ifndef DEVICE_MAPPER_VDO_TARGET_H
+#define DEVICE_MAPPER_VDO_TARGET_H
+
+#include <stdbool.h>
+#include <stdint.h>
+
+//----------------------------------------------------------------
+
+enum vdo_operating_mode {
+ VDO_MODE_RECOVERING,
+ VDO_MODE_READ_ONLY,
+ VDO_MODE_NORMAL
+};
+
+enum vdo_compression_state {
+ VDO_COMPRESSION_ONLINE,
+ VDO_COMPRESSION_OFFLINE
+};
+
+enum vdo_index_state {
+ VDO_INDEX_ERROR,
+ VDO_INDEX_CLOSED,
+ VDO_INDEX_OPENING,
+ VDO_INDEX_CLOSING,
+ VDO_INDEX_OFFLINE,
+ VDO_INDEX_ONLINE,
+ VDO_INDEX_UNKNOWN
+};
+
+struct vdo_status {
+ const char *device;
+ enum vdo_operating_mode operating_mode;
+ bool recovering;
+ enum vdo_index_state index_state;
+ enum vdo_compression_state compression_state;
+ uint64_t used_blocks;
+ uint64_t total_blocks;
+};
+
+void vdo_status_destroy(struct vdo_status *s);
+
+#define VDO_MAX_ERROR 256
+
+struct parse_result {
+ char error[VDO_MAX_ERROR];
+ struct vdo_status *result;
+};
+
+// Parses the status line from the kernel target.
+bool parse_vdo_status(const char *input, struct parse_result *result);
+
+
+//----------------------------------------------------------------
+
+#endif