r266 - in devmapper/upstream/current: . dmeventd dmsetup include lib lib/datastruct lib/ioctl lib/mm po

Bastian Blank waldi at costa.debian.org
Sun Feb 12 10:06:33 UTC 2006


Author: waldi
Date: Sun Feb 12 10:06:32 2006
New Revision: 266

Modified:
   devmapper/upstream/current/VERSION
   devmapper/upstream/current/WHATS_NEW
   devmapper/upstream/current/dmeventd/.exported_symbols
   devmapper/upstream/current/dmeventd/Makefile.in
   devmapper/upstream/current/dmeventd/dmeventd.c
   devmapper/upstream/current/dmeventd/dmeventd.h
   devmapper/upstream/current/dmeventd/libdevmapper-event.c
   devmapper/upstream/current/dmeventd/libdevmapper-event.h
   devmapper/upstream/current/dmsetup/dmsetup.c
   devmapper/upstream/current/include/log.h
   devmapper/upstream/current/lib/.exported_symbols
   devmapper/upstream/current/lib/datastruct/bitset.c
   devmapper/upstream/current/lib/datastruct/hash.c
   devmapper/upstream/current/lib/ioctl/libdm-iface.c
   devmapper/upstream/current/lib/libdevmapper.h
   devmapper/upstream/current/lib/libdm-common.c
   devmapper/upstream/current/lib/libdm-deptree.c
   devmapper/upstream/current/lib/libdm-file.c
   devmapper/upstream/current/lib/mm/dbg_malloc.c
   devmapper/upstream/current/lib/mm/pool-fast.c
   devmapper/upstream/current/make.tmpl.in
   devmapper/upstream/current/po/Makefile.in
   devmapper/upstream/current/po/pogen.h
Log:
Load device-mapper.1.02.03 into /devmapper/upstream/current.


Modified: devmapper/upstream/current/VERSION
==============================================================================
--- devmapper/upstream/current/VERSION	(original)
+++ devmapper/upstream/current/VERSION	Sun Feb 12 10:06:32 2006
@@ -1 +1 @@
-1.02.02 (2005-12-02)
+1.02.03 (2006-02-08)

Modified: devmapper/upstream/current/WHATS_NEW
==============================================================================
--- devmapper/upstream/current/WHATS_NEW	(original)
+++ devmapper/upstream/current/WHATS_NEW	Sun Feb 12 10:06:32 2006
@@ -1,3 +1,17 @@
+Version 1.02.03 - 7 Feb 2006
+============================
+  Add exported functions to set uid, gid and mode.
+  Rename _log to dm_log and export.
+  Add dm_tree_skip_lockfs.
+  Fix dm_strdup debug definition.
+  Fix hash function to avoid using a negative array offset.
+  Don't inline _find in hash.c and tidy signed/unsigned etc.
+  Fix libdevmapper.h #endif.
+  Fix dmsetup version driver version.
+  Add sync, nosync and block_on_error mirror log parameters.
+  Add hweight32.
+  Fix dmeventd build.
+
 Version 1.02.02 - 2 Dec 2005
 ============================
   dmeventd added.

Modified: devmapper/upstream/current/dmeventd/.exported_symbols
==============================================================================
--- devmapper/upstream/current/dmeventd/.exported_symbols	(original)
+++ devmapper/upstream/current/dmeventd/.exported_symbols	Sun Feb 12 10:06:32 2006
@@ -1,5 +1,5 @@
-dm_register_for_event
-dm_unregister_for_event
-dm_get_registered_device
-dm_set_event_timeout
-dm_get_event_timeout
+dm_event_register
+dm_event_unregister
+dm_event_get_registered_device
+dm_event_set_timeout
+dm_event_get_timeout

Modified: devmapper/upstream/current/dmeventd/Makefile.in
==============================================================================
--- devmapper/upstream/current/dmeventd/Makefile.in	(original)
+++ devmapper/upstream/current/dmeventd/Makefile.in	Sun Feb 12 10:06:32 2006
@@ -14,7 +14,6 @@
 srcdir = @srcdir@
 top_srcdir = @top_srcdir@
 VPATH = @srcdir@
-interface = @interface@
 
 SOURCES = libdevmapper-event.c \
 	  dmeventd.c
@@ -27,10 +26,10 @@
   LIB_SHARED = libdevmapper-event.so
 endif
 
-CLDFLAGS += -ldl -ldevmapper -lpthread
-
 include ../make.tmpl
 
+CLDFLAGS += -ldl -ldevmapper -lpthread
+
 .PHONY: install_dynamic install_static
 
 INSTALL_TYPE = install_dynamic

Modified: devmapper/upstream/current/dmeventd/dmeventd.c
==============================================================================
--- devmapper/upstream/current/dmeventd/dmeventd.c	(original)
+++ devmapper/upstream/current/dmeventd/dmeventd.c	Sun Feb 12 10:06:32 2006
@@ -32,7 +32,6 @@
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
-#include <syslog.h>
 #include <sys/file.h>
 #include <sys/mman.h>
 #include <sys/types.h>
@@ -45,11 +44,6 @@
 #include <malloc.h>
 #endif
 
-/* FIXME Use dm library */
-#define	dbg_malloc(x...)	malloc(x)
-#define	dbg_strdup(x...)	strdup(x)
-#define	dbg_free(x...)		free(x)
-
 /* List (un)link macros. */
 #define	LINK(x, head)		list_add(head, &(x)->list)
 #define	LINK_DSO(dso)		LINK(dso, &dso_registry)
@@ -132,7 +126,8 @@
 	struct dso_data *dso_data;/* DSO this thread accesses. */
 	
 	char *device_path;	/* Mapped device path. */
-	int event_nr;           /* event number */
+	uint32_t event_nr;           /* event number */
+	int processing;         /* Set when event is being processed */
 	enum dm_event_type events;	/* bitfield for event filter. */
 	enum dm_event_type current_events;/* bitfield for occured events. */
 	enum dm_event_type processed_events;/* bitfield for processed events. */
@@ -141,6 +136,7 @@
 	struct list timeout_list;
 };
 static LIST_INIT(thread_registry);
+static LIST_INIT(thread_registry_unused);
 
 static int timeout_running;
 static LIST_INIT(timeout_registry);
