public inbox for cluster-cvs@sourceware.org
help / color / mirror / Atom feed
From: Lon Hohberger <lon@fedoraproject.org>
To: cluster-cvs-relay@redhat.com
Subject: cluster: STABLE3 - rgmanager: Remove unused proof-of-concept code
Date: Mon, 22 Jun 2009 13:33:00 -0000	[thread overview]
Message-ID: <20090622133232.79ECE1201EF@lists.fedorahosted.org> (raw)

Gitweb:        http://git.fedorahosted.org/git/cluster.git?p=cluster.git;a=commitdiff;h=52685e0f57063583d6af537d1ea2e1539e437372
Commit:        52685e0f57063583d6af537d1ea2e1539e437372
Parent:        a4c5b74ee1152c6645e77b0a778a83c491d07597
Author:        Lon Hohberger <lhh@redhat.com>
AuthorDate:    Fri May 29 10:30:19 2009 -0400
Committer:     Lon Hohberger <lhh@redhat.com>
CommitterDate: Mon Jun 22 09:32:02 2009 -0400

rgmanager: Remove unused proof-of-concept code

This code implmented a rudimentary A* search
dependency engine.  Unfortunately:

* rgmanager didn't use it
* it was buggy and incomplete
* it causes lots of compiler warnings

Signed-off-by: Lon Hohberger <lhh@redhat.com>
---
 rgmanager/include/depends.h     |  134 ---
 rgmanager/src/daemons/Makefile  |    6 +-
 rgmanager/src/daemons/depends.c | 2512 ---------------------------------------
 rgmanager/src/daemons/dtest.c   |  810 -------------
 rgmanager/src/daemons/test.c    |   40 -
 5 files changed, 2 insertions(+), 3500 deletions(-)

diff --git a/rgmanager/include/depends.h b/rgmanager/include/depends.h
deleted file mode 100644
index 72f2958..0000000
--- a/rgmanager/include/depends.h
+++ /dev/null
@@ -1,134 +0,0 @@
-#ifndef _DEPENDS_H
-#define _DEPENDS_H
-
-#include <resgroup.h>
-#include <list.h>
-
-typedef enum {
-	DEP_COLO_UNSPEC		= 0,
-	DEP_COLO_ALWAYS		= 1,
-	DEP_COLO_NEVER		= 2
-} dep_colo_t;
-
-typedef enum {
-	DEP_REQ_UNSPEC		= 0,
-	DEP_REQ_START		= 1,
-	DEP_REQ_ALWAYS		= 2
-} dep_req_t;
-
-typedef enum {
-	DEP_FLAG_CYCLIC		= 0x1,
-	DEP_FLAG_TERMINAL	= 0x2,
-	DEP_FLAG_IMPOSSIBLE	= 0x4,
-	DEP_FLAG_IMPLIED	= 0x8,
-	DEP_FLAG_NEVER		= 0x10,
-	DEP_FLAG_ALWAYS		= 0x20
-} dep_flag_t;
-
-typedef enum {
-	RS_ILLEGAL_NODE	= 0x1,
-	RS_DEAD_NODE	= 0x2,
-	RS_BEEN_STARTED	= 0x4,
-	RS_BEEN_STOPPED = 0x8,
-	RS_IMMUTABLE    = 0x10,
-	RS_ORDERED	= 0x20,
-	RS_FAILBACK	= 0x40,
-	RS_BROKEN	= 0x80
-} rs_flag_t;
-
-typedef enum {
-	DN_BROKEN_COLO	= 0x1,
-	DN_BROKEN_NONCOLO	= 0x2,
-	DN_BROKEN_REQ	= 0x4
-} dep_node_flag_t;
-
-typedef struct _dn_node {
-	list_head();
-	char		*dn_name;
-	struct _dep	*dn_ptr;
-	dep_colo_t	dn_colo;
-	dep_req_t	dn_req;
-	int		dn_traversed;
-	dep_node_flag_t	dn_flags;
-} dep_node_t;
-
-typedef struct _dep {
-	list_head();
-	char *d_name;
-	dep_node_t *d_nodes;
-	dep_flag_t d_flags;
-	int d_hits;
-	int d_deps;
-} dep_t;
-
-
-typedef struct _res_state {
-	rg_state_t	rs_status;
-	int 		*rs_allowed;
-	int		rs_allowed_len;
-	rs_flag_t	rs_flags;
-} dep_rs_t;
-
-
-/* List of operations to take current state -> ideal state */
-typedef struct _dep_op {
-	list_head();
-	struct _dep_op	*do_child;
-	char		do_res[64];	
-	int		do_op;
-	int		do_nodeid;
-	int		do_iter;
-} dep_op_t;
-	
-
-
-int construct_depends(int ccsfd, dep_t **deps);
-void deconstruct_depends(dep_t **deps);
-void print_depends(FILE *fp, dep_t **deps);
-void print_depends_dot(FILE *fp, dep_t **deps);
-
-/* Check cluster state given:
- * all resource (service) states,
- * all available nodes to each resource,
- * all online nodes.
- * 
- * Returns # of errors (negative), # of stopped services (positive), or
- * 0 if the cluster state is ideal.
- * 
- * Note: Call dep_reset() when you're done to clear error flags in the
- * graph.
- */
-int dep_check(dep_t **deps, dep_rs_t *states, int slen,
-		    int *nodes, int nlen);
-
-/* Clear error flags in the graph + states */
-void dep_reset(dep_t **deps, dep_rs_t *rs, int slen);
-
-/* Print out our errors */
-void dep_print_errors(dep_t **deps, dep_rs_t *rs, int slen);
-
-dep_rs_t * dep_rstate_alloc(resource_node_t **restree, fod_t **domains,
-			     int *nodes, int nlen, int *rs_cnt);
-void dep_rstate_free(dep_rs_t *states, int cnt);
-
-/* Dump graphviz-compatible output to fp (includes errors in graph */
-int dep_cluster_state_dot(FILE *fp, dep_t **deps, dep_rs_t *states, int slen,
-			  int *nodes, int nlen);
-int dep_cluster_state(FILE *fp, dep_t **deps, dep_rs_t *states, int slen,
-		      int *nodes, int nlen);
-
-/* Calculate transition list */
-int dep_calc_trans(dep_t **deps, dep_rs_t *states, int slen,
-		   int *nodes, int nlen, dep_op_t **op_list, int *iter);
-
-int dep_copy_tree(dep_t **dest, dep_t **src);
-
-int dep_apply_trans(dep_t **deps, dep_rs_t *states,
-		    int slen, dep_op_t **op_list);
-
-int dep_check_operation(char *res, int operation, int target, 
-		    dep_t **deps, dep_rs_t *_states,
-		    int slen, int *nodes, int nlen, dep_op_t **oplist);
-int dep_tree_dup(dep_t **dest, dep_t **src);
-
-#endif
diff --git a/rgmanager/src/daemons/Makefile b/rgmanager/src/daemons/Makefile
index 14f269a..7ce5a96 100644
--- a/rgmanager/src/daemons/Makefile
+++ b/rgmanager/src/daemons/Makefile
@@ -14,8 +14,7 @@ include $(OBJDIR)/make/clean.mk
 include $(OBJDIR)/make/install.mk
 include $(OBJDIR)/make/uninstall.mk
 
-OBJS1=	depends.o \
-	fo_domain.o \
+OBJS1=	fo_domain.o \
 	groups.o \
 	main.o \
 	reslist.o \
@@ -37,8 +36,7 @@ OBJS2=	test-noccs.o
 
 OBJS3=	dtest-noccs.o
 
-SHAREDOBJS=	depends-noccs.o \
-		fo_domain-noccs.o \
+SHAREDOBJS=	fo_domain-noccs.o \
 		restart_counter.o \
 		reslist-noccs.o \
 		resrules-noccs.o \
