[Ocfs2-tools-commits] mfasheh commits r833 - in trunk: libo2cb libo2cb/include libocfs2 libocfs2/include mount.ocfs2 ocfs2console/ocfs2interface

svn-commits at oss.oracle.com svn-commits at oss.oracle.com
Thu Apr 21 18:35:42 CDT 2005


Author: mfasheh
Signed-off-by: manish
Date: 2005-04-21 18:35:40 -0500 (Thu, 21 Apr 2005)
New Revision: 833

Added:
   trunk/libo2cb/include/o2cb_crc32.h
   trunk/libo2cb/o2cb_crc32.c
Modified:
   trunk/libo2cb/Makefile
   trunk/libo2cb/include/o2cb.h
   trunk/libo2cb/o2cb_abi.c
   trunk/libo2cb/o2cb_err.et
   trunk/libocfs2/heartbeat.c
   trunk/libocfs2/include/ocfs2.h
   trunk/mount.ocfs2/mount.ocfs2.c
   trunk/mount.ocfs2/ocfs2_hb_ctl.c
   trunk/ocfs2console/ocfs2interface/o2cbmodule.c
Log:
* Implement userspace ref counting of heartbeat regions. 

* This required some api changes, some of which were incompatible with
  ocfs2console. That code has been commented out for manish to get to after 
  this commit.

Signed-off-by: manish



Modified: trunk/libo2cb/Makefile
===================================================================
--- trunk/libo2cb/Makefile	2005-04-21 05:36:22 UTC (rev 832)
+++ trunk/libo2cb/Makefile	2005-04-21 23:35:40 UTC (rev 833)
@@ -37,10 +37,12 @@
 endif
 
 CFILES = 		\
-	o2cb_abi.c
+	o2cb_abi.c	\
+	o2cb_crc32.c
 
 HFILES =				\
 	include/o2cb_abi.h		\
+	include/o2cb_crc32.h		\
 	include/o2cb.h
 
 HFILES_GEN =		\
@@ -48,7 +50,7 @@
 
 OBJS = $(subst .c,.o,$(CFILES)) \
 	o2cb_err.o
-	
+
 $(OBJS): $(HFILES_GEN)
 
 include/o2cb_err.h: o2cb_err.h

Modified: trunk/libo2cb/include/o2cb.h
===================================================================
--- trunk/libo2cb/include/o2cb.h	2005-04-21 05:36:22 UTC (rev 832)
+++ trunk/libo2cb/include/o2cb.h	2005-04-21 23:35:40 UTC (rev 833)
@@ -59,15 +59,33 @@
 errcode_t o2cb_list_nodes(char *cluster_name, char ***nodes);
 void o2cb_free_nodes_list(char **nodes);
 
-errcode_t o2cb_create_heartbeat_region_disk(const char *cluster_name,
-					    const char *region_name,
-					    const char *device_name,
-					    int block_bytes,
-					    uint64_t start_block,
-					    uint64_t blocks);
-errcode_t o2cb_remove_heartbeat_region_disk(const char *cluster_name,
-					    const char *region_name);
+struct o2cb_region_desc {
+	char		*r_name;
+	char		*r_device_name;
+	int		r_block_bytes;
+	uint64_t	r_start_block;
+	uint64_t	r_blocks;
+};
 
+/* Expected use case for the region descriptor is to allocate it on
+ * the stack and completely fill it before calling
+ * start_heartbeat_region. */
+errcode_t o2cb_start_heartbeat_region(const char *cluster_name,
+				      struct o2cb_region_desc *desc);
+errcode_t o2cb_stop_heartbeat_region(const char *cluster_name,
+				     const char *region_name);
+errcode_t o2cb_start_heartbeat_region_perm(const char *cluster_name,
+					   struct o2cb_region_desc *desc);
+errcode_t o2cb_stop_heartbeat_region_perm(const char *cluster_name,
+					  const char *region_name);
+
+errcode_t o2cb_get_region_ref(const char *region_name,
+			      int undo);
+errcode_t o2cb_put_region_ref(const char *region_name,
+			      int undo);
+errcode_t o2cb_num_region_refs(const char *region_name,
+			       int *num_refs);
+
 errcode_t o2cb_get_node_num(const char *cluster_name,
 			    const char *node_name,
 			    uint16_t *node_num);

Added: trunk/libo2cb/include/o2cb_crc32.h
===================================================================
--- trunk/libo2cb/include/o2cb_crc32.h	2005-04-21 05:36:22 UTC (rev 832)
+++ trunk/libo2cb/include/o2cb_crc32.h	2005-04-21 23:35:40 UTC (rev 833)
@@ -0,0 +1,31 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * o2cb_crc32.h
+ *
+ * libo2cb interface to crc32 functionality.
+ *
+ * Copyright (C) 2005 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.
+ * 
+ * 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.
+ * 
+ */
+
+#ifndef _O2CB_CRC32_H
+#define _O2CB_CRC32_H
+
+unsigned long o2cb_crc32(const char *s);
+
+#endif /* _O2CB_CRC32_H */

