[Cluster-devel] [PATCH] Clean up some rgmanager cruft

Lon Hohberger lhh at redhat.com
Mon Nov 10 14:09:03 UTC 2008


* Rename clurgmgrd -> rgmanager
* Remove clurmtabd and references since it's not used.



diff --git a/rgmanager/init.d/rgmanager.in
b/rgmanager/init.d/rgmanager.in
index a827aa9..2a3a30c 100644
--- a/rgmanager/init.d/rgmanager.in
+++ b/rgmanager/init.d/rgmanager.in
@@ -39,7 +39,7 @@ PATH=/sbin:/bin:/usr/sbin:/usr/bin
 export PATH
 
 ID="Cluster Service Manager"
-RGMGRD="clurgmgrd"
+RGMGRD="rgmanager"
 
 LOG_ERR=3
 LOG_WARNING=4
diff --git a/rgmanager/src/daemons/Makefile
b/rgmanager/src/daemons/Makefile
index 97819f2..0691677 100644
--- a/rgmanager/src/daemons/Makefile
+++ b/rgmanager/src/daemons/Makefile
@@ -1,7 +1,6 @@
-TARGET1= clurgmgrd
-#TARGET2= clurmtabd  # Not needed on 2.6 kernels
-TARGET3= rg_test
-TARGET4= dtest
+TARGET1= rgmanager
+TARGET2= rg_test
+TARGET3= dtest
 
 SBINDIRT=$(TARGET1) $(TARGET3)
 
@@ -32,13 +31,10 @@ OBJS1=	depends.o \
 	event_config.o \
 	watchdog.o
 
-OBJS2=	clurmtabd.o \
-	clurmtabd_lib.o
-
-OBJS3=	test-noccs.o \
+OBJS2=	test-noccs.o \
 	restart_counter.o
 
-OBJS4=	dtest-noccs.o
+OBJS3=	dtest-noccs.o
 
 SHAREDOBJS=	depends-noccs.o \
 		fo_domain-noccs.o \
@@ -80,9 +76,6 @@ ${TARGET1}: ${OBJS1} ${LDDEPS}
 			$(SLANG_LDFLAGS) $(EXTRA_LDFLAGS) \
 			$(LOGSYS_LDFLAGS) $(LD_FLAGS)
 
-#${TARGET2}: ${OBJS2} ${LDDEPS}
-#	$(CC) -o $@ $^ $(LDFLAGS)
-
 #
 # Our test program links against the local allocator so that
 # we can see if our program is leaking memory during XML parsing, tree
@@ -97,11 +90,11 @@ ${TARGET1}: ${OBJS1} ${LDDEPS}
 # This is NOT meant to be an installed binary.  Rather, RPMs and/or
other
 # packages should run 'make check' as part of the build process.
 #
-${TARGET3}: ${SHAREDOBJS} ${OBJS3} ${LDDEPS} ${LOCAL_LDDEPS}
+${TARGET2}: ${SHAREDOBJS} ${OBJS3} ${LDDEPS} ${LOCAL_LDDEPS}
 	$(CC) -o $@ $^ $(CMAN_LDFLAGS) $(LOCAL_LDFLAGS) $(EXTRA_LDFLAGS) \
 			$(XML2_LDFLAGS) $(LOGSYS_LDFLAGS) $(LDFLAGS)
 
-${TARGET4}: ${SHAREDOBJS} ${OBJS4} ${LDDEPS} ${LOCAL_LDDEPS}
+${TARGET3}: ${SHAREDOBJS} ${OBJS4} ${LDDEPS} ${LOCAL_LDDEPS}
 	$(CC) -o $@ $^ $(CCS_LDFLAGS) $(CMAN_LDFLAGS) \
 			$(LOCAL_LDFLAGS) $(EXTRA_LDFLAGS) $(XML2_LDFLAGS) \
 			$(READLINE_LDFLAGS) $(LDFLAGS)
