[ogfs-dev]Patch for integrating OpenDLM into OpenGFS
Hi, folks
Following is the patch support OpenDLM (with HOWTO and design doc).
Please give me your feedback :)
BTW, I will check all codes into cvs if there is not big problem in it.
Thanks!
Best Regards,
Stan
--
Opinions expressed are those of the author and do not represent Intel
Corporation
"gpg --recv-keys --keyserver wwwkeys.pgp.net E1390A7F"
{E1390A7F:3AD1 1B0C 2019 E183 0CFF 55E8 369A 8B75 E139 0A7F}
diff -Naur opengfs/configure.ac opengfs-opendlm/configure.ac
--- opengfs/configure.ac 2003-07-29 18:19:46.000000000 +0800
+++ opengfs-opendlm/configure.ac 2003-09-24 11:11:01.000000000 +0800
@@ -383,6 +383,20 @@
exec_prefix="";
fi
+AC_ARG_ENABLE(
+ opendlm,
+ [ --enable-opendlm Using opendlm],
+ [enable_opendlm=true])
+
+AM_CONDITIONAL(ENABLE_OPENDLM, test x$enable_opendlm = xtrue)
+
+dnl get the opendlm includes path.
+
+AC_ARG_WITH(opendlm_includes,
+ [ --with-opendlm_includes=DIR dir for your opendlm package],
+ opendlm_includes="$withval")
+AC_SUBST(opendlm_includes)
+
dnl default CFLAGS, can be overridden on command line
dnl dv (29-Jul-2003): This nukes debugging and is confusing. Let the
person
dnl who builds the package decide about optimisation.
@@ -437,6 +451,7 @@
src/locking/modules/memexp/Makefile
src/locking/modules/nolock/Makefile
src/locking/modules/stats/Makefile
+ src/locking/modules/opendlm/Makefile
src/locking/servers/Makefile
src/locking/servers/memexp/Makefile
src/pool/Makefile
diff -Naur opengfs/docs/HOWTO-opendlm opengfs-opendlm/docs/HOWTO-opendlm
--- opengfs/docs/HOWTO-opendlm 1970-01-01 08:00:00.000000000 +0800
+++ opengfs-opendlm/docs/HOWTO-opendlm 2003-09-24 11:11:18.000000000
+0800
@@ -0,0 +1,132 @@
+HOWTO use OpenDLM as the locking manager (V0.01)
+
+This document descries how to use OpenDLM as the locking mangaer in
+an OpenGFS cluster. It provides a simple example configuration for
+a 2 nodes cluster. In order to understand this example, you also
+need to read some documents from OpenGFS(HOWTO-nopool), OpenDLM
+and HA heartbeat.
+
+BUILDING AND INSTALLING LOCKING MODULE FOR OPENDLM
+--------------------------------------------------
+
+1. Get HA heartbeat, OpenDLM and OpenGFS' source codes from:
+ http://www.linux-ha.org/heartbeat/
+ http://www.sf.net/projects/opendlm/
+ http://www.sf.net/projects/opengfs/
+
+2. Build and install HA heartbeat, OpenDLM.(For more information,
+please read the documents from these two projects).
+
+3. Patch your kernel and reboot:
+ Please read section 1.b in HOWTO-nopool
+
+4. Build OpenGFS:
+ ./bootstrap
+ ./configure --enable-opendlm --with-opendlm_includes=/YOUR/PATH
+ make
+ make install
+ depmod -a
+
+5. Insert OpenGFS module:
+ modprobe ogfs
+
+6. Partition the shared drive:
+ Please read section 5 in HOWTO-nopool
+
+7. Make the OpenGFS Filesystem
+ Please read section 6 in HOWTO-nopool first.
+
+ In order to use OpenDLM as the locking manager, we need
+specify the locking protocol as "opendlm" when we make the filesystem.
+
+ mkfs.ogfs -p opendlm -t /dev/sdx1 -c journal.cf
+
+8. Configure the OpdnGFS Cluster.
+ Please read section 7 in HWWTO-nopool first.
+
+ # cat ogfscf.cf
+
+ datadev: /dev/sdx3
+ cidev: /dev/sdx1
+ lockdev: 192.168.0.37:15697
+ cbport: 3001
+
+ timeout: 30
+ STOMITH: manual
+ name: manual
+
+ node: 192.168.0.37 0 SM: manual 1
+ node: 192.168.0.203 1 SM: manual 2
+
+ NOTE: a. The "lockdev" and "cbport" in "ogfscf.cf" are useless now.
+ b. The order of nodes is important, it should be the same in
+ OpenDLM's config file.
+
+9. Configure HA heartbeat and OpenDLM
+ For more detailed information, please read HA heartbeat and OpenDLM's
+ documents.
+
+ #cat /etc/ha.d/ha.cf
+
+ debugfile /var/log/ha-debug
+ logfile /var/log/ha-log
+ logfacility local0
+ bcast eth0 # Linux
+ node wv1 #192.168.0.37
+ node wv2 #192.168.0.203
+
+ NOTE: ha.cf should be same in these two nodes.
+
+ #cat /etc/dlm.conf
+
+ NODECOUNT 2
+ 1 wv1 192.168.0.37
+ 2 wv2 192.168.0.203
+ DLMNAME haDLM
+ DLMMAJOR 250
+ DLMCMGR heartbeat
+ DLMADMIN admin 0
+ DLMLOCKS locks 1
+
+ NOTE: a. dlm.conf should be same in these two nodes
+ b. The order of nodes is important, it should be the same in
+ OpenGFS's config file.
+
+10. Start locking service
+
+ Start HA heartbeat:
+
+ On wv1: #/etc/init.d/heartbeat start
+ On wv2: #/etc/init.d/heartbeat start
+
+ Start OpenDLM:
+
+ On wv1: #dlmdu -C /etc/dlm.conf
+ On wv2: #dlmdu -C /etc/dlm.conf
+
+11. Mount the File system:
+
+ a. Insert the locking module:
+ modprobe libdlmk
+ modprobe opendlm
+
+ b. Mkdir and mount file system:
+ mkdir /ogfs
+ mount -t ogfs /dev/sdx3 /ogfs -o hostdate=192.168.0.x
+
+SHUTTING DOWN CLEANLY
+---------------------
+
+1. Unmount file system:
+ umount /ogfs
+
+2. Stop OpenDLM and HA heartbeat:
+ killall dlmdu
+ /etc/init.d/heartbeat stop
+
+3. Unload the modules:
+ modprobe -r opendlm
+ modprobe -r ogfs
+ modprobe -r libdlmk
+ modprobe -r dlmdk.core
+
diff -Naur opengfs/docs/opendlm2glock opengfs-opendlm/docs/opendlm2glock
--- opengfs/docs/opendlm2glock 1970-01-01 08:00:00.000000000 +0800
+++ opengfs-opendlm/docs/opendlm2glock 2003-09-24 11:11:28.000000000
+0800
@@ -0,0 +1,137 @@
+Map OpenDLM to G-lock (V0.01)
+
+This document describes the implementation details of the OpenDLM
locking module.
+You could find corresponding codes at src/locking/modules/opendlm/.
+
+1. How to implement all "lm_lockops".
+
+Fields in struct lm_lockops:
+
+* mount
+ Do almost same things as memexp locking module's mount function.
First, this
+ function uses a hash value(hash the cidev's name) as ID of an ogfs
instance.
+ Then this function reads cidev to get all cluster configuration
information.
+ At last, this function initializes deadman lock and return the
lockspace
+ structure.
+
+ lockspace:
+ Get lockspace basing on cidev(because different ogfs instants
+ using different cidev). Record lockspace and node's information(such
as
+ CB, fsdata, etc) in a private data sturct.
+
+ Following is the definition of lockspace structure:
+
+ struct opendlm {
+ struct list_head list;
+ char table_name[256];
+ uint32 name_space; /* hash value of
table_name */
+ lm_callback_t cb;
+ lm_fsdata_t *fsdata;
+
+ struct file *cfile;
+ unsigned int jid;
+ unsigned int nodes_count;
+ struct opendlm_lock *mount_lock;
+ struct list_head deadman;
+ };
+
+
+
+ ls_jid:
+ Get it by reading cidev.
+
+ ls_first:
+ Determined by using deadman lock. The first node grabs the mount lock
and
+ blocks all other nodes untile "others_may_mount" is called.
+
+
+*others_may_mount
+ Release the mount lock.
+
+*unmount
+ Clean up all data struct.
+
+*get_lock
+ Allocate and initialize a private lock struct.
+
+*put_lock
+ Clean and free a private lock struct.
+
+*lock
+ Do the lock operation.
+ Lock state translation:
+ LM_ST_UNLOCKED -> NL
+ LM_ST_EXCLUSIVE -> EX
+ LM_ST_SHARED -> PR
+ LM_ST_DEFERRED -> CW
+
+ Lock flag translation:
+ LM_FLAG_TRY -> LKM_NOQUEUE
+ LM_FLAG_NOEXP -> purge this lock first
+
+ Note: Shared locks are treated non-persistent.
+ Exclusive locks are treated persistent.
+
+*unlock
+ Do the unlock operation
+
+*reset
+ Do the unlock operation.
+
+*cancel
+ Cancel a lock/convert request.
+
+*hold_lvb
+ Specify LKM_VALBLK in all lock operations.
+
+ Note: The default size of lvb in OpenDLM is 16 bytes, we need to
change
+ it to 32bytes.
+
+*unhold_lvb
+ N/A
+
+*sync_lvb
+ N/A
+
+*reset_exp
+ Purge all locks that hold by the failed node.
+
+
+Fields in struct lm_lockstruct
+
+*ls_jid
+See previous section.
+
+*ls_first
+See previous section.
+
+*ls_lockspace
+See previous section.
+
+*ls_ops
+See previous section.
+
+
+2. Private lock structure and lock name.
+Following is the definition of private lock structure:
+
+struct opendlm_lock {
+ struct opendlm_lockname lockname;
+ struct lockstatus lksb; /* Lock status block for
OpenDLM*/
+ lm_lvb_t *lvb; /* Lock value block */
+ struct opendlm *dlm;
+ int done; /* Used to implement the
synchronizing lock operations*/
+};
+
+Following is the definition of lock name:
+
+#define OGFS_DLM_MAGICLEN 4
+#define OGFS_DLM_MAGIC "OGFS"
+
+struct opendlm_lockname {
+ uint64 lock_num; /*lock number*/
+ uint32 name_space;
+ unsigned int lock_type;
+ char magic[OGFS_DLM_MAGICLEN];
+}__attribute__((packed));
+
diff -Naur opengfs/src/include/lm_interface.h
opengfs-opendlm/src/include/lm_interface.h
--- opengfs/src/include/lm_interface.h 2003-03-04 18:51:17.000000000
+0800
+++ opengfs-opendlm/src/include/lm_interface.h 2003-09-24
11:13:04.000000000 +0800
@@ -66,6 +66,7 @@
#define LM_TYPE_PLOCK (0x09)
#define LM_TYPE_PLOCK_HEAD (0x0A)
#define LM_TYPE_LVB_MASK (0x80)
+#define LM_TYPE_DEADMAN (0x0B)
/* States passed to lock() */
diff -Naur opengfs/src/locking/modules/Makefile.am
opengfs-opendlm/src/locking/modules/Makefile.am
--- opengfs/src/locking/modules/Makefile.am 2002-09-18
18:20:15.000000000 +0800
+++ opengfs-opendlm/src/locking/modules/Makefile.am 2003-09-24
11:12:00.000000000 +0800
@@ -1,2 +1,7 @@
# -*-Makefile-*-
-SUBDIRS = nolock memexp stats
+if ENABLE_OPENDLM
+opendlmdir = opendlm
+endif
+
+SUBDIRS = nolock memexp stats $(opendlmdir)
+
diff -Naur opengfs/src/locking/modules/opendlm/cluster_config.h
opengfs-opendlm/src/locking/modules/opendlm/cluster_config.h
--- opengfs/src/locking/modules/opendlm/cluster_config.h 1970-01-01
08:00:00.000000000 +0800
+++
opengfs-opendlm/src/locking/modules/opendlm/cluster_config.h 2003-09-24
11:11:46.000000000 +0800
@@ -0,0 +1,57 @@
+/*
+ *
+ * Copyright 1999-2001 Sistina Software, Inc.
+ *
+ * This is free software released under the GNU General Public
License.
+ * There is no warranty for this software. See the file COPYING for
+ * details.
+ *
+ * See the file AUTHORS for a list of contributors.
+ *
+ * This file was maintained by:
+ * David C. Teigland <teigland@sistina.com>
+ *
+ */
+#ifndef _CLUSTER_CONFIG_H
+#define _CLUSTER_CONFIG_H
+
+//#include "ogfs_ondisk.h"
+#include "global.h"
+
+#define OGFS_LOCKNAME_LEN (64)
+
+#define OGFS_CLUSTER_GLOBAL (0x47465341)
+#define OGFS_CLUSTER_NODE (0x47465342)
+
+#define OGFS_CLUSTER_VERSION (0x47010000)
+
+#define CIDEV_BLOCKSIZE (4096)
+
+/* First sector of cidev */
+
+struct cluster_global {
+ uint32 cg_magic; /* magic number */
+ uint32 cg_version; /* version number */
+ char cg_lockdev[64]; /* lock device */
+ char cg_datadev[64]; /* data device */
+ uint32 cg_cbport; /* call-back port */
+ uint32 cg_node_timeout; /* in seconds */
+};
+typedef struct cluster_global cluster_global_t;
+
+/* One struct per sector. Implicit: JID = block - 1 */
+
+struct cluster_node {
+ uint32 cn_magic; /* Magic number */
+ uint32 cn_ipaddr; /* IP address of node */
+ uint32 cn_cid; /* Client ID of node */
+ uint32 cn_num_stomith; /* Number of stomith structs */
+};
+typedef struct cluster_node cluster_node_t;
+
+/* On-disk format translation functions */
+
+void cluster_global_in(struct cluster_global *cg, char *buf);
+void cluster_node_in(struct cluster_node *cn, char *buf);
+
+#endif /* _CLUSTER_CONFIG_H */
diff -Naur opengfs/src/locking/modules/opendlm/cluster_ondisk.c
opengfs-opendlm/src/locking/modules/opendlm/cluster_ondisk.c
--- opengfs/src/locking/modules/opendlm/cluster_ondisk.c 1970-01-01
08:00:00.000000000 +0800
+++
opengfs-opendlm/src/locking/modules/opendlm/cluster_ondisk.c 2003-09-24
11:11:46.000000000 +0800
@@ -0,0 +1,66 @@
+/*
+ *
+ * Copyright 1995-2001 Regents of the University of Minnesota
+ *
+ * This is free software released under the GNU General Public
License.
+ * There is no warranty for this software. See the file COPYING for
+ * details.
+ *
+ * See the file AUTHORS for a list of contributors.
+ *
+ * This file was maintained by:
+ * David C. Teigland <teigland@sistina.com>
+ *
+ */
+
+#include "config.h"
+
+#ifdef __KERNEL__
+#include <linux/module.h>
+#include <linux/string.h>
+#include "osi.h"
+#else /* __KERNEL__ */
+#include <string.h>
+#include "osi_endian.h"
+#endif /* __KERNEL__ */
+
+#include "cluster_config.h"
+
+#define CPIN_8(x, y, z) {memcpy((x), (y), (z));}
+#define CPOUT_8(x, y, z) {memcpy((y), (x), (z));}
+#define CPIN_16(x, y) {(x) = be16_to_cpu((y));}
+#define CPOUT_16(x, y) {(y) = cpu_to_be16((x));}
+#define CPIN_32(x, y) {(x) = be32_to_cpu((y));}
+#define CPOUT_32(x, y) {(y) = cpu_to_be32((x));}
+#define CPIN_64(x, y) {(x) = be64_to_cpu((y));}
+#define CPOUT_64(x, y) {(y) = cpu_to_be64((x));}
+
+
+/* Nothing STOMITH-specific below */
+
+void
+cluster_global_in(cluster_global_t * cg, char *buf)
+{
+ cluster_global_t *bufcg = (cluster_global_t *) buf;
+
+ CPIN_32(cg->cg_magic, bufcg->cg_magic);
+ CPIN_32(cg->cg_version, bufcg->cg_version);
+
+ CPIN_8(cg->cg_lockdev, bufcg->cg_lockdev, OGFS_LOCKNAME_LEN);
+ CPIN_8(cg->cg_datadev, bufcg->cg_datadev, OGFS_LOCKNAME_LEN);
+
+ CPIN_32(cg->cg_cbport, bufcg->cg_cbport);
+ CPIN_32(cg->cg_node_timeout, bufcg->cg_node_timeout);
+}
+
+void
+cluster_node_in(cluster_node_t * cn, char *buf)
+{
+ cluster_node_t *bufcn = (cluster_node_t *) buf;
+
+ CPIN_32(cn->cn_magic, bufcn->cn_magic);
+ CPIN_32(cn->cn_ipaddr, bufcn->cn_ipaddr);
+ CPIN_32(cn->cn_cid, bufcn->cn_cid);
+ CPIN_32(cn->cn_num_stomith, bufcn->cn_num_stomith);
+}
+
diff -Naur opengfs/src/locking/modules/opendlm/deadman.c
opengfs-opendlm/src/locking/modules/opendlm/deadman.c
--- opengfs/src/locking/modules/opendlm/deadman.c 1970-01-01
08:00:00.000000000 +0800
+++ opengfs-opendlm/src/locking/modules/opendlm/deadman.c 2003-09-24
11:11:46.000000000 +0800
@@ -0,0 +1,236 @@
+/* -*- linux-c -*- */
+
+/*
+** Copyright (C) 2003 Stanley Wang <stanley.wang@linux.co.intel.com>
+**
+** 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.
+**
+*/
+
+
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/init.h>
+#include <linux/kmod.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/list.h>
+
+
+#include <lm_interface.h>
+#include "opendlm.h"
+
+#define OGFS_DLM_SUCCESS 0
+#define OGFS_DLM_FAILED 1
+#define OGFS_DLM_NONFIRST 2
+
+struct deadman_lock {
+ struct list_head list;
+ struct opendlm_lock lock;
+};
+
+struct timer_list refresh_timer;
+void deadman_block_others(void *bastargs, int mode);
+
+void ignore_bast(void *bastargs, int mode)
+{
+ return;
+}
+
+void ignore_ast(void *bastargs)
+{
+ return;
+}
+
+void ignore_unlockast(void *unlockastargs, int lstat, void* extrap)
+{
+ return;
+}
+
+void other_node_die(void* bastargs)
+{
+ struct opendlm_lock *lock = (struct opendlm_lock *)bastargs;
+ struct opendlm *dlm = lock->dlm;
+
+ if(!dlm) {
+ err("Can not find failed node!");
+ return;
+ }
+
+ dlm->cb(dlm->fsdata, LM_CB_EXPIRED,
+ (void *)(&lock->lockname.lock_num));
+}
+
+void refresh_deadman_lock(unsigned long arg)
+{
+ struct opendlm_lock *lock = (struct opendlm_lock *)arg;
+
+ del_timer(&refresh_timer);
+
+ dlmunlock(lock->lksb.lockid, NULL, LKM_FORCE, ignore_unlockast, NULL,
NULL);
+
+ dlmlock(LKM_CRMODE, &lock->lksb, 0, (void *)(&lock->lockname),
+ sizeof(struct opendlm_lockname), other_node_die,
+ (void *)lock, deadman_block_others);
+ return;
+}
+
+
+void deadman_block_others(void *bastargs, int mode)
+{
+ init_timer(&refresh_timer);
+
+ refresh_timer.expires = 1*HZ;
+ refresh_timer.data = (unsigned long)bastargs;
+ refresh_timer.function = refresh_deadman_lock;
+
+ add_timer(&refresh_timer);
+
+ return;
+}
+
+void cleanup_deadman_list(struct opendlm *dlm)
+{
+ struct deadman_lock *tmp;
+
+ tmp = list_entry(dlm->deadman.next, typeof(*tmp), list);
+
+ while(&tmp->list != &dlm->deadman){
+ dbg("clean up deadman list");
+
+ dlmunlock(tmp->lock.lksb.lockid, NULL, LKM_FORCE,
+ ignore_unlockast, NULL, NULL);
+ list_del(&tmp->list);
+ kfree(tmp);
+ tmp = list_entry(dlm->deadman.next,
+ typeof(*tmp), list);
+ }
+}
+
+
+int init_deadman(struct opendlm *dlm, int first)
+{
+ unsigned int lock_num;
+ struct deadman_lock *deadman;
+ dlm_stats_t status;
+
+ dbg("enter init_deadman, nodes_count %d!", dlm->nodes_count);
+
+ for(lock_num = 0; lock_num < dlm->nodes_count; lock_num++){
+ deadman = (struct deadman_lock *)kmalloc(sizeof(struct deadman_lock),
GFP_KERNEL);
+ if(!deadman)
+ return OGFS_DLM_FAILED;
+
+ memset(deadman, 0, sizeof(struct deadman_lock));
+
+ strncpy(deadman->lock.lockname.magic, OGFS_DLM_MAGIC,
OGFS_DLM_MAGICLEN);
+ deadman->lock.lockname.name_space = dlm->name_space;
+ deadman->lock.lockname.lock_num = (unsigned long long)lock_num;
+ deadman->lock.lockname.lock_type = LM_TYPE_DEADMAN;
+ deadman->lock.dlm = dlm;
+
+ dbg("before get deadman lock!lksb: %p", &deadman->lock.lksb);
+
+ if(lock_num != dlm->jid){
+ if(first){
+ dbg("first&others");
+ status = my_dlmlock_sync(LKM_EXMODE, &deadman->lock.lksb,
LKM_NOQUEUE, &deadman->lock,
+ deadman_block_others);
+ } else {
+ dbg("non-first&others");
+ status = dlmlock(LKM_CRMODE, &deadman->lock.lksb, 0, (void
*)(&deadman->lock.lockname),
+ sizeof(struct opendlm_lockname), other_node_die,
+ (void *)&deadman->lock, deadman_block_others);
+ }
+ } else {
+ dbg("myself");
+ status = my_dlmlock_sync(LKM_EXMODE, &(deadman->lock.lksb), 0,
&(deadman->lock), ignore_bast);
+ }
+
+ dbg("after get deadman lock!lksb: %p, status %d",
&deadman->lock.lksb, status);
+
+ if(status != DLM_NORMAL){
+ kfree(deadman);
+ return OGFS_DLM_FAILED;
+ }
+
+ dbg("deadman success");
+
+ if(first && deadman->lock.lksb.status != DLM_NORMAL){
+ kfree(deadman);
+ return OGFS_DLM_NONFIRST;
+ }
+
+ list_add(&deadman->list, &dlm->deadman);
+ }
+
+ dbg("exit init deadman!");
+
+ return OGFS_DLM_SUCCESS;
+}
+
+int start_deadman_lock(struct opendlm *dlm, unsigned int *first)
+{
+ int error;
+
+ dbg("enter start deadman!");
+
+ error = grab_mount_lock(dlm);
+ if(error)
+ return -1;
+
+ dbg("grab_mount_lock %d!", error);
+
+ error = init_deadman(dlm, 1);
+
+ dbg("init deadman %d!", error);
+
+ switch (error) {
+
+ case OGFS_DLM_FAILED:
+ cleanup_deadman_list(dlm);
+ release_mount_lock(dlm);
+ return -1;
+
+ case OGFS_DLM_NONFIRST:
+ cleanup_deadman_list(dlm);
+ release_mount_lock(dlm);
+ break;
+ case OGFS_DLM_SUCCESS:
+ *first = TRUE;
+ return 0;
+ }
+
+ *first = FALSE;
+ error = init_deadman(dlm, 0);
+
+ dbg("2nd init deadman %d!", error);
+
+ if(error == OGFS_DLM_FAILED){
+ cleanup_deadman_list(dlm);
+ release_mount_lock(dlm);
+ return -1;
+ }
+
+ dbg("exit start deadman!");
+
+ return 0;
+}
+
+int stop_deadman_lock(struct opendlm *dlm)
+{
+ cleanup_deadman_list(dlm);
+ return 0;
+}
diff -Naur opengfs/src/locking/modules/opendlm/dlm.c
opengfs-opendlm/src/locking/modules/opendlm/dlm.c
--- opengfs/src/locking/modules/opendlm/dlm.c 1970-01-01
08:00:00.000000000 +0800
+++ opengfs-opendlm/src/locking/modules/opendlm/dlm.c 2003-09-24
11:11:46.000000000 +0800
@@ -0,0 +1,343 @@
+/* -*- linux-c -*- */
+
+/*
+** Copyright (C) 2003 Stanley Wang <stanley.wang@linux.co.intel.com>
+**
+** 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.
+**
+*/
+
+/* Some codes are copied from Sistina Software Inc's GFS */
+
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/kmod.h>
+#include <linux/list.h>
+
+#include <lm_interface.h>
+#include "opendlm.h"
+
+int debug=0;
+MODULE_PARM(debug, "i");
+
+LIST_HEAD(dlm_list);
+struct lm_lockops opendlm_ops;
+
+lm_lockspace_t *opendlm_mount(char *table_name, char *host_data,
lm_callback_t cb,
+ lm_fsdata_t * fsdata,unsigned int *jid, unsigned int *first)
+{
+ struct opendlm *dlm;
+ char name[256];
+ uint32 ip;
+ uint32 hash;
+ int error;
+
+ dbg("enter mount!");
+
+ MOD_INC_USE_COUNT;
+
+ name[255] = '\0';
+ strncpy(name, table_name, 255);
+ hash = locktable_hash(table_name, strlen(table_name));
+
+ inet_aton(host_data, &ip);
+
+ /* Check to make sure this lock table isn't already being used */
+
+ dbg("find_dlm! table_name %s hash %d", table_name, hash);
+ dlm = find_dlm(hash);
+ if(dlm) {
+ err("\"%s\" encount a name space collision", name);
+ goto fail;
+ }
+
+ /* Set up our main structure */
+
+ dlm = (struct opendlm *)kmalloc(sizeof(struct opendlm), GFP_KERNEL);
+ if (!dlm) {
+ err("out of memory");
+ goto fail;
+ }
+ memset(dlm, 0, sizeof(struct opendlm));
+
+ strcpy(dlm->table_name, name);
+
+ dlm->cb = cb;
+ dlm->fsdata = fsdata;
+ dlm->name_space = hash;
+ INIT_LIST_HEAD(&dlm->deadman);
+
+ dbg("file open!");
+
+ dlm->cfile = filp_open(name, O_RDONLY, 0);
+ if (IS_ERR(dlm->cfile)) {
+ err("open error %ld", PTR_ERR(dlm->cfile));
+ dlm->cfile = NULL;
+ }
+ if (!dlm->cfile) {
+ err("can't open cidev %s", name);
+ goto fail_free_dlm;
+ }
+
+ if (!S_ISBLK(dlm->cfile->f_dentry->d_inode->i_mode)) {
+ err("cidev %s is not a blockdevice", name);
+ goto fail_free_dlm;
+ }
+
+ /* Get information from cidev */
+
+ dbg("setup jid!");
+
+ error = setup_jid(dlm, ip);
+ if (error) {
+ err("bad parameters from %s", name);
+ goto fail_dput;
+ }
+ *jid = dlm->jid;
+
+ /* Wait for possible mount state recovery */
+
+ dbg("start deadman lock!");
+
+ error = start_deadman_lock(dlm, first);
+ if (error < 0) {
+ err("start deadman lock failed (%d)", error);
+ goto fail_dput;
+ }
+
+ list_add(&dlm->list, &dlm_list);
+
+ dbg("normal exit!");
+
+ return ((lm_lockspace_t *) dlm);
+
+fail_dput:
+ filp_close(dlm->cfile, NULL);
+
+fail_free_dlm:
+ kfree(dlm);
+
+fail:
+ MOD_DEC_USE_COUNT;
+
+ err("failed exit!");
+
+ return (NULL);
+}
+
+void opendlm_others_may_mount(lm_lockspace_t * lockspace)
+{
+ /*unlock mount lock*/
+ release_mount_lock((struct opendlm *)lockspace);
+}
+
+void opendlm_unmount(lm_lockspace_t * lockspace)
+{
+ struct opendlm *dlm = (struct opendlm *)lockspace;
+ struct opendlm *tmp;
+ int done = FALSE;
+
+ list_for_each_entry(tmp, &dlm_list, list)
+ if (tmp == dlm) {
+ list_del(&dlm->list);
+ done = TRUE;
+ break;
+ }
+
+ if(!done) {
+ err("given a weird lockspace pointer");
+ } else {
+ stop_deadman_lock(dlm);
+ filp_close(dlm->cfile, NULL);
+ kfree(dlm);
+ }
+ MOD_DEC_USE_COUNT;
+}
+
+lm_lock_t *opendlm_get_lock(lm_lockspace_t * lockspace, lm_lockname_t *
name)
+{
+ struct opendlm_lock *lock;
+ struct opendlm *dlm = (struct opendlm *)lockspace;
+
+ lock = (struct opendlm_lock *)kmalloc(sizeof(struct opendlm_lock),
GFP_KERNEL);
+ if(!lock)
+ goto lock_failed;
+
+ memset(lock, 0, sizeof(struct opendlm_lock));
+
+ lock->lvb = (lm_lvb_t *)kmalloc(sizeof(lm_lvb_t), GFP_KERNEL);
+
+ if(lock->lvb == NULL)
+ goto lvb_failed;
+
+ lock->lvb->lvb_data = (char *)&lock->lksb.value;
+ lock->lvb->lvb_length = MAXLOCKVAL;
+
+ strncpy(lock->lockname.magic, OGFS_DLM_MAGIC, OGFS_DLM_MAGICLEN);
+ lock->lockname.name_space = dlm->name_space;
+ lock->lockname.lock_type = name->ln_type;
+ lock->lockname.lock_num = name->ln_number;
+ lock->dlm = dlm;
+ lock->done = 0;
+
+ return (lm_lock_t *)lock;
+
+ lvb_failed:
+ kfree(lock);
+ lock_failed:
+ return NULL;
+}
+
+void opendlm_put_lock(lm_lock_t * lk)
+{
+ struct opendlm_lock *lock = (struct opendlm_lock *)lk;
+ kfree(lock->lvb);
+ kfree(lock);
+}
+
+int opendlm_lock(lm_lock_t * lk, unsigned int cur_state, unsigned int
req_state,
+ unsigned int flags)
+{
+ dlm_stats_t status;
+ struct opendlm_lock *lock = (struct opendlm_lock *)lk;
+ int node_id = lock->dlm->jid + 1; /* node_id = jid+1; specified in
config file*/
+ int lockmode = 0;
+ int lockflags = 0;
+
+ dbg("lock number %Ld", lock->lockname.lock_num);
+
+ parse_lockreq(cur_state, req_state, &lockmode, &lockflags);
+
+ if (flags | LM_FLAG_TRY){
+ lockflags |= LKM_NOQUEUE;
+ }
+
+ if (flags | LM_FLAG_NOEXP) {
+ dlm_purge(node_id, 0, 0);
+ }
+
+ lockflags |= LKM_VALBLK;
+
+ status = my_dlmlock_sync(lockmode, &lock->lksb, lockflags, (void
*)lock, block_others);
+
+ if(status != DLM_NORMAL) {
+ err("opendlm_lock invalid param");
+ goto fail;
+ }
+
+ if(lock->lksb.status != DLM_NORMAL) {
+ dbg("opendlm_lock can't grab lock, status %d", lock->lksb.status);
+ goto fail;
+ }
+
+ return req_state;
+
+ fail:
+ if (status == DLM_CANCEL)
+ return OPENDLM_CANCELED;
+
+ if (lock->lksb.status == DLM_NOTQUEUED)
+ return OPENDLM_TRYFAILED;
+
+ return -1;
+}
+
+int opendlm_unlock(lm_lock_t * lk, unsigned int cur_state)
+{
+ struct opendlm_lock *lock = (struct opendlm_lock *)lk;
+
+ dlmunlock(lock->lksb.lockid, lock->lvb->lvb_data,
LKM_FORCE|LKM_VALBLK,
+ ignore_unlockast, NULL, NULL);
+
+ return 0;
+}
+
+int opendlm_reset(lm_lock_t * lk)
+{
+ struct opendlm_lock *lock = (struct opendlm_lock *)lk;
+
+ dlmunlock(lock->lksb.lockid, NULL, LKM_FORCE,
+ ignore_unlockast, NULL, NULL);
+
+ return 0;
+}
+
+void opendlm_cancel(lm_lock_t * lk, int on)
+{
+ struct opendlm_lock *lock = (struct opendlm_lock *)lk;
+
+ dlmunlock(lock->lksb.lockid, NULL, LKM_CANCEL,
+ ignore_unlockast, NULL, NULL);
+}
+
+lm_lvb_t *opendlm_hold_lvb(lm_lock_t * lk)
+{
+ struct opendlm_lock *lock = (struct opendlm_lock *)lk;
+
+ return lock->lvb;
+}
+
+void opendlm_unhold_lvb(lm_lock_t * lk, lm_lvb_t * lvb)
+{
+ return;
+}
+
+void opendlm_sync_lvb(lm_lock_t * lk, lm_lvb_t * lvb)
+{
+ return;
+}
+
+void opendlm_reset_exp(lm_lockspace_t * lockspace, unsigned int jid)
+{
+ dlm_purge(jid+1, 0, 0);
+}
+
+struct lm_lockops opendlm_ops = {
+ proto_name: PROTO_NAME,
+ mount: opendlm_mount,
+ others_may_mount: opendlm_others_may_mount,
+ unmount: opendlm_unmount,
+ get_lock: opendlm_get_lock,
+ put_lock: opendlm_put_lock,
+ lock: opendlm_lock,
+ unlock: opendlm_unlock,
+ reset: opendlm_reset,
+ cancel: opendlm_cancel,
+ hold_lvb: opendlm_hold_lvb,
+ unhold_lvb: opendlm_unhold_lvb,
+ sync_lvb: opendlm_sync_lvb,
+ reset_exp: opendlm_reset_exp,
+};
+
+
+int opendlm_start(void)
+{
+ return lm_register_proto(&opendlm_ops);
+}
+
+void opendlm_stop(void)
+{
+ return lm_unregister_proto(&opendlm_ops);
+}
+
+module_init(opendlm_start);
+module_exit(opendlm_stop);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Stanley Wang");
+MODULE_DESCRIPTION("Locking module for using OpenDLM");
diff -Naur opengfs/src/locking/modules/opendlm/Makefile.am
opengfs-opendlm/src/locking/modules/opendlm/Makefile.am
--- opengfs/src/locking/modules/opendlm/Makefile.am 1970-01-01
08:00:00.000000000 +0800
+++ opengfs-opendlm/src/locking/modules/opendlm/Makefile.am 2003-09-24
11:11:46.000000000 +0800
@@ -0,0 +1,27 @@
+# -*-Makefile-*-
+
+#
+# Copyright 2001 The OpenGFS Project
+#
+# This is free software released under the GNU General Public
License.
+# There is no warranty for this software. See the file COPYING for
+# details.
+#
+# See the file AUTHORS for a list of contributors.
+#
+
+EXTRA_INCL = \
+ -I$(top_srcdir)/src/fs -I$(top_srcdir)/src/pool \
+ -I$(top_srcdir)/src/stomith/module \
+ -I$(opendlm_includes)
+
+include $(top_srcdir)/make/modules.mk
+
+module_PROGRAMS = opendlm.o
+opendlm_o_SOURCES = dlm.c deadman.c misc.c cluster_ondisk.c
cluster_config.h opendlm.h
+
+EXEEXT =
+opendlm.o$(EXEEXT): $(opendlm_o_OBJECTS)
+ $(KLD) -r $^ -o $@
+
+
diff -Naur opengfs/src/locking/modules/opendlm/misc.c
opengfs-opendlm/src/locking/modules/opendlm/misc.c
--- opengfs/src/locking/modules/opendlm/misc.c 1970-01-01
08:00:00.000000000 +0800
+++ opengfs-opendlm/src/locking/modules/opendlm/misc.c 2003-09-24
11:11:46.000000000 +0800
@@ -0,0 +1,428 @@
+/* -*- linux-c -* */
+
+/*
+** Copyright (C) 2003 Stanley Wang <stanley.wang@linux.co.intel.com>
+**
+** 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.
+**
+*/
+
+
+/* Some codes are copied from Sistina Software Inc's GFS */
+
+
+#include <linux/module.h>
+#include <linux/version.h>
+#include <linux/init.h>
+#include <linux/kmod.h>
+#include <linux/kernel.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/sched.h>
+#include <linux/list.h>
+#include <linux/kdev_t.h>
+#include <linux/timer.h>
+
+#include <lm_interface.h>
+#include <cluster_config.h>
+#include <crc.h>
+#include "opendlm.h"
+
+struct cb_args
+{
+ void *bastargs;
+ int mode;
+};
+
+
+struct opendlm *find_dlm(uint32 namespace)
+{
+ struct opendlm *tmp;
+
+ list_for_each_entry(tmp, &dlm_list, list) {
+ if (tmp->name_space == namespace) {
+ return tmp;
+ }
+ }
+ return NULL;
+}
+
+
+int setup_jid(struct opendlm *dlm, uint32 ip)
+{
+ struct buffer_head *bh;
+ cluster_global_t cg;
+ cluster_node_t cn;
+ int block = 0, found = 0;
+ kdev_t dev;
+
+ dev = dlm->cfile->f_dentry->d_inode->i_rdev;
+ set_blocksize(dev, CIDEV_BLOCKSIZE);
+
+ bh = bread(dev, 0, CIDEV_BLOCKSIZE);
+ if (!bh) {
+ err("can't read Cluster Information Device");
+ return (-1);
+ }
+
+ cluster_global_in(&cg, bh->b_data);
+
+ if (cg.cg_magic != OGFS_CLUSTER_GLOBAL) {
+ mark_buffer_uptodate(bh, FALSE);
+ brelse(bh);
+ return (-1);
+ }
+
+ if ((((cg.cg_version >> 16) & 0xff) !=
+ ((OGFS_CLUSTER_VERSION >> 16) & 0xff))
+ || (((cg.cg_version >> 8) & 0xff) !=
+ ((OGFS_CLUSTER_VERSION >> 8) & 0xff))) {
+ mark_buffer_uptodate(bh, FALSE);
+ brelse(bh);
+ err("version mismatch: cidev (%u, %u), memexp (%u, %u)",
+ (cg.cg_version >> 16) & 0xff,
+ (cg.cg_version >> 8) & 0xff,
+ (OGFS_CLUSTER_VERSION >> 16) & 0xff,
+ (OGFS_CLUSTER_VERSION >> 8) & 0xff);
+ return (-1);
+ }
+
+ mark_buffer_uptodate(bh, FALSE);
+ brelse(bh);
+
+ block++;
+
+ /* Read cluster info */
+
+ while (1) {
+ bh = bread(dev, block, CIDEV_BLOCKSIZE);
+
+ if (!bh) {
+ err("error reading Cluster Information Device.");
+ goto fail;
+ }
+
+ cluster_node_in(&cn, bh->b_data);
+
+ if (cn.cn_magic == OGFS_CLUSTER_GLOBAL) { /* end of the configured
nodes */
+ mark_buffer_uptodate(bh, FALSE);
+ brelse(bh);
+ break;
+ }
+
+ if (cn.cn_magic != OGFS_CLUSTER_NODE) /* a node was removed from the
config */
+ goto next;
+
+ if (cn.cn_ipaddr == ip) { /* our own config block */
+ dlm->jid = block - 1;
+ found = TRUE;
+ }
+
+ next:
+ mark_buffer_uptodate(bh, FALSE);
+ brelse(bh);
+ block++;
+ }
+
+ if (!found) {
+ char ipstr[16];
+ inet_ntoa(ip, ipstr);
+ err("no cluster info for %s", ipstr);
+ goto fail_2;
+ }
+
+ dlm->nodes_count = block - 1;
+
+ return (0);
+
+ fail:
+
+ if (bh) {
+ mark_buffer_uptodate(bh, FALSE);
+ brelse(bh);
+ }
+
+ fail_2:
+
+ return (-1);
+}
+
+int grab_mount_lock(struct opendlm *dlm)
+{
+ struct opendlm_lock *lock;
+ dlm_stats_t status;
+
+ lock = (struct opendlm_lock *)kmalloc(sizeof(struct opendlm_lock),
GFP_KERNEL);
+
+ if(!lock)
+ return -1;
+
+ memset(lock, 0, sizeof(struct opendlm_lock));
+
+ strncpy(lock->lockname.magic, OGFS_DLM_MAGIC, OGFS_DLM_MAGICLEN);
+ lock->lockname.name_space = dlm->name_space;
+ lock->lockname.lock_type = LM_TYPE_MOUNT;
+ lock->lockname.lock_num = 0;
+ lock->dlm = dlm;
+
+ status = my_dlmlock_sync(LKM_EXMODE, &lock->lksb, 0, lock,
ignore_bast);
+
+ if(status != DLM_NORMAL)
+ return -1;
+
+ if(lock->lksb.status != DLM_NORMAL)
+ return -1;
+
+ dlm->mount_lock = lock;
+
+ return 0;
+}
+
+void release_mount_lock(struct opendlm *dlm)
+{
+ dlmunlock(dlm->mount_lock->lksb.lockid, NULL, LKM_FORCE,
ignore_unlockast, NULL, NULL);
+ kfree(dlm->mount_lock);
+}
+
+void parse_lockreq(unsigned int cur_state, unsigned int req_state, int
*lockmode, int *lockflags)
+{
+ if(cur_state != LM_ST_UNLOCKED) {
+ *lockflags |= LKM_CONVERT;
+ }
+
+ switch(req_state){
+ case LM_ST_EXCLUSIVE:
+ *lockmode = LKM_EXMODE;
+ *lockflags |= LKM_ORPHAN;
+ break;
+ case LM_ST_SHARED:
+ *lockmode = LKM_PRMODE;
+ break;
+ case LM_ST_DEFERRED:
+ *lockmode = LKM_CWMODE;
+ break;
+ default:
+ err("Invalid lock state %d", req_state);
+ }
+}
+
+
+void lock_ast(void *astarg)
+{
+ struct opendlm_lock *lock = (struct opendlm_lock *)astarg;
+ dbg("enter lock_ask");
+
+ lock->done = 1;
+
+ dbg("exit lock_ast");
+}
+
+
+dlm_stats_t my_dlmlock_sync(int mode, struct lockstatus *lksb, int
flags,
+ struct opendlm_lock *lock, dlm_bastlockfunc_t * bast)
+{
+ dlm_stats_t status;
+ dbg("enter my_dlmlock_sync");
+
+ dbg("mode %d lksb %p flags %d lockname %s lock %p", mode, lksb, flags,
(char *)(&lock->lockname), lock);
+ status = dlmlock(mode, lksb, flags, (void *)(&lock->lockname),
+ sizeof(struct opendlm_lockname), lock_ast,
+ (void *)lock, bast);
+
+ dbg("after dlmlock");
+
+ if(status != DLM_NORMAL)
+ goto out;
+
+ sleep:
+ if(!lock->done) {
+ current->policy |= SCHED_YIELD;
+ schedule();
+ goto sleep;
+ }
+
+ lock->done = 0;
+
+ out:
+ return status;
+}
+
+
+
+
+void opendlm_cb(void *args)
+{
+ struct cb_args *p = (struct cb_args *)args;
+ struct opendlm_lock *lock = (struct opendlm_lock *)(p->bastargs);
+ struct tq_struct *tqp = container_of(args, struct tq_struct, data);
+ lm_lockname_t name;
+
+
+ name.ln_type = lock->lockname.lock_type;
+ name.ln_number = lock->lockname.lock_num;
+
+ schedule_timeout(1*HZ);
+
+ switch(p->mode) {
+ case LKM_EXMODE:
+ lock->dlm->cb(lock->dlm->fsdata, LM_CB_NEED_E, (void *)&name);
+ break;
+
+ case LKM_PRMODE:
+ lock->dlm->cb(lock->dlm->fsdata, LM_CB_NEED_S, (void *)&name);
+ break;
+
+ case LKM_CWMODE:
+ lock->dlm->cb(lock->dlm->fsdata, LM_CB_NEED_D, (void *)&name);
+ break;
+
+ default:
+ err("Unknown lock mode %d!", p->mode);
+ }
+
+ kfree(p);
+ kfree(tqp);
+
+ return;
+}
+
+
+void block_others(void *bastargs, int mode)
+{
+ struct tq_struct *tqp = NULL;
+ struct cb_args *p;
+
+ tqp = (struct tq_struct *)kmalloc(sizeof(struct tq_struct),
GFP_KERNEL);
+
+ if (!tqp) {
+ err("Can't alloc memeory for tq!");
+ return;
+ }
+
+ /*FIXME: How to deal with kmalloc fail? maintain a pool?*/
+ p = (struct cb_args *)kmalloc(sizeof(struct cb_args), GFP_KERNEL);
+
+ if (!p) {
+ err("Can't alloc memory for cb_args!");
+ kfree(tqp);
+ return;
+ }
+
+ p->bastargs = bastargs;
+ p->mode = mode;
+
+ tqp->sync = 0;
+ INIT_LIST_HEAD(&(tqp->list));
+ tqp->routine = opendlm_cb;
+ tqp->data = (void *)p;
+
+ /*Fixme schedule_task may fail*/
+ schedule_task(tqp);
+
+ return;
+}
+
+
+/*
+
*
+ * Copyright 1995-1999 Regents of the University of
Minnesota
+ * Portions Copyright 2001 Sistina Software,
Inc.
+
*
+ * This is free software released under the GNU General Public
License.
+ * There is no warranty for this software. See the file COPYING
for
+ *
details.
+
*
+ * See the file AUTHORS for a list of
contributors.
+
*
+ */
+
+
+/**
+ * locktable_hash - hash an array of data
+ * @data: the data to be hashed
+ * @len: the length of data to be hashed
+ *
+ * Take some data and convert it to a 32-bit hash.
+ *
+ * The hash function is a 32-bit CRC of the data. The algorithm uses
+ * the crc_32_tab table above.
+ *
+ * This may not be the fastest hash function, but it does a fair bit
better
+ * at providing uniform results than the others I've looked at. That's
+ * really important for efficient directories.
+ *
+ * Returns: the hash
+ */
+
+uint32
+locktable_hash(const char *data, int len)
+{
+ uint32 hash = 0xFFFFFFFF;
+
+ for (; len--; data++)
+ hash = crc_32_tab[(hash ^ *data) & 0xFF] ^ (hash >> 8);
+
+ hash = ~hash;
+
+ return (hash);
+}
+
+int atoi(char *c)
+{
+ int x = 0;
+
+ while ('0' <= *c && *c <= '9') {
+ x = x * 10 + (*c - '0');
+ c++;
+ }
+
+ return (x);
+}
+
+int inet_aton(char *ascii, uint32 * ip)
+{
+ uint32 value;
+ int x;
+
+ *ip = 0;
+
+ for (x = 0; x < 4; x++) {
+ value = atoi(ascii);
+ if (value > 255)
+ return (-1);
+ *ip = (*ip << 8) | value;
+ if (x != 3) {
+ ascii = strstr(ascii, ".");
+ if (!ascii)
+ return (-1);
+ ascii++;
+ }
+ }
+ return (0);
+}
+
+void inet_ntoa(uint32 ip, char *buf)
+{
+ int i;
+ char *p;
+
+ p = buf;
+ for (i = 3; i >= 0; i--) {
+ p += sprintf(p, "%d", (ip >> (8 * i)) & 0xFF);
+ if (i > 0)
+ *(p++) = '.';
+ }
+
+}
diff -Naur opengfs/src/locking/modules/opendlm/opendlm.h
opengfs-opendlm/src/locking/modules/opendlm/opendlm.h
--- opengfs/src/locking/modules/opendlm/opendlm.h 1970-01-01
08:00:00.000000000 +0800
+++ opengfs-opendlm/src/locking/modules/opendlm/opendlm.h 2003-09-24
11:11:46.000000000 +0800
@@ -0,0 +1,106 @@
+/* -*- linux-c -*- */
+
+#include <dlm.h>
+
+#define PROTO_NAME "opendlm"
+#define OPENDLM_TRYFAILED (13)
+#define OPENDLM_CANCELED (14)
+
+
+struct opendlm_lock;
+
+struct opendlm {
+ struct list_head list;
+ char table_name[256];
+ uint32 name_space; /* hash value of table_name */
+ lm_callback_t cb;
+ lm_fsdata_t *fsdata;
+
+ struct file *cfile;
+ unsigned int jid;
+ unsigned int nodes_count;
+ struct opendlm_lock *mount_lock;
+ struct list_head deadman;
+};
+
+#define OGFS_DLM_MAGICLEN 4
+#define OGFS_DLM_MAGIC "OGFS"
+
+struct opendlm_lockname {
+ uint64 lock_num;
+ uint32 name_space;
+ unsigned int lock_type;
+ char magic[OGFS_DLM_MAGICLEN];
+}__attribute__((packed));
+
+struct opendlm_lock {
+ struct opendlm_lockname lockname;
+ struct lockstatus lksb;
+ lm_lvb_t *lvb;
+ struct opendlm *dlm;
+ int done;
+};
+
+extern struct list_head dlm_list;
+
+/* function defined in deadman.c */
+void ignore_bast(void *bastargs, int mode);
+void ignore_ast(void *bastargs);
+void ignore_unlockast(void *unlockast, int lstat, void *extrap);
+int start_deadman_lock(struct opendlm *dlm, unsigned int *first);
+int stop_deadman_lock(struct opendlm *dlm);
+
+/* function defined in misc.c */
+struct opendlm* find_dlm(uint32 namespace);
+int setup_jid(struct opendlm *dlm, uint32 ip);
+int grab_mount_lock(struct opendlm *dlm);
+void release_mount_lock(struct opendlm *dlm);
+void parse_lockreq(unsigned int cur_state, unsigned int req_state, int
*lockmode, int *lockflags);
+uint32 locktable_hash(const char *data, int len);
+void block_others(void *bastargs, int mode);
+int inet_aton(char *ascii, uint32 * ip);
+void inet_ntoa(uint32 ip, char *buf);
+dlm_stats_t my_dlmlock_sync(int mode, struct lockstatus *lksb, int
flags,
+ struct opendlm_lock *lock, dlm_bastlockfunc_t * bast);
+
+
+/*Copy from linux 2.6*/
+/**
+ * container_of - cast a member of a structure out to the containing
structure
+ *
+ * @ptr: the pointer to the member.
+ * @type: the type of the container struct this is embedded in.
+ * @member: the name of the member within the struct.
+ *
+ */
+#define container_of(ptr, type, member) ({ \
+ const typeof( ((type *)0)->member ) *__mptr = (ptr); \
+ (type *)( (char *)__mptr - offsetof(type,member) );})
+
+
+
+
+/* DEBUG utilities */
+
+extern int debug;
+
+#define dbg(format, arg...) \
+ do { \
+ if(debug) \
+ printk (KERN_DEBUG "%s %s: " format "\n", \
+ PROTO_NAME, __FUNCTION__, ## arg); \
+ } while(0)
+
+
+#define err(format, arg...) \
+ printk(KERN_ERR "%s %s: " format "\n", \
+ PROTO_NAME, __FUNCTION__ , ## arg)
+#define info(format, arg...) \
+ printk(KERN_INFO "%s %s: " format "\n", \
+ PROTO_NAME, __FUNCTION__ , ## arg)
+#define warn(format, arg...) \
+ printk(KERN_WARNING "%s %s: " format "\n", \
+ PROTO_NAME, __FUNCTION__ , ## arg)
+#define trace(format, arg...) \
+ printk(KERN_INFO "%s %s(" format ")\n", \
+ PROTO_NAME, __FUNCTION__ , ## arg)
-------------------------------------------------------
This sf.net email is sponsored by:ThinkGeek
Welcome to geek heaven.
http://thinkgeek.com/sf
_______________________________________________
Opengfs-devel mailing list
Opengfs-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/opengfs-devel
[Kernel]
[Security]
[Bugtraq]
[Photo]
[Yosemite]
[MIPS Linux]
[ARM Linux]
[Linux Clusters]
[Linux RAID]
[Yosemite Hiking]
[Linux Resources]