diff --git a/rgmanager/src/daemons/depends.c b/rgmanager/src/daemons/depends.c
deleted file mode 100644
index d9dda8d..0000000
--- a/rgmanager/src/daemons/depends.c
+++ /dev/null
@@ -1,2512 +0,0 @@
-/** @file
- * CCS dependency parsing, based on failover domain parsing
- * Transition generation based on simple brute-force / best-first
- * tree search.
- * 
- * Allows specification of two types of rules concerning service states:
- * 
- * - requirement: A -> B means B must be running either for A to start or
- *                at all times (if B stops, A will be stopped)
- * - colocation: A -> B means that A must be run on the same node as B
- *               (note that colocation doesn't mean that B must be running;
- *               to do both, you must enable a requirement).
- *               A X> B means that A must be run on a different node from B.
- *
- * Known bugs:  If more than 1 error is introduced in the graph,
- *              the 'find-ideal-state' function sometimes will refuse to run
- */
-#include <string.h>
-#include <list.h>
-#include <time.h>
-#include <restart_counter.h>
-#include <logging.h>
-#include <resgroup.h>
-#include <reslist.h>
-#include <ccs.h>
-#include <pthread.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <members.h>
-#include <reslist.h>
-#include <depends.h>
-#include <ctype.h>
-
-struct _try {
-	dep_op_t *ops;
-	int score;
-	int depth;
-};
-
-void deconstruct_dep(dep_t *dep);
-int dep_graph_validate(dep_t **deps);
-fod_t *fod_find_domain(fod_t **domains, char *name);
-
-//#define DEBUG
-
-#ifdef NO_CCS
-#define ccs_get(fd, query, ret) conf_get(query, ret)
-#endif
-
-/*
-   <dependencies>
-     <dependency name="service:bar">
-       <target name="service:foo" colocate="always|never|unspec"
-               require="start|always|unspec"/>
-     </dependency>
-   </dependencies>
- */
-
-static dep_node_t *
-get_dep_node(int ccsfd, char *base, int idx, dep_t *dep, int *_done)
-{
-	dep_node_t *dn;
-	char xpath[256];
-	char *ret;
-	int c;
-
-	*_done = 0;
-	snprintf(xpath, sizeof(xpath), "%s/target[%d]/@name",
-		 base, idx);
-	if (ccs_get(ccsfd, xpath, &ret) != 0) {
-		*_done = 1;
-		return NULL;
-	}
-
-	list_for(&dep->d_nodes, dn, c) {
-		if (strcasecmp(ret, dn->dn_name))
-			continue;
-
-		printf("#XX: Target %s defined multiple times in "
-		       "dependency block %s\n", ret, dep->d_name);
-		free(ret);
-		return NULL;
-	}
-
-	dn = malloc(sizeof(*dn));
-	if (!dn)
-		return NULL;
-	memset(dn, 0, sizeof(*dn));
-
-	/* Already malloc'd; simply store */
-	dn->dn_name = ret;
-	dn->dn_ptr = NULL;
-	dn->dn_req = DEP_REQ_UNSPEC;
-	dn->dn_colo = DEP_COLO_UNSPEC;
-
-	snprintf(xpath, sizeof(xpath), "%s/target[%d]/@require",
-		 base, idx);
-	if (ccs_get(ccsfd, xpath, &ret) == 0 && ret) {
-		
-		if (!strcasecmp(ret, "start")) {
-			dn->dn_req = DEP_REQ_START;
-		} else if (!strcasecmp(ret, "always")) {
-			dn->dn_req = DEP_REQ_ALWAYS;
-		} else if (!strcasecmp(ret, "unspec")) {
-			dn->dn_req = DEP_REQ_UNSPEC;
-		} else {
-			dn->dn_req = atoi(ret);
-		}
-		
-		free(ret);
-	}
-	
-	snprintf(xpath, sizeof(xpath), "%s/target[%d]/@colocate",
-		 base, idx);
-	if (ccs_get(ccsfd, xpath, &ret) == 0 && ret) {
-		
-		if (!strcasecmp(ret, "never")) {
-			dn->dn_colo = DEP_COLO_NEVER;
-		} else if (!strcasecmp(ret, "always")) {
-			dn->dn_colo = DEP_COLO_ALWAYS;
-		} else if (!strcasecmp(ret, "unspec")) {
-			dn->dn_colo = DEP_COLO_UNSPEC;
-		} else {
-			dn->dn_colo = atoi(ret);
-		}
-		
-		free(ret);
-	}
-	
-	if (dn->dn_req == DEP_REQ_UNSPEC &&
-	    dn->dn_colo == DEP_COLO_UNSPEC) {
-		printf("Dropping dependency target %s: no rule in use\n",
-		       dn->dn_name);
-		free(dn->dn_name);
-		free(dn);
-		return NULL;
-	}
-
-	return dn;
-}
-
-
-static dep_t *
-get_dep(int ccsfd, char *base, int idx, dep_t **deps, int *_done)
-{
-	dep_t *dep;
-	dep_node_t *dn;
-	char xpath[256];
-	char *ret;
-	int x = 1, c;
-	int done;
-
-	*_done = 0;
-	snprintf(xpath, sizeof(xpath), "%s/dependency[%d]/@name",
-		 base, idx);
-	if (ccs_get(ccsfd, xpath, &ret) != 0) {
-		*_done = 1;
-		return NULL;
-	}
-
-	list_for(deps, dep, c) {
-		if (strcasecmp(dep->d_name, ret))
-			continue;
-		    
-		printf("#XX: Dependency block %s defined multiple "
-				"times\n", ret);
-		free(ret);
-		return NULL;
-	}
-
-	dep = malloc(sizeof(*dep));
-	if (!dep)
-		return NULL;
-	memset(dep, 0, sizeof(*dep));
-	dep->d_name = ret;
-	dep->d_nodes = NULL;
-	dep->d_flags = 0;
-	dep->d_hits = 0;
-	dep->d_deps = 0;
-
-	snprintf(xpath, sizeof(xpath), "%s/dependency[%d]",
-		 base, idx);
-
-	do {
-		dn = get_dep_node(ccsfd, xpath, x++, dep, &done);
-		if (dn) {
-			dep->d_deps++;
-			list_insert(&dep->d_nodes, dn);
-		}
-	} while (!done);
-	
-	if (!dep->d_nodes) {
-		printf("Dropping dependency block %s: No targets\n",
-		       dep->d_name);
-		free(dep->d_name);
-		free(dep);
-		return NULL;
-	}
-
-	return dep;
-}
-
-
-/**
- * Constructs links in the dependency tree
- */
-static void
-dep_construct_tree(dep_t **deps)
-{
-	dep_t *curr, *curr2, *dep;
-	dep_node_t *dn;
-	int done, found, a, b, c;
-	
-	do {
-		done = 1;
-		list_for(deps, curr, a) {
-			list_for(&curr->d_nodes, dn, b) {
-				found = 0;
-				list_for(deps, curr2, c) {
-					if (!strcasecmp(curr2->d_name,
-							dn->dn_name)) {
-						if (!dn->dn_ptr) {
-							dn->dn_ptr = curr2;
-							dn->dn_ptr->d_hits++;
-						}
-						found = 1;
-					}
-				}
-				
-				if (!found) {
-					done=0;
-					
-					dep = malloc(sizeof(*dep));
-					if (!dep)
-						return;
-					memset(dep, 0, sizeof(*dep));
-					dep->d_name = strdup(dn->dn_name);
-					if (!dep->d_name)
-						return;
-					dep->d_nodes = NULL;
-					dep->d_flags = DEP_FLAG_IMPLIED;
-					dep->d_hits = 1;
-					dep->d_deps = 0;
-					dn->dn_ptr = dep;
-					
-					list_insert(deps, dep);
-					
-					break;
-				}
-			}
-			
-			if (!done)
-				break;
-		}
-	} while (!done);
-}
-	
-
-/**
- * similar API to failover domain
- */
-int
-construct_depends(int ccsfd, dep_t **deps)
-{
-	char xpath[256];
-	int x = 1, done, c;
-	dep_t *dep, *curr;
-
-	snprintf(xpath, sizeof(xpath),
-		 RESOURCE_TREE_ROOT "/dependencies");
-
-	do {
-		dep = get_dep(ccsfd, xpath, x++, deps, &done);
-		if (dep) {
-			list_insert(deps, dep);
-		}
-	} while (!done);
-	
-	/* Insert terminal dependency nodes & construct tree */
-	/* XXX optimize */
-	dep_construct_tree(deps);
-
-	dep_graph_validate(deps);
-	
-	do {
-		done = 1;
-		list_for(deps, curr, c) {
-			if (curr->d_flags &
-			    (DEP_FLAG_CYCLIC | DEP_FLAG_IMPOSSIBLE)) {
-				printf("Removing dependency block %s: "
-				       "Invalid\n", curr->d_name);
-				done = 0;
-				
-				list_remove(deps, curr);
-				deconstruct_dep(curr);
-				break;
-			}
-		}
-	} while (!done);
-	
-	return 0;
-}
-
-
-void
-deconstruct_dep(dep_t *dep)
-{
-	dep_node_t *node;
-	
-	while ((node = dep->d_nodes)) {
-		list_remove(&dep->d_nodes, node);
-		if (node->dn_name)
-			free(node->dn_name);
-		free(node);
-	}
-
-	if (dep->d_name)
-		free(dep->d_name);
-	free(dep);
-}
-
-
-void
-deconstruct_depends(dep_t **deps)
-{
-	dep_t *dep = NULL;
-	
-	while ((dep = *deps)) {
-		list_remove(deps, dep);
-		deconstruct_dep(dep);
-	}
-}
-
-
-static inline dep_rs_t *
-_find_state(char *name, dep_rs_t *sl, int slen)
-{
-	int x;
-
-	for (x = 0; x < slen; x++)
-		if (!strcasecmp(sl[x].rs_status.rs_name, name))
-			return &sl[x];
-	
-	return NULL;
-}
-
-
-static int
-rs_running(char *name, dep_rs_t *sl, int slen)
-{
-	dep_rs_t *rs = NULL;
-	
-	if (name) {
-		rs = _find_state(name, sl, slen);
-	} else if (slen == 1) {
-		rs = sl;
-	}
-	
-	if (rs) {
-		if (rs->rs_flags & RS_BROKEN)
-			return -1;
-		return (rs->rs_status.rs_state == RG_STATE_STARTING ||
-			rs->rs_status.rs_state == RG_STATE_STARTED ||
-			rs->rs_status.rs_state == RG_STATE_STOPPING );
-	}
-	
-	return 0;
-}
-
-
-int
-dep_tree_dup(dep_t **dest, dep_t **src)
-{
-	dep_t *dep, *dep_cpy;
-	dep_node_t *dn, *dn_cpy;
-	int a, b;
-	
-	list_for(src, dep, a) {
-		while ((dep_cpy = malloc(sizeof(dep_t))) == NULL)
-			usleep(10000);
-		memset(dep_cpy, 0, sizeof(dep_t));
-		while ((dep_cpy->d_name = strdup(dep->d_name)) == NULL)
-			usleep(10000);
-		
-		dep_cpy->d_flags &= ~(DEP_FLAG_ALWAYS|DEP_FLAG_NEVER);
-		
-		list_for(&dep->d_nodes, dn, b) {
-			while ((dn_cpy = malloc(sizeof(dep_node_t))) == NULL)
-			 	usleep(10000);
-			memset(dn_cpy, 0, sizeof(dep_node_t));
-			while ((dn_cpy->dn_name = strdup(dn->dn_name)) == NULL)
-				usleep(10000);
-			dn_cpy->dn_colo = dn->dn_colo;
-			dn_cpy->dn_req = dn->dn_req;
-			
-			/* Flags are all errors right now... */
-			/* dn_cpy->dn_flags = dn->dn_flags; */
-			list_insert(&dep_cpy->d_nodes, dn_cpy);
-		}
-		
-		list_insert(dest, dep_cpy);
-	}
-	
-	/* Construct internal tree */
-	dep_construct_tree(dest);
-	
-	return 0;
-}
-
-
-static void
-dep_tree_print(FILE *fp, dep_t *start, dep_t *dep, int level)
-{
-	dep_node_t *dn = NULL;
-	int x, c;
-	
-	if (!dep)
-		return;
-	
-	if ((dep == start) && level) {
-		fprintf(fp, "[cycles to %s]\n", start->d_name);
-		return;
-	}
-	
-	fprintf(fp, "%s\n",dep->d_name);
-	
-	if (dep->d_nodes) {
-		list_for(&dep->d_nodes, dn, c) {
-			for (x = 0; x < level; x++)
-				fprintf(fp, "         ");
-			fprintf(fp, "|\n");
-			for (x = 0; x < level; x++)
-				fprintf(fp, "         ");
-			fprintf(fp, "+-");
-			switch(dn->dn_colo) {
-			case DEP_COLO_UNSPEC:
-				fprintf(fp, "--");
-				break;
-			case DEP_COLO_ALWAYS:
-				fprintf(fp, "Ca");
-				break;
-			case DEP_COLO_NEVER:
-				fprintf(fp, "Cn");
-				break;
-			}
-			switch(dn->dn_req) {
-			case DEP_REQ_UNSPEC:
-				fprintf(fp, "--");
-				break;
-			case DEP_REQ_START:
-				fprintf(fp, "Rs");
-				break;
-			case DEP_REQ_ALWAYS:
-				fprintf(fp, "Ra");
-				break;
-			}
-			fprintf(fp, "-> ");
-			
-			if (dn->dn_traversed) {
-				fprintf(fp, "[cycles to %s]\n",
-					dn->dn_ptr->d_name);
-			} else {
-				dn->dn_traversed = 1;
-				dep_tree_print(fp, start, dn->dn_ptr, level+1);
-				dn->dn_traversed = 0;
-			}
-			      
-		}
-	}
-}
-
-
-static void
-_dot_clean_string(char *str)
-{
-	int x;
-	
-	/*
-	if (strncmp(str, "service:", 8) == 0)
-		memmove(str, str+8, strlen(str)-8+1);
-	*/
-	
-	if (!isalpha(str[0]))
-		str[0] = '_';
-	
-	for (x = 0; x < strlen(str); x++) {
-		if (isalnum(str[x]))
-			continue;
-		if (str[x] == '_' || str[x] == '-')
-			continue;
-		str[x] = '_';
-	}
-}
-
-
-void
-print_dep_tree_dot(FILE *fp, dep_t *start, dep_t *dep, int level)
-{
-	dep_node_t *dn = NULL;
-	char src[64], dest[64];
-	int c;
-	
-	if (!dep)
-		return;
-	
-	if ((dep == start) && level)
-		return;
-	
-	if (dep->d_nodes) {
-		list_for(&dep->d_nodes, dn, c) {
-			if (dn->dn_traversed)
-				continue;
-			
-			strncpy(src, dep->d_name, sizeof(src));
-			strncpy(dest, dn->dn_name, sizeof(dest));
-			_dot_clean_string(src);
-			_dot_clean_string(dest);
-		
-			dn->dn_traversed = 1;
-			switch(dn->dn_colo) {
-			case DEP_COLO_UNSPEC:
-				break;
-			case DEP_COLO_ALWAYS:
-				fprintf(fp, "\tedge [color=black, "
-					    "arrowhead=diamond, label=\"Ca\"");
-				if (dn->dn_flags & DN_BROKEN_COLO)
-					fprintf(fp, ", style=dashed");
-				else
-					fprintf(fp, ", style=solid");
-				fprintf(fp, "];\n");
-				fprintf(fp, "\t%s -> %s;\n", src, dest);
-				break;
-			case DEP_COLO_NEVER:
-				fprintf(fp, "\tedge [color=red, "
-					    "arrowhead=diamond, label=\"Cn\"");
-				if (dn->dn_flags & DN_BROKEN_NONCOLO)
-					fprintf(fp, ", style=dashed");
-				else
-					fprintf(fp, ", style=solid");
-				fprintf(fp, "];\n");
-				fprintf(fp, "\t%s -> %s;\n", src, dest);
-				break;
-			}
-			switch(dn->dn_req) {
-			case DEP_REQ_UNSPEC:
-				break;
-			case DEP_REQ_START:
-				fprintf(fp, "\tedge [color=green, "
-					    "arrowhead=vee, label=\"Rs\"");
-				if (dn->dn_flags & DN_BROKEN_REQ)
-					fprintf(fp, ", style=dashed");
-				else
-					fprintf(fp, ", style=solid");
-				fprintf(fp, "];\n");
-				fprintf(fp, "\t%s -> %s;\n", src, dest);
-				break;
-			case DEP_REQ_ALWAYS:
-				fprintf(fp, "\tedge [color=black, "
-					    "arrowhead=vee, label=\"Ra\"");
-				if (dn->dn_flags & DN_BROKEN_REQ)
-					fprintf(fp, ", style=dashed");
-				else
-					fprintf(fp, ", style=solid");
-				fprintf(fp, "];\n");
-				fprintf(fp, "\t%s -> %s;\n", src, dest);
-				break;
-			}
-			
-			print_dep_tree_dot(fp, start, dn->dn_ptr, level+1);
-			      
-		}
-	}
-}
-
-
-/**
- * Check for cyclic 'require' dependency.
- */
-static int
-find_cyclic_req(dep_t *dep, dep_t *what)
-{
-	dep_node_t *dn;
-	int ret, c;
-	
-	if (dep == what)
-		return 2;
-	
-	if (!dep->d_nodes)
-		return 0;
-	
-	/* initialize */
-	if (what == NULL)
-		what = dep;
-	
-	list_for(&dep->d_nodes, dn, c) {
-		
-		if (!dn->dn_traversed &&
-		    dn->dn_req != DEP_REQ_UNSPEC) {
-			dn->dn_traversed = 1;
-			ret = find_cyclic_req(dn->dn_ptr, what);
-			dn->dn_traversed = 0;
-			
-			if (ret == 2) {
-				printf("Error: Cyclic Requirement: \n");
-				printf("   %s ... -> %s -> %s\n",
-					what->d_name,
-					dep->d_name,
-					dn->dn_ptr->d_name);
-			}
-			if (ret)
-				return 1;
-		} else if (dn->dn_traversed)
-			return 1;
-	}
-	
-	return 0;
-}
-
-
-/**
- * Tag all nodes which have colocation requirements
- */
-static int
-tag_colo(dep_t *dep, dep_t *what, dep_colo_t colo)
-{
-	dep_node_t *dn;
-	int ret = 0, c;
-	
-	/* How did we get here? */
-	switch(colo) {
-	case DEP_COLO_ALWAYS:
-		if (dep->d_flags & DEP_FLAG_NEVER)
-			ret = 1;
-		dep->d_flags |= DEP_FLAG_ALWAYS;
-		break;
-	case DEP_COLO_NEVER:
-		if (dep->d_flags & DEP_FLAG_ALWAYS)
-			ret = 1;
-		dep->d_flags |= DEP_FLAG_NEVER;
-		break;
-	default:
-		break;
-	}
-	
-	if (dep == what) 
-		goto out;
-	
-	if (!dep->d_nodes)
-		goto out;
-	
-	/* Start if this is the first call*/
-	if (what == NULL)
-		what = dep;
-	
-	list_for(&dep->d_nodes, dn, c) {
-		
-		if (!dn->dn_traversed) {
-			dn->dn_traversed = 1;
-			ret += tag_colo(dn->dn_ptr, what, dn->dn_colo);
-			dn->dn_traversed = 0;
-		}
-		
-	}
-	
-out:
-	if (ret)
-		dep->d_flags |= DEP_FLAG_IMPOSSIBLE;
-	return ret;
-}
-
-
-int
-dep_print_dep_errors(dep_t **deps)
-{
-	dep_t *dep;
-	dep_node_t *dn;
-	int a, b;
-	
-	list_for(deps, dep, a) {
-		list_for(&dep->d_nodes, dn, b) {
-			if (dn->dn_flags & DN_BROKEN_COLO) {
-				printf("Resource %s must colocate with "
-				       "resource %s\n", dep->d_name,
-				       dn->dn_name);
-			}
-			if (dn->dn_flags & DN_BROKEN_NONCOLO) {
-				printf("Resource %s must never colocate with "
-					"resource %s\n", dep->d_name,
-					dn->dn_name);
-			}
-			if (dn->dn_flags & DN_BROKEN_REQ) {
-				printf("Resource %s depends on "
-					"resource %s\n", dep->d_name,
-					dn->dn_name);
-			}
-		}
-	}
-	
-	return 0;
-}
-
-
-int
-dep_print_state_errors(dep_rs_t *rs, int slen)
-{
-	int x;
-	
-	for (x = 0; x < slen; x++) {
-		if (rs[x].rs_flags & RS_ILLEGAL_NODE)
-			printf("Resource %s on illegal node %d\n",
-				rs[x].rs_status.rs_name,
-				rs[x].rs_status.rs_owner);
-		if (rs[x].rs_flags & RS_DEAD_NODE)
-			printf("Resource %s on dead/offline node %d\n",
-				rs[x].rs_status.rs_name,
-				rs[x].rs_status.rs_owner);
-	}
-	return 0;
-}
-
-
-/**
- * clear our loop detection
- */
-int
-dep_clear_dep_errors(dep_t **deps)
-{
-	dep_t *dep;
-	dep_node_t *dn;
-	int a, b;
-	
-	list_for(deps, dep, a) {
-		dep->d_flags &= ~(DEP_FLAG_ALWAYS | DEP_FLAG_NEVER);
-		
-		list_for(&dep->d_nodes, dn, b) {
-			dn->dn_traversed = 0;
-			dn->dn_flags = 0;
-		}
-	}
-	
-	return 0;
-}
-
-
-int
-dep_clear_traversed(dep_t **deps)
-{
-	dep_t *dep;
-	dep_node_t *dn;
-	int a, b;
-	
-	list_for(deps, dep, a) {
-		list_for(&dep->d_nodes, dn, b) {
-			dn->dn_traversed = 0;
-		}
-	}
-	
-	return 0;
-}
-
-
-int
-dep_clear_state_errors(dep_rs_t *rs, int slen)
-{
-	int x;
-	for (x = 0; x < slen; x++)
-		rs[x].rs_flags &= ~(RS_ILLEGAL_NODE|RS_DEAD_NODE);
-	return 0;
-}
-
-
-void
-dep_reset(dep_t **deps, dep_rs_t *rs, int slen)
-{
-	dep_clear_dep_errors(deps);
-	dep_clear_state_errors(rs, slen);
-}
-
-
-void
-dep_print_errors(dep_t **deps, dep_rs_t *rs, int slen)
-{
-	dep_print_dep_errors(deps);
-	dep_print_state_errors(rs, slen);
-}
-
-
-int
-dep_graph_validate(dep_t **deps)
-{
-	dep_t *dep;
-	dep_flag_t f;
-	int a;
-	
-	list_for(deps, dep, a) {
-		
-		if (find_cyclic_req(dep, NULL)) {
-			printf("Cyclic requirement dependency in block %s\n",
-					dep->d_name);
-			dep->d_flags |= DEP_FLAG_CYCLIC;
-		}
-		
-		tag_colo(dep, NULL, 0);
-	}
-	
-	f = (DEP_FLAG_ALWAYS | DEP_FLAG_NEVER);
-	list_for(deps, dep, a) {
-		if (((dep->d_flags & f) == f) ||
-		    (dep->d_flags & DEP_FLAG_IMPOSSIBLE)) {
-			printf("Graph %s: colocation conflict\n", dep->d_name);
-			dep->d_flags |= DEP_FLAG_IMPOSSIBLE;
-		}
-	}
-	
-	return 0;
-}
-
-
-void
-print_depends(FILE *fp, dep_t **deps)
-{
-	dep_t *dep;
-	int a;
-
-	list_for(deps, dep, a) {
-		if (dep->d_nodes && !(dep->d_flags & DEP_FLAG_IMPLIED) &&
-		    dep->d_hits == 0) {
-			dep_tree_print(fp, dep, dep, 0); 
-			fprintf(fp,"\n");
-		}
-	}
-}
-
-
-static void
-_print_depends_dot(FILE *fp, dep_t **deps)
-{
-	dep_t *dep;
-	int a;
-
-	list_for(deps, dep, a) {
-		print_dep_tree_dot(fp, dep, dep, 0); 
-	}
-	
-	dep_clear_traversed(deps);
-}
-
-
-void
-print_depends_dot(FILE *fp, dep_t **deps)
-{
-	fprintf(fp, "digraph G {\n");
-	_print_depends_dot(fp, deps);
-	fprintf(fp, "}\n");
-}
-
-
-/**
- * check to ensure a resource is on an allowed node.
- * Note - makes no assumption about the actual resource state; it could be
- * in the stopped state.
- */
-int
-dep_check_res_loc(dep_rs_t *state)
-{
-	int x;
-	
-	if (!rs_running(NULL, state, 1)) {
-		/* Not running = location is perfectly fine ... sort of */
-		return 0;
-	}
-		
-	if (!state->rs_allowed || state->rs_allowed_len <= 0)
-		return 0;
-	
-	for (x = 0; x < state->rs_allowed_len; x++) {
-		if (state->rs_status.rs_owner == state->rs_allowed[x])
-			return 0;
-	}
-	
-	/* Didn't match a legal node -> fail */
-	state->rs_flags |= RS_ILLEGAL_NODE;
-	return 1;
-}
-
-
-static dep_t *
-find_dep(dep_t **deps, char *name)
-{
-	dep_t *dep = NULL;
-	int a;
-	
-	if (!deps)
-		return NULL;
-	
-	list_for(deps, dep, a) {
-		if (!strcasecmp(dep->d_name, name))
-			return dep;
-	}
-	
-	return NULL;
-}
-
-
-/**
- * traverses the requirements tree looking for 'name'
- * returns 1 if found, 0 if not
- */
-static int
-_tree_walk_req(dep_t *dep, dep_rs_t *state, dep_rs_t *sl, int slen)
-{
-	dep_node_t *dn;
-	int errors = 0, ret, a;
-	
-	if (!dep  || !dep->d_nodes)
-		return 0;
-	
-	list_for(&dep->d_nodes, dn, a) {
-		
-		/* If we have a specified requirement... */
-		ret = 0;
-		if (!dn->dn_traversed &&
-		    dn->dn_req != DEP_REQ_UNSPEC) {
-			
-			/* see if our child is running.  If not, we're done */
-			ret = rs_running(dn->dn_name, sl, slen);
-			
-			/* XXX check for req-start vs. req-always */
-			if (ret <= 0) {
-				dn->dn_flags |= DN_BROKEN_REQ;
-				state->rs_flags |= RS_BROKEN;
-				ret = 1;
-			} else {
-				dn->dn_traversed = 1;
-				ret = _tree_walk_req(dn->dn_ptr,
-						_find_state(dn->dn_name, sl, slen), sl, slen);
-				dn->dn_traversed = 0;
-			}
-			
-			if (ret) {
-				errors += ret;
-				dn->dn_flags |= DN_BROKEN_REQ;
-				state->rs_flags |= RS_BROKEN;
-			}
-		}
-	}
-	
-	return errors;
-}
-
-/*
- * Returns nonzero if something requires this resource, 0 if not
- */
-int
-dep_check_requires(dep_t **deps, dep_rs_t *state, dep_rs_t *states, int slen)
-{
-	dep_t *dep;
-	int errors = 0, a;
-	
-	/* Check to see if anything depends on this (not-running) resource */
-	list_for(deps, dep, a) {
-		errors += _tree_walk_req(dep, NULL, /*state->rs_status.rs_name,*/
-					 states, slen);
-	}
-	
-	/* Flag requirements on any broken-dep resources as broken, too... */
-	dep_clear_traversed(deps);
-	
-	return errors;
-}
-
-
-/**
- * Check to see if this resource is causing a conflict.  It can cause a
- * conflict if it is stopped but other resources depend on it.
- * If it is running, it can not cause a requirement conflict, but it might
- * cause a colocation conflict.
- */
-static int
-_dep_check_requires(dep_t **deps, dep_rs_t *state, dep_rs_t *states, int slen)
-{
-	/* if not running, it has no dependencies */
-	if (!rs_running(NULL, state, 1))
-		return 0;
-	
-	return _tree_walk_req(find_dep(deps, state->rs_status.rs_name),
-			state, states, slen);
-	
-	//return dep_check_requires(deps, state, states, slen);
-}
-
-/**
- * Checks the tree to see if there's a colocation requiremet on the given
- * resource.  Returns 1 if found, 0 if not.
- * returns 1 if found, 0 if not  We don't need to recurse on this one.
- */
-static int
-_tree_walk_colo(dep_t *dep, dep_t *start, char *name, dep_rs_t *sl, int slen)
-{
-	dep_node_t *dn;
-	dep_rs_t *state;
-	int errors = 0, a;
-	
-	if (dep == start) 
-		return 0;
-	
-	if (!dep->d_nodes)
-		return 0;
-	
-	/* Start if this is the first call*/
-	if (start == NULL)
-		start = dep;
-	
-	state = _find_state(dep->d_name, sl, slen);
-	if (!state)
-		return 0;
-	
-	list_for(&dep->d_nodes, dn, a) {
-		
-		/* If we have a specified requirement... */
-		if (!dn->dn_traversed &&
-		    dn->dn_colo == DEP_COLO_ALWAYS) {
-			
-			if (!strcasecmp(dn->dn_name, name) &&
-			    !(dn->dn_flags & DN_BROKEN_COLO)) {
-				/* Broken colocation req */
-				state->rs_flags |= RS_BROKEN;
-				dn->dn_flags |= DN_BROKEN_COLO;
-				++errors;
-			}
-			dn->dn_traversed = 1;
-			errors += _tree_walk_colo(dn->dn_ptr, start, name,
-						  sl, slen);
-			dn->dn_traversed = 0;
-		}
-	}
-	
-	return errors;
-}
-
-
-/**
- * Checks the immediate children of the given dependency to see if there's a
- * non-colocation requiremet on the given resource.  Returns 1 if found,
- * 0 if not.
- */
-static int
-_tree_walk_noncolo(dep_t *dep, dep_t *start, char *name, dep_rs_t *sl,
-		   int slen)
-{
-	dep_node_t *dn;
-	dep_rs_t *state;
-	int errors = 0, a;
-	
-	if (dep == start) 
-		return 0;
-	
-	if (!dep->d_nodes)
-		return 0;
-	
-	/* Start if this is the first call*/
-	if (start == NULL)
-		start = dep;
-	
-	state = _find_state(dep->d_name, sl, slen);
-	if (!state)
-		return 0;
-	
-	list_for(&dep->d_nodes, dn, a) {
-		
-		/* If we have a specified requirement... */
-		if (dn->dn_colo == DEP_COLO_NEVER) {
-			
-			if (!strcasecmp(dn->dn_name, name) &&
-			    !(dn->dn_flags & DN_BROKEN_COLO)) {
-				/* Broken noncolo req */
-				state->rs_flags |= RS_BROKEN;
-				dn->dn_flags |= DN_BROKEN_NONCOLO;
-				++errors;
-			}
-		}
-	}
-	
-	return errors;
-}
-
-
-int
-dep_check_colo(dep_t **deps, dep_rs_t *states, int slen,
-	       char *name, int nodeid)
-{
-	dep_t *dep;
-	int x, errors = 0;
-	
-	if (!deps)
-		return 0;
-	dep = find_dep(deps, name);
-	if (!dep)
-		return 0;
-	
-	for (x = 0; x < slen; x++) {
-		
-		if (!rs_running(NULL, &states[x], 1)) {
-			/*
-			 * Non-running resources don't cause colo/noncolo
-			 * conflicts
-			 */
-			continue;
-		}
-		
-		/*
-		 * Two resources on different nodes... see if the specified
-		 * one is causing a colocation conflict (e.g. another one
-		 * must colocate with it)
-		 */
-		if (states[x].rs_status.rs_owner != nodeid) {
-			errors += _tree_walk_colo(dep, NULL,
-					states[x].rs_status.rs_name, states,
-					slen);
-		}
-		
-		/*
-		 * two resources on the same node... see if the specified one
-		 * is causing a colocation conflict (e.g. another one must
-		 * NOT colocate with it)
-		 */
-		if (states[x].rs_status.rs_owner == nodeid) {
-			errors += _tree_walk_noncolo(dep, NULL,
-					states[x].rs_status.rs_name,
-					states, slen);
-		}
-	}
-	
-	dep_clear_traversed(deps);
-	
-	return errors;
-}
-
-
-/**
- * Check to see if this resource is causing a colocation conflict.  It can
- * not cause if it is stopped.  If it is running, it can cause a colocation
- * conflict if something must not colocate with it.
- */
-static int
-_dep_check_colo(dep_t **deps, dep_rs_t *states, int slen, dep_rs_t *state)
-{
-	if (!rs_running(NULL, state, 1)) {
-		/* not running : cannot be causing a colo conflict */
-		return 0;
-	}
-	
-	return dep_check_colo(deps,
-			      states,
-			      slen,
-			      state->rs_status.rs_name,
-			      state->rs_status.rs_owner);
-}
-
-
-int
-dep_check_online(dep_rs_t *rs, int *nodes, int nlen)
-{
-	int x;
-	
-	if (!rs_running(NULL, rs, 1)) {
-		return 0;
-	}
-	for (x = 0; x < nlen; x++){
-		if (rs->rs_status.rs_owner == nodes[x])
-			return 0;
-	}
-	
-	rs->rs_flags |= RS_DEAD_NODE;
-	return 1;
-}
-
-
-/**
- * Validate the current state of the cluster.  This traverses the dependency
- * graph looking for conflicts, as well as obvious errors (e.g. resource
- * outside failover domain constraint, for example.
- * 
- * @return		-1 for invalid, 0 for ideal, or the # of services 
- * 			which need to be started to become ideal.
- */
-int
-dep_check(dep_t **deps, dep_rs_t *states, int slen, int *nodes, int nlen)
-{
-	int x, ret = 0, errors = 0;
-	
-	dep_clear_dep_errors(deps);
-	dep_clear_state_errors(states, slen);
-	
-	for (x = 0; x < slen; x++) {
-		
-		if (states[x].rs_status.rs_state == RG_STATE_STOPPED)
-			++ret;
-			
-		/*
-		 * Pass 1: Check for services started on dead nodes
-		 */
-		errors += dep_check_online(&states[x], nodes, nlen);
-	
-		/*
-		 * Pass 2: Check obvious legal-targets for resources
-		 * (failover domain)
-		 */
-		errors += dep_check_res_loc(&states[x]);
-	
-		/*
-		 * Pass 3: Check to see if this resource has all of its a 
-		 * resource dependencies satisfied.
-		 */
-		errors += _dep_check_requires(deps, &states[x], states, slen);
-		
-		/*
-		 * Pass 4: Check to see if this resource is causing a
-		 * colocation conflict (e.g. is cohabiting with a resource
-		 * which must run apart from it)
-		 */
-		errors += _dep_check_colo(deps, states, slen, &states[x]);
-	}
-	
-	if (errors)
-		return -errors;
-	
-	return ret;
-}
-
-
-int
-dep_cluster_state_dot(FILE *fp, dep_t **deps, dep_rs_t *states, int slen,
-		      int *nodes, int nlen)
-{
-	int x, y, z, tmp, off = 0;
-	char str[64];
-	
-	fprintf(fp, "digraph G {\n");
-	
-	/* Print out node states */
-	for (x = 0; x < nlen; x++) {
-		fprintf(fp, "\tsubgraph cluster_%d {\n", x);
-		fprintf(fp, "\t\tlabel=node%d;\n", nodes[x]);
-		fprintf(fp, "\t\tstyle=filled;\n");
-		fprintf(fp, "\t\tcolor=lightgrey;\n");
-		fprintf(fp, "\t\tfontcolor=black;\n");
-		fprintf(fp, "\t\tnode [style=filled, color=lightgrey, "
-			"fontcolor=lightgrey];\n");
-		
-		z = 0;
-		
-		for (y = 0; y < slen; y++) {
-			if (rs_running(NULL, &states[y], 1) &&
-			    states[y].rs_status.rs_owner == nodes[x]) {
-				tmp = 0;
-				if (!states[y].rs_allowed_len)
-					tmp = 1;
-				else {
-					for (z = 0; z<states[y].rs_allowed_len;
-					     z++) {
-						if (states[y].rs_allowed[z] == 
-						    states[y].rs_status.rs_owner) {
-							tmp = 1;
-							break;
-						}
-					}
-				}
-				
-				++z;
-				
-				if (!tmp) {
-					fprintf(fp, "\t\tnode [style=filled, "
-						    "color=\"#ff6060\", "
-						    "shape=box, "
-						    "fontcolor=black];\n");
-				} else {
-					fprintf(fp, "\t\tnode [style=filled, "
-						    "color=white, shape=box, "
-						    "fontcolor=black];\n");
-				}
-				
-				strncpy(str, states[y].rs_status.rs_name,
-					sizeof(str));
-				_dot_clean_string(str);
-				fprintf(fp, "\t\t%s;\n", str);
-			}
-		}
-		
-		if (!z) {
-			snprintf(str, sizeof(str), "node%d", x);
-			fprintf(fp, "\t\t%s;\n", str);
-		}
-		fprintf(fp, "\t}\n");
-	}
-	
-	/* Show all 'started' on dead node resources in a red "node" */
-	off = 0;
-	for (x = 0; x < slen; x++) {
-		
-		if (!(states[x].rs_flags & RS_DEAD_NODE))
-			continue;
-		
-		if (!off) {
-			off = 1;
-			fprintf(fp, "\tsubgraph cluster_%d {\n", nlen+1);
-			fprintf(fp, "\t\tlabel=Dead;\n");
-			fprintf(fp, "\t\tstyle=filled;\n");
-			fprintf(fp, "\t\tcolor=\"#ff6060\";\n");
-			fprintf(fp, "\t\tfontcolor=black;\n");
-			fprintf(fp, "\t\tnode [color=white, style=filled, "
-				    "shape=box, fontcolor=black];\n");
-		}
-			
-		strncpy(str, states[x].rs_status.rs_name, sizeof(str));
-		_dot_clean_string(str);
-		fprintf(fp, "\t\t%s;\n", str);
-	}
-	
-	if (off)
-		fprintf(fp, "\t}\n");
-	
-	/* Show all 'stopped' in a 'stopped' "node" */
-	fprintf(fp, "\tsubgraph cluster_%d {\n", nlen+2);
-	fprintf(fp, "\t\tstyle=filled;\n");
-	fprintf(fp, "\t\tcolor=\"#60ff60\";\n");
-	fprintf(fp, "\t\tfontcolor=black;\n");
-	fprintf(fp, "\t\tlabel=Stopped;\n");
-	fprintf(fp, "\t\tnode [color=white, style=filled, shape=box, "
-		    "fontcolor=black];\n");
-	
-	z = 0;
-	for (x = 0; x < slen; x++) {
-		
-		if (states[x].rs_status.rs_state != RG_STATE_STOPPED)
-			continue;
-		
-		strncpy(str, states[x].rs_status.rs_name, sizeof(str));
-		_dot_clean_string(str);
-		
-		++z;
-		fprintf(fp, "\t\t%s;\n", str);
-	}
-	
-	if (!z) {
-		fprintf(fp, "\t\tnode [style=filled, color=\"#60ff60\", "
-			    "fontcolor=\"#60ff60\"];\n");
-		fprintf(fp, "\t\tStopped;\n");
-	}
-	
-	fprintf(fp, "\t}\n");
-	
-	/* Show all 'disabled' in a 'disabled' "node" */
-	fprintf(fp, "\tsubgraph cluster_%d {\n", nlen+3);
-	fprintf(fp, "\t\tlabel=Disabled;\n");
-	fprintf(fp, "\t\tstyle=filled;\n");
-	fprintf(fp, "\t\tcolor=\"#6060ff\";\n");
-	fprintf(fp, "\t\tfontcolor=black;\n");
-	fprintf(fp, "\t\tnode [color=white, style=filled, shape=box, "
-		    "fontcolor=black];\n");
-	
-	z = 0;
-	for (x = 0; x < slen; x++) {
-		
-		if (states[x].rs_status.rs_state != RG_STATE_DISABLED)
-			continue;
-		
-		++z;
-		strncpy(str, states[x].rs_status.rs_name, sizeof(str));
-		_dot_clean_string(str);
-		fprintf(fp, "\t\t%s;\n", str);
-	}
-	
-	if (!z) {
-		fprintf(fp, "\t\tnode [style=filled, color=\"#6060ff\", "
-			    "fontcolor=\"#6060ff\"];\n");
-		fprintf(fp, "\t\tDisabled;\n");
-	}
-		
-	fprintf(fp, "\t}\n");
-			
-	_print_depends_dot(fp, deps);
-	
-	fprintf(fp, "}\n");
-	
-	return 0;
-}
-
-
-int
-dep_cluster_state(FILE *fp, dep_t **deps, dep_rs_t *states, int slen,
-		  int *nodes, int nlen)
-{
-	int x, y, z, tmp, off = 0;
-	
-	/* Print out node states */
-	for (x = 0; x < nlen; x++) {
-		fprintf(fp, "Node %d\n", nodes[x]);
-		
-		for (y = 0; y < slen; y++) {
-			if (rs_running(NULL, &states[y], 1) &&
-			    states[y].rs_status.rs_owner == nodes[x]) {
-				tmp = 0;
-				if (!states[y].rs_allowed_len)
-					tmp = 1;
-				else {
-					for (z = 0; z<states[y].rs_allowed_len;
-					     z++) {
-						if (states[y].rs_allowed[z] == 
-						    states[y].rs_status.rs_owner) {
-							tmp = 1;
-							break;
-						}
-					}
-				}
-				
-				if (!tmp) {
-					fprintf(fp, "\t[ILLEGAL] ");
-				} else {
-					fprintf(fp, "\t");
-				}
-				
-				fprintf(fp, "%s\n",
-					states[y].rs_status.rs_name);
-			}
-		}
-		fprintf(fp, "\n");
-	}
-	
-	/* Show all 'started' on dead node resources in a red "node" */
-	off = 0;
-	for (x = 0; x < slen; x++) {
-		
-		if (!(states[x].rs_flags & RS_DEAD_NODE))
-			continue;
-		
-		if (!off) {
-			off = 1;
-			fprintf(fp, "Resources on dead nodes:\n");
-		}
-			
-		fprintf(fp, "\t%s\n", states[x].rs_status.rs_name);
-	}
-	
-	if (off)
-		fprintf(fp, "\n");
-	
-	/* Show all 'stopped' in a 'stopped' "node" */
-	fprintf(fp, "Stopped resources:\n");
-	
-	z = 0;
-	for (x = 0; x < slen; x++) {
-		
-		if (states[x].rs_status.rs_state != RG_STATE_STOPPED)
-			continue;
-		
-		fprintf(fp, "\t%s;\n", states[x].rs_status.rs_name);
-	}
-	
-	fprintf(fp, "\n");
-	
-	/* Show all 'disabled' */
-	fprintf(fp, "Disabled resources:\n");
-	
-	z = 0;
-	for (x = 0; x < slen; x++) {
-		
-		if (states[x].rs_status.rs_state != RG_STATE_DISABLED)
-			continue;
-		
-		fprintf(fp, "\t%s;\n", states[x].rs_status.rs_name);
-	}
-	
-	fprintf(fp, "\n");
-	
-	return 0;
-}
-
-/**
-   Gets an attribute of a resource group.
-
-   @param res		Resource
-   @param property	Name of property to check for
-   @param ret		Preallocated return buffer
-   @param len		Length of buffer pointed to by ret
-   @return		0 on success, -1 on failure.
- */
-int
-res_property(resource_t *res, char *property, char *ret, size_t len)
-{
-	int x = 0;
-
-	if (!res)
-		return -1;
-
-	for (; res->r_attrs[x].ra_name; x++) {
-		if (strcasecmp(res->r_attrs[x].ra_name, property))
-			continue;
-		strncpy(ret, res->r_attrs[x].ra_value, len);
-		return 0;
-	}
-
-	return 1;
-}
-
-
-static void
-_set_allowed(dep_rs_t *state, fod_t *domain, int *nodes, int nlen)
-{
-	fod_node_t *fdn;
-	int cnt = 0, allowed = 0, x, y, z, tmp;
-	
-	if (!domain) {
-		state->rs_allowed = malloc(sizeof(int)*nlen);
-		state->rs_allowed_len = nlen;
-		
-		if (!state->rs_allowed)
-			return;
-		memcpy(state->rs_allowed, nodes, sizeof(int)*nlen);
-		return;
-	}
-	
-	if (domain->fd_flags & FOD_RESTRICTED) {
-		list_for(&domain->fd_nodes, fdn, allowed);
-	} else {
-		allowed = nlen;
-	}
-	
-	state->rs_allowed = malloc(sizeof(int)*allowed);
-	state->rs_allowed_len = allowed;
-	state->rs_flags = 0;
-	
-	if (!state->rs_allowed)
-		return;
-	
-	memset(state->rs_allowed, 0, sizeof(int)*allowed);
-	
-	cnt = 0;
-	/* Failover domain prios are 1..100 */
-	if (!(domain->fd_flags & FOD_ORDERED)) {
-		
-		/* Non-prio failover domain */
-		list_for(&domain->fd_nodes, fdn, x) {
-			state->rs_allowed[cnt++] = fdn->fdn_nodeid;
-		}
-	} else {
-		for (x = 0; x <= 100; x++) {
-			list_for(&domain->fd_nodes, fdn, y) {
-				if (fdn->fdn_prio != x)
-					continue;
-				state->rs_allowed[cnt++] = fdn->fdn_nodeid;
-			}
-		}
-		
-		state->rs_flags |= RS_ORDERED;
-		
-		if (!(domain->fd_flags & FOD_NOFAILBACK))
-			state->rs_flags |= RS_FAILBACK;
-	}
-	
-	if (domain->fd_flags & FOD_RESTRICTED)
-		return;
-	
-	/* allowed == nlen */
-	/* find missing nodes and fill them in */
-	for (x = 0; x < allowed; x++) {
-		if (state->rs_allowed[x] != 0)
-			continue;
-		for (y = 0; y < nlen; y++) {
-			
-			tmp = 0;
-			for (z = 0; z < x; z++) {
-				if (nodes[y] == state->rs_allowed[z]) {
-					tmp = 1;
-					break;
-				}
-			}
-			
-			if (!tmp) {
-				state->rs_allowed[x] = nodes[y];
-			}
-		}
-	}
-}
-
-
-dep_rs_t *
-dep_rstate_alloc(resource_node_t **restree, fod_t **domains, int *nodes,
-		 int nlen, int *rs_cnt)
-{
-	dep_rs_t *rstates;
-	resource_node_t *rn;
-	int tl_res_count = 0, x;
-	char dom[64];
-	fod_t *fod;
-	
-	list_for(restree, rn, tl_res_count);
-	
-	rstates = malloc(sizeof(dep_rs_t) * tl_res_count);
-	if (!rstates)
-		return NULL;
-	
-	memset(rstates, 0, (sizeof(dep_rs_t) * tl_res_count));
-	
-	list_for(restree, rn, x) {
-		snprintf(rstates[x].rs_status.rs_name,
-			 sizeof(rstates[x].rs_status.rs_name),
-			 "%s:%s", rn->rn_resource->r_rule->rr_type,
-			 rn->rn_resource->r_attrs[0].ra_value);
-		
-		rstates[x].rs_status.rs_last_owner = 0;
-		rstates[x].rs_status.rs_owner = 0;
-		rstates[x].rs_status.rs_state = RG_STATE_STOPPED;
-		
-		fod = NULL;
-		if (!res_property(rn->rn_resource, "domain", dom,
-				sizeof(dom))) {
-			
-			fod = fod_find_domain(domains, dom);
-		} 
-		_set_allowed(&rstates[x], fod, nodes, nlen);
-	}
-	
-	*rs_cnt = tl_res_count;
-	
-	return rstates;
-}
-
-
-void
-dep_rstate_free(dep_rs_t *states, int slen)
-{
-	int x;
-	
-	if (!states)
-		return;
-	if (!slen)
-		return;
-	
-	for (x = 0; x < slen; x++) {
-		if (states[x].rs_allowed && states[x].rs_allowed_len) {
-			free(states[x].rs_allowed);
-			states[x].rs_allowed = NULL;
-			states[x].rs_allowed_len = 0;
-		}
-	}
-	
-	free(states);
-}
-
-
-dep_rs_t *
-dep_rstate_dup(dep_rs_t *states, int slen)
-{
-	dep_rs_t *states_new;
-	int x;
-	
-	while ((states_new = malloc(sizeof(dep_rs_t) * slen)) == NULL)
-		usleep(10000);
-	
-	memcpy(states_new, states, sizeof(dep_rs_t) * slen);
-	
-	for (x = 0; x < slen; x++) {
-		if (!states[x].rs_allowed || !states[x].rs_allowed_len) {
-			states_new[x].rs_allowed = NULL;
-			continue;
-		}
-		
-		while ((states_new[x].rs_allowed =
-			malloc(sizeof(int) * states[x].rs_allowed_len))==NULL)
-			usleep(10000);
-		
-		memcpy(states_new[x].rs_allowed,
-		       states[x].rs_allowed,
-		       sizeof(int) * states[x].rs_allowed_len);
-	}
-		
-	return states_new;
-}	
-
-
-/**
- * copy everything from src into dest except for the allowed pointer arrays
- */
-void
-dep_rstate_copy(dep_rs_t *dest, dep_rs_t *src, int slen)
-{
-	int x, *ap;
-	
-	for (x = 0; x < slen; x ++) {
-		ap = dest[x].rs_allowed;
-		memcpy(&dest[x], &src[x], sizeof(dep_rs_t));
-		dest[x].rs_allowed = ap;
-	}
-}	
-
-
-static int
-dep_srt_cmp(dep_t *l, dep_rs_t *ls, dep_t *r, dep_rs_t *rs)
-{
-	
-	if (ls->rs_status.rs_state == RG_STATE_STOPPED &&
-	    rs->rs_status.rs_state != RG_STATE_STOPPED)
-		return 1;
-	
-	if (ls->rs_status.rs_state != RG_STATE_STOPPED &&
-	    rs->rs_status.rs_state == RG_STATE_STOPPED)
-		return -1;
-	
-	if (ls->rs_status.rs_state != RG_STATE_STOPPED &&
-	    rs->rs_status.rs_state != RG_STATE_STOPPED) {
-		
-		if (!l && r)
-			return -1;
-		if (r && !l)
-			return 1;
-		if (!r && !l)
-			return 0;
-		
-		/* running resource */
-		/*
-		 * Left is greater if the hits exceed, or left's
-		 * hits are zero
-		 */
-		if (l->d_hits == 0 && r->d_hits != 0)
-			return -1;
-		if (l->d_hits != 0 && r->d_hits == 0)
-			return 1;
-		
-		/* Otherwise, more hits, the farther away */
-		if (l->d_hits > r->d_hits)
-			return -1;
-		if (l->d_hits < r->d_hits)
-			return 1;
-		return 0;
-	}
-	
-	/* both states are stopped */
-	if (!l && r)
-		return 1;
-	if (l && !r)
-		return -1;
-	if (!r && !l)
-		return 0;
-	if (l->d_deps > r->d_deps)
-		return -1;
-	if (l->d_deps < r->d_deps)
-		return 1;
-	if (l->d_hits > r->d_hits)
-		return -1;
-	if (l->d_hits < r->d_hits)
-		return 1;
-	return 0;
-}
-
-
-void
-dep_rstate_sort(dep_t **deps, dep_rs_t *states, int slen)
-{
-	dep_t *xd, *yd;
-	int x, y;
-	dep_rs_t tmp;
-	
-	/* brute force sort */
-	for (x = 0; x < slen; x++) {
-		for (y = 0; y < x; y++) {
-			xd = find_dep(deps, states[x].rs_status.rs_name);
-			yd = find_dep(deps, states[y].rs_status.rs_name);
-			
-			if (dep_srt_cmp(yd, &states[y], xd, &states[x]) < 0) {
-				memcpy(&tmp, &states[y], sizeof(dep_rs_t));
-				memcpy(&states[y], &states[x],
-				       sizeof(dep_rs_t));
-				memcpy(&states[x], &tmp, sizeof(dep_rs_t));
-			}
-		}
-	}
-}
-
-
-static inline int
-_alter_state_start(dep_t **deps, dep_rs_t *state, int newowner)
-{
-	/* Try starting a resource */
-	if (state->rs_flags & RS_BEEN_STARTED)
-		return 0;
-				
-	/* we just stopped this on this node */
-	if (state->rs_status.rs_last_owner == newowner)
-		return 0;
-				
-	state->rs_status.rs_state = RG_STATE_STARTED;
-	state->rs_status.rs_owner = newowner;
-				
-	/*
-	 * Optimization: don't allow start+stop+start.
-	 * of the same resource, unless it was in an
-	 * error state.
-	 */
-	state->rs_flags |= (RS_BEEN_STARTED | RS_BEEN_STOPPED);
-	
-	return 1;
-}
-
-
-static inline int
-_alter_state_stop(dep_t **deps, dep_rs_t *state)
-{
-	dep_t *dep;
-	dep_node_t *dn;
-	int x;
-	
-	if (state->rs_flags & RS_BEEN_STOPPED)
-		return 0;
-	
-	dep = find_dep(deps, state->rs_status.rs_name);
-	if (!dep) {
-		printf("Dependency missing for %s\n",
-			state->rs_status.rs_name);
-		return 0;
-	}
-	
-#if 0
-	if (dep->d_hits == 0) {
-		/* If nothing depends on this resource, stopping it is 
-		 * pointless
-		 */
-		return 0;
-	}
-#endif
-		
-	state->rs_status.rs_state = RG_STATE_STOPPED;
-	state->rs_status.rs_last_owner = state->rs_status.rs_owner;
-	state->rs_status.rs_owner = 0;
-	state->rs_flags |= RS_BEEN_STOPPED;
-	
-	/* We can clear the state now.  Set the last owner to nobody */
-	if (state->rs_flags & (RS_ILLEGAL_NODE | 
-			       RS_DEAD_NODE    )) {
-		state->rs_status.rs_last_owner = 0;
-		state->rs_flags &= ~(RS_ILLEGAL_NODE | RS_DEAD_NODE);
-		return 1;
-	}
-
-	/*
-	 * If we stopped it because of a broken dependency, then we can
-	 * restart it on the same node. 
-	 */
-	list_for(&dep->d_nodes, dn, x) {
-		if (dn->dn_flags & (DN_BROKEN_COLO   |
-				    DN_BROKEN_REQ    |
-				    DN_BROKEN_NONCOLO)) {
-			state->rs_status.rs_last_owner = 0;
-			return 1;
-		}
-	}
-	
-	return 1;
-}
-
-
-static inline int
-_alter_state(dep_t **deps, dep_rs_t *state, dep_op_t *op)
-{
-	if (!op) {
-		printf("No operation\n");
-		return 0;
-	}
-	
-	if (op->do_op == RG_START)
-		return _alter_state_start(deps, state, op->do_nodeid);
-	return _alter_state_stop(deps, state);
-}	
-
-
-static int *
-build_try_indices(struct _try *tries, int try_cnt, int idx_cnt)
-{
-	int *indices, x, y;
-	/* Build our indices according to score */
-	
-	while ((indices = malloc(sizeof(int)*idx_cnt)) == 0)
-		usleep(10000);
-	y = 0;
-	for (x = 0; x < try_cnt; x++) {
-		if (!tries[x].ops)
-			continue;
-		indices[y] = x;
-		++y;
-	}
-	
-	return indices;
-}
-
-
-static void
-nuke_op_list(dep_op_t **ops)
-{
-	dep_op_t *op;
-	
-	while ((op = *ops) != NULL) {
-		list_remove(ops, op);
-		free(op);
-	}
-}
-
-
-static void
-sort_try_indices(struct _try *tries, int *indices, int idx_cnt,
-		 dep_rs_t *states, int slen)
-{
-	int x, y, z, swp;
-	dep_rs_t *cstate;
-
-	/*
-	 * Got our list of indices into our 'tries' branch array, 
-	 * now sort.  Brutish sort..  Really should take into account error
-	 * states.; e.g. 0 1 2 3 4 5 -1 -2 -3... 
-	 */
-	for (x = 0; x < idx_cnt; x++) {
-		for (y = 0; y < x; y++) {
-			
-			if (tries[indices[x]].score < tries[indices[y]].score){
-				swp = indices[x];
-				indices[x] = indices[y];
-				indices[y] = swp;
-			}
-			
-			if (tries[indices[x]].score != tries[indices[y]].score)
-				continue;
-				
-			/* See if we're ordered */
-			cstate = NULL;
-			for (z = 0; z < slen; z++) {
-				if (!strcmp(tries[indices[y]].ops->do_res,
-					    states[z].rs_status.rs_name)) {
-					    cstate = &states[z];
-					    break;
-				}
-			}
-			
-			if (!cstate || !(cstate->rs_flags & RS_ORDERED))
-				continue;
-			
-			swp = 0;
-			for (z = 0; z < cstate->rs_allowed_len; z++) {
-				if (tries[indices[x]].ops->do_nodeid ==
-				    cstate->rs_allowed[z]) {
-					swp = 1;
-					break;
-				} else if (tries[indices[y]].ops->do_nodeid ==
-				    cstate->rs_allowed[z]) {
-					break;
-				}
-			}
-			
-			if (!swp)
-				continue;
-			
-			swp = indices[x];
-			indices[x] = indices[y];
-			indices[y] = swp;
-		}
-	}
-}
-
-
-static void
-free_try_list(struct _try *tries, int len)
-{
-	int x;
-		
-	/* Clean up all remaining branch lists */
-	for (x = 0; x < len; x++) {
-		if (!tries[x].ops)
-			continue;
-		nuke_op_list(&(tries[x].ops));
-	}
-	
-	/* Clean up branch list array */
-	free(tries);
-}
-
-
-static int
-check_online(int n, int *nodes, int nlen, int *nidx)
-{
-	for (*nidx = 0; *nidx < nlen; (*nidx)++)
-		if (n == nodes[*nidx])
-			return nodes[*nidx];
-	return -1;
-}
-
-
-static void
-insert_try(struct _try *tries, int idx, dep_op_t *op, int score, int iter)
-{
-	dep_op_t *newop;
-	
-	while ((newop = malloc(sizeof(dep_op_t))) == NULL)
-		usleep(10000);
-	memcpy(newop, op, sizeof(dep_op_t));
-	newop->do_iter = iter;
-	list_insert(&(tries[idx].ops), newop);
-	tries[idx].score = score;
-}
-
-
-/**
- * Calculate all of the possible branches from this point.
- * Returns the number of possible branches.
- */
-static int
-build_all_possible_tries(dep_t **deps, dep_rs_t *states_cpy, int slen,
-			 int *nodes, int nlen, int start_score,
-			 struct _try *tries, int iter, int depth)
-{
-	int x, y, nidx, err;
-	dep_rs_t tmp;
-	dep_op_t op;
-	int idx_cnt = 0;
-	
-	for (x = 0; x < slen; x++) {
-		
-		/* Immutable resources can't be moved */
-		if (states_cpy[x].rs_flags & RS_IMMUTABLE)
-			continue;
-		
-		/* can't bother with non-running resources */
-		if (states_cpy[x].rs_status.rs_state == RG_STATE_DISABLED ||
-		    states_cpy[x].rs_status.rs_state == RG_STATE_FAILED)
-			continue;
-		
-		/*
-		 * see if this set has already tried to manipulate this
-		 * service
-		 */
-		if ((states_cpy[x].rs_flags & 
-		    (RS_BEEN_STARTED|RS_BEEN_STOPPED)) ==
-		    (RS_BEEN_STARTED|RS_BEEN_STOPPED))
-			continue;
-		
-		/*
-		 * Since we are operating on the same allowed list (and
-		 * will not be freeing tmp), it's ok to just use memcpy here.
-		 */
-		memcpy(&tmp, &states_cpy[x], sizeof(tmp));
-		
-		op.do_op = RG_START; /* XXX the loop below must happen
-		 		        at least once...*/
-		
-		/* try for each nodeid that's a legal target */
-		for (y = 0; (op.do_op == RG_START) &&
-		            y < states_cpy[x].rs_allowed_len; y++) {
-			
-			memcpy(&states_cpy[x], &tmp, sizeof(tmp));
-			/* 
-			 * Find next node online in our allowed list
-			 * nidx is the offset into the online nodes array
-			 * where this node was found - since the online list
-			 * of nodes might be smaller than the allowed list
-			 * for the resource, we need to keep track of it for
-			 * later.
-			 * 
-			 * XXX Since we sort later in the alg., we can probably
-			 * reverse these loops to get rid of nidx.
-			 */
-			if ((err = check_online(states_cpy[x].rs_allowed[y],
-						nodes, nlen, &nidx)) < 0)
-				continue;
-			
-			/* Reset flags, etc. */
-			memset(&op, 0, sizeof(dep_op_t));
-			
-			if (rs_running(NULL, &states_cpy[x], 1)) {
-			
-				/* Try stopping a resource */
-				op.do_op = RG_STOP;
-				strncpy(op.do_res,
-					states_cpy[x].rs_status.rs_name,
-					sizeof(op.do_res));
-				/*printf("stop %s %d %d %d ", op.do_res,
-					depth, iter, start_score);*/
-				
-			} else if (states_cpy[x].rs_status.rs_state ==
-				   RG_STATE_STOPPED &&
-				   start_score >= 0) {
-			
-				/* Try starting a resource.  We can only
-				 * do this after we clear the errors (e.g. stop)
-				 * resources */
-				op.do_op = RG_START;
-				op.do_nodeid = err;
-				strncpy(op.do_res,
-					states_cpy[x].rs_status.rs_name,
-					sizeof(op.do_res));
-				/*printf("start %s %d %d %d ", op.do_res,
-					depth, iter, start_score);*/
-			} else {
-				/* Other states = can't do anything */
-				continue;
-			}
-			
-			/*
-			 * Try to apply our operation.  If it was an invalid,
-			 * operation, we just move on
-			 */
-			if (_alter_state(deps, &states_cpy[x], &op) == 0)
-				continue;
-	
-			/* Check each possible move at this level */
-			err = dep_check(deps, states_cpy, slen, nodes, nlen);
-			//printf(" [score: %d]\n", err);
-		
-			/* 
-			 * Make sure the operation does not introduce an
-			 * error
-			 */
-			if ((start_score < 0 && err <= start_score) ||
-			    (start_score >= 0 && err < 0)) {
-				/*
-				 * Introduce new error = bad; drop this
-				 * operation.
-				 */
-				/*
-				printf("%s of %s introduced new err %d %d\n",
-					op.do_op==RG_START?"start":"stop",
-					op.do_res,
-					start_score, err);
-				 */
-				continue;
-			}
-			
-			/* No new error - this op is a valid thing to do */
-			/* Insert the op on to the try list and move on */
-			insert_try(tries, x * nlen + nidx, &op, err, iter);
-			
-			/*
-			 * Keep track of how many places we actually
-			 * found a possible branch for returning
-			 */
-			++idx_cnt;
-		}
-		memcpy(&states_cpy[x], &tmp, sizeof(tmp));
-	}
-	
-	return idx_cnt;
-}
-
-			
-/**
- * Breadth-first-search.
- */
-static int
-_dep_calc_trans(dep_t **deps, dep_rs_t *states, int slen, int *nodes, int nlen,
-		int depth, int errors, dep_op_t **oplist, int *iter)
-{
-	int x, y, err;
-	struct _try *tries;
-	dep_rs_t *states_cpy;
-	dep_op_t *newop;
-	int best_idx = -1, best_score, start_score;
-	int *indices = NULL, idx_cnt = 0;
-	
-	x = dep_check(deps, states, slen, nodes, nlen);
-	/* Ideal? */
-	if (x == 0)
-		return 0;
-	/* Introduced a new error? */
-	if ((*iter) && errors < 0 && x <= errors)
-		return x;
-		
-	/* Went from sub-optimal to outright broken? */
-	if (errors > 0 && x < 0)
-		return x;
-	
-	/*
-	 * Impossible to try branch more than 2*slen times: we can only 
-	 * on the outside stop/start every resource in the cluster.
-	 */
-	if (depth > (2*slen))
-		return errors;
-	
-	/* Set up */
-	best_score = start_score = x;
-	++(*iter);
-	/*
-	printf("[%d] start depth %d errors %d init %d\n",
-		*iter, depth, errors, start_score);
-	*/
-	
-	while ((tries = malloc(sizeof(*tries) * slen * nlen)) == NULL)
-		usleep(10000);
-	memset(tries, 0, sizeof(*tries) * slen * nlen);
-	
-	/* Copy our states (don't alter parent's states) */
-	states_cpy = dep_rstate_dup(states, slen);
-	
-	/* Find all possible things to try */
-	idx_cnt = build_all_possible_tries(deps, states_cpy, slen, nodes, nlen,
-					   start_score, tries, *iter, depth);
-
-	/* Build our indices into an array */
-	indices = build_try_indices(tries, nlen*slen, idx_cnt);
-	
-	/* Sort array indices */
-	sort_try_indices(tries, indices, idx_cnt, states_cpy, slen);
-	
-	/*
-	 * Now, do a recurse on the tree in order of best-score-first...
-	 * (that's why we sorted above)
-	 */
-	dep_rstate_copy(states_cpy, states, slen);
-	for (x = 0; x < idx_cnt; x++) {
-		
-		/* state index = tries_index/node count len */
-		y = indices[x] / nlen;
-		
-		/* Back this up for later */
-		dep_rstate_copy(&states_cpy[y], &states[y], 1);
-		
-		/* Flip our state. */
-		if (_alter_state(deps, &states_cpy[y],
-				 tries[indices[x]].ops) == 0) {
-			/* :( */
-			printf("Error: Logic error\n");
-			continue;
-		}
-	
-		/* Recurse */
-		err = _dep_calc_trans(deps, states_cpy, slen, nodes, nlen,
-				      depth + 1, start_score,
-				      &(tries[indices[x]].ops), iter);
-		
-		//dep_rstate_copy(&states_cpy[y], &states[y], 1);
-		
-		/* Store the score for branching on this operation */
-		tries[indices[x]].score = err;
-		
-		/* ... and the depth.  XXX  not done yet; someday, we should
-		 * select the shortest path... 
-		tries[indices[x]].depth = 0;
-		list_for_count(&tries[indices[x]].ops, newop,
-			       tries[indices[x]].depth);
-		 */
-		
-		/* Keep track of our best score */
-		if ((best_score < 0 && err > best_score) ||
-		    (best_score >= 0 && err >= 0 && err < best_score))  {
-			best_idx = indices[x];
-			best_score = err;
-		}
-	}
-	
-	/* Free our index array; we don't need it anymore */
-	free(indices);
-	
-	/* We don't need our temporary space anymore */
-	dep_rstate_free(states_cpy, slen);
-	
-	if ((errors < 0 && best_score < errors) ||
-	    (errors >= 0 && best_score > errors)) {
-		/* No good branch to take from here */
-		best_idx = -1;
-		best_score = start_score;
-	}
-	
-	/* Append the so-called best list on to our passed-in list of
-	 * operations (this goes on tries[...] above) */
-	if (best_idx != -1) {
-		while ((newop = tries[best_idx].ops) != NULL) {
-			list_remove(&(tries[best_idx].ops), newop);
-			list_insert(oplist, newop);
-		}
-		
-		/* Get the best score */
-		best_score = tries[best_idx].score;
-	}
-	
-	free_try_list(tries, nlen * slen);
-	
-	/*
-	printf("[%d] end start score: %d, bestscore: %d  depth: %d\n", *iter,
-		start_score, best_score, depth);
-	 */
-	
-	return best_score;
-}
-
-
-int
-dep_calc_trans(dep_t **deps, dep_rs_t *_states, int slen,
-		int *nodes, int nlen, dep_op_t **op_list, int *iter)
-{
-	int x, my_i, ops = 0, err = 0;
-	dep_op_t *newop;
-	dep_rs_t *states = NULL;
-	
-	if (iter)
-		*iter = 0;
-	else {
-		my_i = 0;
-		iter = &my_i;
-	}
-	
-	x = dep_check(deps, _states, slen, nodes, nlen);
-	if (x == 0)
-		return 0;
-	
-	states = dep_rstate_dup(_states, slen);
-	for (x = 0; x < slen; x++) {
-		if (states[x].rs_flags & (RS_DEAD_NODE|RS_ILLEGAL_NODE)) {
-			states[x].rs_status.rs_state = RG_STATE_STOPPED;
-			while ((newop = malloc(sizeof(*newop))) == NULL)
-				sleep(1);
-			memset(newop, 0, sizeof(*newop));
-			newop->do_op = RG_STOP;
-			strncpy(newop->do_res, states[x].rs_status.rs_name,
-					sizeof(newop->do_res));
-			list_insert(op_list, newop);
-			++ops;
-		}
-	}
-	
-	/*
-	 * Sort: 
-	 * low...
-	 * (a) stopped resources which are not depended on (starting these
-	 *     will not affect any other resources)
-	 * (b) stopped resources which are depended on - where the # of
-	 *     deps is increasing 
-	 * (c) started resources w/ deps, ordered from lowest to highest
-	 * (d) started resources w/ no deps (transitioning these will have
-	 *     -no- effect.)
-	 * ... high
-	 */
-	dep_rstate_sort(deps, states, slen);
-	err = dep_check(deps, states, slen, nodes, nlen);
-	if (err) {
-		err = _dep_calc_trans(deps, states, slen, nodes, nlen, 0,
-				      err, op_list, iter);
-	}
-	
-	dep_rstate_free(states, slen);
-	return err;
-}
-
-
-int
-dep_apply_trans(dep_t **deps, dep_rs_t *states, int slen, dep_op_t **op_list)
-{
-	dep_op_t *op;
-	int ops = 0, x;
-
-	list_for(op_list, op, ops) {
-		for (x = 0; x < slen; x++) {
-			if (strcasecmp(op->do_res, states[x].rs_status.rs_name))
-				continue;
-			if (op->do_op == RG_START) {
-				printf("Start %s on %d [%d]\n",
-				       op->do_res, op->do_nodeid, op->do_iter);
-				states[x].rs_status.rs_state = RG_STATE_STARTED;
-				states[x].rs_status.rs_owner = op->do_nodeid;
-			} else {
-				printf("Stop %s [%d]\n", op->do_res,
-				       op->do_iter);
-				states[x].rs_status.rs_state = RG_STATE_STOPPED;
-				states[x].rs_status.rs_owner = 0;
-				states[x].rs_flags &= ~(RS_ILLEGAL_NODE|
-						        RS_DEAD_NODE);
-			}
-		}
-	}
-	
-	printf("Applied %d operations\n", ops);
-	
-	return 0;
-}
-
-
-void
-reverse_list(dep_op_t **oplist)
-{
-	dep_op_t *new_ol = NULL;
-	dep_op_t *op;
-
-	if (!*oplist)
-		return;
-	
-	while ((op = *oplist)) {
-		list_remove(oplist, op);
-		list_prepend(&new_ol, op);
-	}
-	
-	*oplist = new_ol;
-}
-
-
-void
-insert_after_stops(dep_op_t **oplist, dep_op_t *newop)
-{
-	dep_op_t *new_ol = NULL;
-	dep_op_t *op;
-
-	if (!*oplist)
-		return;
-	
-	while ((op = *oplist) && op->do_op == RG_STOP) {
-		list_remove(oplist, op);
-		list_insert(&new_ol, op);
-	}
-	
-	list_insert(&new_ol, newop);
-	
-	while ((op = *oplist)) {
-		list_remove(oplist, op);
-		list_insert(&new_ol, op);
-	}
-		
-	*oplist = new_ol;
-}
-
-
-/**
- * Generate the list of operations which would satisfy a requested (user)
- * operation (e.g. start, relocate, disable)
- */
-int
-dep_check_operation(char *res, int operation, int target, 
-		    dep_t **deps, dep_rs_t *_states,
-		    int slen, int *nodes, int nlen, dep_op_t **oplist)
-{
-	int ret = -1;
-	dep_rs_t *state = NULL, *states = NULL;
-	dep_op_t *newop = NULL;
-	int start_score, score;
-	
-	states = dep_rstate_dup(_states, slen);
-	start_score = dep_check(deps, _states, slen, nodes, nlen);
-	
-	/* Find the state dealing with */
-	if (!(state = _find_state(res, states, slen))) {
-		printf("No record of that service...\n");
-		dep_rstate_free(states, slen);
-		return -1;
-	}
-	
-	switch(operation) {
-	case RG_DISABLE:
-	case RG_STOP:
-	case RG_START:
-		while ((newop = malloc(sizeof(dep_op_t))) == NULL)
-			usleep(10000);
-		memset(newop, 0, sizeof(dep_op_t));
-	
-		/* Set it up */
-		strncpy(newop->do_res, res, sizeof(newop->do_res));
-		newop->do_op = operation;
-		newop->do_nodeid = target;
-		
-		if (_alter_state(deps, state, newop) == 0)
-			break;
-		
-		state->rs_flags |= RS_IMMUTABLE;
-		
-		start_score = dep_check(deps, states, slen, nodes, nlen);
-		score = dep_calc_trans(deps, states, slen, nodes, nlen,
-					oplist, NULL);
-		if (start_score < 0 && score <= start_score)
-			break;
-		
-		/* Reverse the list if we breake dependencies */
-		if (operation == RG_STOP || operation == RG_DISABLE) {
-			/* Append the operation */
-			reverse_list(oplist);
-			list_insert(oplist, newop);
-		} else {
-			/* append after stops... */
-			insert_after_stops(oplist, newop);
-		}
-		
-		ret = 0; /* Woot */
-		break;
-	case RG_RELOCATE:
-		if (dep_check_operation(res, RG_STOP, -1, deps, states, slen, nodes,
-					nlen, oplist) < 0)
-			break;
-		if (dep_check_operation(res, RG_START, target, deps, states, slen,
-				        nodes, nlen, oplist) < 0)
-			break;
-		ret = 0; /* Woot */
-		break;
-	case RG_MIGRATE:
-	default:
-		break;
-	}
-	
-	/* Ret will be -1 unless we succeeded */
-	if (ret < 0) {
-		if (newop)
-			free(newop);
-			
-		while ((newop = *oplist)) {
-			list_remove(oplist, newop);
-			free(newop);
-		}
-	}
-
-	if (states)
-		dep_rstate_free(states, slen);
-	return ret;
-}
diff --git a/rgmanager/src/daemons/dtest.c b/rgmanager/src/daemons/dtest.c
deleted file mode 100644
index d554939..0000000
--- a/rgmanager/src/daemons/dtest.c
+++ /dev/null
@@ -1,810 +0,0 @@
-#include <libxml/parser.h>
-#include <libxml/xmlmemory.h>
-#include <libxml/xpath.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <restart_counter.h>
-#include <resgroup.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <list.h>
-#include <reslist.h>
-#include <pthread.h>
-#include <depends.h>
-#include <ccs.h>
-#include <readline/readline.h>
-#include <readline/history.h>
-
-
-
-#ifndef NO_CCS
-#error "Can not be built with CCS support."
-#endif
-
-#ifdef NO_CCS
-#define ccs_get(fd, query, ret) conf_get(query, ret)
-#endif
-
-void malloc_stats(void);
- 
-
-resource_rule_t	*rules = NULL;
-resource_t	*resources = NULL;
-resource_node_t *restree = NULL;
-dep_t		*depends = NULL;
-dep_rs_t	*resource_states = NULL;
-int	 	resource_state_count = 0;
-fod_t		*domains = NULL;
-int		*nodes_all = NULL;
-int		nodes_all_count = 0;
-int 		*nodes_online = NULL;
-int		nodes_online_count = 0;
-
-
-void
-visualize_state(char *png_viewer)
-{
-	char cmd[1024];
-	char tf_dot[128];
-	char tf_png[128];
-	FILE *fp;
-	int fd, x;
-		
-	snprintf(tf_dot, sizeof(tf_dot), "/tmp/dtest.dot.XXXXXX");
-	fd = mkstemp(tf_dot);
-	if (fd < 0) {
-		printf("Couldn't create temporary file: %s\n", strerror(errno));
-		return;
-	}
-	
-	fp = fdopen(fd, "w+");
-	if (!fp) {
-		printf("Couldn't init temporary file: %s\n", strerror(errno));
-		return;
-	}
-	
-	x = dep_check(&depends, resource_states,
-		  resource_state_count, nodes_online,
-		  nodes_online_count);
-	printf("State score: %d\n", x);
-	dep_cluster_state_dot(fp, &depends, resource_states,
-			resource_state_count, nodes_online,
-			nodes_online_count);
-	
-	fclose(fp);
-	close(fd);
-	
-	snprintf(tf_png, sizeof(tf_png), "/tmp/dtest.png.XXXXXX");
-	fd = mkstemp(tf_png);
-	if (fd < 0) {
-		printf("Couldn't init temporary file: %s\n", strerror(errno));
-		return;
-	}
-	
-	close(fd);
-	
-	snprintf(cmd, sizeof(cmd), "dot -Tpng -o %s %s", tf_png, tf_dot);
-	if (system(cmd) != 0) {
-		printf("Error: system('%s') failed\n", cmd);
-		return;
-	}
-	
-	snprintf(cmd, sizeof(cmd), "%s %s", png_viewer, tf_png);
-	if (system(cmd) != 0) {
-		printf("Error: system('%s') failed\n", cmd);
-		return;
-	}
-	
-	unlink(tf_png);
-	unlink(tf_dot);
-}
-
-
-int
-vis_dep_apply_trans(dep_op_t **op_list, char *pngviewer)
-{
-	dep_op_t *op;
-	int x;
-	int ops = 0;
-	dep_rs_t *states = resource_states;
-	int slen = resource_state_count;
-	
-	visualize_state(pngviewer);
-
-	list_do(op_list, op) {
-		
-		++ops;
-		
-		for (x = 0; x < slen; x++) {
-			if (strcasecmp(op->do_res, states[x].rs_status.rs_name))
-				continue;
-			if (op->do_op == RG_START) {
-				printf("Start %s on %d\n", op->do_res, op->do_nodeid);
-				states[x].rs_status.rs_state = RG_STATE_STARTED;
-				states[x].rs_status.rs_owner = op->do_nodeid;
-			} else {
-				printf("Stop %s\n", op->do_res);
-				states[x].rs_status.rs_state = RG_STATE_STOPPED;
-				states[x].rs_status.rs_owner = 0;
-				states[x].rs_flags &= ~(RS_ILLEGAL_NODE|
-						        RS_DEAD_NODE);
-			}
-			break;
-		}
-		
-		visualize_state(pngviewer);
-
-	} while (!list_done(op_list, op));
-	
-	printf("Applied %d operations\n", ops);
-	
-	return 0;
-}
-
-void
-print_help(void)
-{
-	printf("nodes                     view all nodes\n");
-	printf("online [id1 id2...|none]  set or view online nodes\n");
-	printf("res [resource]            view a resource state (or all)\n");
-	printf("start <res> <id>          start res on id\n");
-	printf("dep [res]                 print dependency tree(s)\n");
-	printf("stop <res1> [res2...]     stop res\n");
-	printf("disable <res1> [res2...]  disable res\n");
-	printf("check                     check cluster state against deps\n");
-	printf("calc                      calculate transition to valid state\n");
-	printf("apply [pngviewer]         Apply previous transition list\n");
-	printf("                          If pngviewer is specified, send\n");
-	printf("                          graphviz & bring up viewer\n");
-	printf("state [pngviewer]         dump cluster state in DOT format\n");
-	printf("                          If pngviewer is specified, send\n");
-	printf("                          graphviz & bring up viewer\n");
-	printf("quit, exit                exit\n");
-}
-
-
-void
-show_rs_t(dep_rs_t *rs)
-{
-	int *allowed, cnt, x;
-	
-	printf("Resource %s\n  State: %s\n  Owner: %d\n",
-	       rs->rs_status.rs_name,
-	       rg_state_str(rs->rs_status.rs_state),
-	       rs->rs_status.rs_owner);
-	
-	if (rs->rs_allowed) {
-		allowed = rs->rs_allowed;
-		cnt = rs->rs_allowed_len;
-	} else {
-		printf("  Allowed Nodes = [ all ]\n");
-		return;
-	}
-		
-	printf("  Allowed Nodes = [ ");
-	
-	for (x = 0; x < cnt; x++) {
-		printf("%d ", allowed[x]);
-	}
-	printf("]\n");
-}
-
-
-int 
-show_resources(char *name)
-{
-	int x, found = 0;
-	
-	for (x = 0; x < resource_state_count; x++) {
-		if (!name || !strcmp(name,
-		    resource_states[x].rs_status.rs_name)) {
-			found = 1;
-			
-			show_rs_t(&resource_states[x]);
-		}
-		
-		if (!name)
-			printf("\n");
-	}
-	
-	return !found;
-}
-
-
-void
-show_calc_result(int final_score, dep_op_t **ops, int iter)
-{
-	int x = 0;
-	dep_op_t *op;
-	
-	list_do(ops, op) {
-		++x;
-		if (op->do_op == RG_START) {
-			printf("Start %s on %d [%d]\n", op->do_res, op->do_nodeid, op->do_iter);
-		} else {
-			printf("Stop %s [%d]\n", op->do_res, op->do_iter);
-		}
-	} while (!list_done(ops, op));
-	
-	if (iter >= 0)
-		printf("%d operations reduced in %d iterations; final score = %d\n", x, iter,
-			final_score);
-	else
-		printf("%d operations\n", x);
-}
-		
-
-
-dep_rs_t *
-get_rs_byname(char *name)
-{
-	int x, found = 0;
-	
-	if (!name)
-		return NULL;
-	
-	for (x = 0; x < resource_state_count; x++) {
-		if (!name || !strcmp(name,
-		    resource_states[x].rs_status.rs_name)) {
-			found = 1;
-			
-			return &resource_states[x];
-		}
-		
-	}
-	
-	return NULL;
-}
-
-
-
-void
-dtest_shell(void)
-{
-	resource_t *res;
-	char name[64];
-	char *cmd = NULL;
-	int done = 0;
-	char *save, *curr, *tmp;
-	int cnt, err;
-	int *nodes;
-	int x;
-	dep_rs_t *rs;
-	dep_t *depcpy;
-	dep_op_t *ops = NULL, *op;
-	
-	nodes = malloc(sizeof(int)*nodes_all_count);
-	// FIXME: handle failed malloc
-	
-	while (!done) {
-		
-		if (cmd)
-			free(cmd);
-		cmd = readline("> ");
-		if (!cmd || !strlen(cmd)) {
-			printf("\n");
-		}
-		if (!cmd) {
-			break;
-		}
-		
-		/*
-		if (cmd && cmd[0])
-			add_history(cmd);
-		 */
-		
-		if (!cmd[0])
-			continue;
-		
-		curr = strtok_r(cmd, " ", &save);
-		err = 0;
-		
-		if (!strcmp(curr, "online")) {
-			cnt = 0;
-			err = 0;
-			while ((curr = strtok_r(NULL, " ", &save))) {
-				nodes[cnt] = atoi(curr);
-				if (nodes[cnt] <= 0) {
-					printf("Error: Node '%s' invalid\n",
-					       curr);
-					err = 1;
-					break;
-				}
-				
-				err = 1;
-				for (x = 0; x < nodes_all_count; x++) {
-					if (nodes_all[x] == nodes[cnt]) {
-						err = 0;
-						break;
-					}
-				}
-				++cnt;
-			}
-			
-			if (cnt && !err) {
-				if (nodes_online)
-					free(nodes_online);
-				
-				nodes_online = malloc(sizeof(int) * cnt);
-				// FIXME: handle failed malloc
-				
-				for (x = 0; x < cnt; x++)
-					nodes_online[x] = nodes[x];
-				nodes_online_count = cnt;
-			}
-			
-			if (!err) {
-				printf("Online = [ ");
-				for (x = 0; x < nodes_online_count; x++) {
-					printf("%d ", nodes_online[x]);
-				}
-				printf("]\n");
-			}
-		} else if (!strcmp(curr, "start")) {
-			
-			curr = strtok_r(NULL, " ", &save);
-			
-			if (!curr) {
-				printf("usage: start <resource> <nodeid>"
-					" [test]\n");
-				continue;
-			}
-			
-			if (!strchr(curr,':')) {
-				snprintf(name, sizeof(name), "service:%s",
-						curr);
-				curr = name;
-			}
-			
-			rs = get_rs_byname(curr);
-			if (!rs) {
-				printf("Error: Resource '%s' not found\n", curr);
-				++err;
-			}
-			
-			curr = strtok_r(NULL, " ", &save);
-			cnt = 0;
-			if (!curr) {
-				printf("Error: No node ID specified\n");
-				++err;
-			} else {
-				cnt = atoi(curr);
-				x = 0;
-				if (cnt <= 0) {
-					printf("Error: Node '%s' invalid\n",
-					       curr);
-					++err;
-				} else {
-					for (x = 0; x < nodes_online_count; x++) {
-						if (nodes_online[x] == cnt) {
-							x = -1;
-							break;
-						}
-					}
-				}
-				
-				if (x != -1) {
-					printf("Error: Node '%s' not online\n",
-					       curr);
-					++err;
-				}
-			}
-			
-			if (err)
-				continue;
-			
-			curr = strtok_r(NULL, " ", &save);
-			if (curr) {
-				if (strcmp(curr, "test")) 
-					printf("Error: start ... %s\n", curr);
-			
-				while ((op = ops)) {
-					list_remove(&ops, op);
-					free(op);
-				}
-				/*
-int
-dep_check_operation(char *res, int operation, int target, 
-		    dep_t **deps, dep_rs_t *_states,
-		    int slen, int *nodes, int nlen, dep_op_t **oplist)
-		    */
-				if (dep_check_operation(rs->rs_status.rs_name,
-						RG_START,
-						cnt,
-						&depends,
-						resource_states,
-						resource_state_count,
-						nodes_online,
-						nodes_online_count,
-						&ops) < 0) {
-					printf("No, thanks.\n");
-				} else
-					show_calc_result(0, &ops, 0);
-				continue;
-			} 
-			
-			
-			rs->rs_status.rs_owner = cnt;
-			rs->rs_status.rs_state = RG_STATE_STARTED;
-			printf("%s is started on %d\n", rs->rs_status.rs_name,
-				cnt);
-			
-		} else if (!strcmp(curr, "domains")) {
-			print_domains(&domains);
-			
-		} else if (!strcmp(curr, "calc")) {
-			
-			while ((op = ops)) {
-				list_remove(&ops, op);
-				free(op);
-			}
-			
-			err = dep_calc_trans(&depends, resource_states,
-					     resource_state_count,
-					     nodes_online, nodes_online_count,
-					     &ops, &x);
-			show_calc_result(err, &ops, x);
-			
-		} else if (!strcmp(curr, "apply")) {
-		
-			curr = strtok_r(NULL, " ", &save);
-			dep_check(&depends, resource_states,
-				  resource_state_count, nodes_online,
-				  nodes_online_count);
-			if (!curr) {
-				dep_apply_trans(&depends, resource_states,
-						resource_state_count,
-						&ops);
-			} else {
-				vis_dep_apply_trans(&ops, curr);
-			}
-			
-			while ((op = ops)) {
-				list_remove(&ops, op);
-				free(op);
-			}
-		} else if (!strcmp(curr, "state")) {
-			
-			x = dep_check(&depends, resource_states,
-				      resource_state_count,
-				      nodes_online, nodes_online_count);
-			
-			if (x < 0) {
-				printf("Cluster state is invalid (%d errors)\n",
-					-x);
-				dep_print_errors(&depends,
-						 resource_states,
-						 resource_state_count);
-			} else if (x > 0) {
-				printf("Cluster state is valid, "
-				       "but not ideal (%d stopped)\n",x);
-			} else {
-				printf("Cluster state is ideal\n");
-			}	
-			
-			curr = strtok_r(NULL, " ", &save);
-			if (!curr) {
-				dep_cluster_state(stdout, &depends,
-						resource_states,
-						resource_state_count, nodes_online,
-						nodes_online_count);
-			} else {
-				visualize_state(curr);
-			}
-			
-			dep_reset(&depends, resource_states,
-					resource_state_count);
-			
-		} else if (!strcmp(curr, "reslist")) {
-			list_do(&resources, res) {
-				print_resource(res);
-			} while (!list_done(&resources, res));
-			
-		} else if (!strcmp(curr, "nodes")) {
-			
-			printf("Nodes = [ ");
-			for (x = 0; x < nodes_all_count; x++) {
-				printf("%d ", nodes_all[x]);
-			}
-			printf("]\n");
-		} else if (!strcmp(curr, "stop") || !strcmp(curr, "disable")) {
-			
-			tmp = curr;
-			
-			curr = strtok_r(NULL, " ", &save);
-			
-			if (!curr) {
-				printf("usage: %s <resource>\n", tmp);
-				continue;
-			}
-		#if 0	
-			do {
-				if (!strchr(curr,':')) {
-					snprintf(name, sizeof(name), "service:%s",
-							curr);
-					curr = name;
-				}
-				rs = get_rs_byname(curr);
-				if (!rs) {
-					printf("Error: Resource '%s' not found\n",curr);
-					break;
-				}
-			
-				rs->rs_status.rs_owner = 0;
-				if (!strcmp(cmd, "stop")) {
-					rs->rs_status.rs_state = RG_STATE_STOPPED;
-					printf("%s is stopped\n",
-						rs->rs_status.rs_name);
-				} else {
-					rs->rs_status.rs_state = RG_STATE_DISABLED;
-					printf("%s is disabled\n",
-						rs->rs_status.rs_name);
-				}
-				curr = strtok_r(NULL, " ", &save);
-			} while (curr);
-			
-			curr = strtok_r(NULL, " ", &save);
-			
-			if (!curr) {
-				printf("usage: start <resource> <nodeid>"
-					" [test]\n");
-				continue;
-			}
-		#endif
-			
-			if (!strchr(curr,':')) {
-				snprintf(name, sizeof(name), "service:%s",
-						curr);
-				curr = name;
-			}
-			
-			rs = get_rs_byname(curr);
-			if (!rs) {
-				printf("Error: Resource '%s' not found\n", curr);
-				++err;
-			}
-			
-			if (err)
-				continue;
-			
-			curr = strtok_r(NULL, " ", &save);
-			if (curr) {
-				if (strcmp(curr, "test")) 
-					printf("Error: stop ... %s\n", curr);
-			
-				while ((op = ops)) {
-					list_remove(&ops, op);
-					free(op);
-				}
-				
-				if(dep_check_operation(rs->rs_status.rs_name,
-						!strcmp(tmp,"stop")?RG_STOP:RG_DISABLE,
-						-1,
-						&depends,
-						resource_states,
-						resource_state_count,
-						nodes_online,
-						nodes_online_count,
-						&ops) < 0) {
-					printf("No.\n");
-				} else 
-				show_calc_result(0, &ops, 0);
-				continue;
-			} 
-			
-			rs->rs_status.rs_owner = 0;
-			if (!strcmp(cmd, "stop")) {
-				rs->rs_status.rs_state = RG_STATE_STOPPED;
-				printf("%s is stopped\n",
-					rs->rs_status.rs_name);
-			} else {
-				rs->rs_status.rs_state = RG_STATE_DISABLED;
-				printf("%s is disabled\n",
-					rs->rs_status.rs_name);
-			}
-			
-			
-		} else if (!strcmp(curr, "res")) {
-			
-			curr = strtok_r(NULL, " ", &save);
-			
-			if (curr && !strchr(curr,':')) {
-				snprintf(name, sizeof(name), "service:%s",
-						curr);
-				curr = name;
-			}
-			err = show_resources(curr);
-			if (err) {
-				printf("Error: Invalid resource '%s'", curr);
-			}
-			
-		} else if (!strcmp(curr, "dep")) {
-			
-			curr = strtok_r(NULL, " ", &save);
-			
-			if (!curr) {
-				print_depends(stdout, &depends);
-				continue;
-			}
-			
-			if (!strcmp(curr, "dot")) {
-				print_depends_dot(stdout, &depends);
-				continue;
-			} else if (!strcmp(curr, "copy")) {
-				printf("Copying tree...");
-				depcpy = NULL;
-				dep_tree_dup(&depcpy, &depends);
-				printf("Done\n");
-				print_depends(stdout, &depcpy);
-				deconstruct_depends(&depcpy);
-				depcpy = NULL;
-			} else {
-				printf("Error: Invalid command 'dep %s'\n",
-					curr);
-			}
-				
-		} else if (!strcmp(curr, "check")) {
-			dep_reset(&depends, resource_states,
-				  resource_state_count);
-			
-			x = dep_check(&depends, resource_states,
-				      resource_state_count,
-				      nodes_online, nodes_online_count);
-			
-			if (x < 0) {
-				printf("Cluster state is invalid (%d errors)\n",
-					-x);
-				dep_print_errors(&depends,
-						 resource_states,
-						 resource_state_count);
-				dep_reset(&depends, resource_states,
-					  resource_state_count);
-			} else if (x > 0) {
-				printf("Cluster state is valid, "
-				       "but not ideal (%d stopped)\n",x);
-			} else {
-				printf("Cluster state is ideal\n");
-			}
-		} else if (!strcmp(curr, "?") || !strcmp(curr,"help")) {
-			print_help();
-		} else if (!strcmp(curr, "quit") || !strcmp(curr,"exit")) {
-			done = 1;
-		} else if (!strcmp(curr, "mem")) {
-			
-			tmp = curr;
-			curr = strtok_r(NULL, " ", &save);
-			if (!curr) {
-				malloc_stats();
-				continue;
-			}
-			
-			printf("Unknown command '%s %s'\n", tmp , curr);
-		} else {
-			printf("Unknown command '%s'\n", curr);
-		}
-	}
-	if (cmd)
-		free(cmd);
-}
-
-
-int *
-load_node_ids(int ccsfd, int *count)
-{
-	int ncount, x;
-	int *nodes;
-	char *val;
-	char xpath[256];
-	
-	for (ncount = 1; ; ncount++) {
-		snprintf(xpath, sizeof(xpath),
-			 "/cluster/clusternodes/clusternode[%d]/@nodeid",
-			 ncount);
-		
-		if (ccs_get(ccsfd, xpath, &val)!=0) {
-			--ncount;
-			break;
-		}
-	}
-	
-	if (!ncount)
-		return NULL;
-	
-	nodes = malloc(sizeof(int) * ncount);
-	if (!nodes) {
-		fprintf(stderr, "out of memory?\n");
-		return NULL;
-	}
-	
-	for (x = 1; x <= ncount; x++) {
-		snprintf(xpath, sizeof(xpath),
-			 "/cluster/clusternodes/clusternode[%d]/@nodeid", x);
-		
-		if (ccs_get(ccsfd, xpath, &val)!=0) {
-			fprintf(stderr,
-				"Code path error: # of nodes changed\n");
-			free(nodes);
-			return NULL;
-		}
-		
-		nodes[x-1] = atoi(val);
-		free(val);
-	}
-	
-	*count = ncount;
-	return nodes;
-}
-
-
-int
-main(int argc, char **argv)
-{
-	int ccsfd, ret = 0;
-	char *agentpath;
-	char *config;
-	
-	if (argc < 3) {
-		printf("usage: %s <agentpath> <config>\n", argv[0]);
-		return -1;
-	}
-	
-	agentpath = argv[1];
-	config = argv[2];
-
-	conf_setconfig(config);
-	
-       	ccsfd = ccs_lock();
-	if (ccsfd < 0) {
-		printf("Error parsing %s\n", argv[1]);
-		return -1;
-	}
-
-	load_resource_rules(agentpath, &rules);
-	construct_domains(ccsfd, &domains);
-	load_resources(ccsfd, &resources, &rules);
-	build_resource_tree(ccsfd, &restree, &rules, &resources);
-	construct_depends(ccsfd, &depends);
-	
-	if (argc >= 4) {
-		if (!strcmp(argv[3], "dot")) {
-			print_depends_dot(stdout, &depends);
-		} else {
-			fprintf(stderr,"Invalid command: %s\n", argv[3]);
-			ret = 1;
-		}
-		goto out;
-	}
-	
-	nodes_all = load_node_ids(ccsfd, &nodes_all_count);
-		
-	ccs_unlock(ccsfd);
-	
-	printf("Nodes = [ ");
-	for (ret = 0; ret < nodes_all_count; ret++) {
-		printf("%d ", nodes_all[ret]);
-	}
-	printf("]\n");
-	
-	if ((resource_states = dep_rstate_alloc(&restree, &domains,
-			nodes_all,
-			nodes_all_count,
-			&resource_state_count)) == NULL) {
-		printf("oops\n");
-		return -1;
-	}
-	
-	/* Ok!  We have it all! */
-	dtest_shell();
-			
-out:
-	
-	deconstruct_depends(&depends);
-	destroy_resource_tree(&restree);
-	destroy_resources(&resources);
-	deconstruct_domains(&domains);
-	destroy_resource_rules(&rules);
-
-	return ret;
-}
-
-
diff --git a/rgmanager/src/daemons/test.c b/rgmanager/src/daemons/test.c
index 8b6b441..f981424 100644
--- a/rgmanager/src/daemons/test.c
+++ b/rgmanager/src/daemons/test.c
@@ -11,7 +11,6 @@
 #include <reslist.h>
 #include <pthread.h>
 #include <libgen.h>