Modified: trunk/libo2cb/o2cb_abi.c
===================================================================
--- trunk/libo2cb/o2cb_abi.c	2005-04-21 05:36:22 UTC (rev 832)
+++ trunk/libo2cb/o2cb_abi.c	2005-04-21 23:35:40 UTC (rev 833)
@@ -31,6 +31,8 @@
 #include <sys/types.h>
 #include <sys/stat.h>
 #include <sys/ioctl.h>
+#include <sys/ipc.h>
+#include <sys/sem.h>
 #include <dirent.h>
 #include <fcntl.h>
 #include <unistd.h>
@@ -43,6 +45,8 @@
 
 #include "o2cb_abi.h"
 
+#include "o2cb_crc32.h"
+
 errcode_t o2cb_create_cluster(const char *cluster_name)
 {
 	char path[PATH_MAX];
@@ -369,12 +373,12 @@
 	return 0;
 }
 
-errcode_t o2cb_create_heartbeat_region_disk(const char *cluster_name,
-					    const char *region_name,
-					    const char *device_name,
-					    int block_bytes,
-					    uint64_t start_block,
-					    uint64_t blocks)
+static errcode_t o2cb_create_heartbeat_region(const char *cluster_name,
+					      const char *region_name,
+					      const char *device_name,
+					      int block_bytes,
+					      uint64_t start_block,
+					      uint64_t blocks)
 {
 	char _fake_cluster_name[NAME_MAX];
 	char region_path[PATH_MAX];
@@ -516,9 +520,241 @@
 	return err;
 }
 
-errcode_t o2cb_remove_heartbeat_region_disk(const char *cluster_name,
-					    const char *region_name)
+static errcode_t o2cb_destroy_sem_set(int semid)
 {
+	int error;
+	errcode_t ret = 0;
+
+	error = semctl(semid, 0, IPC_RMID);
+	if (error) {
+		switch(errno) {
+			case EPERM:
+			case EACCES:
+				ret = O2CB_ET_PERMISSION_DENIED;
+				break;
+
+			case EIDRM:
+				/* Someone raced us to it... can this
+				 * happen? */
+				ret = 0;
+				break;
+
+			default:
+				ret = O2CB_ET_INTERNAL_FAILURE;
+		}
+	}
+
+	return ret;
+}
+
+static errcode_t o2cb_get_semid(const char *region,
+				int *semid)
+{
+	int ret;
+	key_t key;
+
+	key = (key_t) o2cb_crc32(region);
+
+	ret = semget(key, 2, IPC_CREAT);
+	if (ret < 0)
+		return O2CB_ET_BAD_SEM;
+
+	*semid = ret;
+
+	return 0;
+}
+
+static inline errcode_t o2cb_semop_err(int err)
+{
+	errcode_t ret;
+
+	switch (err) {
+		case EACCES:
+			ret = O2CB_ET_PERMISSION_DENIED;
+			break;
+
+		case EIDRM:
+			/* Other paths depend on us returning this for EIDRM */
+			ret = O2CB_ET_NO_SEM;
+			break;
+
+		case EINVAL:
+			ret = O2CB_ET_SERVICE_UNAVAILABLE;
+			break;
+
+		case ENOMEM:
+			ret = O2CB_ET_NO_MEMORY;
+			break;
+
+		default:
+			ret = O2CB_ET_INTERNAL_FAILURE;
+	}
+	return ret;
+}
+
+static errcode_t o2cb_mutex_down(int semid)
+{
+	int err;
+	struct sembuf sops[2] = { 
+		{ .sem_num = 0, .sem_op = 0, .sem_flg = SEM_UNDO },
+		{ .sem_num = 0, .sem_op = 1, .sem_flg = SEM_UNDO }
+	};
+
+	err = semop(semid, sops, 2);
+	if (err)
+		return o2cb_semop_err(errno);
+
+	return 0;
+}
+
+/* We have coded our semaphore destruction such that you will legally
+ * only get EIDRM when waiting on the mutex. Use this function to look
+ * it up and return it locked - it knows how to loop around on
+ * EIDRM. */
+static errcode_t o2cb_mutex_down_lookup(const char *region,
+					int *semid)
+{
+	int tmpid;
+	errcode_t ret;
+
+	ret = O2CB_ET_NO_SEM;
+	while (ret == O2CB_ET_NO_SEM) {
+		ret = o2cb_get_semid(region, &tmpid);
+		if (ret)
+			return ret;
+
+		ret = o2cb_mutex_down(tmpid);
+		if (!ret) {
+			/* At this point, we're the only ones who can destroy
+			 * this sem set. */
+			*semid = tmpid;
+		}
+	}
+
+	return ret;
+}
+
+static errcode_t o2cb_mutex_up(int semid)
+{
+	int err;
+	struct sembuf sop = { .sem_num = 0,
+			      .sem_op = -1,
+			      .sem_flg = SEM_UNDO };
+
+	err = semop(semid, &sop, 1);
+	if (err)
+		return o2cb_semop_err(errno);
+
+	return 0;
+}
+
+static errcode_t __o2cb_get_ref(int semid,
+			      int undo)
+{
+	int err;
+	struct sembuf sop = { .sem_num = 1,
+			      .sem_op = 1,
+			      .sem_flg = undo ? SEM_UNDO : 0 };
+
+	err = semop(semid, &sop, 1);
+	if (err)
+		return o2cb_semop_err(errno);
+
+	return 0;
+}
+
+errcode_t o2cb_get_region_ref(const char *region_name,
+			      int undo)
+{
+	errcode_t ret, up_ret;
+	int semid;
+
+	ret = o2cb_mutex_down_lookup(region_name, &semid);
+	if (ret)
+		return ret;
+
+	ret = __o2cb_get_ref(semid, undo);
+
+	/* XXX: Maybe try to drop ref if we get an error here? */
+	up_ret = o2cb_mutex_up(semid);
+	if (up_ret && !ret)
+		ret = up_ret;
+
+	return ret;
+}
+
+static errcode_t __o2cb_drop_ref(int semid,
+				 int undo)
+{
+	int err;
+	struct sembuf sop = { .sem_num = 1,
+			      .sem_op = -1,
+			      .sem_flg = undo ? SEM_UNDO : 0 };
+
+	err = semop(semid, &sop, 1);
+	if (err)
+		return o2cb_semop_err(errno);
+
+	return 0;
+}
+
+errcode_t o2cb_put_region_ref(const char *region_name,
+			      int undo)
+{
+	errcode_t ret, up_ret;
+	int semid;
+
+	ret = o2cb_mutex_down_lookup(region_name, &semid);
+	if (ret)
+		return ret;
+
+	ret = __o2cb_drop_ref(semid, undo);
+
+	up_ret = o2cb_mutex_up(semid);
+	if (up_ret && !ret)
+		ret = up_ret;
+
+	return ret;
+}
+
+static errcode_t __o2cb_get_num_refs(int semid, int *num_refs)
+{
+	int ret;
+
+	ret = semctl(semid, 1, GETVAL, NULL);
+	if (ret == -1)
+		return o2cb_semop_err(errno);
+
+	*num_refs = ret;
+
+	return 0;
+}
+
+errcode_t o2cb_num_region_refs(const char *region_name,
+			       int *num_refs)
+{
+	errcode_t ret;
+	int semid;
+
+	ret = o2cb_get_semid(region_name, &semid);
+	if (ret)
+		return ret;
+
+	ret = __o2cb_get_num_refs(semid, num_refs);
+
+	/* The semaphore set was destroyed underneath us. We treat
+	 * that as zero reference and return success. */
+	if (ret == O2CB_ET_NO_SEM) {
+		*num_refs = 0;
+		ret = 0;
+	}
+
+	return ret;
+}
+
+static errcode_t o2cb_remove_heartbeat_region(const char *cluster_name,
+					      const char *region_name)
+{
 	char _fake_cluster_name[NAME_MAX];
 	char region_path[PATH_MAX];
 	int ret;
@@ -572,6 +808,116 @@
 	return err;
 }
 