@@ -151,12 +147,12 @@
 static struct thread_status *alloc_thread_status(struct message_data *data,
 						 struct dso_data *dso_data)
 {
-	struct thread_status *ret = (typeof(ret)) dbg_malloc(sizeof(*ret));
+	struct thread_status *ret = (typeof(ret)) dm_malloc(sizeof(*ret));
 
 	if (ret) {
 		if (!memset(ret, 0, sizeof(*ret)) ||
-		    !(ret->device_path = dbg_strdup(data->device_path))) {
-			dbg_free(ret);
+		    !(ret->device_path = dm_strdup(data->device_path))) {
+			dm_free(ret);
 			ret = NULL;
 		} else {
 			ret->dso_data = dso_data;
@@ -171,19 +167,19 @@
 
 static void free_thread_status(struct thread_status *thread)
 {
-	dbg_free(thread->device_path);
-	dbg_free(thread);
+	dm_free(thread->device_path);
+	dm_free(thread);
 }
 
 /* Allocate/free DSO data. */
 static struct dso_data *alloc_dso_data(struct message_data *data)
 {
-	struct dso_data *ret = (typeof(ret)) dbg_malloc(sizeof(*ret));
+	struct dso_data *ret = (typeof(ret)) dm_malloc(sizeof(*ret));
 
 	if (ret) {
 		if (!memset(ret, 0, sizeof(*ret)) ||
-		    !(ret->dso_name = dbg_strdup(data->dso_name))) {
-			dbg_free(ret);
+		    !(ret->dso_name = dm_strdup(data->dso_name))) {
+			dm_free(ret);
 			ret = NULL;
 		}
 	}
@@ -193,8 +189,8 @@
 
 static void free_dso_data(struct dso_data *data)
 {
-	dbg_free(data->dso_name);
-	dbg_free(data);
+	dm_free(data->dso_name);
+	dm_free(data);
 }
 
 /* FIXME: Factor out. */
@@ -220,11 +216,11 @@
 	if ((p = strchr(*src, delimiter)))
 		*p = 0;
 
-	if ((*ptr = dbg_strdup(*src))) {
+	if ((*ptr = dm_strdup(*src))) {
 		if ((len = strlen(*ptr)))
 			*src += len;
 		else {
-			dbg_free(*ptr);
+			dm_free(*ptr);
 			*ptr = NULL;
 		}
 
@@ -242,10 +238,10 @@
 static void free_message(struct message_data *message_data)
 {
 	if (message_data->dso_name)
-		dbg_free(message_data->dso_name);
+		dm_free(message_data->dso_name);
 
 	if (message_data->device_path)
-		dbg_free(message_data->device_path);
+		dm_free(message_data->device_path);
 }
 
 /* Parse a register message from the client. */
@@ -268,12 +264,12 @@
 			 * Free string representaion of events.
 			 * Not needed an more.
 			 */
-			dbg_free(message_data->events.str);
+			dm_free(message_data->events.str);
 			message_data->events.field = i;
 		}
 		if (message_data->timeout.str) {
 			uint32_t secs = atoi(message_data->timeout.str);
-			dbg_free(message_data->timeout.str);
+			dm_free(message_data->timeout.str);
 			message_data->timeout.secs = secs ? secs :
 							    DM_EVENT_DEFAULT_TIMEOUT;
 		}
@@ -304,10 +300,10 @@
 	if ((len = snprintf(pid, sizeof(pid), "%u\n", getpid())) < 0)
 		return 0;
 
-	if (len > sizeof(pid))
-		len = sizeof(pid);
+	if (len > (int) sizeof(pid))
+		len = (int) sizeof(pid);
 
-	if (write(lf, pid, len) != len)
+	if (write(lf, pid, (size_t) len) != len)
 		return 0;
 
 	fsync(lf);
@@ -315,19 +311,29 @@
 	return 1;
 }
 
-
+/* FIXME This is unreliable: should use DM_DEVICE_INFO ioctl instead. */
 /* Check, if a device exists. */
 static int device_exists(char *device)
 {
 	struct stat st_buf;
+	char path2[PATH_MAX];
+
+	if (!device)
+		return 0;
+
+	if (device[0] == '/') /* absolute path */
+		return !stat(device, &st_buf) && S_ISBLK(st_buf.st_mode);
 
-	return !stat(device, &st_buf) && S_ISBLK(st_buf.st_mode);
+	if (PATH_MAX <= snprintf(path2, PATH_MAX, "%s/%s", dm_dir(), device))
+		return 0;
+
+	return !stat(path2, &st_buf) && S_ISBLK(st_buf.st_mode);
 }
 
 /*
  * Find an existing thread for a device.
  *
- * Mutex must be hold when calling this.
+ * Mutex must be held when calling this.
  */
 static struct thread_status *lookup_thread_status(struct message_data *data)
 {
@@ -579,13 +585,15 @@
 
 /* Device monitoring thread. */
 static void *monitor_thread(void *arg)
+    __attribute((noreturn));
+static void *monitor_thread(void *arg)
 {
 	struct thread_status *thread = arg;
 
 	pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
 	pthread_cleanup_push(monitor_unregister, thread);
 
-	/* Wait for do_process_reques() to finish its task. */
+	/* Wait for do_process_request() to finish its task. */
 	lock_mutex();
 	unlock_mutex();
 
@@ -593,6 +601,11 @@
 	while (1) {
 		thread->current_events = 0;
 
+		/*
+		 * FIXME: if unrecoverable error (ENODEV) happens,
+		 * we loop indefinitely.  event_wait should return
+		 * more than 0/1.
+		 */
 		if (!event_wait(thread))
 			continue;
 
@@ -603,12 +616,22 @@
 		 * the device got registered for those events AND
 		 * those events haven't been processed yet, call
 		 * the DSO's process_event() handler.
+		 *
+		 * FIXME: when does processed_events get cleared?  What if
+		 * the same type of event happens later... after the first
+		 * was handled properly?
 		 */
 		if (thread->events &
 		    thread->current_events &
 		    ~thread->processed_events) {
+			lock_mutex();
+			thread->processing = 1;
+			unlock_mutex();
 			do_process_event(thread);
 			thread->processed_events |= thread->current_events;
+			lock_mutex();
+			thread->processing = 0;
+			unlock_mutex();
 		}
 	}
 
@@ -689,41 +712,27 @@
 			     "unregister_device");
 }
 
-/* Create a DSO file name based on its name. */
-static char *create_dso_file_name(char *dso_name)
-{
-	char *ret;
-	static char prefix[] = "libdmeventd";
-	static char suffix[] = ".so";
-
-	if ((ret = dbg_malloc(strlen(prefix) +
-			      strlen(dso_name) +
-			      strlen(suffix) + 1)))
-		sprintf(ret, "%s%s%s", prefix, dso_name, suffix);
-
-	return ret;
-}
-
 /* Load an application specific DSO. */
 static struct dso_data *load_dso(struct message_data *data)
 {
 	void *dl;
 	struct dso_data *ret = NULL;
-	char *dso_file;
-
-	if (!(dso_file = create_dso_file_name(data->dso_name)))
-		return NULL;
 
-	if (!(dl = dlopen(dso_file, RTLD_NOW))){
+	if (!(dl = dlopen(data->dso_name, RTLD_NOW))){
 		log_error("%s\n", dlerror());
-		goto free_dso_file;
+		return NULL;
 	}
 
-	if (!(ret = alloc_dso_data(data)))
-		goto close;
+	if (!(ret = alloc_dso_data(data))) {
+		dlclose(dl);
+		return NULL;
+	}
 
-	if (!(lookup_symbols(dl, ret)))
-		goto free_all;
+	if (!(lookup_symbols(dl, ret))) {
+		free_dso_data(ret);
+		dlclose(dl);
+		return NULL;
+	}
 
 	/*
 	 * Keep handle to close the library once
@@ -736,17 +745,6 @@
 	LINK_DSO(ret);
 	unlock_mutex();
 
-	goto free_dso_file;
-
-   free_all:
-	free_dso_data(ret);
-
-   close:
-	dlclose(dl);
-
-   free_dso_file:
-	dbg_free(dso_file);
-
 	return ret;
 }
 
@@ -875,27 +873,11 @@
 	 * In case there's no events to monitor on this device ->
 	 * unlink and terminate its monitoring thread.
 	 */
-	if (!thread->events)
-		UNLINK_THREAD(thread);
-
-	unlock_mutex();
-
 	if (!thread->events) {
-		/* turn codes negative */
-		if ((ret = -terminate_thread(thread)))
-			stack;
-		else {
-			pthread_join(thread->thread, NULL);
-			free_thread_status(thread);
-			lib_put(thread->dso_data);
-
-			lock_mutex();
-			if (list_empty(&thread_registry))
-				exit_dm_lib();
-			unlock_mutex();
-		}
+		UNLINK_THREAD(thread);
+		LINK(thread, &thread_registry_unused);
 	}
-
+	unlock_mutex();
 
    out:
 	return ret;
@@ -1054,7 +1036,8 @@
  */
 static int client_read(struct dm_event_fifos *fifos, struct dm_event_daemon_message *msg)
 {
-	int bytes = 0, ret = 0;
+	unsigned bytes = 0;
+	int ret = 0;
 	fd_set fds;
 
 	errno = 0;
@@ -1077,7 +1060,8 @@
  */
 static int client_write(struct dm_event_fifos *fifos, struct dm_event_daemon_message *msg)
 {
-	int bytes = 0, ret = 0;
+	unsigned bytes = 0;
+	int ret = 0;
 	fd_set fds;
 
 	errno = 0;
@@ -1139,7 +1123,6 @@
 		stack;
 		ret = -EINVAL;
 	} else {
-log_print("%s: %u \"%s\"\n", __func__, msg->opcode.cmd, message_data.msg->msg);
 		ret = handle_request(msg, &message_data);
 	}
 
@@ -1164,11 +1147,43 @@
 
 	msg.opcode.status = do_process_request(&msg);
 
-log_print("%s: status: %s\n", __func__, strerror(-msg.opcode.status));
 	if (!client_write(fifos, &msg))
 		stack;
 }
 
+static void cleanup_unused_threads(void)
+{
+	int ret;
+	struct list *l;
+	struct thread_status *thread;
+
+	lock_mutex();
+	while ((l = list_first(&thread_registry_unused))) {
+		thread = list_item(l, struct thread_status);
+		if (thread->processing) {
+			goto out;  /* cleanup on the next round */
+		}
+		list_del(l);
+
+		if (!thread->events) {
+			/* turn codes negative -- should we be returning this? */
+			if ((ret = -terminate_thread(thread)))
+				stack;
+			else {
+				pthread_join(thread->thread, NULL);
+				lib_put(thread->dso_data);
+				free_thread_status(thread);
+			}
+		} else {
+			log_error("thread can't be on unused list unless !thread->events");
+			LINK_THREAD(thread);
+		}
+
+	}
+out:
+	unlock_mutex();
+}
+
 static void sig_alarm(int signum)
 {
 	pthread_testcancel();
@@ -1264,8 +1279,25 @@
 	 */
 	do {
 		process_request(&fifos);
+		cleanup_unused_threads();
 	} while(!list_empty(&thread_registry));
 
+	/*
+	 * There may still have been some threads that were doing work,
+	 * make sure these are cleaned up
+	 *
+	 * I don't necessarily like the sleep there, but otherwise,
+	 * cleanup_unused_threads could get called many many times.
+	 * It's worth noting that the likelyhood of it being called
+	 * here is slim.
+	 */
+	while(!list_empty(&thread_registry_unused)) {
+		sleep(1);
+		cleanup_unused_threads();
+	}
+
+	exit_dm_lib();
+
 #ifdef MCL_CURRENT
 	munlockall();
 #endif

Modified: devmapper/upstream/current/dmeventd/dmeventd.h
==============================================================================
--- devmapper/upstream/current/dmeventd/dmeventd.h	(original)
+++ devmapper/upstream/current/dmeventd/dmeventd.h	Sun Feb 12 10:06:32 2006
@@ -7,6 +7,7 @@
 #define EXIT_FIFO_FAILURE        5
 #define EXIT_CHDIR_FAILURE       6
 
-void dmeventd(void);
+void dmeventd(void)
+    __attribute((noreturn));
 
 #endif /* __DMEVENTD_DOT_H__ */

Modified: devmapper/upstream/current/dmeventd/libdevmapper-event.c
==============================================================================
--- devmapper/upstream/current/dmeventd/libdevmapper-event.c	(original)
+++ devmapper/upstream/current/dmeventd/libdevmapper-event.c	Sun Feb 12 10:06:32 2006
@@ -44,7 +44,7 @@
 	if ((p = strchr(*src, delimiter)))
 		*p = 0;
 
-	if ((ret = strdup(*src)))
+	if ((ret = dm_strdup(*src)))
 		*src += strlen(ret) + 1;
 
 	if (p)
@@ -69,52 +69,80 @@
 	return -ENOMEM;
 }
 
-/* Read message from daemon. */
+/*
+ * daemon_read
+ * @fifos
+ * @msg
+ *
+ * Read message from daemon.
+ *
+ * Returns: 0 on failure, 1 on success
+ */
 static int daemon_read(struct dm_event_fifos *fifos, struct dm_event_daemon_message *msg)
 {
-	int bytes = 0, ret = 0;
+	unsigned bytes = 0;
+	int ret = 0;
 	fd_set fds;
 
 	memset(msg, 0, sizeof(*msg));
-	errno = 0;
-	/* FIXME Fix error handling. Check 'ret' before errno. EINTR? EAGAIN? */
-	/* FIXME errno != EOF?   RTFM! */
-	while (bytes < sizeof(*msg) && errno != EOF) {
+	while (bytes < sizeof(*msg)) {
 		do {
 			/* Watch daemon read FIFO for input. */
 			FD_ZERO(&fds);
 			FD_SET(fifos->server, &fds);
-		/* FIXME Check for errors e.g. EBADF */
-		} while (select(fifos->server+1, &fds, NULL, NULL, NULL) != 1);
+			ret = select(fifos->server+1, &fds, NULL, NULL, NULL);
+			if (ret < 0 && errno != EINTR) {
+				/* FIXME Log error */
+				return 0;
+			}
+		} while (ret < 1);
 
 		ret = read(fifos->server, msg, sizeof(*msg) - bytes);
-		bytes += ret > 0 ? ret : 0;
+		if (ret < 0) {
+			if ((errno == EINTR) || (errno == EAGAIN))
+				continue;
+			else {
+				/* FIXME Log error */
+				return 0;
+			}
+		}
+
+		bytes += ret;
 	}
 
-// log_print("%s: \"%s\"\n", __func__, msg->msg);
 	return bytes == sizeof(*msg);
 }
 
 /* Write message to daemon. */
 static int daemon_write(struct dm_event_fifos *fifos, struct dm_event_daemon_message *msg)
 {
-	int bytes = 0, ret = 0;
+	unsigned bytes = 0;
+	int ret = 0;
 	fd_set fds;
 
-
-// log_print("%s: \"%s\"\n", __func__, msg->msg);
-	errno = 0;
-	/* FIXME Fix error handling. Check 'ret' before errno. EINTR? EAGAIN? */
-	while (bytes < sizeof(*msg) && errno != EIO) {
+	while (bytes < sizeof(*msg)) {
 		do {
 			/* Watch daemon write FIFO to be ready for output. */
 			FD_ZERO(&fds);
 			FD_SET(fifos->client, &fds);
-		/* FIXME Check for errors e.g. EBADF */
-		} while (select(fifos->client +1, NULL, &fds, NULL, NULL) != 1);
+			ret = select(fifos->client +1, NULL, &fds, NULL, NULL);
+			if ((ret < 0) && (errno != EINTR)) {
+				/* FIXME Log error */
+				return 0;
+			}
+		} while (ret < 1);
 
 		ret = write(fifos->client, msg, sizeof(*msg) - bytes);
-		bytes += ret > 0 ? ret : 0;
+		if (ret < 0) {
+			if ((errno == EINTR) || (errno == EAGAIN))
+				continue;
+			else {
+				/* fixme: log error */
+				return 0;
+			}
+		}
+
+		bytes += ret;
 	}
 
 	return bytes == sizeof(*msg);
@@ -132,11 +160,11 @@
 	 */
 	msg->opcode.cmd = cmd;
 
-	if (sizeof(msg->msg) <= snprintf(msg->msg, sizeof(msg->msg),
-					 "%s %s %u %"PRIu32,
-					 dso_name ? dso_name : "",
-					 device ? device : "",
-					 events, timeout)) {
+	if (sizeof(msg->msg) <= (unsigned) snprintf(msg->msg, sizeof(msg->msg),
+						    "%s %s %u %"PRIu32,
+						    dso_name ? dso_name : "",
+						    device ? device : "",
+						    events, timeout)) {
 		stack;
 		return -ENAMETOOLONG;
 	}
@@ -178,8 +206,8 @@
 static int start_daemon(void)
 {
 	int pid, ret=0;
-	int old_mask;
 	void *old_hand;
+	sigset_t set, oset;
 
 	/* Must be able to acquire signal */
 	old_hand = signal(SIGUSR1, &daemon_running_signal_handler);
@@ -188,12 +216,11 @@
 		return 0;
 	}
 
-#ifdef linux
-	/* FIXME Deprecated. Try posix sigprocmask instead. */
-	old_mask = siggetmask();
-	old_mask &= ~sigmask(SIGUSR1);
-	old_mask = sigsetmask(old_mask);
-#endif
+	if (sigemptyset(&set) || sigaddset(&set, SIGUSR1)) {
+		log_error("Unable to fill signal set.");
+	} else if (sigprocmask(SIG_UNBLOCK, &set, &oset)) {
+		log_error("Can't unblock the potentially blocked signal SIGUSR1");
+	}
 	
 	pid = fork();
 
@@ -207,7 +234,6 @@
 			sleep(1);
 
 		if (daemon_running) {
-			log_print("dmeventd started.\n");
 			ret = 1;
 		} else {
 			switch (WEXITSTATUS(status)) {
@@ -225,6 +251,13 @@
 				break;
 			}
 		}
+		/*
+		 * Sometimes, a single process may perform multiple calls
+		 * that result in a daemon starting and exiting.  If we
+		 * don't reset this, the second (or greater) time the daemon
+		 * is started will cause this logic not to work.
+		 */
+		daemon_running = 0;
 	} else {
 		signal(SIGUSR1, SIG_IGN); /* don't care about error */
 
@@ -238,9 +271,11 @@
 	/* FIXME What if old_hand is SIG_ERR? */
 	if (signal(SIGUSR1, old_hand) == SIG_ERR)
 		log_error("Unable to reset signal handler.");
-	sigsetmask(old_mask);
 
-        return ret;
+	if (sigprocmask(SIG_SETMASK, &oset, NULL))
+		log_error("Unable to reset signal mask.");
+
+	return ret;
 }
 
 /* Initialize client. */
@@ -251,15 +286,15 @@
 
 	/* init fifos */
 	memset(fifos, 0, sizeof(*fifos));
-        fifos->client_path = DM_EVENT_FIFO_CLIENT;
-        fifos->server_path = DM_EVENT_FIFO_SERVER;
+	fifos->client_path = DM_EVENT_FIFO_CLIENT;
+	fifos->server_path = DM_EVENT_FIFO_SERVER;
 
 	/* FIXME The server should be responsible for these, not the client. */
 	/* Create fifos */
 	if (((mkfifo(fifos->client_path, 0600) == -1) && errno != EEXIST) ||
 	    ((mkfifo(fifos->server_path, 0600) == -1) && errno != EEXIST)) {
 		log_error("%s: Failed to create a fifo.\n", __func__);
-                return 0;
+		return 0;
 	}
 
 	/* FIXME Warn/abort if perms are wrong - not something to fix silently. */
@@ -296,11 +331,11 @@
 	}
 
 	/* Anyone listening?  If not, errno will be ENXIO */
-	if ((fifos->client = open(fifos->client_path,
+	while ((fifos->client = open(fifos->client_path,
 				  O_WRONLY | O_NONBLOCK)) < 0) {
 		if (errno != ENXIO) {
-			log_error("%s: open client fifo %s\n",
-				__func__, fifos->client_path);
+			log_error("%s: Can't open client fifo %s: %s\n",
+				  __func__, fifos->client_path, strerror(errno));
 			close(fifos->server);
 			stack;
 			return 0;
@@ -311,17 +346,6 @@
 			stack;
 			return 0;
 		}
-
-		/* FIXME Unnecessary if daemon was started before calling this */
-		/* Daemon is started, retry the open */
-		fifos->client = open(fifos->client_path, O_WRONLY | O_NONBLOCK);
-		if (fifos->client < 0) {
-			log_error("%s: open client fifo %s\n",
-				__func__, fifos->client_path);
-			close(fifos->server);
-			stack;
-			return 0;
-		}
 	}
 	
 	return 1;
@@ -330,7 +354,7 @@
 static void dtr_client(struct dm_event_fifos *fifos)
 {
 	if (flock(fifos->server, LOCK_UN))
-                log_error("flock unlock %s\n", fifos->server_path);
+		log_error("flock unlock %s\n", fifos->server_path);
 
 	close(fifos->client);
 	close(fifos->server);
@@ -363,12 +387,13 @@
 	struct dm_event_fifos fifos;
 
 	/* FIXME Start the daemon here if it's not running e.g. exclusive lock file */
-
+	/* FIXME Move this to separate 'dm_event_register_handler' - if no daemon here, fail */
 	if (!init_client(&fifos)) {
 		stack;
 		return -ESRCH;
 	}
 
+	/* FIXME Use separate 'dm_event_register_handler' function to pass in dso? */
 	ret = daemon_talk(&fifos, msg, cmd, dso_name, device, events, timeout);
 
 	/* what is the opposite of init? */
@@ -377,29 +402,49 @@
 	return ret;
 }
 
+/* FIXME remove dso_name - use handle instead */
+/* FIXME Use uuid not path! */
 /* External library interface. */
 int dm_event_register(char *dso_name, char *device_path,
-			  enum dm_event_type events)
+		      enum dm_event_type events)
 {
+	int ret;
 	struct dm_event_daemon_message msg;
 
-	if (!device_exists(device_path))
-		return -ENODEV;
+	if (!device_exists(device_path)) {
+		log_error("%s: device not found", device_path);
+		return 0;
+	}
+
+	if ((ret = do_event(DM_EVENT_CMD_REGISTER_FOR_EVENT, &msg,
+			    dso_name, device_path, events, 0)) < 0) {
+		log_error("%s: event registration failed: %s", device_path,
+			  strerror(-ret));
+		return 0;
+	}
 
-	return do_event(DM_EVENT_CMD_REGISTER_FOR_EVENT, &msg,
-			dso_name, device_path, events, 0);
+	return 1;
 }
 
 int dm_event_unregister(char *dso_name, char *device_path,
-			    enum dm_event_type events)
+			enum dm_event_type events)
 {
+	int ret;
 	struct dm_event_daemon_message msg;
 
-	if (!device_exists(device_path))
-		return -ENODEV;
+	if (!device_exists(device_path)) {
+		log_error("%s: device not found", device_path);
+		return 0;
+	}
 
-	return do_event(DM_EVENT_CMD_UNREGISTER_FOR_EVENT, &msg,
-			dso_name, device_path, events, 0);
+	if ((ret = do_event(DM_EVENT_CMD_UNREGISTER_FOR_EVENT, &msg,
+			    dso_name, device_path, events, 0)) < 0) {
+		log_error("%s: event deregistration failed: %s", device_path,
+			  strerror(-ret));
+		return 0;
+	}
+
+	return 1;
 }
 
 int dm_event_get_registered_device(char **dso_name, char **device_path,
@@ -417,9 +462,9 @@
 
 	if (next){
 		if (*dso_name)
-			free(*dso_name);
+			dm_free(*dso_name);
 		if (*device_path)
-			free(*device_path);
+			dm_free(*device_path);
 		*dso_name = dso_name_arg;
 		*device_path = device_path_arg;
 	} else {

Modified: devmapper/upstream/current/dmeventd/libdevmapper-event.h
==============================================================================
--- devmapper/upstream/current/dmeventd/libdevmapper-event.h	(original)
+++ devmapper/upstream/current/dmeventd/libdevmapper-event.h	Sun Feb 12 10:06:32 2006
@@ -82,6 +82,15 @@
 			     DM_EVENT_PATH_ERROR | DM_EVENT_ADAPTOR_ERROR)
 
 /* Prototypes for event lib interface. */
+
+/* FIXME Replace device with standard name/uuid/devno choice */
+/* Interface changes: 
+   First register a handler, passing in a unique ref for the device. */
+//  int dm_event_register_handler(const char *dso_name, const char *device);
+//  int dm_event_register(const char *dso_name, const char *name, const char *uuid, uint32_t major, uint32_t minor, enum dm_event_type events);
+/* Or (better?) add to task structure and use existing functions - run a task to register/unregister events - we may need to run task withe that with the new event mechanism anyway, then the dso calls just hook in.
+*/
+ 
 /* FIXME Missing consts? */
 int dm_event_register(char *dso_name, char *device, enum dm_event_type events);
 int dm_event_unregister(char *dso_name, char *device,

Modified: devmapper/upstream/current/dmsetup/dmsetup.c
==============================================================================
--- devmapper/upstream/current/dmsetup/dmsetup.c	(original)
+++ devmapper/upstream/current/dmsetup/dmsetup.c	Sun Feb 12 10:06:32 2006
@@ -86,8 +86,10 @@
 	READ_ONLY = 0,
 	COLS_ARG,
 	EXEC_ARG,
+	GID_ARG,
 	MAJOR_ARG,
 	MINOR_ARG,
+	MODE_ARG,
 	NOHEADINGS_ARG,
 	NOLOCKFS_ARG,
 	NOOPENCOUNT_ARG,
@@ -95,6 +97,7 @@
 	OPTIONS_ARG,
 	TARGET_ARG,
 	TREE_ARG,
+	UID_ARG,
 	UUID_ARG,
 	VERBOSE_ARG,
 	VERSION_ARG,
@@ -390,6 +393,15 @@
 	if (_switches[MINOR_ARG] && !dm_task_set_minor(dmt, _values[MINOR_ARG]))
 		goto out;
 
+	if (_switches[UID_ARG] && !dm_task_set_uid(dmt, _values[UID_ARG]))
+		goto out;
+
+	if (_switches[GID_ARG] && !dm_task_set_gid(dmt, _values[GID_ARG]))
+		goto out;
+
+	if (_switches[MODE_ARG] && !dm_task_set_mode(dmt, _values[MODE_ARG]))
+		goto out;
+
 	if (_switches[NOOPENCOUNT_ARG] && !dm_task_no_open_count(dmt))
 		goto out;
 
@@ -438,7 +450,8 @@
 
 static int _message(int argc, char **argv, void *data)
 {
-	int r = 0, sz = 1, i;
+	int r = 0, i;
+	size_t sz = 1;
 	struct dm_task *dmt;
 	char *str;
 
@@ -455,7 +468,7 @@
 		argv++;
 	}
 
-	if (!dm_task_set_sector(dmt, atoll(argv[1])))
+	if (!dm_task_set_sector(dmt, (uint64_t) atoll(argv[1])))
 		goto out;
 
 	argc -= 2;
@@ -502,7 +515,7 @@
 	if (dm_get_library_version(version, sizeof(version)))
 		printf("Library version:   %s\n", version);
 
-	if (dm_driver_version(version, sizeof(version)))
+	if (!dm_driver_version(version, sizeof(version)))
 		return 0;
 
 	printf("Driver version:    %s\n", version);
@@ -580,7 +593,7 @@
 	}
 
 	return _simple(DM_DEVICE_WAITEVENT, name,
-		       (argc > 1) ? atoi(argv[argc - 1]) : 0, 1);
+		       (argc > 1) ? (uint32_t) atoi(argv[argc - 1]) : 0, 1);
 }
 
 static int _process_all(int argc, char **argv,
@@ -622,7 +635,7 @@
 	return r;
 }
 
-static void _display_dev(struct dm_task *dmt, char *name)
+static void _display_dev(struct dm_task *dmt, const char *name)
 {
 	struct dm_info info;
 
@@ -635,7 +648,7 @@
 	return dm_mknodes(argc > 1 ? argv[1] : NULL);
 }
 
-static int _exec_command(char *name)
+static int _exec_command(const char *name)
 {
 	int n;
 	static char path[PATH_MAX];
@@ -651,7 +664,7 @@
 		return 0;
 
 	n = snprintf(path, sizeof(path), "%s/%s", dm_dir(), name);
-	if (n < 0 || n > sizeof(path) - 1)
+	if (n < 0 || n > (int) sizeof(path) - 1)
 		return 0;
 
 	if (!argc) {
@@ -704,7 +717,7 @@
 	char *params;
 	int cmd;
 	struct dm_names *names = (struct dm_names *) data;
-	char *name = NULL;
+	const char *name = NULL;
 	int matched = 0;
 	int ls_only = 0;
 	struct dm_info info;
@@ -742,7 +755,7 @@
 		goto out;
 
 	if (!name)
-		name = (char *) dm_task_get_name(dmt);
+		name = dm_task_get_name(dmt);
 
 	/* Fetch targets and print 'em */
 	do {
@@ -1292,6 +1305,7 @@
 
 static struct command _commands[] = {
 	{"create", "<dev_name> [-j|--major <major> -m|--minor <minor>]\n"
+	  "\t                  [-U|--uid <uid>] [-G|--gid <gid>] [-M|--mode <octal_mode>]\n"
 	  "\t                  [-u|uuid <uuid>] [--notable] [<table_file>]",
 	 1, 2, _create},
 	{"remove", "<device>", 0, 1, _remove},
@@ -1418,8 +1432,10 @@
 		{"readonly", 0, &ind, READ_ONLY},
 		{"columns", 0, &ind, COLS_ARG},
 		{"exec", 1, &ind, EXEC_ARG},
+		{"gid", 1, &ind, GID_ARG},
 		{"major", 1, &ind, MAJOR_ARG},
 		{"minor", 1, &ind, MINOR_ARG},
+		{"mode", 1, &ind, MODE_ARG},
 		{"noheadings", 0, &ind, NOHEADINGS_ARG},
 		{"nolockfs", 0, &ind, NOLOCKFS_ARG},
 		{"noopencount", 0, &ind, NOOPENCOUNT_ARG},
@@ -1427,6 +1443,7 @@
 		{"options", 1, &ind, OPTIONS_ARG},
 		{"target", 1, &ind, TARGET_ARG},
 		{"tree", 0, &ind, TREE_ARG},
+		{"uid", 1, &ind, UID_ARG},
 		{"uuid", 1, &ind, UUID_ARG},
 		{"verbose", 1, &ind, VERBOSE_ARG},
 		{"version", 0, &ind, VERSION_ARG},
@@ -1478,7 +1495,7 @@
 
 	optarg = 0;
 	optind = OPTIND_INIT;
-	while ((ind = -1, c = GETOPTLONG_FN(*argc, *argv, "cCj:m:no:ru:v",
+	while ((ind = -1, c = GETOPTLONG_FN(*argc, *argv, "cCGj:m:Mno:ru:Uv",
 					    long_options, NULL)) != -1) {
 		if (c == 'c' || c == 'C' || ind == COLS_ARG)
 			_switches[COLS_ARG]++;
@@ -1504,6 +1521,19 @@
 			_switches[UUID_ARG]++;
 			_uuid = optarg;
 		}
+		if (c == 'G' || ind == GID_ARG) {
+			_switches[GID_ARG]++;
+			_values[GID_ARG] = atoi(optarg);
+		}
+		if (c == 'U' || ind == UID_ARG) {
+			_switches[UID_ARG]++;
+			_values[UID_ARG] = atoi(optarg);
+		}
+		if (c == 'M' || ind == MODE_ARG) {
+			_switches[MODE_ARG]++;
+			/* FIXME Accept modes as per chmod */
+			_values[MODE_ARG] = (int) strtol(optarg, NULL, 8);
+		}
 		if ((ind == EXEC_ARG)) {
 			_switches[EXEC_ARG]++;
 			_command = optarg;

Modified: devmapper/upstream/current/include/log.h
==============================================================================
--- devmapper/upstream/current/include/log.h	(original)
+++ devmapper/upstream/current/include/log.h	Sun Feb 12 10:06:32 2006
@@ -25,9 +25,9 @@
 #define _LOG_ERR 3
 #define _LOG_FATAL 2
 
-extern dm_log_fn _log;
+extern dm_log_fn dm_log;
 
-#define plog(l, x...) _log(l, __FILE__, __LINE__, ## x)
+#define plog(l, x...) dm_log(l, __FILE__, __LINE__, ## x)
 
 #define log_error(x...) plog(_LOG_ERR, x)
 #define log_print(x...) plog(_LOG_WARN, x)

Modified: devmapper/upstream/current/lib/.exported_symbols
==============================================================================
--- devmapper/upstream/current/lib/.exported_symbols	(original)
+++ devmapper/upstream/current/lib/.exported_symbols	Sun Feb 12 10:06:32 2006
@@ -2,6 +2,7 @@
 dm_lib_exit
 dm_driver_version
 dm_get_library_version
+dm_log
 dm_log_init
 dm_log_init_verbose
 dm_task_create
@@ -22,6 +23,9 @@
 dm_task_set_minor
 dm_task_set_sector
 dm_task_set_message
+dm_task_set_uid
+dm_task_set_gid
+dm_task_set_mode
 dm_task_suppress_identical_reload
 dm_task_add_target
 dm_task_no_open_count
@@ -60,11 +64,12 @@
 dm_tree_node_add_mirror_target
 dm_tree_node_add_mirror_target_log
 dm_tree_node_add_target_area
+dm_tree_skip_lockfs
 dm_is_dm_major
 dm_mknodes
 dm_malloc_aux
 dm_malloc_aux_debug
-dm_strdup
+dm_strdup_aux
 dm_free_aux
 dm_realloc_aux
 dm_dump_memory_debug

Modified: devmapper/upstream/current/lib/datastruct/bitset.c
==============================================================================
--- devmapper/upstream/current/lib/datastruct/bitset.c	(original)
+++ devmapper/upstream/current/lib/datastruct/bitset.c	Sun Feb 12 10:06:32 2006
@@ -57,7 +57,7 @@
  */
 static inline int _test_word(uint32_t test, int bit)
 {
-	while (bit < DM_BITS_PER_INT) {
+	while (bit < (int) DM_BITS_PER_INT) {
 		if (test & (0x1 << bit))
 			return bit;
 		bit++;
@@ -73,7 +73,10 @@
 
 	last_bit++;		/* otherwise we'll return the same bit again */
 
-	while (last_bit < bs[0]) {
+	/*
+	 * bs[0] holds number of bits
+	 */
+	while (last_bit < (int) bs[0]) {
 		word = last_bit >> INT_SHIFT;
 		test = bs[word + 1];
 		bit = last_bit & (DM_BITS_PER_INT - 1);

Modified: devmapper/upstream/current/lib/datastruct/hash.c
==============================================================================
--- devmapper/upstream/current/lib/datastruct/hash.c	(original)
+++ devmapper/upstream/current/lib/datastruct/hash.c	Sun Feb 12 10:06:32 2006
@@ -18,13 +18,13 @@
 struct dm_hash_node {
 	struct dm_hash_node *next;
 	void *data;
-	int keylen;
+	unsigned keylen;
 	char key[0];
 };
 
 struct dm_hash_table {
-	int num_nodes;
-	int num_slots;
+	unsigned num_nodes;
+	unsigned num_slots;
 	struct dm_hash_node **slots;
 };
 
@@ -56,7 +56,7 @@
 	209
 };
 
-static struct dm_hash_node *_create_node(const char *str, int len)
+static struct dm_hash_node *_create_node(const char *str, unsigned len)
 {
 	struct dm_hash_node *n = dm_malloc(sizeof(*n) + len);
 
@@ -68,13 +68,14 @@
 	return n;
 }
 
-static unsigned _hash(const char *str, uint32_t len)
+static unsigned long _hash(const unsigned char *str, unsigned len)
 {
-	unsigned long h = 0, g, i;
+	unsigned long h = 0, g;
+	unsigned i;
 
 	for (i = 0; i < len; i++) {
 		h <<= 4;
-		h += _nums[(int) *str++];
+		h += _nums[*str++];
 		g = h & ((unsigned long) 0xf << 16u);
 		if (g) {
 			h ^= g >> 16u;
@@ -120,7 +121,7 @@
 static void _free_nodes(struct dm_hash_table *t)
 {
 	struct dm_hash_node *c, *n;
-	int i;
+	unsigned i;
 
 	for (i = 0; i < t->num_slots; i++)
 		for (c = t->slots[i]; c; c = n) {
@@ -136,8 +137,8 @@
 	dm_free(t);
 }
 
-static inline struct dm_hash_node **_find(struct dm_hash_table *t, const char *key,
-				       uint32_t len)
+static struct dm_hash_node **_find(struct dm_hash_table *t, const char *key,
+				   uint32_t len)
 {
 	unsigned h = _hash(key, len) & (t->num_slots - 1);
 	struct dm_hash_node **c;
@@ -153,11 +154,12 @@
 			 uint32_t len)
 {
 	struct dm_hash_node **c = _find(t, key, len);
+
 	return *c ? (*c)->data : 0;
 }
 
 int dm_hash_insert_binary(struct dm_hash_table *t, const char *key,
-		       uint32_t len, void *data)
+			  uint32_t len, void *data)
 {
 	struct dm_hash_node **c = _find(t, key, len);
 
@@ -214,7 +216,7 @@
 void dm_hash_iter(struct dm_hash_table *t, dm_hash_iterate_fn f)
 {
 	struct dm_hash_node *c;
-	int i;
+	unsigned i;
 
 	for (i = 0; i < t->num_slots; i++)
 		for (c = t->slots[i]; c; c = c->next)
@@ -225,7 +227,7 @@
 {
 	_free_nodes(t);
 	memset(t->slots, 0, sizeof(struct dm_hash_node *) * t->num_slots);
-	t->num_nodes = 0;
+	t->num_nodes = 0u;
 }
 
 char *dm_hash_get_key(struct dm_hash_table *t, struct dm_hash_node *n)
@@ -241,7 +243,7 @@
 static struct dm_hash_node *_next_slot(struct dm_hash_table *t, unsigned s)
 {
 	struct dm_hash_node *c = NULL;
-	int i;
+	unsigned i;
 
 	for (i = s; i < t->num_slots && !c; i++)
 		c = t->slots[i];
@@ -257,5 +259,6 @@
 struct dm_hash_node *dm_hash_get_next(struct dm_hash_table *t, struct dm_hash_node *n)
 {
 	unsigned h = _hash(n->key, n->keylen) & (t->num_slots - 1);
+
 	return n->next ? n->next : _next_slot(t, h + 1);
 }

Modified: devmapper/upstream/current/lib/ioctl/libdm-iface.c
==============================================================================
--- devmapper/upstream/current/lib/ioctl/libdm-iface.c	(original)
+++ devmapper/upstream/current/lib/ioctl/libdm-iface.c	Sun Feb 12 10:06:32 2006
@@ -877,7 +877,7 @@
 	if (bufsize < 8)
 		return 0;
 
-	r = snprintf(buf, bufsize, "%u:%u", dev_major, dev_minor);
+	r = snprintf(buf, (size_t) bufsize, "%u:%u", dev_major, dev_minor);
 	if (r < 0 || r > bufsize - 1)
 		return 0;
 
@@ -1028,7 +1028,8 @@
 	struct target *t = dm_malloc(sizeof(*t));
 
 	if (!t) {
-		log_error("create_target: malloc(%d) failed", sizeof(*t));
+		log_error("create_target: malloc(%" PRIsize_t ") failed",
+			  sizeof(*t));
 		return NULL;
 	}
 
@@ -1310,6 +1311,9 @@
 
 	task->major = dmt->major;
 	task->minor = dmt->minor;
+	task->uid = dmt->uid;
+	task->gid = dmt->gid;
+	task->mode = dmt->mode;
 
 	r = dm_task_run(task);
 	dm_task_destroy(task);
@@ -1434,7 +1438,7 @@
 	if (dmt->no_open_count)
 		dmi->flags |= DM_SKIP_BDGET_FLAG;
 
-	log_debug("dm %s %s %s%s%s %s%0.0d%s%0.0d%s"
+	log_debug("dm %s %s %s%s%s %s%.0d%s%.0d%s"
 		  "%s%c %.0llu %s [%u]",
 		  _cmd_data_v4[dmt->type].name,
 		  dmi->name, dmi->uuid, dmt->newname ? " " : "",

Modified: devmapper/upstream/current/lib/libdevmapper.h
==============================================================================
--- devmapper/upstream/current/lib/libdevmapper.h	(original)
+++ devmapper/upstream/current/lib/libdevmapper.h	Sun Feb 12 10:06:32 2006
@@ -42,7 +42,8 @@
  */
 
 typedef void (*dm_log_fn) (int level, const char *file, int line,
-			   const char *f, ...);
+			   const char *f, ...)
+    __attribute__ ((format(printf, 4, 5)));
 
 /*
  * The library user may wish to register their own
@@ -140,6 +141,9 @@
 int dm_task_set_newname(struct dm_task *dmt, const char *newname);
 int dm_task_set_minor(struct dm_task *dmt, int minor);
 int dm_task_set_major(struct dm_task *dmt, int major);
+int dm_task_set_uid(struct dm_task *dmt, uid_t uid);
+int dm_task_set_gid(struct dm_task *dmt, gid_t gid);
+int dm_task_set_mode(struct dm_task *dmt, mode_t mode);
 int dm_task_set_event_nr(struct dm_task *dmt, uint32_t event_nr);
 int dm_task_set_message(struct dm_task *dmt, const char *message);
 int dm_task_set_sector(struct dm_task *dmt, uint64_t sector);
@@ -300,6 +304,13 @@
 				   size_t uuid_prefix_len);
 
 /*
+ * Skip the filesystem sync when suspending.
+ * Does nothing with other functions.
+ * Use this when no snapshots are involved.
+ */ 
+void dm_tree_skip_lockfs(struct dm_tree_node *dnode);
+
+/*
  * Is the uuid prefix present in the tree?
  * Only returns 0 if every node was checked successfully.
  * Returns 1 if the tree walk has to be aborted.
@@ -331,11 +342,18 @@
 				       uint32_t stripe_size);
 int dm_tree_node_add_mirror_target(struct dm_tree_node *node,
 				      uint64_t size);
+ 
+/* Mirror log flags */
+#define DM_NOSYNC		0x00000001	/* Known already in sync */
+#define DM_FORCESYNC		0x00000002	/* Force resync */
+#define DM_BLOCK_ON_ERROR	0x00000004	/* On error, suspend I/O */
+
 int dm_tree_node_add_mirror_target_log(struct dm_tree_node *node,
 					  uint32_t region_size,
 					  unsigned clustered,
 					  const char *log_uuid,
-					  unsigned area_count);
+					  unsigned area_count,
+					  uint32_t flags);
 int dm_tree_node_add_target_area(struct dm_tree_node *node,
 				    const char *dev_name,
 				    const char *dlid,
@@ -349,10 +367,9 @@
  * Memory management
  *******************/
 
-char *dm_strdup(const char *str);
-
 void *dm_malloc_aux(size_t s, const char *file, int line);
 void *dm_malloc_aux_debug(size_t s, const char *file, int line);
+char *dm_strdup_aux(const char *str);
 void dm_free_aux(void *p);
 void *dm_realloc_aux(void *p, unsigned int s, const char *file, int line);
 int dm_dump_memory_debug(void);
@@ -361,6 +378,7 @@
 #ifdef DEBUG_MEM
 
 #  define dm_malloc(s) dm_malloc_aux_debug((s), __FILE__, __LINE__)
+#  define dm_strdup(s) dm_strdup_aux(s)
 #  define dm_free(p) dm_free_aux(p)
 #  define dm_realloc(p, s) dm_realloc_aux(p, s, __FILE__, __LINE__)
 #  define dm_dump_memory() dm_dump_memory_debug()
@@ -369,6 +387,7 @@
 #else
 
 #  define dm_malloc(s) dm_malloc_aux((s), __FILE__, __LINE__)
+#  define dm_strdup(s) strdup(s)
 #  define dm_free(p) free(p)
 #  define dm_realloc(p, s) realloc(p, s)
 #  define dm_dump_memory() {}
@@ -509,6 +528,17 @@
 #define dm_bit_copy(bs1, bs2) \
    memcpy(bs1 + 1, bs2 + 1, ((*bs1 / DM_BITS_PER_INT) + 1) * sizeof(int))
 
+/* Returns number of set bits */
+static inline unsigned hweight32(uint32_t i)
+{
+	unsigned r = (i & 0x55555555) + ((i >> 1) & 0x55555555);
+
+	r =    (r & 0x33333333) + ((r >>  2) & 0x33333333);
+	r =    (r & 0x0F0F0F0F) + ((r >>  4) & 0x0F0F0F0F);
+	r =    (r & 0x00FF00FF) + ((r >>  8) & 0x00FF00FF);
+	return (r & 0x0000FFFF) + ((r >> 16) & 0x0000FFFF);
+}
+
 /****************
  * hash functions
  ****************/
@@ -543,9 +573,9 @@
 	for (v = dm_hash_get_first(h); v; \
 	     v = dm_hash_get_next(h, v))
 
-#endif				/* LIB_DEVICE_MAPPER_H */
-
 /*********
  * selinux
  *********/
 int dm_set_selinux_context(const char *path, mode_t mode);
+
+#endif				/* LIB_DEVICE_MAPPER_H */

Modified: devmapper/upstream/current/lib/libdm-common.c
==============================================================================
--- devmapper/upstream/current/lib/libdm-common.c	(original)
+++ devmapper/upstream/current/lib/libdm-common.c	Sun Feb 12 10:06:32 2006
@@ -61,14 +61,14 @@
 		fprintf(stdout, "\n");
 }
 
-dm_log_fn _log = _default_log;
+dm_log_fn dm_log = _default_log;
 
 void dm_log_init(dm_log_fn fn)
 {
 	if (fn)
-		_log = fn;
+		dm_log = fn;
 	else
-		_log = _default_log;
+		dm_log = _default_log;
 }
 
 void dm_log_init_verbose(int level)
@@ -96,7 +96,8 @@
 	struct dm_task *dmt = dm_malloc(sizeof(*dmt));
 
 	if (!dmt) {
-		log_error("dm_task_create: malloc(%d) failed", sizeof(*dmt));
+		log_error("dm_task_create: malloc(%" PRIsize_t ") failed",
+			  sizeof(*dmt));
 		return NULL;
 	}
 
@@ -180,6 +181,27 @@
 	return 1;
 }
 
+int dm_task_set_uid(struct dm_task *dmt, uid_t uid)
+{
+	dmt->uid = uid;
+
+	return 1;
+}
+
+int dm_task_set_gid(struct dm_task *dmt, gid_t gid)
+{
+	dmt->gid = gid;
+
+	return 1;
+}
+
+int dm_task_set_mode(struct dm_task *dmt, mode_t mode)
+{
+	dmt->mode = mode;
+
+	return 1;
+}
+
 int dm_task_add_target(struct dm_task *dmt, uint64_t start, uint64_t size,
 		       const char *ttype, const char *params)
 {

Modified: devmapper/upstream/current/lib/libdm-deptree.c
==============================================================================
--- devmapper/upstream/current/lib/libdm-deptree.c	(original)
+++ devmapper/upstream/current/lib/libdm-deptree.c	Sun Feb 12 10:06:32 2006
@@ -85,6 +85,8 @@
 	uint32_t region_size;		/* Mirror */
 	unsigned clustered;		/* Mirror */
 	unsigned mirror_area_count;	/* Mirror */
+	uint32_t flags;			/* Mirror log */
+	char *uuid;			/* Clustered mirror log */
 };
 
 /* Per-device properties */
@@ -127,6 +129,7 @@
 	struct dm_hash_table *devs;
 	struct dm_hash_table *uuids;
 	struct dm_tree_node root;
+	int skip_lockfs;		/* 1 skips lockfs (for non-snapshots) */
 };
 
 /* FIXME Consider exporting this */
@@ -139,7 +142,7 @@
         n = vsnprintf(buf, bufsize, format, ap);
         va_end(ap);
 
-        if (n < 0 || (n > bufsize - 1))
+        if (n < 0 || (n > (int) bufsize - 1))
                 return -1;
 
         return n;
@@ -158,6 +161,7 @@
 	dtree->root.dtree = dtree;
 	list_init(&dtree->root.uses);
 	list_init(&dtree->root.used_by);
+	dtree->skip_lockfs = 0;
 
 	if (!(dtree->mem = dm_pool_create("dtree", 1024))) {
 		log_error("dtree pool creation failed");
@@ -899,12 +903,13 @@
 }
 
 static int _suspend_node(const char *name, uint32_t major, uint32_t minor,
-			 struct dm_info *newinfo)
+			 int skip_lockfs, struct dm_info *newinfo)
 {
 	struct dm_task *dmt;
 	int r;
 
-	log_verbose("Suspending %s (%" PRIu32 ":%" PRIu32 ")", name, major, minor);
+	log_verbose("Suspending %s (%" PRIu32 ":%" PRIu32 ")%s", name, major,
+		    minor, skip_lockfs ? "" : " with filesystem sync.");
 
 	if (!(dmt = dm_task_create(DM_DEVICE_SUSPEND))) {
 		log_error("Suspend dm_task creation failed for %s", name);
@@ -920,6 +925,9 @@
 	if (!dm_task_no_open_count(dmt))
 		log_error("Failed to disable open_count");
 
+	if (skip_lockfs && !dm_task_skip_lockfs(dmt))
+		log_error("Failed to set skip_lockfs flag.");
+
 	if ((r = dm_task_run(dmt)))
 		r = dm_task_get_info(dmt, newinfo);
 
@@ -978,6 +986,11 @@
 	return 1;
 }
 
+void dm_tree_skip_lockfs(struct dm_tree_node *dnode)
+{
+	dnode->dtree->skip_lockfs = 1;
+}
+
 int dm_tree_suspend_children(struct dm_tree_node *dnode,
 				   const char *uuid_prefix,
 				   size_t uuid_prefix_len)
@@ -1018,7 +1031,8 @@
 		    !info.exists)
 			continue;
 
-		if (!_suspend_node(name, info.major, info.minor, &newinfo)) {
+		if (!_suspend_node(name, info.major, info.minor,
+				   child->dtree->skip_lockfs, &newinfo)) {
 			log_error("Unable to suspend %s (%" PRIu32
 				  ":%" PRIu32 ")", name, info.major,
 				  info.minor);
@@ -1211,10 +1225,12 @@
 
 static int _emit_segment_line(struct dm_task *dmt, struct load_segment *seg, uint64_t *seg_start, char *params, size_t paramsize)
 {
+	unsigned log_parm_count;
         int pos = 0;
 	int tw;
         int r;
 	char originbuf[10], cowbuf[10], logbuf[10];
+	const char *logtype;
 
 	switch(seg->type) {
 	case SEG_ERROR:
@@ -1223,33 +1239,84 @@
 	case SEG_LINEAR:
 		break;
 	case SEG_MIRRORED:
+		log_parm_count = 1;	/* Region size */
+		log_parm_count += hweight32(seg->flags);	/* [no]sync, block_on_error etc. */
+
 		if (seg->clustered) {
-			if ((tw = _dm_snprintf(params + pos, paramsize - pos, "clustered ")) < 0) {
+			if (seg->uuid)
+				log_parm_count++;	/* uuid */
+			if ((tw = _dm_snprintf(params + pos, paramsize - pos, "clustered_")) < 0) {
                         	stack;	/* Out of space */
                         	return -1;
                 	}
 			pos += tw;
 		}
-		if (!seg->log) {
-			if ((tw = _dm_snprintf(params + pos, paramsize - pos, "core 1 ")) < 0) {
-                        	stack;	/* Out of space */
-                        	return -1;
-                	}
-			pos += tw;
-		} else {
+
+		if (!seg->log)
+			logtype = "core";
+		else {
+			logtype = "disk";
+			log_parm_count++;
 			if (!_build_dev_string(logbuf, sizeof(logbuf), seg->log))
 				return_0;
-			if ((tw = _dm_snprintf(params + pos, paramsize - pos, "disk 2 %s ", logbuf)) < 0) {
+		}
+
+		if ((tw = _dm_snprintf(params + pos, paramsize - pos, "%s %u ", logtype, log_parm_count)) < 0) {
+                        stack;	/* Out of space */
+                        return -1;
+                }
+		pos += tw;
+
+		if (seg->log) {
+			if ((tw = _dm_snprintf(params + pos, paramsize - pos, "%s ", logbuf)) < 0) {
                         	stack;	/* Out of space */
                         	return -1;
                 	}
 			pos += tw;
 		}
-		if ((tw = _dm_snprintf(params + pos, paramsize - pos, "%u %u ", seg->region_size, seg->mirror_area_count)) < 0) {
+
+		if ((tw = _dm_snprintf(params + pos, paramsize - pos, "%u ", seg->region_size)) < 0) {
                        	stack; /* Out of space */
                        	return -1;
                	}
 		pos += tw;
+
+		if (seg->clustered && seg->uuid) {
+			if ((tw = _dm_snprintf(params + pos, paramsize - pos, "%s ", seg->uuid)) < 0) {
+				stack;  /* Out of space */
+				return -1;
+			}
+			pos += tw;
+		}
+
+		if ((seg->flags & DM_NOSYNC)) {
+			if ((tw = _dm_snprintf(params + pos, paramsize - pos, "nosync ")) < 0) {
+                       		stack; /* Out of space */
+                       		return -1;
+               		}
+			pos += tw;
+		} else if ((seg->flags & DM_FORCESYNC)) {
+			if ((tw = _dm_snprintf(params + pos, paramsize - pos, "sync ")) < 0) {
+                       		stack; /* Out of space */
+                       		return -1;
+               		}
+			pos += tw;
+		}
+
+		if ((seg->flags & DM_BLOCK_ON_ERROR)) {
+			if ((tw = _dm_snprintf(params + pos, paramsize - pos, "block_on_error ")) < 0) {
+                       		stack; /* Out of space */
+                       		return -1;
+               		}
+			pos += tw;
+		}
+
+		if ((tw = _dm_snprintf(params + pos, paramsize - pos, "%u ", seg->mirror_area_count)) < 0) {
+                       	stack; /* Out of space */
+                       	return -1;
+               	}
+		pos += tw;
+
 		break;
 	case SEG_SNAPSHOT:
 		if (!_build_dev_string(originbuf, sizeof(originbuf), seg->origin))
@@ -1620,7 +1687,8 @@
 					  uint32_t region_size,
 					  unsigned clustered, 
 					  const char *log_uuid,
-					  unsigned area_count)
+					  unsigned area_count,
+					  uint32_t flags)
 {
 	struct dm_tree_node *log_node = NULL;
 	struct load_segment *seg;
@@ -1637,14 +1705,21 @@
 			log_error("Couldn't find mirror log uuid %s.", log_uuid);
 			return 0;
 		}
+
 		if (!_link_tree_nodes(node, log_node))
 			return_0;
+
+		if (!(seg->uuid = dm_pool_strdup(node->dtree->mem, log_uuid))) {
+			log_error("log uuid pool_strdup failed");
+			return 0;
+		}
 	}
 
 	seg->log = log_node;
 	seg->region_size = region_size;
 	seg->clustered = clustered;
 	seg->mirror_area_count = area_count;
+	seg->flags = flags;
 
 	return 1;
 }

Modified: devmapper/upstream/current/lib/libdm-file.c
==============================================================================
--- devmapper/upstream/current/lib/libdm-file.c	(original)
+++ devmapper/upstream/current/lib/libdm-file.c	Sun Feb 12 10:06:32 2006
@@ -20,10 +20,6 @@
 #include <fcntl.h>
 #include <dirent.h>
 
-#ifdef linux
-#  include <malloc.h>
-#endif
-
 static int _create_dir_recursive(const char *dir)
 {
 	char *orig, *s;
@@ -31,7 +27,7 @@
 
 	log_verbose("Creating directory \"%s\"", dir);
 	/* Create parent directories */
-	orig = s = strdup(dir);
+	orig = s = dm_strdup(dir);
 	while ((s = strchr(s, '/')) != NULL) {
 		*s = '\0';
 		if (*orig) {
@@ -39,13 +35,13 @@
 			if (rc < 0 && errno != EEXIST) {
 				log_error("%s: mkdir failed: %s", orig,
 					  strerror(errno));
-				free(orig);
+				dm_free(orig);
 				return 0;
 			}
 		}
 		*s++ = '/';
 	}
-	free(orig);
+	dm_free(orig);
 
 	/* Create final directory */
 	rc = mkdir(dir, 0777);

Modified: devmapper/upstream/current/lib/mm/dbg_malloc.c
==============================================================================
--- devmapper/upstream/current/lib/mm/dbg_malloc.c	(original)
+++ devmapper/upstream/current/lib/mm/dbg_malloc.c	Sun Feb 12 10:06:32 2006
@@ -18,7 +18,7 @@
 #include <assert.h>
 #include <stdarg.h>
 
-char *dm_strdup(const char *str)
+char *dm_strdup_aux(const char *str)
 {
 	char *ret = dm_malloc(strlen(str) + 1);
 
@@ -198,9 +198,9 @@
 		}
 		str[sizeof(str) - 1] = '\0';
 
-		_log(_LOG_INFO, mb->file, mb->line,
-		     "block %d at %p, size %" PRIsize_t "\t [%s]",
-		     mb->id, mb->magic, mb->length, str);
+		dm_log(_LOG_INFO, mb->file, mb->line,
+		       "block %d at %p, size %" PRIsize_t "\t [%s]",
+		       mb->id, mb->magic, mb->length, str);
 		tot += mb->length;
 	}
 

Modified: devmapper/upstream/current/lib/mm/pool-fast.c
==============================================================================
--- devmapper/upstream/current/lib/mm/pool-fast.c	(original)
+++ devmapper/upstream/current/lib/mm/pool-fast.c	Sun Feb 12 10:06:32 2006
@@ -85,7 +85,7 @@
 	/* have we got room ? */
 	if (!c || (c->begin > c->end) || (c->end - c->begin < s)) {
 		/* allocate new chunk */
-		int needed = s + alignment + sizeof(struct chunk);
+		size_t needed = s + alignment + sizeof(struct chunk);
 		c = _new_chunk(p, (needed > p->chunk_size) ?
 			       needed : p->chunk_size);
 

Modified: devmapper/upstream/current/make.tmpl.in
==============================================================================
--- devmapper/upstream/current/make.tmpl.in	(original)
+++ devmapper/upstream/current/make.tmpl.in	Sun Feb 12 10:06:32 2006
@@ -73,6 +73,7 @@
 endif
 
 LDFLAGS += -L$(interfacedir)
+CLDFLAGS += -L$(interfacedir)
 
 ifeq ("@COMPAT@", "yes")
   CFLAGS += -DDM_COMPAT

Modified: devmapper/upstream/current/po/Makefile.in
==============================================================================
--- devmapper/upstream/current/po/Makefile.in	(original)
+++ devmapper/upstream/current/po/Makefile.in	Sun Feb 12 10:06:32 2006
@@ -37,7 +37,7 @@
 
 device-mapper.po: Makefile $(POSOURCES)
 	@echo Compiling string table
-	@xgettext -C -F --keyword=_log --keyword=log_debug \
+	@xgettext -C -F --keyword=dm_log --keyword=log_debug \
 		--keyword=log_info --keyword=_ --keyword=N_ \
 		--keyword=log_notice --keyword=log_warn --keyword=log_err \
 		--keyword=log_fatal --keyword=log_debug --keyword=log_error \

Modified: devmapper/upstream/current/po/pogen.h
==============================================================================
--- devmapper/upstream/current/po/pogen.h	(original)
+++ devmapper/upstream/current/po/pogen.h	Sun Feb 12 10:06:32 2006
@@ -20,5 +20,5 @@
  * different architectures.
  */
 
-#define _log(level, file, line, format, args...) _log(format, args)
+#define dm_log(level, file, line, format, args...) dm_log(format, args)
 



More information about the pkg-lvm-commits mailing list