-#include <depends.h>
 #include <event.h>
 
 #ifndef NO_CCS
@@ -111,37 +110,9 @@ rules_func(int __attribute__((unused)) argc,
 
 
 int
-deps_func(int argc, char**argv)
-{
-	dep_t *depends = NULL;
-	int ccsfd;
-
-	conf_setconfig(argv[1]);
-       	ccsfd = ccs_lock();
-	if (ccsfd < 0) {
-		printf("Error parsing %s\n", argv[1]);
-		goto out;
-	}
-
-	construct_depends(ccsfd, &depends);
-	if (depends) {
-		print_depends(stdout, &depends);
-	}
-	
-	deconstruct_depends(&depends);
-
-out:
-	ccs_unlock(ccsfd);
-	return 0;
-}
-
-
-
-int
 test_func(int argc, char **argv)
 {
 	fod_t *domains = NULL;
-	dep_t *depends = NULL;
 	resource_rule_t *rulelist = NULL, *currule;
 	resource_t *reslist = NULL, *curres;
 	resource_node_t *tree = NULL, *tmp, *rn = NULL;
@@ -160,7 +131,6 @@ test_func(int argc, char **argv)
 	load_resource_rules(agentpath, &rulelist);
 	construct_domains(ccsfd, &domains);
 	construct_events(ccsfd, &events);
-	construct_depends(ccsfd, &depends);
 	load_resources(ccsfd, &reslist, &rulelist);
 	build_resource_tree(ccsfd, &tree, &rulelist, &reslist);
 
@@ -196,11 +166,6 @@ test_func(int argc, char **argv)
 			print_domains(&domains);
 		}
 		
-		if (depends) {
-			printf("=== Dependencies ===\n");
-			print_depends(stdout, &depends);
-		}
-
 		if (events) {
 			printf("=== Event Triggers ===\n");
 			print_events(events);
@@ -275,7 +240,6 @@ test_func(int argc, char **argv)
 	}
 
 out:
-	deconstruct_depends(&depends);
 	deconstruct_events(&events);
 	deconstruct_domains(&domains);
 	destroy_resource_tree(&tree);
@@ -446,10 +410,6 @@ main(int argc, char **argv)
 			shift();
 			ret = test_func(argc, argv);
 			goto out;
-		} else if (!strcmp(argv[1], "depends")) {
-			shift();
-			ret = deps_func(argc, argv);
-			goto out;
 		} else if (!strcmp(argv[1], "noop")) {
 			shift();
 			_no_op_mode(1);


                 reply	other threads:[~2009-06-22 13:33 UTC|newest]

Thread overview: [no followups] expand[flat|nested]  mbox.gz  Atom feed

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20090622133232.79ECE1201EF@lists.fedorahosted.org \
    --to=lon@fedoraproject.org \
    --cc=cluster-cvs-relay@redhat.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).