[Ocfs2-tools-commits] mfasheh commits r460 - in branches/dlm-glue:
. clusterbo documentation documentation/samples listuuid mount.ocfs2
svn-commits at oss.oracle.com
svn-commits at oss.oracle.com
Fri Dec 3 20:56:30 CST 2004
Author: mfasheh
Date: 2004-12-03 20:56:28 -0600 (Fri, 03 Dec 2004)
New Revision: 460
Added:
branches/dlm-glue/clusterbo/
branches/dlm-glue/clusterbo/Makefile
branches/dlm-glue/clusterbo/clusterbo.c
branches/dlm-glue/documentation/
branches/dlm-glue/documentation/samples/
branches/dlm-glue/documentation/samples/cluster.conf
branches/dlm-glue/listuuid/
branches/dlm-glue/listuuid/Makefile
branches/dlm-glue/listuuid/listuuid.c
branches/dlm-glue/mount.ocfs2/
branches/dlm-glue/mount.ocfs2/Makefile
branches/dlm-glue/mount.ocfs2/mount.ocfs2.c
Removed:
branches/dlm-glue/dlmtools/
Modified:
branches/dlm-glue/Makefile
Log:
* start getting this stuff organized properly
Modified: branches/dlm-glue/Makefile
===================================================================
--- branches/dlm-glue/Makefile 2004-12-04 01:51:08 UTC (rev 459)
+++ branches/dlm-glue/Makefile 2004-12-04 02:56:28 UTC (rev 460)
@@ -22,7 +22,7 @@
$(error could not detect architecture for tools)
endif
-SUBDIRS = libocfs2 fsck.ocfs2 mkfs.ocfs2 mounted.ocfs2 tunefs.ocfs2 debugfs.ocfs2 dlmtools extras load_ocfs ocfs_uid_gen patches
+SUBDIRS = libocfs2 fsck.ocfs2 mkfs.ocfs2 mounted.ocfs2 tunefs.ocfs2 debugfs.ocfs2 clusterbo mount.ocfs2 listuuid extras load_ocfs ocfs_uid_gen patches
ifdef BUILD_OCFS2CDSL
SUBDIRS += ocfs2cdsl
Added: branches/dlm-glue/clusterbo/Makefile
===================================================================
--- branches/dlm-glue/clusterbo/Makefile 2004-12-04 01:51:08 UTC (rev 459)
+++ branches/dlm-glue/clusterbo/Makefile 2004-12-04 02:56:28 UTC (rev 460)
@@ -0,0 +1,36 @@
+TOPDIR = ..
+
+include $(TOPDIR)/Preamble.make
+
+SBIN_PROGRAMS = clusterbo
+
+INCLUDES = -Iinclude -I$(TOPDIR)/libocfs2/include \
+ -I$(TOPDIR)/libocfs2cluster/include
+LIBOCFS2_LIBS = -L$(TOPDIR)/libocfs2 -locfs2
+LIBOCFS2_DEPS = $(TOPDIR)/libocfs2/libocfs2.a
+
+ifdef OCFS_DEBUG
+OPTS += -ggdb
+else
+OPTS += -O2
+endif
+
+CFLAGS := $(OPTS) -Wall -Wstrict-prototypes -Wmissing-prototypes \
+ -Wmissing-declarations
+
+DEFINES = -DOCFS2_FLAT_INCLUDES
+
+CFILES = clusterbo.c
+
+OBJS = $(subst .c,.o,$(CFILES))
+
+DIST_FILES = $(CFILES)
+DIST_RULES = dist-subdircreate
+
+dist-subdircreate:
+ $(TOPDIR)/mkinstalldirs $(DIST_DIR)/include
+
+clusterbo: $(OBJS) $(LIBOCFS2_DEPS)
+ $(LINK) $(LIBOCFS2_LIBS) $(COM_ERR_LIBS)
+
+include $(TOPDIR)/Postamble.make
Added: branches/dlm-glue/clusterbo/clusterbo.c
===================================================================
--- branches/dlm-glue/clusterbo/clusterbo.c 2004-12-04 01:51:08 UTC (rev 459)
+++ branches/dlm-glue/clusterbo/clusterbo.c 2004-12-04 02:56:28 UTC (rev 460)
@@ -0,0 +1,373 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/types.h>
+#include <asm/types.h>
+#include <sys/stat.h>
+#include <sys/wait.h>
+#include <sys/mount.h>
+#include <fcntl.h>
+#include <string.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <ctype.h>
+#include <errno.h>
+#include <sys/ioctl.h>
+
+#define __u8 unsigned char
+#define u8 unsigned char
+#define u16 unsigned short int
+#define u32 unsigned int
+#define u64 unsigned long long
+#define atomic_t int
+#define spinlock_t unsigned long
+typedef unsigned short kdev_t;
+
+typedef struct list_head {
+ struct list_head *next, *prev;
+} list_t;
+
+#include "ocfs2_nodemanager.h"
+
+#define NIPQUAD(addr) \
+ ((unsigned char *)&addr)[0], \
+ ((unsigned char *)&addr)[1], \
+ ((unsigned char *)&addr)[2], \
+ ((unsigned char *)&addr)[3]
+
+
+#define CLUSTER_FILE "/proc/cluster/nm/.cluster"
+#define GROUP_FILE "/proc/cluster/nm/.group"
+#define NODE_FILE "/proc/cluster/nm/.node"
+
+#define CONF_FILE "/etc/cluster.conf"
+
+/* are these right ? */
+#define MIN_PORT_NUM 1024
+#define MAX_PORT_NUM 65535
+
+#define NET_IOC_MAGIC 'O'
+#define NET_IOC_ACTIVATE _IOR(NET_IOC_MAGIC, 1, net_ioc)
+#define NET_IOC_GETSTATE _IOR(NET_IOC_MAGIC, 2, net_ioc)
+
+
+typedef struct _net_ioc
+{
+ unsigned int status;
+} net_ioc;
+
+
+
+
+int activate_cluster(void);
+int add_node(nm_node_info *newnode);
+int set_cluster_name(char *cluster_name);
+int activate_net(void);
+int load_module(char *module, char *mountpoint, char *fstype);
+
+
+nm_node_info *nodes;
+int total_nodes = 0;
+
+int main(int argc, char **argv)
+{
+ int ret, i;
+ FILE *conf;
+ char *cluster_name = NULL;
+
+ ret = load_module("onm", "/proc/cluster/nm", "nm");
+ if (ret) {
+ fprintf(stderr, "failed to load and/or mount nm: %d\n", ret);
+ exit(1);
+ }
+ ret = load_module("ohb", "/proc/cluster/heartbeat", "hb");
+ if (ret) {
+ fprintf(stderr, "failed to load and/or mount hb: %d\n", ret);
+ exit(1);
+ }
+ ret = load_module("otcp", NULL, NULL);
+ if (ret) {
+ fprintf(stderr, "failed to load tcp: %d\n", ret);
+ exit(1);
+ }
+
+ nodes = malloc(NM_MAX_NODES * sizeof(nm_node_info));
+ if (!nodes) {
+ fprintf(stderr, "failed to malloc node array\n");
+ exit(1);
+ }
+ memset(nodes, 0, NM_MAX_NODES * sizeof(nm_node_info));
+
+ conf = fopen(CONF_FILE, "r");
+ if (!conf) {
+ fprintf(stderr, "failed to open %s: %s\n", CONF_FILE, strerror(errno));
+ exit(1);
+ }
+
+ ret = fscanf(conf, "cluster_name=%64as\n", &cluster_name);
+ if (ret != 1) {
+ fprintf(stderr, "bad file format: expected cluster_name=XXX\n");
+ exit(1);
+ }
+ printf("found cluster named %s\n", cluster_name);
+
+ while (1) {
+ int node_num, port;
+ char *node_name = NULL;
+ char *ip = NULL;
+ u32 real_ip;
+
+ ret = fscanf(conf, "%d,%64a[^,],%15a[0-9.],%d\n", &node_num, &node_name, &ip, &port);
+ if (ret == 0 || ret == -1) {
+ printf("done. found %d nodes\n", total_nodes);
+ break;
+ }
+ if (ret != 4) {
+ fprintf(stderr, "bad file format: node_num,node_name,ipaddr,ipport\n");
+ exit(1);
+ }
+
+ if (node_num < 0 || node_num >= NM_MAX_NODES) {
+ fprintf(stderr, "bad node number: got %d, range is 0 - %d\n", node_num, NM_MAX_NODES-1);
+ exit(1);
+ }
+ if (nodes[node_num].node_name[0]) {
+ fprintf(stderr, "already have a node in slot %d: orig=%s, this=%s\n",
+ node_num, nodes[node_num].node_name, node_name);
+ exit(1);
+ }
+ if (port < MIN_PORT_NUM || port > MAX_PORT_NUM) {
+ fprintf(stderr, "bad port number: got %d, range is %d - %d\n", port, MIN_PORT_NUM, MAX_PORT_NUM);
+ exit(1);
+ }
+ if (!inet_aton(ip, (struct in_addr*)&real_ip)) {
+ fprintf(stderr, "bad ipv4 address: %s\n", ip);
+ exit(1);
+ }
+
+
+ total_nodes++;
+ nodes[node_num].node_num = node_num;
+ memcpy(nodes[node_num].node_name, node_name, NM_MAX_NAME_LEN);
+ nodes[node_num].node_name[NM_MAX_NAME_LEN]=0;
+ nodes[node_num].ifaces[0].ip_port = htons(port);
+ nodes[node_num].ifaces[0].addr_u.ip_addr4 = real_ip;
+ free(ip);
+ free(node_name);
+ }
+ fclose(conf);
+
+ set_cluster_name(cluster_name);
+ i=0;
+ while (1) {
+ if (!total_nodes--)
+ break;
+ if (!nodes[i].node_name[0]) {
+ i++;
+ continue;
+ }
+ add_node(&nodes[i]);
+ i++;
+ }
+ printf("done. activating cluster now...\n");
+ activate_cluster();
+ printf("done. nm ready!\n");
+ activate_net();
+ printf("done. net ready!\n");
+ free(nodes);
+ return 0;
+}
+
+int set_cluster_name(char *cluster_name)
+{
+ int fd;
+ nm_op *op;
+ int ret;
+ char *buf;
+
+ buf = malloc(4096);
+ op = (nm_op *)buf;
+ memset(buf, 0, 4096);
+ op->magic = NM_OP_MAGIC;
+
+ printf("setting cluster name...\n");
+ fd = open(CLUSTER_FILE, O_RDWR);
+ if (fd == -1) {
+ printf("failed to open %s\n", CLUSTER_FILE);
+ exit(1);
+ }
+ op->opcode = NM_OP_NAME_CLUSTER;
+ strcpy(&op->arg_u.name[0], cluster_name);
+
+ ret = write(fd, op, sizeof(nm_op));
+ printf("write called returned %d\n", ret);
+ if (ret < 0) {
+ printf("error is: %s\n", strerror(errno));
+ exit(1);
+ }
+ memset(buf, 0, 4096);
+ ret = read(fd, buf, 4096);
+ printf("read returned %d\n", ret);
+ if (ret < 0)
+ exit(1);
+ printf("<<<<%*s>>>>\n", ret, buf);
+ close(fd);
+ free(buf);
+ return 0;
+
+}
+
+int add_node(nm_node_info *newnode)
+{
+ int fd;
+ nm_op *op;
+ int ret;
+ char *buf;
+ nm_node_info *node;
+
+ buf = malloc(4096);
+ op = (nm_op *)buf;
+ memset(buf, 0, 4096);
+ op->magic = NM_OP_MAGIC;
+
+
+ printf("adding cluster node....\n");
+ fd = open(CLUSTER_FILE, O_RDWR);
+ if (fd == -1) {
+ printf("failed to open %s\n", CLUSTER_FILE);
+ exit(1);
+ }
+ op->opcode = NM_OP_ADD_CLUSTER_NODE;
+ node = &(op->arg_u.node);
+ memcpy(node, newnode, sizeof(nm_node_info));
+ printf("passing port=%u, vers=%u, addr=%d.%d.%d.%d\n",
+ node->ifaces[0].ip_port,
+ node->ifaces[0].ip_version,
+ NIPQUAD(node->ifaces[0].addr_u.ip_addr4));
+
+ ret = write(fd, op, sizeof(nm_op));
+ printf("write called returned %d\n", ret);
+ if (ret < 0) {
+ printf("error is: %s\n", strerror(errno));
+ exit(1);
+ }
+ memset(buf, 0, 4096);
+ ret = read(fd, buf, 4096);
+ printf("read returned %d\n", ret);
+ if (ret < 0)
+ exit(1);
+ printf("<<<<%*s>>>>\n", ret, buf);
+ close(fd);
+
+ free(buf);
+ return 0;
+
+}
+
+int activate_cluster(void)
+{
+ int fd;
+ nm_op *op;
+ int ret;
+ char *buf;
+
+ buf = malloc(4096);
+ op = (nm_op *)buf;
+ memset(buf, 0, 4096);
+ op->magic = NM_OP_MAGIC;
+
+ printf("activating cluster....\n");
+ fd = open(CLUSTER_FILE, O_RDWR);
+ if (fd == -1) {
+ printf("failed to open %s\n", CLUSTER_FILE);
+ exit(1);
+ }
+ op->opcode = NM_OP_CREATE_CLUSTER;
+
+ ret = write(fd, op, sizeof(nm_op));
+ printf("write called returned %d\n", ret);
+ if (ret < 0) {
+ printf("error is: %s\n", strerror(errno));
+ exit(1);
+ }
+ memset(buf, 0, 4096);
+ ret = read(fd, buf, 4096);
+ printf("read returned %d\n", ret);
+ if (ret < 0)
+ exit(1);
+ printf("<<<<%*s>>>>\n", ret, buf);
+ close(fd);
+
+ free(buf);
+ return 0;
+
+}
+
+
+int activate_net(void)
+{
+ int fd;
+ net_ioc net;
+
+ memset(&net, 0, sizeof(net_ioc));
+ fd = open("/proc/cluster/net", O_RDONLY);
+ if (fd == -1) {
+ printf("eeek. failed to open\n");
+ exit(1);
+ }
+
+ if (ioctl(fd, NET_IOC_ACTIVATE, &net) == -1) {
+ printf("eeek. ioctl failed\n");
+ close(fd);
+ exit(1);
+ }
+ close(fd);
+ printf("ioctl returned: %u\n", net.status);
+ return 0;
+}
+
+
+int load_module(char *module, char *mountpoint, char *fstype)
+{
+ int ret;
+ int pid;
+ int status;
+ struct stat st;
+
+ pid = fork();
+ switch (pid) {
+ case 0:
+ ret = execl("/sbin/modprobe", "/sbin/modprobe", module, (char *)NULL);
+ fprintf(stderr, "eeek! exec returned %d: %s\n", ret, strerror(errno));
+ exit(1);
+ break;
+ case -1:
+ fprintf(stderr, "fork failed: %s\n", strerror(errno));
+ return -errno;
+
+ default:
+ ret = wait(&status);
+ if (WIFEXITED(status)) {
+ if (WEXITSTATUS(status) != 0) {
+ fprintf(stderr, "modprobe returned %d!\n", WEXITSTATUS(status));
+ return -WEXITSTATUS(status);
+ }
+ } else {
+ fprintf(stderr, "modprobe has not exited!\n");
+ return -EINVAL;
+ }
+ break;
+ }
+ if (!mountpoint)
+ return 0;
+
+ if (stat("/proc/cluster", &st) != 0 ||
+ stat(mountpoint, &st) != 0) {
+ fprintf(stderr, "mountpoint %s does not exist!\n", mountpoint);
+ return -EINVAL;
+ }
+
+ ret = mount("none", mountpoint, fstype, 0, "");
+ return ret;
+}
Added: branches/dlm-glue/documentation/samples/cluster.conf
===================================================================
--- branches/dlm-glue/documentation/samples/cluster.conf 2004-12-04 01:51:08 UTC (rev 459)
+++ branches/dlm-glue/documentation/samples/cluster.conf 2004-12-04 02:56:28 UTC (rev 460)
@@ -0,0 +1,4 @@
+cluster_name=foofers
+0,ca-test31,139.185.118.131,8765
+1,ca-test32,139.185.118.132,7654
+2,ca-test33,139.185.118.133,9977
Added: branches/dlm-glue/listuuid/Makefile
===================================================================
--- branches/dlm-glue/listuuid/Makefile 2004-12-04 01:51:08 UTC (rev 459)
+++ branches/dlm-glue/listuuid/Makefile 2004-12-04 02:56:28 UTC (rev 460)
@@ -0,0 +1,36 @@
+TOPDIR = ..
+
+include $(TOPDIR)/Preamble.make
+
+SBIN_PROGRAMS = listuuid
+
+INCLUDES = -Iinclude -I$(TOPDIR)/libocfs2/include \
+ -I$(TOPDIR)/libocfs2cluster/include
+LIBOCFS2_LIBS = -L$(TOPDIR)/libocfs2 -locfs2
+LIBOCFS2_DEPS = $(TOPDIR)/libocfs2/libocfs2.a
+
+ifdef OCFS_DEBUG
+OPTS += -ggdb
+else
+OPTS += -O2
+endif
+
+CFLAGS := $(OPTS) -Wall -Wstrict-prototypes -Wmissing-prototypes \
+ -Wmissing-declarations
+
+DEFINES = -DOCFS2_FLAT_INCLUDES
+
+CFILES = listuuid.c
+
+OBJS = $(subst .c,.o,$(CFILES))
+
+DIST_FILES = $(CFILES)
+DIST_RULES = dist-subdircreate
+
+dist-subdircreate:
+ $(TOPDIR)/mkinstalldirs $(DIST_DIR)/include
+
+listuuid: $(OBJS) $(LIBOCFS2_DEPS)
+ $(LINK) $(LIBOCFS2_LIBS) $(COM_ERR_LIBS)
+
+include $(TOPDIR)/Postamble.make
Added: branches/dlm-glue/listuuid/listuuid.c
===================================================================
--- branches/dlm-glue/listuuid/listuuid.c 2004-12-04 01:51:08 UTC (rev 459)
+++ branches/dlm-glue/listuuid/listuuid.c 2004-12-04 02:56:28 UTC (rev 460)
@@ -0,0 +1,258 @@
+/*
+ * listuuid.c
+ *
+ * Lists UUIDs of all the devices
+ *
+ * Copyright (C) 2004 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 as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ *
+ * Authors: Sunil Mushran
+ */
+
+#define _LARGEFILE64_SOURCE
+#define _GNU_SOURCE /* Because libc really doesn't want us using O_DIRECT? */
+
+#include <sys/types.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <linux/fd.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#define OCFS2_FLAT_INCLUDES 1
+#include <ocfs2.h>
+#include <ocfs2_fs.h>
+#include <ocfs2_disk_dlm.h>
+#include <ocfs1_fs_compat.h>
+#include <kernel-list.h>
+
+char *device = NULL;
+char *progname = NULL;
+int all_devices = 0;
+
+char *usage_string =
+"usage: %s [-a] [device]\n";
+
+/*
+ * ocfs2_partition_list()
+ *
+ */
+static errcode_t ocfs2_partition_list (struct list_head *dev_list)
+{
+ errcode_t ret = 0;
+ FILE *proc;
+ char line[256];
+ char name[256];
+ char major[256];
+ char minor[256];
+ ocfs2_devices *dev;
+
+ proc = fopen ("/proc/partitions", "r");
+ if (proc == NULL) {
+ ret = OCFS2_ET_IO;
+ goto bail;
+ }
+
+ while (fgets (line, sizeof(line), proc) != NULL) {
+ *major = *minor = *name = '\0';
+ if (sscanf(line, "%*[ ]%[0-9]%*[ ]%[0-9] %*d %99[^ \t\n]",
+ major, minor, name) != 3)
+ continue;
+
+ ret = ocfs2_malloc0(sizeof(ocfs2_devices), &dev);
+ if (ret)
+ goto bail;
+
+ snprintf(dev->dev_name, sizeof(dev->dev_name), "/dev/%s", name);
+ dev->maj_num = strtoul(major, NULL, 0);
+ dev->min_num = strtoul(minor, NULL, 0);
+ list_add_tail(&(dev->list), dev_list);
+ }
+
+bail:
+ if (proc)
+ fclose(proc);
+
+ return ret;
+}
+
+/*
+ * ocfs2_print_uuids()
+ *
+ */
+static void ocfs2_print_uuids(struct list_head *dev_list)
+{
+ ocfs2_devices *dev;
+ struct list_head *pos;
+ char uuid[40];
+ char devstr[10];
+ char *p;
+ int i;
+
+ printf("%-20s %7s %-32s\n", "Device", "maj,min", "UUID");
+ list_for_each(pos, dev_list) {
+ dev = list_entry(pos, ocfs2_devices, list);
+ if (dev->fs_type == 0)
+ continue;
+
+ memset(uuid, 0, sizeof(uuid));
+ for (i = 0, p = uuid; i < 16; i++, p += 2)
+ sprintf(p, "%02X", dev->uuid[i]);
+
+ sprintf(devstr, "%3d,%-d", dev->maj_num, dev->min_num);
+ printf("%-20s %-7s %-32s\n", dev->dev_name, devstr, uuid);
+ }
+
+ return ;
+}
+
+/*
+ * ocfs2_detect()
+ *
+ */
+static errcode_t ocfs2_detect(char *device)
+{
+ errcode_t ret = 0;
+ struct list_head dev_list;
+ struct list_head *pos1, *pos2;
+ ocfs2_devices *dev;
+ ocfs2_filesys *fs = NULL;
+ char *dev_name;
+
+ INIT_LIST_HEAD(&(dev_list));
+
+ if (device) {
+ ret = ocfs2_malloc0(sizeof(ocfs2_devices), &dev);
+ if (ret)
+ goto bail;
+ strncpy(dev->dev_name, device, sizeof(dev->dev_name));
+ list_add(&(dev->list), &dev_list);
+ } else {
+ ret = ocfs2_partition_list(&dev_list);
+ if (ret) {
+ com_err(progname, ret, "while reading /proc/partitions");
+ goto bail;
+ }
+ }
+
+ list_for_each(pos1, &dev_list) {
+ dev = list_entry(pos1, ocfs2_devices, list);
+ dev_name = dev->dev_name;
+
+ /* open fs */
+ fs = NULL;
+ ret = ocfs2_open(dev_name, OCFS2_FLAG_RO, 0, 0, &fs);
+ if (ret) {
+ dev->fs_type = 0;
+ ret = 0;
+ continue;
+ } else
+ dev->fs_type = 2;
+
+ /* get uuid for ocfs2 */
+ if (dev->fs_type == 2) {
+ memcpy(dev->uuid, OCFS2_RAW_SB(fs->fs_super)->s_uuid,
+ sizeof(dev->uuid));
+ }
+
+ /* close fs */
+ ocfs2_close(fs);
+ }
+
+ ocfs2_print_uuids(&dev_list);
+
+bail:
+
+ list_for_each_safe(pos1, pos2, &(dev_list)) {
+ dev = list_entry(pos1, ocfs2_devices, list);
+ list_del(&(dev->list));
+ ocfs2_free(&dev);
+ }
+
+ return ret;
+}
+
+/*
+ * usage()
+ *
+ */
+static void usage(char *progname)
+{
+ printf(usage_string, progname);
+ return ;
+}
+
+/*
+ * read_options()
+ *
+ */
+static int read_options(int argc, char **argv)
+{
+ int ret = 0;
+ int c;
+
+ progname = basename(argv[0]);
+
+ if (argc < 2) {
+ usage(progname);
+ ret = 1;
+ goto bail;
+ }
+
+ while(1) {
+ c = getopt(argc, argv, "a");
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'a': /* all devices */
+ all_devices = 1;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (!ret && optind < argc && argv[optind])
+ device = argv[optind];
+
+bail:
+ return ret;
+}
+
+/*
+ * main()
+ *
+ */
+int main(int argc, char **argv)
+{
+ errcode_t ret = 0;
+
+ initialize_ocfs_error_table();
+
+ ret = read_options (argc, argv);
+ if (ret)
+ goto bail;
+
+ ret = ocfs2_detect(device);
+
+bail:
+ return ret;
+}
Added: branches/dlm-glue/mount.ocfs2/Makefile
===================================================================
--- branches/dlm-glue/mount.ocfs2/Makefile 2004-12-04 01:51:08 UTC (rev 459)
+++ branches/dlm-glue/mount.ocfs2/Makefile 2004-12-04 02:56:28 UTC (rev 460)
@@ -0,0 +1,36 @@
+TOPDIR = ..
+
+include $(TOPDIR)/Preamble.make
+
+SBIN_PROGRAMS = mount.ocfs2
+
+INCLUDES = -Iinclude -I$(TOPDIR)/libocfs2/include \
+ -I$(TOPDIR)/libocfs2cluster/include
+LIBOCFS2_LIBS = -L$(TOPDIR)/libocfs2 -locfs2
+LIBOCFS2_DEPS = $(TOPDIR)/libocfs2/libocfs2.a
+
+ifdef OCFS_DEBUG
+OPTS += -ggdb
+else
+OPTS += -O2
+endif
+
+CFLAGS := $(OPTS) -Wall -Wstrict-prototypes -Wmissing-prototypes \
+ -Wmissing-declarations
+
+DEFINES = -DOCFS2_FLAT_INCLUDES
+
+CFILES = mount.ocfs2.c
+
+OBJS = $(subst .c,.o,$(CFILES))
+
+DIST_FILES = $(CFILES)
+DIST_RULES = dist-subdircreate
+
+dist-subdircreate:
+ $(TOPDIR)/mkinstalldirs $(DIST_DIR)/include
+
+mount.ocfs2: $(OBJS) $(LIBOCFS2_DEPS)
+ $(LINK) $(LIBOCFS2_LIBS) $(COM_ERR_LIBS)
+
+include $(TOPDIR)/Postamble.make
Added: branches/dlm-glue/mount.ocfs2/mount.ocfs2.c
===================================================================
--- branches/dlm-glue/mount.ocfs2/mount.ocfs2.c 2004-12-04 01:51:08 UTC (rev 459)
+++ branches/dlm-glue/mount.ocfs2/mount.ocfs2.c 2004-12-04 02:56:28 UTC (rev 460)
@@ -0,0 +1,967 @@
+/*
+ * listuuid.c
+ *
+ * Lists UUIDs of all the devices
+ *
+ * Copyright (C) 2004 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 as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * 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.
+ *
+ * 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., 59 Temple Place - Suite 330,
+ * Boston, MA 021110-1307, USA.
+ *
+ * Authors: Sunil Mushran
+ */
+
+
+#define _LARGEFILE64_SOURCE
+#define _GNU_SOURCE /* Because libc really doesn't want us using O_DIRECT? */
+
+#include <sys/types.h>
+#include <asm/types.h>
+
+#define u8 __u8
+#define s8 __s8
+#define u16 __u16
+#define s16 __s16
+#define u32 __u32
+#define s32 __s32
+#define u64 __u64
+#define s64 __s64
+#define atomic_t int
+#define spinlock_t unsigned long
+typedef unsigned short kdev_t;
+
+
+
+
+#include <asm/page.h>
+#include <sys/mount.h>
+#include <dirent.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <linux/fd.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#define OCFS2_FLAT_INCLUDES 1
+#include <ocfs2.h>
+#include <ocfs2_fs.h>
+#include <ocfs2_disk_dlm.h>
+#include <ocfs1_fs_compat.h>
+#include <kernel-list.h>
+
+#include "bitops.h"
+
+#include "ocfs2_nodemanager.h"
+#include "ocfs2_heartbeat.h"
+#include "ocfs2_tcp.h"
+
+#define CLUSTER_FILE "/proc/cluster/nm/.cluster"
+#define GROUP_FILE "/proc/cluster/nm/.group"
+#define NODE_FILE "/proc/cluster/nm/.node"
+#define HEARTBEAT_DISK_FILE "/proc/cluster/heartbeat/.disk"
+
+
+int create_remote_group(char *group_name, __u16 node);
+int get_node_map(__u16 group_num, char *bitmap);
+int get_raw_node_map(__u16 groupnum, char *groupdev, __u32 block_bits, __u32 num_blocks, __u64 start_block, char *bitmap);
+int get_ocfs2_disk_hb_params(char *group_dev, __u32 *block_bits, __u32 *cluster_bits,
+ __u64 *start_block, __u32 *num_clusters);
+int activate_group(char *group_name, char *group_dev, __u16 group_num,
+ __u32 block_bits, __u64 num_blocks, __u64 start_block);
+int add_to_local_group(char *uuid, __u16 group_num, __u16 node_num);
+int create_group(char *uuid, __u16 *group_num);
+int get_my_nodenum(__u16 *nodenum);
+int add_me_to_group(char *groupname, char *groupdev);
+static errcode_t ocfs2_partition_list (struct list_head *dev_list);
+static void ocfs2_partition_list_destroy (struct list_head *dev_list);
+static errcode_t ocfs2_detect_all(struct list_head *dev_list);
+static int read_options(int argc, char **argv, char **hbuuid, char **hbdev, char **device, char **mp);
+
+char *op_buf = NULL;
+
+
+
+/*
+ * ocfs2_partition_list()
+ *
+ */
+static errcode_t ocfs2_partition_list (struct list_head *dev_list)
+{
+ errcode_t ret = 0;
+ FILE *proc;
+ char line[256];
+ char name[256];
+ ocfs2_devices *dev;
+
+ proc = fopen ("/proc/partitions", "r");
+ if (proc == NULL) {
+ ret = OCFS2_ET_IO;
+ goto bail;
+ }
+
+ while (fgets (line, sizeof(line), proc) != NULL) {
+ if (sscanf(line, "%*d %*d %*d %99[^ \t\n]", name) != 1)
+ continue;
+
+ ret = ocfs2_malloc0(sizeof(ocfs2_devices), &dev);
+ if (ret)
+ goto bail;
+
+ snprintf(dev->dev_name, sizeof(dev->dev_name), "/dev/%s", name);
+ list_add_tail(&(dev->list), dev_list);
+ }
+
+bail:
+ if (proc)
+ fclose(proc);
+
+ return ret;
+}
+
+
+/*
+ * ocfs2_partition_list_destroy()
+ *
+ */
+static void ocfs2_partition_list_destroy (struct list_head *dev_list)
+{
+ struct list_head *iter, *tmpiter;
+ ocfs2_devices *dev;
+
+ list_for_each_safe(iter, tmpiter, dev_list) {
+ dev = list_entry(iter, ocfs2_devices, list);
+ list_del(&dev->list);
+ free(dev);
+ }
+}
+
+
+/*
+ * ocfs2_detect_all()
+ *
+ */
+static errcode_t ocfs2_detect_all(struct list_head *dev_list)
+{
+ errcode_t ret = 0;
+ struct list_head *pos1;
+ ocfs2_devices *dev;
+ ocfs2_filesys *fs = NULL;
+ char *dev_name;
+
+ ret = ocfs2_partition_list(dev_list);
+ if (ret) {
+ com_err("mount.ocfs2", ret, "while reading /proc/partitions");
+ return ret;
+ }
+
+ list_for_each(pos1, dev_list) {
+ dev = list_entry(pos1, ocfs2_devices, list);
+ dev_name = dev->dev_name;
+
+ /* open fs */
+ fs = NULL;
+ ret = ocfs2_open(dev_name, OCFS2_FLAG_RO, 0, 0, &fs);
+ if (ret) {
+ dev->fs_type = 0;
+ ret = 0;
+ continue;
+ } else
+ dev->fs_type = 2;
+
+ /* get uuid for ocfs2 */
+ if (dev->fs_type == 2) {
+ memcpy(dev->uuid, OCFS2_RAW_SB(fs->fs_super)->s_uuid,
+ sizeof(dev->uuid));
+ }
+
+ /* close fs */
+ ocfs2_close(fs);
+ }
+ return ret;
+}
+
+
+/*
+ * read_options()
+ *
+ */
+static int read_options(int argc, char **argv, char **hbuuid, char **hbdev, char **device, char **mp)
+{
+ int ret = 0;
+ int c;
+ char *tmp, *tmp2;
+
+ if (argc < 2) {
+ ret = 1;
+ goto bail;
+ }
+
+ while(1) {
+ c = getopt(argc, argv, "o:");
+ if (c == -1)
+ break;
+
+ switch (c) {
+ case 'o': /* options */
+ ret = 1;
+ tmp = optarg;
+ while (*tmp) {
+ if (strncasecmp(tmp, "hbuuid=", strlen("hbuuid="))==0) {
+ tmp += strlen("hbuuid=");
+ tmp2 = strchr(tmp, ',');
+
+ /* uuid should be exactly 32 hex chars */
+ if (tmp2) {
+ if (tmp2-tmp != 32)
+ goto bail;
+ } else {
+ if (strlen(tmp) != 32)
+ goto bail;
+ }
+ *hbuuid = strndup(tmp, 32);
+ } else if (strncasecmp(tmp, "hbdev=", strlen("hbdev="))==0) {
+ tmp += strlen("hbdev=");
+ tmp2 = strchr(tmp, ',');
+ if (!tmp2)
+ tmp2 = tmp + strlen(tmp);
+ if (tmp2-tmp <= 0)
+ goto bail;
+ *hbdev = strndup(tmp, tmp2-tmp);
+ } else {
+ /* unknown option, ignore
+ * these for now, but we need
+ * to eventually handle
+ * them. */
+ tmp2 = strchr(tmp, ',');
+ }
+ tmp = tmp2;
+ if (!tmp || !*tmp)
+ break;
+ tmp++;
+ }
+ ret = 0;
+ break;
+
+ default:
+ break;
+ }
+ }
+
+ if (!ret) {
+ ret = 1;
+ /* need device and mountpoint */
+ if (optind+1 < argc && argv[optind] && argv[optind+1]) {
+ *device = strdup(argv[optind]);
+ *mp = strdup(argv[optind+1]);
+ ret = 0;
+ }
+ }
+
+bail:
+ return ret;
+}
+
+
+/*
+ * main()
+ *
+ */
+int main(int argc, char **argv)
+{
+ char *device = NULL, *mountpoint = NULL;
+ char *hbdev = NULL, *hbuuid = NULL;
+ errcode_t ret = 0;
+ struct list_head dev_list;
+ char uuid[40];
+ ocfs2_devices *dev;
+ struct list_head *iter;
+ char *p;
+ int i, found = 0;
+ unsigned long flags = 0;
+ char *args = NULL;
+
+ INIT_LIST_HEAD(&dev_list);
+
+ op_buf = malloc(PAGE_SIZE);
+ if (!op_buf) {
+ ret = 1;
+ goto bail;
+ }
+
+ ret = read_options (argc, argv, &hbuuid, &hbdev, &device, &mountpoint);
+ if (ret)
+ goto bail;
+
+ ret = 1;
+ if (!device)
+ goto bail;
+
+ /* provide nothing or one, not both */
+ if (hbuuid && hbdev)
+ goto bail;
+
+ ret = ocfs2_detect_all(&dev_list);
+ if (ret)
+ goto bail;
+
+ found = 0;
+ /* sort out which device is to be used for heartbeat */
+ if (hbuuid) {
+ list_for_each(iter, &dev_list) {
+ dev = list_entry(iter, ocfs2_devices, list);
+ if (dev->fs_type != 2)
+ continue;
+
+ memset(uuid, 0, sizeof(uuid));
+ for (i = 0, p = uuid; i < 16; i++, p += 2)
+ sprintf(p, "%02X", dev->uuid[i]);
+ if (strncasecmp(uuid, hbuuid, 32)==0) {
+ /* found it */
+ strncpy(hbuuid, uuid, 32); // normalized uuid
+ hbdev = strdup(dev->dev_name);
+ found = 1;
+ break;
+ }
+ }
+ } else {
+ char *look_for = (hbdev ? hbdev : device);
+
+ /* broken for now. have to give exact dev name in /proc/partitions */
+ list_for_each(iter, &dev_list) {
+ dev = list_entry(iter, ocfs2_devices, list);
+ if (dev->fs_type != 2)
+ continue;
+
+ if (strcasecmp(dev->dev_name, look_for)==0) {
+ /* found it */
+ if (!hbdev)
+ hbdev = strdup(dev->dev_name);
+ else
+ strcpy(hbdev, dev->dev_name);
+ hbuuid = malloc(33);
+ memset(hbuuid, 0, 33);
+ for (i = 0, p = hbuuid; i < 16; i++, p += 2)
+ sprintf(p, "%02X", dev->uuid[i]);
+ found = 1;
+ break;
+ }
+ }
+ }
+ if (!found) {
+ ret = 1;
+ goto bail;
+ }
+
+ /* all three should now have valid values */
+ printf("device=%s hbuuid=%s hbdev=%s\n", device, hbuuid, hbdev);
+
+ ret = add_me_to_group(hbuuid, hbdev);
+ if (ret < 0) {
+ printf("eeek! something bad happened in add_me_to_group: ret=%d\n", (int)ret);
+ goto bail;
+ }
+
+ args = malloc(strlen(hbuuid) + strlen("group=") + 1);
+ if (!args)
+ goto bail;
+ sprintf(args, "group=%s", hbuuid);
+ flags = 0;
+ ret = mount(device, mountpoint, "ocfs2", flags, args);
+
+bail:
+ if (args)
+ free(args);
+ if (device)
+ free(device);
+ if (mountpoint)
+ free(mountpoint);
+ if (hbdev)
+ free(hbdev);
+ if (hbuuid)
+ free(hbuuid);
+
+ ocfs2_partition_list_destroy (&dev_list);
+
+ if (op_buf)
+ free(op_buf);
+
+ return ret;
+}
+
+
+
+/*
+ * this will try to add the group (and the node to the group)
+ * for every mount. luckily, there are many shortcut paths
+ * along the way, so checking for -EEXIST will save time.
+ */
+int add_me_to_group(char *groupname, char *groupdev)
+{
+ int ret;
+ __u16 my_nodenum, groupnum;
+ __u32 pre_nodemap[] = {0, 0, 0, 0, 0, 0, 0, 0};
+ __u32 post_nodemap[] = {0, 0, 0, 0, 0, 0, 0, 0};
+ int start, next, i;
+ __u32 block_bits, cluster_bits, num_clusters;
+ __u64 start_block, num_blocks;
+
+ /* either create the group or find that it already exists */
+ ret = get_my_nodenum(&my_nodenum);
+ if (ret < 0)
+ return ret;
+
+ ret = get_ocfs2_disk_hb_params(groupdev, &block_bits, &cluster_bits,
+ &start_block, &num_clusters);
+ if (ret < 0)
+ return ret;
+
+ num_blocks = num_clusters << cluster_bits;
+ num_blocks >>= block_bits;
+
+ ret = create_group(groupname, &groupnum);
+ if (ret != -EEXIST && ret != 0)
+ return ret;
+
+ ret = activate_group(groupname, groupdev, groupnum, block_bits, num_blocks, start_block);
+ if (ret < 0)
+ return ret;
+
+ ret = add_to_local_group(groupname, groupnum, my_nodenum);
+ if (ret != -EEXIST && ret != 0)
+ return ret;
+
+ /* at this point my node is heartbeating, so any other nodes
+ * joining right now must communicate with me */
+
+ while (1) {
+ ret = get_node_map(groupnum, (char *)pre_nodemap);
+ if (ret < 0)
+ return ret;
+ if (ocfs2_test_bit(my_nodenum, (char *)pre_nodemap)) {
+ printf("found myself (%u) in nodemap! continuing...\n", my_nodenum);
+ break;
+ } else {
+ printf("have not yet found myself (%u) in nodemap...\n", my_nodenum);
+ }
+ /* TODO: set this to the default hb interval. 2 seconds right now */
+ sleep(2);
+ }
+
+ /* now that we see ourself heartbeating, take a look
+ * at ALL of the nodes that seem to be heartbeating
+ * on this device. add them here and have them add
+ * me there... */
+ ret = get_raw_node_map(groupnum, groupdev, block_bits, num_blocks, start_block, (char *)pre_nodemap);
+ if (ret < 0)
+ return ret;
+
+again:
+ /* go create this group and add this node on every other node I see */
+ start = 0;
+ while (1) {
+ next = ocfs2_find_next_bit_set((unsigned long *)pre_nodemap, NM_MAX_NODES, start);
+ if (next >= NM_MAX_NODES) {
+ break;
+ }
+ if (next != my_nodenum) {
+ /* add remote node here... */
+ ret = add_to_local_group(groupname, groupnum, next);
+ if (ret != -EEXIST && ret != 0)
+ return ret;
+
+ /* ...and add this node there */
+ ret = create_remote_group(groupname, next);
+ if (ret != 0 && ret != -EEXIST) {
+ printf("create_remote_group: node=%u returned %d!\n",
+ next, ret);
+ break;
+ }
+ }
+ start = next + 1;
+ }
+ if (ret != 0 && ret != -EEXIST)
+ return ret;
+
+ printf("done creating remote groups\n");
+
+ /* grab the nodemap again and look for changes */
+ ret = get_raw_node_map(groupnum, groupdev, block_bits, num_blocks, start_block, (char *)post_nodemap);
+ if (ret < 0)
+ return ret;
+
+ printf("checking raw node map again.....\n");
+
+ if (memcmp(pre_nodemap, post_nodemap, sizeof(pre_nodemap)) == 0) {
+ /* nothing changed. we are DONE! */
+ printf("woot. nothing changed. all done\n");
+ return 0;
+ }
+
+ printf("something changed\n");
+
+ /* something changed */
+ for (i=0; i<8; i++) {
+ post_nodemap[i] &= ~pre_nodemap[i];
+ pre_nodemap[i] = post_nodemap[i];
+ post_nodemap[i] = 0;
+ }
+
+ /* keep going while there are still nodes to contact */
+ if (ocfs2_find_next_bit_set((unsigned long *)pre_nodemap, NM_MAX_NODES, 0) < NM_MAX_NODES)
+ goto again;
+
+ printf("ah nothing left to care about ... leaving\n");
+
+ return 0;
+}
+
+int get_my_nodenum(__u16 *nodenum)
+{
+ FILE *file;
+ int ret = -EINVAL;
+ int retval=-EINVAL, num;
+ nm_op *op = (nm_op *)op_buf;
+
+ memset(op_buf, 0, PAGE_SIZE);
+ op->magic = NM_OP_MAGIC;
+ op->opcode = NM_OP_GET_GLOBAL_NODE_NUM;
+
+ *nodenum = 255;
+
+ file = fopen(CLUSTER_FILE, "r+");
+ if (!file)
+ return -errno;
+ if (fwrite((char *)op, sizeof(nm_op), 1, file) != 1)
+ goto done;
+ if (fscanf(file, "%d: %d", &retval, &num) != 2 ||
+ retval != 0 || num < 0 || num > 255) {
+ ret = -EINVAL;
+ goto done;
+ }
+ *nodenum = num;
+ ret = 0;
+done:
+ fclose(file);
+ return ret;
+}
+
+int create_group(char *uuid, __u16 *group_num)
+{
+ FILE *file;
+ int ret = -EINVAL, retval;
+ int groupnum = NM_INVALID_SLOT_NUM;
+ nm_op *op = (nm_op *)op_buf;
+ struct stat st;
+ char fname[100];
+
+ if (strlen(uuid) != CLUSTER_DISK_UUID_LEN)
+ return -EINVAL;
+
+ sprintf(fname, "/proc/cluster/nm/%s", uuid);
+ if (stat(fname, &st) == 0) {
+ *group_num = st.st_ino - NM_GROUP_INODE_START;
+ return -EEXIST;
+ }
+
+ *group_num = NM_INVALID_SLOT_NUM;
+
+ memset(op_buf, 0, PAGE_SIZE);
+ op->magic = NM_OP_MAGIC;
+ op->opcode = NM_OP_CREATE_GROUP;
+
+ op->arg_u.gc.group_num = NM_INVALID_SLOT_NUM;
+ strcpy(op->arg_u.gc.name, uuid);
+ strcpy(op->arg_u.gc.disk_uuid, uuid);
+
+ file = fopen(CLUSTER_FILE, "r+");
+ if (!file)
+ return -errno;
+
+ if (fwrite((char *)op, sizeof(nm_op), 1, file) != 1)
+ goto done;
+
+ if (fscanf(file, "%d: group %d", &retval, &groupnum) != 2) {
+ ret = -EINVAL;
+ goto done;
+ }
+ ret = retval;
+ if ((ret == 0 || ret == -EEXIST) &&
+ groupnum >= 0 && groupnum < NM_INVALID_SLOT_NUM)
+ *group_num = groupnum;
+
+done:
+ fclose(file);
+ return ret;
+}
+
+
+int add_to_local_group(char *uuid, __u16 group_num, __u16 node_num)
+{
+ FILE *file;
+ int ret = -EINVAL, retval;
+ nm_op *op = (nm_op *)op_buf;
+ char fname[100];
+ DIR *dir;
+ struct dirent *de;
+
+ if (strlen(uuid) != CLUSTER_DISK_UUID_LEN)
+ return -EINVAL;
+
+ sprintf(fname, "/proc/cluster/nm/%s", uuid);
+ dir = opendir(fname);
+ if (dir) {
+ while ((de = readdir(dir)) != NULL) {
+ if (de->d_ino - NM_NODE_INODE_START == node_num) {
+ closedir(dir);
+ return -EEXIST;
+ }
+ }
+ closedir(dir);
+ }
+
+ memset(op_buf, 0, PAGE_SIZE);
+ op->magic = NM_OP_MAGIC;
+ op->opcode = NM_OP_ADD_GROUP_NODE;
+ op->arg_u.gc.group_num = group_num;
+ op->arg_u.gc.node_num = node_num;
+ op->arg_u.gc.slot_num = node_num;
+
+ file = fopen(GROUP_FILE, "r+");
+ if (!file)
+ return -errno;
+
+ if (fwrite((char *)op, sizeof(nm_op), 1, file) != 1)
+ goto done;
+
+ if (fscanf(file, "%d: node", &retval) != 1) {
+ ret = -EINVAL;
+ goto done;
+ }
+ ret = retval;
+
+done:
+ fclose(file);
+ return ret;
+}
+
+int activate_group(char *group_name, char *group_dev, __u16 group_num,
+ __u32 block_bits, __u64 num_blocks, __u64 start_block)
+{
+ int dev_fd = -1;
+ int ret = -EINVAL, retval;
+ FILE *file;
+ hb_op *op;
+
+ printf("starting disk heartbeat...\n");
+
+ memset(op_buf, 0, PAGE_SIZE);
+ op = (hb_op *)op_buf;
+ op->magic = HB_OP_MAGIC;
+ op->opcode = HB_OP_START_DISK_HEARTBEAT;
+ op->group_num = group_num;
+ strcpy(op->disk_uuid, group_name);
+ op->bits = block_bits;
+ op->blocks = num_blocks;
+ op->start = start_block;
+
+ dev_fd = open(group_dev, O_RDWR);
+ if (dev_fd == -1)
+ return -errno;
+ op->fd = dev_fd;
+
+ file = fopen(HEARTBEAT_DISK_FILE, "r+");
+ if (!file)
+ return -errno;
+
+ if (fwrite((char *)op, sizeof(hb_op), 1, file) != 1)
+ goto done;
+
+ if (fscanf(file, "%d: ", &retval) != 1) {
+ ret = -EINVAL;
+ goto done;
+ }
+ ret = 0;
+done:
+ /* hb will keep its own ref */
+ if (dev_fd != -1)
+ close(dev_fd);
+
+ fclose(file);
+ return 0;
+}
+
+
+int get_ocfs2_disk_hb_params(char *group_dev, __u32 *block_bits, __u32 *cluster_bits,
+ __u64 *start_block, __u32 *num_clusters)
+{
+ int status = -EINVAL;
+ errcode_t ret = 0;
+ uint64_t blkno;
+ char *buf = NULL;
+ ocfs2_dinode *di;
+ ocfs2_extent_rec *rec;
+ ocfs2_filesys *fs = NULL;
+
+ ret = ocfs2_open(group_dev, OCFS2_FLAG_RO, 0, 0, &fs);
+ if (ret)
+ return status;
+
+ ret = ocfs2_lookup(fs, fs->fs_sysdir_blkno,
+ ocfs2_system_inode_names[DLM_SYSTEM_INODE],
+ strlen(ocfs2_system_inode_names[DLM_SYSTEM_INODE]),
+ NULL, &blkno);
+ if (ret)
+ goto leave;
+ ret = ocfs2_malloc_block(fs->fs_io, &buf);
+ if (ret)
+ goto leave;
+
+ ret = ocfs2_read_inode(fs, blkno, buf);
+ if (ret)
+ goto leave;
+
+ di = (ocfs2_dinode *)buf;
+ if (di->id2.i_list.l_tree_depth ||
+ di->id2.i_list.l_next_free_rec != 1) {
+ goto leave;
+ }
+ rec = &(di->id2.i_list.l_recs[0]);
+
+ *block_bits = OCFS2_RAW_SB(fs->fs_super)->s_blocksize_bits;
+ *cluster_bits = OCFS2_RAW_SB(fs->fs_super)->s_clustersize_bits;
+ *start_block = rec->e_blkno;
+ *num_clusters = rec->e_clusters;
+ status = 0;
+
+leave:
+ if (buf)
+ ocfs2_free(&buf);
+ if (fs)
+ ocfs2_close(fs);
+ return status;
+}
+
+int get_node_map(__u16 group_num, char *bitmap)
+{
+ FILE *file = NULL;
+ hb_op *op;
+ int ret = -EINVAL;
+ int retval;
+
+ printf("getting node map...\n");
+
+ memset(op_buf, 0, PAGE_SIZE);
+ op = (hb_op *)op_buf;
+ op->magic = HB_OP_MAGIC;
+ op->opcode = HB_OP_GET_NODE_MAP;
+ op->group_num = group_num;
+
+ file = fopen(HEARTBEAT_DISK_FILE, "r+");
+ if (!file)
+ return -errno;
+
+ if (fwrite((char *)op, sizeof(hb_op), 1, file) != 1)
+ goto done;
+
+ if (fscanf(file, "%d: ", &retval) != 1) {
+ ret = -EINVAL;
+ goto done;
+ }
+ if (retval != 0) {
+ ret = retval;
+ goto done;
+ }
+ if (fread(bitmap, 1, (NM_MAX_NODES+7)/8, file) < (NM_MAX_NODES+7)/8) {
+ ret = -EINVAL;
+ goto done;
+ }
+ ret = 0;
+done:
+ fclose(file);
+ return ret;
+}
+
+
+int get_raw_node_map(__u16 groupnum, char *groupdev, __u32 block_bits, __u32 num_blocks, __u64 start_block, char *bitmap)
+{
+ int i;
+ int ret = -EINVAL;
+ char *buf = NULL, *tmpbuf;
+ hb_disk_heartbeat_block *times = NULL;
+
+ errcode_t err;
+ io_channel *channel;
+
+
+ printf("getting raw node map...\n");
+
+ times = malloc(sizeof(hb_disk_heartbeat_block) * NM_MAX_NODES);
+ if (!times) {
+ ret = -ENOMEM;
+ goto done;
+ }
+
+ err = io_open(groupdev, OCFS2_FLAG_RO, &channel);
+ if (err) {
+ ret = -EINVAL;
+ goto done;
+ }
+
+ err = io_set_blksize(channel, 1 << block_bits);
+ if (err) {
+ ret = -EINVAL;
+ goto done;
+ }
+
+ err = ocfs2_malloc_blocks(channel, (int)NM_MAX_NODES, &buf);
+ if (err) {
+ ret = -ENOMEM;
+ goto done;
+ }
+
+ err = io_read_block(channel, start_block, (int)NM_MAX_NODES, buf);
+ if (err) {
+ ret = -EIO;
+ if (err == OCFS2_ET_SHORT_READ)
+ ret = -EINVAL;
+ goto done;
+ }
+
+ tmpbuf = buf;
+ for (i=0; i<NM_MAX_NODES; i++) {
+ times[i].time = ((hb_disk_heartbeat_block *)tmpbuf)->time;
+ tmpbuf += (1 << block_bits);
+ }
+
+ /* TODO: how long? */
+ sleep(4);
+
+ err = io_read_block(channel, start_block, (int)NM_MAX_NODES, buf);
+ if (err) {
+ ret = -EIO;
+ if (err == OCFS2_ET_SHORT_READ)
+ ret = -EINVAL;
+ goto done;
+ }
+
+ tmpbuf = buf;
+ for (i=0; i<NM_MAX_NODES; i++) {
+ printf("node: %d: before=%llu, after=%llu\n", i, times[i].time, ((hb_disk_heartbeat_block *)tmpbuf)->time);
+ if (times[i].time != ((hb_disk_heartbeat_block *)tmpbuf)->time) {
+ printf(" >>>>> aha node %d seems to be up!\n", i);
+ ocfs2_set_bit(i, bitmap);
+ }
+ tmpbuf += (1 << block_bits);
+ }
+
+ ret = 0;
+done:
+
+ if (buf)
+ ocfs2_free(&buf);
+ io_close(channel);
+ if (times)
+ free(times);
+ return ret;
+}
+
+int create_remote_group(char *group_name, __u16 node)
+{
+ int ret, fd = -1, remote_node = -1;
+ gsd_ioc ioc;
+ char fname[100];
+ DIR *dir = NULL;
+ struct dirent *de = NULL;
+
+ printf("create_remote_group: name=%s, remote node=%u\n", group_name, node);
+
+ /* NOTE: this is a bit of a hack. we actually normally would not
+ * know which "global" node corresponds to this "group relative" node.
+ * but for now, they directly match up. */
+ // sprintf(fname, "/proc/cluster/nm/%s/%03u", group_name, node);
+
+ dir = opendir("/proc/cluster/nm");
+ if (!dir) {
+ ret = -EINVAL;
+ goto leave;
+ }
+
+ fname[0]=0;
+ while ((de = readdir(dir)) != NULL) {
+ if (de->d_ino - NM_NODE_INODE_START == node) {
+ sprintf(fname, "/proc/cluster/nm/%s", de->d_name);
+ break;
+ }
+ }
+ closedir(dir);
+ if (!fname[0]) {
+ ret = -EINVAL;
+ goto leave;
+ }
+ printf("found file %s corresponding to node %u\n", fname, node);
+
+ /* open a file descriptor to the node we want to talk to */
+ remote_node = open(fname, O_RDONLY);
+ if (remote_node == -1) {
+ ret = -errno;
+ goto leave;
+ }
+ printf("fd for remote node=%d\n", remote_node);
+
+ /* TODO: move this over to a transaction file on the inode, eliminate the ioctl */
+ fd = open("/proc/cluster/net", O_RDONLY);
+ if (fd == -1) {
+ ret = -errno;
+ goto leave;
+ }
+
+ printf("fd for net ioctl file=%d\n", fd);
+
+ /* call an ioctl to create the group over there */
+ memset(&ioc, 0, sizeof(gsd_ioc));
+ ioc.fd = remote_node;
+ ioc.namelen = strlen(group_name);
+ memcpy(ioc.name, group_name, ioc.namelen);
+ if (ioctl(fd, GSD_IOC_CREATE_GROUP, &ioc) < 0) {
+ ret = -errno;
+ goto leave;
+ }
+ ret = ioc.status;
+ printf("create group ioctl returned ret=%d\n", ret);
+
+ if (ret != 0 && ret != -EEXIST)
+ goto leave;
+
+ /* call an ioctl to add this node to the group over there */
+ memset(&ioc, 0, sizeof(gsd_ioc));
+ ioc.fd = remote_node;
+ ioc.namelen = strlen(group_name);
+ memcpy(ioc.name, group_name, ioc.namelen);
+ if (ioctl(fd, GSD_IOC_ADD_GROUP_NODE, &ioc) < 0) {
+ ret = -errno;
+ goto leave;
+ }
+ ret = ioc.status;
+ printf("add node ioctl returned ret=%d\n", ret);
+
+leave:
+ if (fd != -1)
+ close(fd);
+ if (remote_node != -1)
+ close(remote_node);
+ return ret;
+}
More information about the Ocfs2-tools-commits
mailing list