[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