+/* For ref counting purposes, we need to know whether this process
+ * called o2cb_create_heartbeat_region_disk. If it did, then we want
+ * to drop the reference taken during startup, otherwise that
+ * reference was dropped automatically at process shutdown so there's
+ * no need to drop one here. */
+static errcode_t __o2cb_stop_heartbeat_region(const char *cluster_name,
+					      const char *region_name,
+					      int undo)
+{
+	errcode_t ret, up_ret;
+	int hb_refs;
+	int semid;
+
+	ret = o2cb_mutex_down_lookup(region_name, &semid);
+	if (ret)
+		return ret;
+
+	ret = __o2cb_get_num_refs(semid, &hb_refs);
+	if (ret)
+		goto up;
+
+	/* A previous process may have died and left us with no
+	 * references on the region. We avoid a negative error count
+	 * here and clean up the region as normal. */
+	if (hb_refs) {
+		ret = __o2cb_drop_ref(semid, undo);
+		if (ret)
+			goto up;
+
+		/* No need to call get_num_refs again -- this was
+		 * atomic so we know what the new value must be. */
+		hb_refs--;
+	}
+
+	if (!hb_refs) {
+		/* XXX: If this fails, shouldn't we still destroy the
+		 * semaphore set? */
+		ret = o2cb_remove_heartbeat_region(cluster_name, region_name);
+		if (ret)
+			goto up;
+
+		ret = o2cb_destroy_sem_set(semid);
+		if (ret)
+			goto up;
+
+		goto done;
+	}
+up:
+	up_ret = o2cb_mutex_up(semid);
+	if (up_ret && !ret) /* XXX: Maybe stop heartbeat here then? */
+		ret = up_ret;
+
+done:
+	return ret;
+}
+
+static errcode_t __o2cb_start_heartbeat_region(const char *cluster_name,
+					       struct o2cb_region_desc *desc,
+					       int undo)
+{
+	errcode_t ret, up_ret;
+	int semid;
+
+	ret = o2cb_mutex_down_lookup(desc->r_name, &semid);
+	if (ret)
+		return ret;
+
+	ret = o2cb_create_heartbeat_region(cluster_name,
+					   desc->r_name,
+					   desc->r_device_name,
+					   desc->r_block_bytes,
+					   desc->r_start_block,
+					   desc->r_blocks);
+	if (ret && ret != O2CB_ET_REGION_EXISTS)
+		goto up;
+
+	ret = __o2cb_get_ref(semid, undo);
+	/* XXX: Maybe stop heartbeat on error here? */
+up:
+	up_ret = o2cb_mutex_up(semid);
+	if (up_ret && !ret)
+		ret = up_ret;
+
+	return ret;
+}
+
+errcode_t o2cb_start_heartbeat_region(const char *cluster_name,
+				      struct o2cb_region_desc *desc)
+{
+	return __o2cb_start_heartbeat_region(cluster_name, desc, 1);
+}
+
+errcode_t o2cb_stop_heartbeat_region(const char *cluster_name,
+				     const char *region_name)
+{
+	return __o2cb_stop_heartbeat_region(cluster_name, region_name, 1);
+}
+
+errcode_t o2cb_start_heartbeat_region_perm(const char *cluster_name,
+					   struct o2cb_region_desc *desc)
+{
+	return __o2cb_start_heartbeat_region(cluster_name, desc, 0);
+}
+
+errcode_t o2cb_stop_heartbeat_region_perm(const char *cluster_name,
+					  const char *region_name)
+{
+	return __o2cb_stop_heartbeat_region(cluster_name, region_name, 0);
+}
+
 static inline int is_dots(const char *name)
 {
 	size_t len = strlen(name);

Added: trunk/libo2cb/o2cb_crc32.c
===================================================================
--- trunk/libo2cb/o2cb_crc32.c	2005-04-21 05:36:22 UTC (rev 832)
+++ trunk/libo2cb/o2cb_crc32.c	2005-04-21 23:35:40 UTC (rev 833)
@@ -0,0 +1,116 @@
+/* -*- mode: c; c-basic-offset: 8; -*-
+ * vim: noexpandtab sw=8 ts=8 sts=0:
+ *
+ * o2cb_crc32.c
+ *
+ * Routines for computing a crc
+ *
+ * Crc code copied from scripts/genksyms/genksysms.c. Original header
+ * from that file follows.
+ */
+
+#include "o2cb_crc32.h"
+
+/* Generate kernel symbol version hashes.
+   Copyright 1996, 1997 Linux International.
+
+   New implementation contributed by Richard Henderson <rth at tamu.edu>
+   Based on original work by Bjorn Ekwall <bj0rn at blox.se>
+
+   This file was part of the Linux modutils 2.4.22: moved back into the
+   kernel sources by Rusty Russell/Kai Germaschewski.
+
+   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 02111-1307, USA.  */
+
+static const unsigned int crctab32[] =
+{
+  0x00000000U, 0x77073096U, 0xee0e612cU, 0x990951baU, 0x076dc419U,
+  0x706af48fU, 0xe963a535U, 0x9e6495a3U, 0x0edb8832U, 0x79dcb8a4U,
+  0xe0d5e91eU, 0x97d2d988U, 0x09b64c2bU, 0x7eb17cbdU, 0xe7b82d07U,
+  0x90bf1d91U, 0x1db71064U, 0x6ab020f2U, 0xf3b97148U, 0x84be41deU,
+  0x1adad47dU, 0x6ddde4ebU, 0xf4d4b551U, 0x83d385c7U, 0x136c9856U,
+  0x646ba8c0U, 0xfd62f97aU, 0x8a65c9ecU, 0x14015c4fU, 0x63066cd9U,
+  0xfa0f3d63U, 0x8d080df5U, 0x3b6e20c8U, 0x4c69105eU, 0xd56041e4U,
+  0xa2677172U, 0x3c03e4d1U, 0x4b04d447U, 0xd20d85fdU, 0xa50ab56bU,
+  0x35b5a8faU, 0x42b2986cU, 0xdbbbc9d6U, 0xacbcf940U, 0x32d86ce3U,
+  0x45df5c75U, 0xdcd60dcfU, 0xabd13d59U, 0x26d930acU, 0x51de003aU,
+  0xc8d75180U, 0xbfd06116U, 0x21b4f4b5U, 0x56b3c423U, 0xcfba9599U,
+  0xb8bda50fU, 0x2802b89eU, 0x5f058808U, 0xc60cd9b2U, 0xb10be924U,
+  0x2f6f7c87U, 0x58684c11U, 0xc1611dabU, 0xb6662d3dU, 0x76dc4190U,
+  0x01db7106U, 0x98d220bcU, 0xefd5102aU, 0x71b18589U, 0x06b6b51fU,
+  0x9fbfe4a5U, 0xe8b8d433U, 0x7807c9a2U, 0x0f00f934U, 0x9609a88eU,
+  0xe10e9818U, 0x7f6a0dbbU, 0x086d3d2dU, 0x91646c97U, 0xe6635c01U,
+  0x6b6b51f4U, 0x1c6c6162U, 0x856530d8U, 0xf262004eU, 0x6c0695edU,
+  0x1b01a57bU, 0x8208f4c1U, 0xf50fc457U, 0x65b0d9c6U, 0x12b7e950U,
+  0x8bbeb8eaU, 0xfcb9887cU, 0x62dd1ddfU, 0x15da2d49U, 0x8cd37cf3U,
+  0xfbd44c65U, 0x4db26158U, 0x3ab551ceU, 0xa3bc0074U, 0xd4bb30e2U,
+  0x4adfa541U, 0x3dd895d7U, 0xa4d1c46dU, 0xd3d6f4fbU, 0x4369e96aU,
+  0x346ed9fcU, 0xad678846U, 0xda60b8d0U, 0x44042d73U, 0x33031de5U,
+  0xaa0a4c5fU, 0xdd0d7cc9U, 0x5005713cU, 0x270241aaU, 0xbe0b1010U,
+  0xc90c2086U, 0x5768b525U, 0x206f85b3U, 0xb966d409U, 0xce61e49fU,
+  0x5edef90eU, 0x29d9c998U, 0xb0d09822U, 0xc7d7a8b4U, 0x59b33d17U,
+  0x2eb40d81U, 0xb7bd5c3bU, 0xc0ba6cadU, 0xedb88320U, 0x9abfb3b6U,
+  0x03b6e20cU, 0x74b1d29aU, 0xead54739U, 0x9dd277afU, 0x04db2615U,
+  0x73dc1683U, 0xe3630b12U, 0x94643b84U, 0x0d6d6a3eU, 0x7a6a5aa8U,
+  0xe40ecf0bU, 0x9309ff9dU, 0x0a00ae27U, 0x7d079eb1U, 0xf00f9344U,
+  0x8708a3d2U, 0x1e01f268U, 0x6906c2feU, 0xf762575dU, 0x806567cbU,
+  0x196c3671U, 0x6e6b06e7U, 0xfed41b76U, 0x89d32be0U, 0x10da7a5aU,
+  0x67dd4accU, 0xf9b9df6fU, 0x8ebeeff9U, 0x17b7be43U, 0x60b08ed5U,
+  0xd6d6a3e8U, 0xa1d1937eU, 0x38d8c2c4U, 0x4fdff252U, 0xd1bb67f1U,
+  0xa6bc5767U, 0x3fb506ddU, 0x48b2364bU, 0xd80d2bdaU, 0xaf0a1b4cU,
+  0x36034af6U, 0x41047a60U, 0xdf60efc3U, 0xa867df55U, 0x316e8eefU,
+  0x4669be79U, 0xcb61b38cU, 0xbc66831aU, 0x256fd2a0U, 0x5268e236U,
+  0xcc0c7795U, 0xbb0b4703U, 0x220216b9U, 0x5505262fU, 0xc5ba3bbeU,
+  0xb2bd0b28U, 0x2bb45a92U, 0x5cb36a04U, 0xc2d7ffa7U, 0xb5d0cf31U,
+  0x2cd99e8bU, 0x5bdeae1dU, 0x9b64c2b0U, 0xec63f226U, 0x756aa39cU,
+  0x026d930aU, 0x9c0906a9U, 0xeb0e363fU, 0x72076785U, 0x05005713U,
+  0x95bf4a82U, 0xe2b87a14U, 0x7bb12baeU, 0x0cb61b38U, 0x92d28e9bU,
+  0xe5d5be0dU, 0x7cdcefb7U, 0x0bdbdf21U, 0x86d3d2d4U, 0xf1d4e242U,
+  0x68ddb3f8U, 0x1fda836eU, 0x81be16cdU, 0xf6b9265bU, 0x6fb077e1U,
+  0x18b74777U, 0x88085ae6U, 0xff0f6a70U, 0x66063bcaU, 0x11010b5cU,
+  0x8f659effU, 0xf862ae69U, 0x616bffd3U, 0x166ccf45U, 0xa00ae278U,
+  0xd70dd2eeU, 0x4e048354U, 0x3903b3c2U, 0xa7672661U, 0xd06016f7U,
+  0x4969474dU, 0x3e6e77dbU, 0xaed16a4aU, 0xd9d65adcU, 0x40df0b66U,
+  0x37d83bf0U, 0xa9bcae53U, 0xdebb9ec5U, 0x47b2cf7fU, 0x30b5ffe9U,
+  0xbdbdf21cU, 0xcabac28aU, 0x53b39330U, 0x24b4a3a6U, 0xbad03605U,
+  0xcdd70693U, 0x54de5729U, 0x23d967bfU, 0xb3667a2eU, 0xc4614ab8U,
+  0x5d681b02U, 0x2a6f2b94U, 0xb40bbe37U, 0xc30c8ea1U, 0x5a05df1bU,
+  0x2d02ef8dU
+};
+
+static inline unsigned long
+partial_crc32_one(unsigned char c, unsigned long crc)
+{
+  return crctab32[(crc ^ c) & 0xff] ^ (crc >> 8);
+}
+
+static inline unsigned long
+partial_crc32(const char *s, unsigned long crc)
+{
+  while (*s)
+    crc = partial_crc32_one(*s++, crc);
+  return crc;
+}
+
+static inline unsigned long
+crc32(const char *s)
+{
+  return partial_crc32(s, 0xffffffff) ^ 0xffffffff;
+}
+
+unsigned long o2cb_crc32(const char *s)
+{
+	return crc32(s);
+}

Modified: trunk/libo2cb/o2cb_err.et
===================================================================
--- trunk/libo2cb/o2cb_err.et	2005-04-21 05:36:22 UTC (rev 832)
+++ trunk/libo2cb/o2cb_err.et	2005-04-21 23:35:40 UTC (rev 833)
@@ -69,4 +69,10 @@
 ec	O2CB_ET_MODULE_NOT_LOADED,
 	"Node manager kernel module is not loaded"
 
+ec	O2CB_ET_BAD_SEM,
+	"Could not access heartbeat region semaphore set"
+
+ec	O2CB_ET_NO_SEM,
+	"Region semaphore set destroyed"
+
 	end

Modified: trunk/libocfs2/heartbeat.c
===================================================================
--- trunk/libocfs2/heartbeat.c	2005-04-21 05:36:22 UTC (rev 832)
+++ trunk/libocfs2/heartbeat.c	2005-04-21 23:35:40 UTC (rev 833)
@@ -34,16 +34,14 @@
 
 #include "ocfs2.h"
 
-static errcode_t ocfs2_get_heartbeat_params(ocfs2_filesys *fs,
-					    uint32_t *block_bits,
-					    uint32_t *cluster_bits,
-					    uint64_t *start_block,
-					    uint64_t *num_blocks)
+errcode_t ocfs2_fill_heartbeat_desc(ocfs2_filesys *fs,
+				    struct o2cb_region_desc *desc)
 {
 	errcode_t ret;
 	char *filename;
 	char *buf = NULL;
 	uint64_t blkno, blocks;
+	uint32_t block_bits, cluster_bits;
 	ocfs2_dinode *di;
 	ocfs2_extent_rec *rec;
 
@@ -70,42 +68,40 @@
 	}
 	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;
+	block_bits = OCFS2_RAW_SB(fs->fs_super)->s_blocksize_bits;
+	cluster_bits = OCFS2_RAW_SB(fs->fs_super)->s_clustersize_bits;
 
-	blocks = rec->e_clusters << *cluster_bits;
-	blocks >>= *block_bits;
-	*num_blocks = blocks;
+	blocks = rec->e_clusters << cluster_bits;
+	blocks >>= block_bits;
 
+	/* clamp to NM_MAX_NODES */
+	if (blocks > 254)
+		blocks = 254;
+
+	desc->r_name = fs->uuid_str;
+	desc->r_device_name = fs->fs_devname;
+	desc->r_block_bytes = 1 << block_bits;
+	desc->r_start_block = rec->e_blkno;
+	desc->r_blocks = blocks;
+
 leave:
 	if (buf)
 		ocfs2_free(&buf);
+
 	return ret;
 }
 
 errcode_t ocfs2_start_heartbeat(ocfs2_filesys *fs)
 {
 	errcode_t ret;
-	uint32_t block_bits, cluster_bits;
-	uint64_t start_block, num_blocks;
+	struct o2cb_region_desc desc;
 
-	ret = ocfs2_get_heartbeat_params(fs, &block_bits, &cluster_bits,
-					 &start_block, &num_blocks);
+	ret = ocfs2_fill_heartbeat_desc(fs, &desc);	
 	if (ret)
 		goto leave;
 
-	/* clamp to NM_MAX_NODES */
-	if (num_blocks > 254)
-		num_blocks = 254;
-
         /* XXX: NULL cluster is a hack for right now */
-	ret = o2cb_create_heartbeat_region_disk(NULL,
-						fs->uuid_str,
-						fs->fs_devname,
-						1 << block_bits,
-						start_block,
-						num_blocks);
+	ret = o2cb_start_heartbeat_region(NULL, &desc);
 
 leave:
 	return ret;
@@ -113,9 +109,5 @@
 
 errcode_t ocfs2_stop_heartbeat(ocfs2_filesys *fs)
 {
-	errcode_t ret;
-
-	ret = o2cb_remove_heartbeat_region_disk(NULL, fs->uuid_str);
-
-	return ret;
+	return o2cb_stop_heartbeat_region(NULL, fs->uuid_str);
 }

Modified: trunk/libocfs2/include/ocfs2.h
===================================================================
--- trunk/libocfs2/include/ocfs2.h	2005-04-21 05:36:22 UTC (rev 832)
+++ trunk/libocfs2/include/ocfs2.h	2005-04-21 23:35:40 UTC (rev 833)
@@ -539,6 +539,9 @@
 errcode_t ocfs2_file_read(ocfs2_cached_inode *ci, void *buf, uint32_t count,
 			  uint64_t offset, uint32_t *got);
 
+errcode_t ocfs2_fill_heartbeat_desc(ocfs2_filesys *fs,
+				    struct o2cb_region_desc *desc);
+
 errcode_t ocfs2_start_heartbeat(ocfs2_filesys *fs);
 
 errcode_t ocfs2_stop_heartbeat(ocfs2_filesys *fs);

Modified: trunk/mount.ocfs2/mount.ocfs2.c
===================================================================
--- trunk/mount.ocfs2/mount.ocfs2.c	2005-04-21 05:36:22 UTC (rev 832)
+++ trunk/mount.ocfs2/mount.ocfs2.c	2005-04-21 23:35:40 UTC (rev 833)
@@ -57,7 +57,7 @@
 	progname = basename(argv[0]);
 
 	if (argc < 2)
-		goto bail;
+		return;
 
 	while(1) {
 		c = getopt(argc, argv, "vno:t:");
@@ -95,9 +95,6 @@
 
 	if (optind < argc && argv[optind])
 		mo->dir = xstrdup(argv[optind]);
-
-bail:
-	return ;
 }
 
 /*

Modified: trunk/mount.ocfs2/ocfs2_hb_ctl.c
===================================================================
--- trunk/mount.ocfs2/ocfs2_hb_ctl.c	2005-04-21 05:36:22 UTC (rev 832)
+++ trunk/mount.ocfs2/ocfs2_hb_ctl.c	2005-04-21 23:35:40 UTC (rev 833)
@@ -48,13 +48,18 @@
 {
 	errcode_t err;
 	ocfs2_filesys *fs = NULL;
+	struct o2cb_region_desc desc;
 
 	err = ocfs2_open(device, OCFS2_FLAG_RO, 0, 0, &fs);
 	if (err)
 		goto bail;
 
-	err = ocfs2_start_heartbeat(fs);
+	err = ocfs2_fill_heartbeat_desc(fs, &desc);
+	if (err)
+		goto bail;
 
+	err = o2cb_start_heartbeat_region_perm(NULL, &desc);
+
 bail:
 	if (fs)
 		ocfs2_close(fs);
@@ -66,16 +71,29 @@
 {
 	errcode_t err;
 
-	err = o2cb_remove_heartbeat_region_disk(NULL, hbuuid);
+	err = o2cb_stop_heartbeat_region_perm(NULL, hbuuid);
 
 	return err;
 }
 
+static errcode_t print_hb_ref_info(const char *hbuuid)
+{
+	errcode_t err;
+	int num;
+
+	err = o2cb_num_region_refs(hbuuid, &num);
+	if (!err)
+		printf("%s: %d refs\n", hbuuid, num);
+
+	return err;
+}
+
 enum hb_ctl_action {
-	HB_ACTION_UKNOWN,
+	HB_ACTION_UNKNOWN,
 	HB_ACTION_USAGE,
 	HB_ACTION_START,
 	HB_ACTION_STOP,
+	HB_ACTION_REFINFO,
 };
 
 struct hb_ctl_options {
@@ -84,15 +102,14 @@
 	char *uuid_str;
 };
 
-static void read_options(int argc, char **argv, struct hb_ctl_options *hbo)
+static int read_options(int argc, char **argv, struct hb_ctl_options *hbo)
 {
-	int c;
+	int c, ret;
 
-	if (argc < 4)
-		return;
+	ret = 0;
 
 	while(1) {
-		c = getopt(argc, argv, "SKd:u:h");
+		c = getopt(argc, argv, "ISKd:u:h");
 		if (c == -1)
 			break;
 
@@ -119,10 +136,19 @@
 				hbo->uuid_str = strdup(optarg);
 			break;
 
+		case 'I':
+			hbo->action = HB_ACTION_REFINFO;
+			break;
+
+		case '?':
+		case ':':
 		default:
+			ret = -1;
 			break;
 		}
 	}
+
+	return ret;
 }
 
 static int process_options(struct hb_ctl_options *hbo)
@@ -143,7 +169,14 @@
 			ret = -EINVAL;
 		break;
 
-	case HB_ACTION_UKNOWN:
+	case HB_ACTION_REFINFO:
+		/* Refinfo needs uuid or device */
+		if ((hbo->uuid_str && hbo->dev_str) ||
+		    (!hbo->uuid_str && !hbo->dev_str))
+			ret = -EINVAL;
+		break;
+
+	case HB_ACTION_UNKNOWN:
 		ret = -EINVAL;
 		break;
 
@@ -162,6 +195,8 @@
 	fprintf(output, "Usage: %s -S -d <device>\n", progname);
 	fprintf(output, "       %s -K -d <device>\n", progname);
 	fprintf(output, "       %s -K -u <uuid>\n", progname);
+	fprintf(output, "       %s -I -d <device>\n", progname);
+	fprintf(output, "       %s -I -u <uuid>\n", progname);
 	fprintf(output, "       %s -h\n", progname);
 }
 