diff --git a/rgmanager/src/daemons/clurmtabd.c
b/rgmanager/src/daemons/clurmtabd.c
deleted file mode 100644
index 9dbb045..0000000
--- a/rgmanager/src/daemons/clurmtabd.c
+++ /dev/null
@@ -1,616 +0,0 @@
-/** @file
- * Keeps /var/lib/nfs/rmtab in sync across the cluster.
- *
- * Author: Lon H. Hohberger <lhh at redhat.com>
- *
- * Synchronizes entries in a mount point with /var/lib/nfs/rmtab.
- */
-
-#define CM_NFS_DIR ".clumanager"
- 
-#include <stdio.h>
-#include <rmtab.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <signal.h>
-#include <errno.h>
-#include <syslog.h>
-#include <logging.h>
-#include <unistd.h>
-#include <limits.h>
-#include <regex.h>
-
-#define POLLINT_DEFAULT 2
-
-/* FIXME DAEMON_STR is equivalent to the one in quorumd.c:
CLURMTABD_DAEMON */
-/* Would be nice to have stuff like this defined in one place */
-#define DAEMON_STR	"clurmtabd"
-#define LOGLEVEL_STR	DAEMON_STR "%logLevel"
-#define POLLINT_STR	DAEMON_STR "%pollInterval"
-
-/*
- * Globals
- */
-
-static int exiting = 0;
-static int poll_interval = POLLINT_DEFAULT;
-
-/*
- * Function Prototypes
- */
-static int rmtab_modified(void);
-static int rmtab_copy_bypath(rmtab_node ** dest, rmtab_node ** src,
-			     const char *path);
-static int rmtab_get_update(rmtab_node ** rmtab, rmtab_node **
pruned_rmtab,
-			    rmtab_node ** diff, char *path);
-
-/* Signal Handlers */
-static void sh_sync(int sig);
-static void sh_exit(int sig);
-static void sh_reconfigure(int sig);
-static inline void register_sighandlers(void);
-
-/* Configuration */
-#if 0
-static inline int __get_int_param(char *str, int *val, int dflt);
-#endif
-static int get_rmtabd_loglevel(void);
-static int get_rmtabd_pollinterval(int *interval);
-static void rmtabd_reconfigure(void);
-
-/* Initialization */
-static int rmtabd_config_init(void);
-int main(int argc, char **argv);
-
-
-/**
- * stat _PATH_RMTAB and see if it's changed.
- *
- * @returns		1 if it's been modified; 0 if not.
- */
-static int
-rmtab_modified(void)
-{
-	/* Preserved data */
-	static struct stat prev_stat;
-	static int __prev_stat = 0;
-
-	struct stat curr_stat;
-	int rv = 1;
-
-	/* Initialize */
-	if (!__prev_stat) {
-		memset(&prev_stat, 0, sizeof (prev_stat));
-		stat(_PATH_RMTAB, &prev_stat);
-		__prev_stat = 1;
-		return 1;
-	}
-
-	memset(&curr_stat, 0, sizeof (curr_stat));
-	while (stat(_PATH_RMTAB, &curr_stat) == -1) {
-		if (errno != ENOENT) {
-			log_printf(LOG_ERR, "#15: %s: stat: %s\n", __FUNCTION__,
-			       strerror(errno));
-			return -1;
-		}
-
-		/* Create the file. */
-		log_printf(LOG_WARNING, "#62: " _PATH_RMTAB
-		       " does not exist - creating");
-		close(open(_PATH_RMTAB, O_CREAT | O_SYNC, 0600));
-	}
-
-	if ((rv = memcmp(&prev_stat.st_mtime, &curr_stat.st_mtime,
-			 sizeof (curr_stat.st_mtime)))) {
-		log_printf(LOG_DEBUG, "Detected modified " _PATH_RMTAB "\n");
-		memcpy(&prev_stat, &curr_stat, sizeof (prev_stat));
-	}
-
-	return !!rv;
-}
-
-
-/**
- * Insert (copy) entries in **src with the same rn_path as *path to
- * destination list **dest.
- *
- * @param dest		Destination list pointer.
- * @param src		Source list pointer.
- * @param path		Path to prune (only copy entries in the specified
- *			path).
- * Returns -1 if rmtab_insert fails; 0 on success
- */
-static int
-rmtab_copy_bypath(rmtab_node ** dest, rmtab_node ** src, const char
*path)
-{
-	rmtab_node *curr, *last = NULL;
-
-	for (curr = *src; curr; curr = curr->rn_next)
-		if (!strcmp(path, curr->rn_path))
-			if ((last = rmtab_insert(dest, last,
-						curr->rn_hostname,
-						curr->rn_path,
-						curr->rn_count)) == NULL)
-				return -1;
-	return 0;
-}
-
-
-/**
- * Update the rmtab from /var/lib/nfs/rmtab.  We need to maintain two
separate
- * lists (rmtab and pruned_rmtab).  This is because we don't want to
sync
- * non-cluster exports.  Non-cluster exports will not show up in
pruned_rmtab,
- * however, when we receive an update from our peer, we'd lose
non-cluster
- * entries if we didn't preserve them when we merge in changes from our
peer.
- *
- * The current (full) rmtab is passed in as **rmtab.  The current
cluster-only
- * (pruned) rmtab is passed in as **pruned_rmtab.  The differences
between
- * the current and new cluster-only rmtabs are passed out in **diff,
and the
- * new versions (if any) of the full rmtab and pruned rmtab are moved
into
- *
- * @return		-1 on error, 0 on success, 1 if no differences exist.
- */
-static int
-rmtab_get_update(rmtab_node ** rmtab, rmtab_node ** pruned_rmtab,
-		 rmtab_node ** diff, char *path)
-{
-	int rv = -1;
-	rmtab_node *old_rmtab = NULL, *old_pruned = NULL;
-
-	if (!rmtab_modified())
-		return 1;
-
-	/* Save the current full list */
-	rmtab_move(&old_rmtab, rmtab);
-
-	if (rmtab_read(rmtab, _PATH_RMTAB) == -1) {
-		log_printf(LOG_ERR, "#16: Failed to reread rmtab: %s\n",
-		       strerror(errno));
-
-		/* Don't kill the list if we fail to reread. */
-		rmtab_move(rmtab, &old_rmtab);
-		goto out;
-	}
-
-	/* Save the current cluster-specific list */
-	rmtab_move(&old_pruned, pruned_rmtab);
-
-	if (rmtab_copy_bypath(pruned_rmtab, rmtab, path) == -1) {
-		log_printf(LOG_ERR, "#17: Failed to prune rmtab: %s\n",
-		       strerror(errno));
-
-		/* 
-		 * Since we couldn't build a new list, restore the old
-		 * one.  Otherwise, next time, we'd send a weird diff to
-		 * our peer with all entries as "added".
-		 */
-		rmtab_move(pruned_rmtab, &old_pruned);
-		goto out;
-	}
-
-	if (!diff) {
-		rv = 1;
-		goto out;
-	}
-
-	/* find the differences */
-	if (rmtab_diff(old_pruned, *pruned_rmtab, diff)) {
-		log_printf(LOG_ERR, "Failed to diff rmtab: %s\n", strerror(errno));
-		goto out;
-	}
-
-	if (!*diff) {
-		/* No differences */
-		rv = 1;
-		goto out;
-	}
-
-	rv = 0;
-      out:
-	/* stick a finger in the memory dike */
-	rmtab_kill(&old_rmtab);	/* these will be NOPs if NULL */
-	rmtab_kill(&old_pruned);
-
-	return rv;
-}
-
-
-
-
-/* **************** *
- * SIGNAL HANDLERS!
- * **************** */
-
-/**
- * INT, USR1, USR2 handler.
- *
- * What these signals actually do is interrupt the select(2) we enter
when we
- * call sleep().  Effectively, this causes sleep() to short out, and
makes 
- * us drop down into rmtab_get_update() - causing us to re-check and
sync
- * changes if there are any.  The service script, svclib_nfs, sends us
a
- * TERM whenever it receives the request to stop a service (which
happens
- * when the service manager relocates as well), thus, when a service is
- * disabled or relocates to the other node, clurmtabd syncs immediately
its
- * current state to the other node, preventing a timing window between
- * "service relocate" and "rmtabd update" during which a client could
- * receive ESTALE.
- */
-static void
-sh_sync(int sig)
-{
-	log_printf(LOG_DEBUG, "Signal %d received; syncing ASAP\n", sig);
-}
-
-
-/**
- * QUIT, TERM
- *
- * In this case, we go down ASAP.  But first, we sync.  These will,
like the
- * above, short-out msg_accept_timeout() and drop down for that one
last
- * sync.
- */
-static void
-sh_exit(int sig)       
-{
-	log_printf(LOG_DEBUG, "Signal %d received; exiting\n", sig);
-	exiting = 1;
-}
-
-
-/**
- * HUP
- *
- * Traditional behavior.  Reconfigure on SIGHUP.
- */
-static void
-sh_reconfigure(int __attribute__ ((unused)) sig)
-{
-	log_printf(LOG_DEBUG, "Re-reading the cluster database\n");
-	rmtabd_reconfigure();
-}
-
-
-/**
- * Set up signal handlers.
- */
-static inline void
-register_sighandlers(void)
-{
-	sigset_t set;
-	struct sigaction act;
-
-	sigemptyset(&set);
-	sigaddset(&set, SIGINT);
-	sigaddset(&set, SIGUSR1);
-	sigaddset(&set, SIGUSR2);
-
-	sigaddset(&set, SIGHUP);
-
-	sigaddset(&set, SIGTERM);
-	sigaddset(&set, SIGQUIT);
-
-	sigaddset(&set, SIGILL);
-	sigaddset(&set, SIGIO);
-	sigaddset(&set, SIGSEGV);
-	sigaddset(&set, SIGBUS);
-
-	sigprocmask(SIG_UNBLOCK, &set, NULL);
-
-	memset(&act, 0, sizeof (act));
-	sigemptyset(&act.sa_mask);
-
-	/* In some cases, just continue */
-	act.sa_handler = sh_sync;
-
-	sigaction(SIGINT, &act, NULL);
-	sigaction(SIGUSR1, &act, NULL);
-	sigaction(SIGUSR2, &act, NULL);
-
-	/* Ok, reconfigure here */
-	act.sa_handler = sh_reconfigure;
-	sigaction(SIGHUP, &act, NULL);
-
-	/* Exit signals */
-	act.sa_handler = sh_exit;
-	sigaction(SIGTERM, &act, NULL);
-	sigaction(SIGQUIT, &act, NULL);
-}
-
-/* ******************************* *
- * Configuration Utility Functions
- * ******************************* */
-
-/**
- * Retrieve an integer parameter from the config file.
- *
- * @param str		config token
- * @param val		return value
- * @param dflt		Default integer value.
- * @return 0                                                      s
- */
-#if 0
-static inline int
-__get_int_param(char *str, int *val, int dflt)
-{
-	char *value;
-	int ret;
-
-	ret = CFG_Get(str, NULL, &value);
-
-	switch (ret) {
-	case CFG_DEFAULT:
-		*val = dflt;
-		break;
-	case CFG_OK:
-		*val = atoi(value);
-		break;
-	default:
-		log_printf(LOG_ERR, "#19: Cannot get \"%s\" from database; "
-		       "CFG_Get() failed, err=%d\n", ret);
-		return 0;
-	}
-
-	return 0;
-}
-#endif
-
-
-/**
- * Gets the loglevel of rmtabd
- */
-static int
-get_rmtabd_loglevel(void)
-{
-#if 0
-	return __get_int_param(LOGLEVEL_STR, level, LOG_DEFAULT);
-#endif
-	return LOG_INFO;
-}
-
-
-/**
- * Retrieves the polling interval, in seconds, of _RMTAB_PATH from the
cluster
- * configuration database.
- */
-static int
-get_rmtabd_pollinterval(int __attribute__((unused)) *interval)
-{
-#if 0
-	return __get_int_param(POLLINT_STR, interval, POLLINT_DEFAULT);
-#endif
-	return POLLINT_DEFAULT;
-}
-
-
-/**
- * This is called at init and by sh_reconfigure and sets up
daemon-specific
- * configuration params.
- */
-static void
-rmtabd_reconfigure(void)
-{
-	int level, old_level, old_interval;
-
-	/* loglevel */
-	old_level = clu_get_loglevel();
-	level = get_rmtabd_loglevel();
-
-	if (old_level != level) {
-		if (clu_set_loglevel(level) == -1)
-			log_printf(LOG_ERR, "#20: Failed set log level\n");
-		else
-			log_printf(LOG_DEBUG, "Log level is now %d\n", level);
-	}
-
-	/* rmtabd polling interval (tw33k4bl3) */
-	old_interval = poll_interval;
-	get_rmtabd_pollinterval(&poll_interval);
-
-	/* bounds-check */
-	if (poll_interval < 1)
-		poll_interval = 1;
-	else if (poll_interval > 10)
-		poll_interval = 10;
-
-	if (old_interval != poll_interval) {
-		log_printf_and_print(LOG_DEBUG,
-				 "Polling interval is now %d seconds\n",
-				 poll_interval);
-	}
-}
-
-
-/**
- * Set up local parameters & signal handlers.
- */
-static int
-rmtabd_config_init(void)
-{
-	/* Yes, it does this twice */
-#if 0
-	if (CFG_ReadFile(CLU_CONFIG_FILE) != CFG_OK)
-		return -1;
-#endif
-
-	rmtabd_reconfigure();
-	register_sighandlers();
-	return 0;
-}
-
-
-/**
- * Initializes and synchronizes /var/lib/nfs/rmtab with
- * [path]/.clumanager/rmtab.
- *
- * @param path		Path to mount point we're monitoring.
- * @param rmtab		Will contain full rmtab upon exit.
- * @param pruned_rmtab	Will contain rmtab entries we care about on
exit.
- */
-int
-rmtab_init(char *path, rmtab_node **rmtab, rmtab_node **pruned_rmtab)
-{
-	char buf[PATH_MAX];
-
-	snprintf(buf, sizeof(buf), "%s/%s", path, CM_NFS_DIR);
-
-	if ((mkdir(buf, 0700) == -1) && (errno != EEXIST)) {
-		log_printf_and_print(LOG_ERR, "#21: Couldn't read/create %s: %s\n",
-				 buf, strerror(errno));
-		return -1;
-	}
-
-	snprintf(buf, sizeof(buf), "%s/%s/rmtab", path, CM_NFS_DIR);
-
-	if (rmtab_read(rmtab, buf) == -1) {
-		log_printf_and_print(LOG_ERR, "#22: Failed to read %s: %s\n", buf,
-				 strerror(errno));
-		return -1;
-	}
-
-	/*
-	 * Read into the same pointer -> inserting each node will
-	 * cause the nodes with the greater count to be kept.
-	 */
-	if (rmtab_read(rmtab, _PATH_RMTAB) == -1) {
-		log_printf_and_print(LOG_ERR, "#23: Failed to read %s: %s\n",
-				 _PATH_RMTAB, strerror(errno));
-		return -1;
-	}
-
-	/*
-	 * Prune by our path
-	 */
-	if (rmtab_copy_bypath(pruned_rmtab, rmtab, path) == -1) {
-		log_printf_and_print(LOG_ERR, "#24: Failed to prune rmtab: %s\n",
-				 strerror(errno));
-		return -1;
-	}
-
-	/*
-	 * XXX could lose a mount if rpc.mountd writes a file before
-	 * we rewrite the file.
-	 */
-	if (rmtab_write_atomic(*rmtab, _PATH_RMTAB) == -1) {
-		log_printf_and_print(LOG_ERR, "#25: Failed to write %s: %s\n",
-				 _PATH_RMTAB, strerror(errno));
-		return -1;
-	}
-	/*
-	 * Write new contents.
-	 */
-	if (rmtab_write_atomic(*pruned_rmtab, buf) == -1) {
-		log_printf_and_print(LOG_ERR, "#26: Failed to write %s: %s\n", buf,
-				 strerror(errno));
-		return -1;
-	}
-	
-	return 0;
-}
-
-
-/**
- * Fork off into the background and store our pid file in
- * [path]/.clumanager/pid
- *
- * @param path		Mount point we're monitoring.
- * @return 		-1 on failure, 0 on success.
- */
-static int
-daemonize(char *path)
-{
-	FILE *fp=NULL;
-	char filename[PATH_MAX];
-
-	if (daemon(0,0) == -1)
-		return -1;
-
-	memset(filename,0,PATH_MAX);
-	snprintf(filename, sizeof(filename), "%s/%s/pid", path, CM_NFS_DIR);
-
-	fp = fopen(filename, "w");
-	if (fp == NULL) {
-		log_printf(LOG_WARNING, "#63: Couldn't write PID!\n");
-	}
-
-	fprintf(fp, "%d", getpid());
-	fclose(fp);
-
-	return 0;
-}
-
-
-/**
- * main
- *
- * Main.  Main.  Main.  Main.  Main.  Main.  Main.  Main.  Main.
Main.  
- */
-int
-main(int argc, char **argv)
-{
-	char path[PATH_MAX];
-	char rmtab_priv[PATH_MAX];
-	
-	rmtab_node *rmtab = NULL, *pruned_rmtab = NULL, *diff = NULL;
-	
-	if (argc < 2) {
-		fprintf(stderr, "usage: clurmtabd <mount-point>\n");
-		return -1;
-	}
-
-	/* Set up configuration parameters */
-	if (rmtabd_config_init() == -1) {
-		log_printf_and_print(LOG_ERR,
-			         "#27: Couldn't initialize - exiting\n");
-		return -1;
-	}
-
-        /* Set up our internal variables */
-	snprintf(path, sizeof(path), "%s", argv[1]);
-	snprintf(rmtab_priv, sizeof(rmtab_priv), "%s/%s/rmtab", path,
-		 CM_NFS_DIR);
-
-	/*
-	 * Synchronize the rmtab files
-	 *
-	 * We do this before we call daemonize() to ensure that when
-	 * the service script calls exportfs, /var/lib/nfs/rmtab has
-	 * all the necessary entries.
-	 */
-	if (rmtab_init(path, &rmtab, &pruned_rmtab) == -1) {
-		log_printf_and_print(LOG_WARNING,
-				 "#64: Could not validate %s\n", path);
-		log_printf_and_print(LOG_WARNING,
-				 "#65: NFS Failover of %s will malfunction\n",
-				 path);
-		return -1;
-	}
-
-	/* Jump off into the background */
-	if (daemonize(path) == -1) {
-		log_printf_and_print(LOG_ERR, "#28: daemonize: %s\n",
-				 strerror(errno));
-		return -1;
-	}
-
-	/* Main loop */
-	while (!exiting) {
-
-		/* Snooze a bit */
-		sleep(poll_interval);
-
-		/* Check for updates */
-		if (rmtab_get_update(&rmtab, &pruned_rmtab, &diff, path)
-		    == 0) {
-			/* Handle updates */
-			rmtab_merge(&pruned_rmtab, diff);
-			rmtab_kill(&diff);
-			if (rmtab_write_atomic(pruned_rmtab, rmtab_priv) == -1)
-				log_printf(LOG_ERR,
-				       "#29: rmtab_write_atomic: %s\n",
-				       strerror(errno));
-		}
-	}
-
-	return 0;
-}
diff --git a/rgmanager/src/daemons/clurmtabd_lib.c
b/rgmanager/src/daemons/clurmtabd_lib.c
deleted file mode 100644
index aa216a2..0000000
--- a/rgmanager/src/daemons/clurmtabd_lib.c
+++ /dev/null
@@ -1,820 +0,0 @@
-/** @file
- * Implements rmtab read/write/list handling functions utilized by
- * clurmtabd.
- *
- * Author: Lon H. Hohberger <lhh at redhat.com>
- *
- * This was written for two reasons:
- * (1) The nfs-utils code was difficult to adapt to the requirements,
and
- * (2) to prevent cross-breeding of nfs-utils with clumanager.
- *
- * So, in a sense, this is a re-invention of the wheel, but it keeps
the
- * pacakges separate, thus easing maintenance by lessening the number
of
- * patches and code forks required for Enterprise Linux.
- */
-#include <platform.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <sys/param.h>
-#include <unistd.h>
-#include <rmtab.h>
-#include <libgen.h>
-
-/*
- * Function Prototypes
- */
-static int fp_lock(FILE *fp, int type);
-static int fp_unlock(FILE *fp);
-static inline void un_diffize(rmtab_node *dest, rmtab_node *src);
-
-
-/*
- * free an rmtab node
- */
-void
-rmtab_free(rmtab_node *ptr)
-{
-	if(ptr->rn_hostname)
-		free(ptr->rn_hostname);
-	if(ptr->rn_path)
-		free(ptr->rn_path);
-	free(ptr);
-}
-
-
-/*
- * take advisory lock.  Retry until we're blue in the face.
- */
-static int
-fp_lock(FILE *fp, int type)
-{
-	int fd;
-	struct flock flock;
-	
-	fd = fileno(fp);
-	memset(&flock,0,sizeof(flock));
-
-	/* Lock. */
-	flock.l_type = type;
-	while (fcntl(fd, F_SETLK, &flock) == -1) {
-		if ((errno != EAGAIN) && (errno != EACCES))
-			return -1;
-
-		usleep(10000);
-	}
-
-	return 0;
-}
-
-
-/*
- * unlock...
- */
-static int
-fp_unlock(FILE *fp)
-{
-	int fd = fileno(fp);
-	struct flock flock;
-
-	memset(&flock,0,sizeof(flock));
-	flock.l_type = F_UNLCK;
-	return fcntl(fd, F_SETLK, &flock);
-}
-
-
-/*
- * Inserts a node into the list in ASCII-sorted order; rnew must have
been
- * a user-allocated chunk of memory. (static = big nono)
- */
-int
-__rmtab_insert(rmtab_node **head, rmtab_node *rnew)
-{
-	rmtab_node *back, *curr;
-	int rv = 1;
-
-	/* insert as first entry */
-	if (!(*head) || (rv = rmtab_cmp_min(rnew, *head)) < 0) {
-		rnew->rn_next = *head;
-		*head = rnew;
-		return 0;
-	}
-
-	/* Duplicate match? */
-	if (!rv) {
-		if ((*head)->rn_count < rnew->rn_count)
-			(*head)->rn_count = rnew->rn_count;
-		return 1;
-	}
-
-	/* Standard insert - not beginning, not end. */
-	back = NULL;
-	curr = *head;
-	while (curr) {
-		/* Insert before current */
-		if ((rv = rmtab_cmp_min(rnew, curr)) < 0) {
-			back->rn_next = rnew;
-			rnew->rn_next = curr;
-			return 0;
-		}
-
-		/* Duplicate match? Snag the greater count. */
-		if (!rv) {
-			if (curr->rn_count < rnew->rn_count)
-				curr->rn_count = rnew->rn_count;
-			return 0;
-		}
-
-		/* Loopy loopy */
-		back = curr;
-		curr = curr->rn_next;
-	}
-
-	/* Tack on at end of list */
-	back->rn_next = rnew;
-
-	return 0;
-}
-
-
-/*
- * Inserts a node into the list in ASCII-sorted order; rnew must have
been
- * a user-allocated chunk of memory. (static = big nono)
- */
-int
-__rmtab_insert_after(rmtab_node *pre, rmtab_node *rnew)
-{
-	rmtab_node *back, *curr;
-	int rv = 1;
-
-	/* insert as first entry */
-	if ((rv = rmtab_cmp_min(rnew, pre)) < 0) {
-		return -1;
-	}
-
-	/* Duplicate match? */
-	if (!rv) {
-		if (pre->rn_count < rnew->rn_count)
-			pre->rn_count = rnew->rn_count;
-		return 1;
-	}
-
-	/* Standard insert - not beginning, not end. */
-	back = NULL;
-	curr = pre;
-	while (curr) {
-		/* Insert before current */
-		if ((rv = rmtab_cmp_min(rnew, curr)) < 0) {
-			back->rn_next = rnew;
-			rnew->rn_next = curr;
-			return 0;
-		}
-
-		/* Duplicate match? Snag the greater count. */
-		if (!rv) {
-			if (curr->rn_count < rnew->rn_count)
-				curr->rn_count = rnew->rn_count;
-			return 0;
-		}
-
-		/* Loopy loopy */
-		back = curr;
-		curr = curr->rn_next;
-	}
-
-	/* Tack on at end of list */
-	back->rn_next = rnew;
-
-	return 0;
-}
-
-
-/*
- * Inserts (host,path) rmtab into a list pointed to by **head
- */
-rmtab_node *
-rmtab_insert(rmtab_node **head, rmtab_node *pre, char *host,
-	     char *path, int count)
-{
-	rmtab_node *rnew;
-
-	/* simple bounds-checking */
-	if (!head || !host || !path || !strlen(host) || !strlen(path))
-		return NULL;
-
-	/* Copy in info */
-	rnew = malloc(sizeof(*rnew));
-	// FIXME: handle failed malloc
-	memset(rnew, 0, sizeof(*rnew));
-	rnew->rn_hostname = strdup(host);
-	rnew->rn_path = strdup(path);
-	rnew->rn_count = count;
-
-	if (pre) {
-		/* We got a preceding node... try to insert */
-		switch(__rmtab_insert_after(pre, rnew)) {
-		case -1:
-			/* Failed insert after... try before? */
-			break;
-		case 0:
-			goto out;
-		case 1:
-			rmtab_free(rnew);
-			rnew = NULL;
-			goto out;
-		}
-	}
-
-
-	/* Insert into our list officially */
-	if (__rmtab_insert(head, rnew) == 1) {
-		/* Duplicate match */
-		rmtab_free(rnew);
-		rnew = NULL;
-	}
-
-out:
-	return rnew;
-}
-
-
-/*
- * removes a node based on contents of *entry 
- * user must free memory, if applicable.
- */
-rmtab_node *
-__rmtab_remove(rmtab_node **head, rmtab_node *entry)
-{
-	int rv = -1;
-	rmtab_node *curr, *back;
-
-	back = NULL; curr = *head;
-
-	for (curr = *head, back = NULL; 
-	     (rv = rmtab_cmp_min(curr, entry)) < 0;
-	     back = curr, curr = curr->rn_next);
-
-	/* overshot => no match */
-	if (rv != 0)
-		return NULL;
-
-	if (back) {
-		back->rn_next = curr->rn_next;
-		curr->rn_next = NULL;
-		return curr;
-	}
-
-	/* no back pointer = first node in list. */
-	back = curr;
-	*head = curr->rn_next;
-	back->rn_next = NULL;
-	return back;
-}
-
-
-/*
- * removes an entry in the list; user must free.
- */
-rmtab_node *
-rmtab_remove(rmtab_node **head, char *host, char *path)
-{
-	rmtab_node tmp;
-	rmtab_node *ret;
-
-	/* Wrappers, wrappers */
-	memset(&tmp, 0, sizeof(tmp));
-	if (host)
-		tmp.rn_hostname = strdup(host);
-	if (path)
-		tmp.rn_path = strdup(path);
-
-	ret = __rmtab_remove(head, &tmp);
-	if (tmp.rn_hostname)
-		free(tmp.rn_hostname);
-	if (tmp.rn_path)
-		free(tmp.rn_path);
-
-	return ret;
-}
-
-
-/*
- * Frees an entire rmtab list.
- */
-void
-rmtab_kill(rmtab_node **head)
-{
-	rmtab_node *curr, *back;
-
-	if (!head || !*head)
-		return;
-
-	curr = *head; back = NULL;
-
-	while (curr) {
-		if (back)
-			rmtab_free(back);
-		back = curr;
-		curr = curr->rn_next;
-	}
-
-	if (back)
-		rmtab_free(back);
-
-	*head = NULL;
-}
-
-
-/*
- * Finds the differences between two rmtabs.  This is generally called
when
- * we read our file locally.  The diff outputs in **diff are collapsed
- * noted as '<' and '>' before the hostname, eg
- *
- * <boris /tmp 1
- * >dragracer /tmp2 1
- */
-int
-rmtab_diff(rmtab_node *old, rmtab_node *new, rmtab_node **diff)
-{
-	rmtab_node *old_curr, *new_curr, *last = NULL;
-	int rv;
-	char buf[MAXHOSTNAMELEN];
-
-	if (!diff)
-		return -1;
-
-	old_curr = old;
-	new_curr = new;
-
-	/* This loop will exit when the first list is exhausted. */
-	while (old_curr && new_curr) {
-
-		/* Entries the same. */
-		if (!(rv = rmtab_cmp(old_curr, new_curr))) {
-			old_curr = old_curr->rn_next;
-			new_curr = new_curr->rn_next;
-			continue;
-		}
-
-		/* Old < new = deleted entry */
-		if (rv < 0) {
-			snprintf(buf, sizeof(buf), "<%s",
-				 old_curr->rn_hostname);
-			last = rmtab_insert(diff, last, buf, old_curr->rn_path,
-			       		    old_curr->rn_count);
-			old_curr = old_curr->rn_next;
-			continue;
-		}
-
-		/* old > new = new entry */
-		snprintf(buf, sizeof(buf), ">%s", new_curr->rn_hostname);
-		last = rmtab_insert(diff, last, buf, new_curr->rn_path,
-			    	    new_curr->rn_count);
-		new_curr = new_curr->rn_next;
-	}
-
-	/* Meaning only one of the two following loops actually is executed:*/
-
-	/* Add remaining stuff in 'old' to 'deleted' list */
-	for (;old_curr; old_curr = old_curr->rn_next) {
-		snprintf(buf, sizeof(buf), "<%s", old_curr->rn_hostname);
-		last = rmtab_insert(diff, last, buf, old_curr->rn_path,
-			    	    old_curr->rn_count);
-	}
-
-	/* Add remaining stuff in 'new' to 'added' list. */
-	for (;new_curr; new_curr = new_curr->rn_next) {
-		snprintf(buf, sizeof(buf), ">%s", new_curr->rn_hostname);
-		last = rmtab_insert(diff, last, buf, new_curr->rn_path,
-			    	    new_curr->rn_count);
-	}
-
-	return 0;
-}
-
-
-/*
- * strips the "diff" character ('>' || '<') from the beginning of the
hostname
- * in *src and stores the resulting stuff in *dest.
- */
-static inline void
-un_diffize(rmtab_node *dest, rmtab_node *src)
-{
-	dest->rn_hostname = strdup(&src->rn_hostname[1]);
-	dest->rn_path = strdup(src->rn_path);
-	dest->rn_count = src->rn_count;
-	dest->rn_next = NULL;
-}
-
-
-/*
- * Merges 'patch' list with **head.
- * Modifies list in **head; leaves *patch unchanged.  This is generally
- * called when we receive an update from a peer.
- */
-int
-rmtab_merge(rmtab_node **head, rmtab_node *patch)
-{
-	rmtab_node *curr, *oldp = NULL, *last = NULL;
-	rmtab_node tmpnode;
-	int rv = -1;
-
-	/* Delete all matching entries */
-	for (curr = patch; curr; curr = curr->rn_next) {
-
-		un_diffize(&tmpnode, curr);
-
-		if (curr->rn_hostname[0] == '<') {
-			if ((oldp = __rmtab_remove(head, &tmpnode))) {
-				rmtab_free(oldp);
-				oldp = NULL;
-			}
-		} else if (curr->rn_hostname[0] == '>') {
-			if ((last = rmtab_insert(head, last,
-						 tmpnode.rn_hostname,
-						 tmpnode.rn_path,
-						 tmpnode.rn_count)) == NULL) {
-				rv = -1;
-				break;
-			}
-		} else {
-			/* EEEEEKKKK */
-			rv = -1;
-			break;
-		}
-
-		/*
-		 * Free anything we allocated
-		 */
-		if (tmpnode.rn_hostname) {
-			free(tmpnode.rn_hostname);
-			tmpnode.rn_hostname = NULL;
-		}
-		if (tmpnode.rn_path) {
-			free(tmpnode.rn_path);
-			tmpnode.rn_path = NULL;
-		}
-	}
-
-	if (tmpnode.rn_hostname)
-		free(tmpnode.rn_hostname);
-	if (tmpnode.rn_path)
-		free(tmpnode.rn_path);
-
-	return 0;
-}
-
-
-/*
- * Builds a list by parsing an rmtab in *fp... pretty simple
- */
-int
-rmtab_import(rmtab_node **head, FILE *fp)
-{
-	int n = 0;
-	char line[MAXPATHLEN];
-	char *hostname, *path, *cnt;
-	int count = 0;
-	rmtab_node *last = NULL;
-
-	if (!fp || !head)
-		return 0;
-
-	if (fp_lock(fp, F_RDLCK) == -1) {
-		perror("fplock");
-		return -1;
-	}
-
-	while (fgets(line,sizeof(line),fp) != NULL) {
-		hostname = strtok(line, ":");
-		path = strtok(NULL, ":");
-
-		/* mount count corresponding to the entry */
-		cnt = strtok(NULL, ":");
-		if (cnt)
-			count = strtol(cnt, NULL, 0);
-
-		if (!hostname || !path || !count)
-			/* End - malformed last line */
-			break;
-
-		if ((last = rmtab_insert(head, last, hostname, path,
-	 				 count)) != NULL)
-			n++;
-	}
-
-	fp_unlock(fp);
-	return n;
-}
-
-
-/*
- * Writes rmtab to export file *fp
- */
-int
-rmtab_export(rmtab_node *head, FILE *fp)
-{
-	rmtab_node *curr;
-
-	/*
-	 * lhh - fix - we removed the check for !head, because we _CAN_ have 
-	 * an empty /var/lib/nfs/rmtab!!
-	 */
-	if (!fp)
-		return -1;
-
-	if (fp_lock(fp, F_WRLCK) == -1)
-		return -1;
-
-	for (curr = head; curr; curr = curr->rn_next)
-		fprintf(fp,"%s:%s:0x%08x\n",curr->rn_hostname, curr->rn_path,
-			curr->rn_count);
-
-	fp_unlock(fp);
-	return 0;
-}
-
-
-/*
- *
- */
-int
-rmtab_read(rmtab_node **head, char *filename)
-{
-	FILE *fp;
-	int rv = 0;
-	int esave = 0;
-
-        if (!filename || !strlen(filename))
-		return -1;
-    
-	fp = fopen(filename, "r");
-	if (!fp) {
-		/* It's ok if it's not there. */
-		if (errno == ENOENT) {
-			close(open(filename, O_WRONLY|O_SYNC|O_CREAT, S_IRUSR | S_IWUSR));
-			return 0;
-		}
-		perror("fopen");
-		return -1;
-	}
-
-	rv = rmtab_import(head, fp);
-	esave = errno;
-
-	fclose(fp);
-	errno = esave;
-	return rv;
-}
-
-
-/*
- * Writes rmtab list in *head to *filename; in an atomic fashion
- */
-int
-rmtab_write_atomic(rmtab_node *head, char *filename)
-{
-	char tmpfn[MAXPATHLEN],
-	     oldfn[MAXPATHLEN],
-	     realfn[MAXPATHLEN];
-	FILE *fp;
-	int len, tfd, ofd;
-	int rv = -1;
-
-	memset(realfn, 0, sizeof(realfn));
-	memset(oldfn, 0, sizeof(oldfn));
-	memset(tmpfn, 0, sizeof(tmpfn));
-
-	len = strlen(filename);
-	if (len > (MAXPATHLEN - 1))
-		len = MAXPATHLEN - 1;
-
-	memcpy(realfn, filename, len);
-
-	/* chop off the end - GLIBC modifies the argument here */
-	dirname(realfn);
-
-	snprintf(oldfn, sizeof(oldfn), "%s/tmp.XXXXXX", realfn);
-	snprintf(tmpfn, sizeof(tmpfn), "%s/tmp.XXXXXX", realfn);
-
-	if ((ofd = mkstemp(oldfn)) == -1)
-		return -1;
-	if ((tfd = mkstemp(tmpfn)) == -1) {
-		close(ofd);
-		unlink(oldfn);
-		return -1;
-	}
-
-	/* Kill the file so we can link it (else it'll not work) */
-	close(ofd);
-	unlink(oldfn);
-
-	/* set up the link */
-	if (link(filename, oldfn) == -1)
-		goto fail;
-
-	/* Export the file.  Yes, we have two fd's on it now.  That's ok :) */
-	if (!(fp = fopen(tmpfn, "w")))
-		goto fail;
-
-	if (rmtab_export(head, fp) == -1)
-		goto fail;
-
-	fsync(fileno(fp));
-	fclose(fp);
-
-	/* atomic update */
-	if (rename(tmpfn, filename) == -1)
-		goto fail;
-
-	if (unlink(oldfn) == -1)
-		goto fail;
-
-	rv = 0;
-fail:
-	close(tfd);
-
-	return rv;
-}
-
-
-/*
- * Well, 1106 bytes per transaction is a bit much, especially for 
- * busy nfs clusters... so, we invent 'compact', which simply
eliminates
- * all dead data.  We basically have two strings + their trailing
NULLs,
- * and one int (the mount count)
- */
-size_t
-rmtab_pack_size(rmtab_node *head)
-{
-	rmtab_node *curr;
-	size_t total = 0;
-
-	for (curr = head; curr; curr = curr->rn_next) {
-		/* leave space for NULLs */
-		total += strlen(curr->rn_hostname) + 1;
-		total += strlen(curr->rn_path) + 1;
-		total += sizeof(curr->rn_count); /* uint32_t */
-	}
-
-	return total;
-}
-
-
-/*
- * rmtab_pack
- *
- * stores the list in *head in *buf - packed as much as possible
without
- * actually employing compression.
- *
- * host.domain.com\0/usr/src\0####host2.domain.com\0/usr/src\0####
- */
-int
-rmtab_pack(char *buf, rmtab_node *head)
-{
-	int n = 0;
-	char *bptr = buf;
-	rmtab_node *curr;
-	size_t len;
-	uint32_t c_tmp;
-	
-	/* Pass 2 */
-	for (curr = head; curr; curr = curr->rn_next) {
-		/* Hostname */
-		len = strlen(curr->rn_hostname);
-		memcpy(bptr, curr->rn_hostname, len);
-		bptr[len] = 0;
-		bptr += (len + 1); /* space for the NULL */
-
-		/* path */
-		len = strlen(curr->rn_path);
-		memcpy(bptr, curr->rn_path, len);
-		bptr[len] = 0;
-		bptr += (len + 1);
-
-		/* count */
-		len = sizeof(curr->rn_count);
-
-		/* Flip-endianness */
-		c_tmp = curr->rn_count; /* uint32_t! */
-		swab32(c_tmp);
-		
-		memcpy(bptr, &c_tmp, len);
-		bptr += len;
-
-		n++;
-	}
-
-	return n;
-}
-
-
-/*
- * rmtab_unpack
- * .... reverse of rmtab_pack.
- */
-int
-rmtab_unpack(rmtab_node **head, char *src, size_t srclen)
-{
-	int n = 0;
-	char *hostp, *pathp;
-	uint32_t *countp;
-	size_t len;
-	size_t total = 0;
-	rmtab_node *last = NULL;
-
-	if (!src[0])
-		return 0;
-
-	hostp = src;
-
-	while (total < srclen) {
-		len = strlen(hostp) + 1;
-		pathp = hostp + len;
-
-		len += strlen(pathp) + 1;
-
-		/* flip-endianness if require */
-		countp = (uint32_t *)(hostp + len);
-		swab32(*countp);
-
-		len += sizeof(uint32_t);
-
-		if ((last = rmtab_insert(head, NULL, hostp, pathp,
-					 *countp)) == NULL)
-			return -1;
-
-		hostp += len;
-		total += len;
-
-		n++;
-	}
-
-	return n;
-}
-
-
-int
-rmtab_cmp_min(rmtab_node *left, rmtab_node *right)
-{
-	int rv = 0;
-
-	if (!left || !right)
-		return ( !!right - !!left );
-
-	if ((rv = strcmp(left->rn_hostname, right->rn_hostname)))
-		return rv;
-
-	return (strcmp(left->rn_path, right->rn_path));
-}
-
-
-/*
- * Compares two rmtab_nodes.
- */
-int
-rmtab_cmp(rmtab_node *left, rmtab_node *right)
-{
-	int rv;
-
-	if ((rv = rmtab_cmp_min(left,right)))
-		return rv;
-
-	if (left->rn_count > right->rn_count)
-		return -1;
-
-	return (left->rn_count < right->rn_count);
-}
-
-
-/*
- * Kill an old rmtab in dest and overwrite with *src.
- */
-int
-rmtab_move(rmtab_node **dest, rmtab_node **src)
-{
-	rmtab_kill(dest);
-
-	*dest = *src;
-	*src = NULL;
-
-	return 0;
-}
-
-
-#ifdef DEBUG
-/*
- * prints the contents of **head
- */
-int
-rmtab_dump(rmtab_node *head)
-{
-	rmtab_node *curr;
-       
-	for (curr = head; curr; curr = curr->rn_next)
-		printf("%s:%s:0x%08x\n",curr->rn_hostname,curr->rn_path,
-		       curr->rn_count);
-	return 0;
-}
-#endif
-





More information about the Cluster-devel mailing list