[Ocfs2-tools-devel] [PATCH 09/32] o2cb_scandisk: Scan heartbeat devices
Sunil Mushran
sunil.mushran at oracle.com
Tue Sep 14 15:54:39 PDT 2010
o2cb_scandisk uses the scandisk library to scan all the partitions to locate
the given heartbeat devices.
Signed-off-by: Sunil Mushran <sunil.mushran at oracle.com>
Signed-off-by: Joel Becker <joel.becker at oracle.com>
---
o2cb_ctl/Makefile | 6 ++
o2cb_ctl/o2cb_scandisk.c | 199 ++++++++++++++++++++++++++++++++++++++++++++++
o2cb_ctl/o2cb_scandisk.h | 43 ++++++++++
3 files changed, 248 insertions(+), 0 deletions(-)
create mode 100644 o2cb_ctl/o2cb_scandisk.c
create mode 100644 o2cb_ctl/o2cb_scandisk.h
diff --git a/o2cb_ctl/Makefile b/o2cb_ctl/Makefile
index d2710e6..0a6cb8b 100644
--- a/o2cb_ctl/Makefile
+++ b/o2cb_ctl/Makefile
@@ -7,12 +7,18 @@ SBIN_PROGRAMS = o2cb_ctl
INCLUDES = -I$(TOPDIR)/include
+LIBTOOLS_INTERNAL_LIBS = -L$(TOPDIR)/libtools-internal -ltools-internal
+LIBTOOLS_INTERNAL_DEPS = $(TOPDIR)/libtools-internal/libtools-internal.a
+
LIBOCFS2_LIBS = -L$(TOPDIR)/libocfs2 -locfs2
LIBOCFS2_DEPS = $(TOPDIR)/libocfs2/libocfs2.a
LIBO2CB_LIBS = -L$(TOPDIR)/libo2cb -lo2cb
LIBO2CB_DEPS = $(TOPDIR)/libo2cb/libo2cb.a
+LIBO2DLM_LIBS = -L$(TOPDIR)/libo2dlm -lo2dlm $(DL_LIBS)
+LIBO2DLM_DEPS = $(TOPDIR)/libo2dlm/libo2dlm.a
+
ifndef OCFS2_DYNAMIC_CTL
LDFLAGS += -static
endif
diff --git a/o2cb_ctl/o2cb_scandisk.c b/o2cb_ctl/o2cb_scandisk.c
new file mode 100644
index 0000000..94d0b55
--- /dev/null
+++ b/o2cb_ctl/o2cb_scandisk.c
@@ -0,0 +1,199 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * o2cb_scandisk.c
+ *
+ * Reads all the partitions and get the ocfs2 uuids
+ *
+ * Copyright (C) 2010 Oracle. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License, version 2, 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 "o2cb_scandisk.h"
+#include "ocfs2/ocfs2.h"
+#include "tools-internal/verbose.h"
+
+struct hb_devices {
+ struct list_head hb_list;
+ char *hb_path;
+};
+
+struct scan_context {
+ struct list_head sc_devlist;
+ int sc_rescan;
+};
+
+static int fill_desc(char *device, struct o2cb_region_desc *reg,
+ struct o2cb_cluster_desc *cluster)
+{
+ ocfs2_filesys *fs;
+ errcode_t ret;
+
+ ret = ocfs2_open(device, OCFS2_FLAG_RO | OCFS2_FLAG_HEARTBEAT_DEV_OK,
+ 0, 0, &fs);
+ if (ret)
+ return ret;
+
+ ret = ocfs2_fill_heartbeat_desc(fs, reg);
+ if (!ret)
+ ret = ocfs2_fill_cluster_desc(fs, cluster);
+
+ if (!ret) {
+ /* TODO free this alloc... or not */
+ reg->r_name = strdup(reg->r_name);
+ reg->r_device_name = strdup(reg->r_device_name);
+ }
+
+ ocfs2_close(fs);
+
+ return ret;
+}
+
+static void get_device_uuids(struct scan_context *ctxt, struct list_head *hbdevs)
+{
+ struct o2cb_device *od;
+ struct list_head *pos, *pos1;
+ struct hb_devices *hb;
+ struct o2cb_region_desc rd;
+ struct o2cb_cluster_desc cd;
+ int numhbdevs = 0;
+
+ list_for_each(pos, hbdevs) {
+ ++numhbdevs;
+ }
+
+ if (!numhbdevs)
+ return;
+
+ list_for_each(pos, &ctxt->sc_devlist) {
+ hb = list_entry(pos, struct hb_devices, hb_list);
+
+ if (fill_desc(hb->hb_path, &rd, &cd))
+ continue;
+
+ list_for_each(pos1, hbdevs) {
+ od = list_entry(pos1, struct o2cb_device, od_list);
+ if (od->od_flags & O2CB_DEVICE_FOUND)
+ continue;
+ if (strcmp(rd.r_name, od->od_uuid))
+ continue;
+ od->od_flags |= O2CB_DEVICE_FOUND;
+ memcpy(&od->od_region, &rd, sizeof(od->od_region));
+ memcpy(&od->od_cluster, &cd, sizeof(od->od_cluster));
+
+ verbosef(VL_DEBUG, "Region %s matched to device %s\n",
+ rd.r_name, rd.r_device_name);
+ --numhbdevs;
+ break;
+ }
+ if (!numhbdevs)
+ break;
+ }
+}
+
+static void free_scan_context(struct scan_context *ctxt)
+{
+ struct list_head *pos, *pos1;
+ struct hb_devices *hb;
+
+ if (!ctxt)
+ return ;
+
+ list_for_each_safe(pos, pos1, &ctxt->sc_devlist) {
+ hb = list_entry(pos, struct hb_devices, hb_list);
+ list_del(pos);
+ free(hb);
+ }
+}
+
+static void add_to_list(struct list_head *device_list, struct devnode *node)
+{
+ struct devpath *path;
+ struct hb_devices *hb;
+ int add = 0;
+
+ path = node->devpath;
+ while (path) {
+ if (node->mapper)
+ add = !strncmp(path->path, "/dev/mapper/", 12);
+ else
+ add = !strncmp(path->path, "/dev/sd", 7);
+ if (add) {
+ hb = malloc(sizeof(struct hb_devices));
+ if (hb) {
+ hb->hb_path = strdup(path->path);
+ list_add_tail(&hb->hb_list, device_list);
+ break;
+ }
+ }
+ path = path->next;
+ }
+}
+
+static void filter_devices(struct devnode *node, void *user_data)
+{
+ struct scan_context *ctxt = user_data;
+
+ /* No information in sysfs? Ignore it! */
+ if (!node->sysfsattrs.sysfs)
+ return;
+
+ /* Not a disk? Ignore it! */
+ if (!node->sysfsattrs.disk)
+ return;
+
+ /* It's part of some other device? Ignore it! */
+ if (node->sysfsattrs.holders)
+ return;
+
+ /*
+ * No path in /dev? Well, udev probably hasn't gotten there. Trigger
+ * a rescan
+ */
+ if (!node->devpath) {
+ ctxt->sc_rescan = 1;
+ return;
+ }
+
+ add_to_list(&ctxt->sc_devlist, node);
+}
+
+void o2cb_scandisk(struct list_head *hbdevs)
+{
+ struct devlisthead *dev = NULL;
+ int delay = 1;
+ struct scan_context scan_ctxt, *ctxt = &scan_ctxt;
+
+ INIT_LIST_HEAD(&ctxt->sc_devlist);
+
+ do {
+ ctxt->sc_rescan = 0;
+ if (delay > 5)
+ break;
+
+ if (dev) {
+ free_scan_context(ctxt);
+ free_dev_list(dev);
+ sleep(delay);
+ delay += 2;
+ }
+
+ dev = scan_for_dev(NULL, 5, filter_devices, ctxt);
+ if (!dev)
+ goto bail;
+ } while (ctxt->sc_rescan);
+
+ get_device_uuids(ctxt, hbdevs);
+
+bail:
+ free_scan_context(ctxt);
+ free_dev_list(dev);
+}
diff --git a/o2cb_ctl/o2cb_scandisk.h b/o2cb_ctl/o2cb_scandisk.h
new file mode 100644
index 0000000..7ff1fe4
--- /dev/null
+++ b/o2cb_ctl/o2cb_scandisk.h
@@ -0,0 +1,43 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * o2cb_scandisk.h
+ *
+ * Copyright (C) 2010 Oracle. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License, version 2, 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 <stdio.h>
+#include <time.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/param.h>
+#include <dirent.h>
+#include <sys/sysmacros.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "tools-internal/scandisk.h"
+#include "o2cb/o2cb.h"
+
+#include "ocfs2-kernel/kernel-list.h"
+
+struct o2cb_device {
+ struct list_head od_list;
+ char *od_uuid;
+#define O2CB_DEVICE_FOUND 0x01
+#define O2CB_DEVICE_HB_STARTED 0x02
+ int od_flags;
+ struct o2cb_region_desc od_region;
+ struct o2cb_cluster_desc od_cluster;
+};
+
+void o2cb_scandisk(struct list_head *hbdevs);
--
1.7.0.4
More information about the Ocfs2-tools-devel
mailing list