@@ -169,14 +204,18 @@
 {
 	errcode_t err = 0;
 	int ret = 0;
-	struct hb_ctl_options hbo = { HB_ACTION_UKNOWN, NULL, NULL };
+	struct hb_ctl_options hbo = { HB_ACTION_UNKNOWN, NULL, NULL };
 	char hbuuid[33];
 
 	initialize_ocfs_error_table();
 	initialize_o2dl_error_table();
 	initialize_o2cb_error_table();
 
-	read_options(argc, argv, &hbo);
+	ret = read_options(argc, argv, &hbo);
+	if (ret) {
+		print_usage(1);
+		goto bail;
+	}
 
 	ret = process_options(&hbo);
 	if (ret) {
@@ -184,6 +223,11 @@
 		goto bail;
 	}
 
+	if (hbo.action == HB_ACTION_USAGE) {
+		print_usage(0);
+		goto bail;
+	}
+
 	if (!hbo.uuid_str) {
 		err = get_uuid(hbo.dev_str, hbuuid);
 		if (err) {
@@ -217,6 +261,14 @@
 		}
 		break;
 
+	case HB_ACTION_REFINFO:
+		err = print_hb_ref_info(hbo.uuid_str);
+		if (err) {
+			com_err(progname, err, "while reading reference counts");
+			ret = -EINVAL;
+		}
+		break;
+
 	default:
 		abort();
 	}

Modified: trunk/ocfs2console/ocfs2interface/o2cbmodule.c
===================================================================
--- trunk/ocfs2console/ocfs2interface/o2cbmodule.c	2005-04-21 05:36:22 UTC (rev 832)
+++ trunk/ocfs2console/ocfs2interface/o2cbmodule.c	2005-04-21 23:35:40 UTC (rev 833)
@@ -212,6 +212,7 @@
   return node_new (self, node_name);
 }
 
