[Ocfs2-tools-commits] mfasheh commits r626 - trunk/mount.ocfs2
svn-commits at oss.oracle.com
svn-commits at oss.oracle.com
Mon Jan 31 14:00:43 CST 2005
Author: mfasheh
Date: 2005-01-31 14:00:41 -0600 (Mon, 31 Jan 2005)
New Revision: 626
Added:
trunk/mount.ocfs2/group.c
Modified:
trunk/mount.ocfs2/Makefile
Log:
* Basically this is mount.ocfs2.c, cleaned up and with the actual
mount stuff removed. "group" allows us to join a cluster without
actually mounting a file system. Things here are *ugly*. Luckily, this
is not built by default and is used by several people for testing
until the usysfs stuff is sorted out.
Modified: trunk/mount.ocfs2/Makefile
===================================================================
--- trunk/mount.ocfs2/Makefile 2005-01-31 19:56:38 UTC (rev 625)
+++ trunk/mount.ocfs2/Makefile 2005-01-31 20:00:41 UTC (rev 626)
@@ -33,4 +33,7 @@
mount.ocfs2: $(OBJS) $(LIBOCFS2_DEPS)
$(LINK) $(LIBOCFS2_LIBS) $(COM_ERR_LIBS)
+group: group.o $(LIBOCFS2_DEPS)
+ $(LINK) $(LIBOCFS2_LIBS) $(COM_ERR_LIBS)
+
include $(TOPDIR)/Postamble.make
Added: trunk/mount.ocfs2/group.c
===================================================================
--- trunk/mount.ocfs2/group.c 2005-01-31 19:56:38 UTC (rev 625)
+++ trunk/mount.ocfs2/group.c 2005-01-31 20:00:41 UTC (rev 626)
@@ -0,0 +1,768 @@
+/*
+ * 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>
+#include <inttypes.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 <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, __u8 node);
+int get_node_map(__u8 group_num, char *bitmap);
+int get_raw_node_map(__u8 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, __u8 group_num,
+ __u32 block_bits, __u64 num_blocks, __u64 start_block);
+int add_to_local_group(char *uuid, __u8 group_num, __u8 node_num);
+int create_group(char *uuid, __u8 *group_num);
+int get_my_nodenum(__u8 *nodenum);
+int add_me_to_group(char *groupname, char *groupdev);
+int ocfs2_detect_one(char *dev, char *uuid, int uuid_size);
+
+char *op_buf = NULL;
+
+/* returns fs_type: 0 for unknown, 1 for ocfs, 2 for ocfs2 */
+int ocfs2_detect_one(char *dev, char *uuid, int uuid_size)
+{
+ ocfs2_filesys *fs = NULL;
+ int fs_type = 0;
+ int fs_size = sizeof(OCFS2_RAW_SB(fs->fs_super)->s_uuid);
+ errcode_t ret;
+
+ if (uuid_size != fs_size)
+ goto out;
+
+ ret = ocfs2_open(dev, OCFS2_FLAG_RO, 0, 0, &fs);
+ if (ret)
+ goto out;
+
+ memcpy(uuid, OCFS2_RAW_SB(fs->fs_super)->s_uuid,
+ uuid_size);
+ fs_type = 2;
+
+ ocfs2_close(fs);
+
+out:
+ return fs_type;
+}
+
+/*
+ * main()
+ *
+ */
+int main(int argc, char **argv)
+{
+ char *device = NULL;
+ char *hbuuid = NULL;
+ errcode_t ret = 0;
+ ocfs2_devices *dev;
+ char *p;
+ int i;
+
+ if (argc < 2) {
+ ret = OCFS2_ET_BAD_DEVICE_NAME;
+ com_err(argv[0], ret, "no device specified");
+ goto bail;
+ }
+
+ device = argv[1];
+
+ op_buf = malloc(PAGE_SIZE);
+ if (!op_buf) {
+ ret = 1;
+ goto bail;
+ }
+
+ dev = calloc(1, sizeof(*dev));
+ if (dev == NULL) {
+ ret = OCFS2_ET_NO_MEMORY;
+ com_err("mount.ocfs2", ret, "while allocating a dev");
+ goto bail;
+ }
+ snprintf(dev->dev_name, sizeof(dev->dev_name), "%s", device);
+
+ ret = ocfs2_detect_one(dev->dev_name, dev->uuid, sizeof(dev->uuid));
+ if (ret != 2) {
+ com_err("mount.ocfs2", ret, "while opening the file system");
+ goto bail;
+ }
+ dev->fs_type = ret;
+
+ hbuuid = malloc(33);
+ memset(hbuuid, 0, 33);
+ for (i = 0, p = hbuuid; i < 16; i++, p += 2)
+ sprintf(p, "%02X", dev->uuid[i]);
+
+ printf("device=%s hbuuid=%s\n", device, hbuuid);
+
+ ret = add_me_to_group(hbuuid, device);
+ if (ret < 0) {
+ printf("eeek! something bad happened in add_me_to_group: "
+ "ret=%d\n", (int)ret);
+ goto bail;
+ }
+
+bail:
+ if (device)
+ free(device);
+ if (hbuuid)
+ free(hbuuid);
+ 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;
+ __u8 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) {
+ printf("I couldn't get my node num!\n");
+ return ret;
+ }
+
+ ret = get_ocfs2_disk_hb_params(groupdev, &block_bits, &cluster_bits,
+ &start_block, &num_clusters);
+ if (ret < 0) {
+ printf("I couldn't get disk hb params!\n");
+ return ret;
+ }
+
+ num_blocks = num_clusters << cluster_bits;
+ num_blocks >>= block_bits;
+
+ ret = create_group(groupname, &groupnum);
+ if (ret != -EEXIST && ret != 0) {
+ printf("add_me_to_group: could not create group!\n");
+ return ret;
+ }
+
+ ret = activate_group(groupname, groupdev, groupnum, block_bits, num_blocks, start_block);
+ if (ret < 0) {
+ printf("add_me_to_group: could not activate group\n");
+ return ret;
+ }
+
+ ret = add_to_local_group(groupname, groupnum, my_nodenum);
+ if (ret != -EEXIST && ret != 0) {
+ printf("add_me_to_group: could not add myself to the local "
+ "group\n");
+ 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) {
+ printf("problem re reading node map!\n");
+ 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) {
+ printf("add_me_to_group: error return %d from "
+ "get_raw_node_map\n", ret);
+ 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) {
+ printf("add_me_to_group: return %d from "
+ "add_to_local_group\n", ret);
+ 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(__u8 *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) {
+ ret = -errno;
+ printf("get_my_nodenum: error %d opening %s\n", ret,
+ CLUSTER_FILE);
+ return ret;
+ }
+ 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, __u8 *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, __u8 group_num, __u8 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, __u8 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;
+ char *heartbeat_filename;
+ 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;
+
+ heartbeat_filename = ocfs2_system_inodes[HEARTBEAT_SYSTEM_INODE].si_name;
+ ret = ocfs2_lookup(fs, fs->fs_sysdir_blkno, heartbeat_filename,
+ strlen(heartbeat_filename), 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(__u8 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(__u8 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=%"PRIu64", after=%"PRIu64"\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, __u8 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