+#if 0
 static PyObject *
 cluster_create_heartbeat_region_disk (Cluster  *self,
 				      PyObject *args,
@@ -264,11 +265,11 @@
   Py_INCREF (Py_None);
   return Py_None;
 }
-
+#endif
 static PyMethodDef cluster_methods[] = {
   {"add_node", (PyCFunction)cluster_add_node, METH_VARARGS | METH_KEYWORDS},
-  {"create_heartbeat_region_disk", (PyCFunction)cluster_create_heartbeat_region_disk, METH_VARARGS | METH_KEYWORDS},
-  {"remove_heartbeat_region_disk", (PyCFunction)cluster_remove_heartbeat_region_disk, METH_VARARGS | METH_KEYWORDS},
+//  {"create_heartbeat_region_disk", (PyCFunction)cluster_create_heartbeat_region_disk, METH_VARARGS | METH_KEYWORDS},
+//  {"remove_heartbeat_region_disk", (PyCFunction)cluster_remove_heartbeat_region_disk, METH_VARARGS | METH_KEYWORDS},
   {NULL, NULL}
 };
 
@@ -442,6 +443,7 @@
   return list;
 }
 
+#if 0
 static PyObject *
 create_heartbeat_region_disk (PyObject *self,
 			      PyObject *args,
@@ -491,6 +493,7 @@
   Py_INCREF (Py_None);
   return Py_None;
 }
+#endif
 
 static PyObject *
 get_hb_ctl_path (PyObject *self)
@@ -505,8 +508,8 @@
 
 static PyMethodDef o2cb_methods[] = {
   {"list_clusters", (PyCFunction)list_clusters, METH_NOARGS},
-  {"create_heartbeat_region_disk", (PyCFunction)create_heartbeat_region_disk, METH_VARARGS | METH_KEYWORDS},
-  {"remove_heartbeat_region_disk", (PyCFunction)remove_heartbeat_region_disk, METH_VARARGS | METH_KEYWORDS},
+//  {"create_heartbeat_region_disk", (PyCFunction)create_heartbeat_region_disk, METH_VARARGS | METH_KEYWORDS},
+//  {"remove_heartbeat_region_disk", (PyCFunction)remove_heartbeat_region_disk, METH_VARARGS | METH_KEYWORDS},
   {"get_hb_ctl_path", (PyCFunction)get_hb_ctl_path, METH_NOARGS},
   {NULL,       NULL}    /* sentinel */
 };



More information about the Ocfs2-tools-commits mailing list