public inbox for lvm2-cvs@sourceware.org
help / color / mirror / Atom feed
* LVM2 ./WHATS_NEW libdm/.exported_symbols libdm ...
@ 2010-05-21 12:24 zkabelac
  0 siblings, 0 replies; 5+ messages in thread
From: zkabelac @ 2010-05-21 12:24 UTC (permalink / raw)
  To: lvm-devel, lvm2-cvs

CVSROOT:	/cvs/lvm2
Module name:	LVM2
Changes by:	zkabelac@sourceware.org	2010-05-21 12:24:15

Modified files:
	.              : WHATS_NEW 
	libdm          : .exported_symbols libdevmapper.h 
	                 libdm-deptree.c 

Log message:
	Replicator: libdm support
	
	Introducing new API calls:
	dm_tree_node_add_replicator_target()
	dm_tree_node_add_replicator_dev_target().
	
	Define new typedef dm_replicator_mode_t.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1576&r2=1.1577
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/libdm/.exported_symbols.diff?cvsroot=lvm2&r1=1.52&r2=1.53
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/libdm/libdevmapper.h.diff?cvsroot=lvm2&r1=1.113&r2=1.114
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/libdm/libdm-deptree.c.diff?cvsroot=lvm2&r1=1.75&r2=1.76

--- LVM2/WHATS_NEW	2010/05/21 12:21:51	1.1576
+++ LVM2/WHATS_NEW	2010/05/21 12:24:15	1.1577
@@ -1,5 +1,6 @@
 Version 2.02.67 -
 ===============================
+  Initial libdm support for Replicator target (API is not stable yet).
   Extend process_each_lv_in_vg() with support for list of failed lvnames.
   Return ECMD_FAILED for break in process_each_lv() and process_each_segment_in_lv().
 
--- LVM2/libdm/.exported_symbols	2010/05/06 10:10:16	1.52
+++ LVM2/libdm/.exported_symbols	2010/05/21 12:24:15	1.53
@@ -80,6 +80,8 @@
 dm_tree_node_add_mirror_target
 dm_tree_node_add_mirror_target_log
 dm_tree_node_add_target_area
+dm_tree_node_add_replicator_target
+dm_tree_node_add_replicator_dev_target
 dm_tree_node_set_read_ahead
 dm_tree_skip_lockfs
 dm_tree_use_no_flush_suspend
--- LVM2/libdm/libdevmapper.h	2010/05/06 10:10:16	1.113
+++ LVM2/libdm/libdevmapper.h	2010/05/21 12:24:15	1.114
@@ -439,6 +439,41 @@
 					  const char *log_uuid,
 					  unsigned area_count,
 					  uint32_t flags);
+
+/*
+ * Replicator operation mode
+ * Note: API for Replicator is not yet stable
+ */
+typedef enum {
+	DM_REPLICATOR_SYNC,			/* Synchronous replication */
+	DM_REPLICATOR_ASYNC_WARN,		/* Warn if async replicator is slow */
+	DM_REPLICATOR_ASYNC_STALL,		/* Stall replicator if not fast enough */
+	DM_REPLICATOR_ASYNC_DROP,		/* Drop sites out of sync */
+	DM_REPLICATOR_ASYNC_FAIL,		/* Fail replicator if slow */
+	NUM_DM_REPLICATOR_MODES
+} dm_replicator_mode_t;
+
+int dm_tree_node_add_replicator_target(struct dm_tree_node *node,
+				       uint64_t size,
+				       const char *rlog_uuid,
+				       const char *rlog_type,
+				       unsigned rsite_index,
+				       dm_replicator_mode_t mode,
+				       uint32_t async_timeout,
+				       uint64_t fall_behind_data,
+				       uint32_t fall_behind_ios);
+
+int dm_tree_node_add_replicator_dev_target(struct dm_tree_node *node,
+					   uint64_t size,
+					   const char *replicator_uuid,	/* Replicator control device */
+					   uint64_t rdevice_index,
+					   const char *rdev_uuid,	/* Rimage device name/uuid */
+					   unsigned rsite_index,
+					   const char *slog_uuid,
+					   uint32_t slog_flags,		/* Mirror log flags */
+					   uint32_t slog_region_size);
+/* End of Replicator API */
+
 int dm_tree_node_add_target_area(struct dm_tree_node *node,
 				    const char *dev_name,
 				    const char *dlid,
--- LVM2/libdm/libdm-deptree.c	2010/04/07 23:51:34	1.75
+++ LVM2/libdm/libdm-deptree.c	2010/05/21 12:24:15	1.76
@@ -27,12 +27,16 @@
 /* FIXME Fix interface so this is used only by LVM */
 #define UUID_PREFIX "LVM-"
 
+#define REPLICATOR_LOCAL_SITE 0
+
 /* Supported segment types */
 enum {
 	SEG_CRYPT,
 	SEG_ERROR,
 	SEG_LINEAR,
 	SEG_MIRRORED,
+	SEG_REPLICATOR,
+	SEG_REPLICATOR_DEV,
 	SEG_SNAPSHOT,
 	SEG_SNAPSHOT_ORIGIN,
 	SEG_SNAPSHOT_MERGE,
@@ -50,6 +54,8 @@
 	{ SEG_ERROR, "error" },
 	{ SEG_LINEAR, "linear" },
 	{ SEG_MIRRORED, "mirror" },
+	{ SEG_REPLICATOR, "replicator" },
+	{ SEG_REPLICATOR_DEV, "replicator-dev" },
 	{ SEG_SNAPSHOT, "snapshot" },
 	{ SEG_SNAPSHOT_ORIGIN, "snapshot-origin" },
 	{ SEG_SNAPSHOT_MERGE, "snapshot-merge" },
@@ -64,6 +70,23 @@
 	struct dm_tree_node *dev_node;
 
 	uint64_t offset;
+
+	unsigned rsite_index;		/* Replicator site index */
+	struct dm_tree_node *slog;	/* Replicator sync log node */
+	uint64_t region_size;		/* Replicator sync log size */
+	uint32_t flags;			/* Replicator sync log flags */
+};
+
+/* Replicator-log has a list of sites */
+/* FIXME: maybe move to seg_area too? */
+struct replicator_site {
+	struct dm_list list;
+
+	unsigned rsite_index;
+	dm_replicator_mode_t mode;
+	uint32_t async_timeout;
+	uint32_t fall_behind_ios;
+	uint64_t fall_behind_data;
 };
 
 /* Per-segment properties */
@@ -74,8 +97,8 @@
 
 	uint64_t size;
 
-	unsigned area_count;		/* Linear + Striped + Mirrored + Crypt */
-	struct dm_list areas;		/* Linear + Striped + Mirrored + Crypt */
+	unsigned area_count;		/* Linear + Striped + Mirrored + Crypt + Replicator */
+	struct dm_list areas;		/* Linear + Striped + Mirrored + Crypt + Replicator */
 
 	uint32_t stripe_size;		/* Striped */
 
@@ -85,7 +108,7 @@
 	struct dm_tree_node *origin;	/* Snapshot + Snapshot origin */
 	struct dm_tree_node *merge;	/* Snapshot */
 
-	struct dm_tree_node *log;	/* Mirror */
+	struct dm_tree_node *log;	/* Mirror + Replicator */
 	uint32_t region_size;		/* Mirror */
 	unsigned clustered;		/* Mirror */
 	unsigned mirror_area_count;	/* Mirror */
@@ -97,6 +120,13 @@
 	const char *iv;			/* Crypt */
 	uint64_t iv_offset;		/* Crypt */
 	const char *key;		/* Crypt */
+
+	const char *rlog_type;		/* Replicator */
+	struct dm_list rsites;		/* Replicator */
+	unsigned rsite_count;		/* Replicator */
+	unsigned rdevice_count;		/* Replicator */
+	struct dm_tree_node *replicator;/* Replicator-dev */
+	uint64_t rdevice_index;		/* Replicator-dev */
 };
 
 /* Per-device properties */
@@ -1342,13 +1372,51 @@
 	struct seg_area *area;
 	char devbuf[DM_FORMAT_DEV_BUFSIZE];
 	unsigned first_time = 1;
+	const char *logtype;
+	unsigned log_parm_count;
 
 	dm_list_iterate_items(area, &seg->areas) {
 		if (!_build_dev_string(devbuf, sizeof(devbuf), area->dev_node))
 			return_0;
 
-		EMIT_PARAMS(*pos, "%s%s %" PRIu64, first_time ? "" : " ",
-			    devbuf, area->offset);
+		switch (seg->type) {
+		case SEG_REPLICATOR_DEV:
+			EMIT_PARAMS(*pos, " %d 1 %s", area->rsite_index, devbuf);
+			if (first_time)
+				EMIT_PARAMS(*pos, " nolog 0");
+			else {
+				/* Remote devices */
+				log_parm_count = (area->flags &
+						  (DM_NOSYNC | DM_FORCESYNC)) ? 2 : 1;
+
+				if (!area->slog) {
+					devbuf[0] = 0;		/* Only core log parameters */
+					logtype = "core";
+				} else {
+					devbuf[0] = ' ';	/* Extra space before device name */
+					if (!_build_dev_string(devbuf + 1,
+							       sizeof(devbuf) - 1,
+							       area->slog))
+						return_0;
+					logtype = "disk";
+					log_parm_count++;	/* Extra sync log device name parameter */
+				}
+
+				EMIT_PARAMS(*pos, " %s %u%s %" PRIu64, logtype,
+					    log_parm_count, devbuf, area->region_size);
+
+				logtype = (area->flags & DM_NOSYNC) ?
+					" nosync" : (area->flags & DM_FORCESYNC) ?
+					" sync" : NULL;
+
+				if (logtype)
+					EMIT_PARAMS(*pos, logtype);
+			}
+			break;
+		default:
+			EMIT_PARAMS(*pos, "%s%s %" PRIu64, first_time ? "" : " ",
+				    devbuf, area->offset);
+		}
 
 		first_time = 0;
 	}
@@ -1356,6 +1424,42 @@
 	return 1;
 }
 
+static int _replicator_emit_segment_line(const struct load_segment *seg, char *params,
+					 size_t paramsize, int *pos)
+{
+	const struct load_segment *rlog_seg;
+	struct replicator_site *rsite;
+	char rlogbuf[DM_FORMAT_DEV_BUFSIZE];
+	unsigned parm_count;
+
+	if (!seg->log || !_build_dev_string(rlogbuf, sizeof(rlogbuf), seg->log))
+		return_0;
+
+	rlog_seg = dm_list_item(dm_list_last(&seg->log->props.segs),
+				struct load_segment);
+
+	EMIT_PARAMS(*pos, "%s 4 %s 0 auto %" PRIu64,
+		    seg->rlog_type, rlogbuf, rlog_seg->size);
+
+	dm_list_iterate_items(rsite, &seg->rsites) {
+		parm_count = (rsite->fall_behind_data
+			      || rsite->fall_behind_ios
+			      || rsite->async_timeout) ? 4 : 2;
+
+		EMIT_PARAMS(*pos, " blockdev %u %u %s", parm_count, rsite->rsite_index,
+			    (rsite->mode == DM_REPLICATOR_SYNC) ? "synchronous" : "asynchronous");
+
+		if (rsite->fall_behind_data)
+			EMIT_PARAMS(*pos, " data %" PRIu64, rsite->fall_behind_data);
+		else if (rsite->fall_behind_ios)
+			EMIT_PARAMS(*pos, " ios %" PRIu32, rsite->fall_behind_ios);
+		else if (rsite->async_timeout)
+			EMIT_PARAMS(*pos, " timeout %" PRIu32, rsite->async_timeout);
+	}
+
+	return 1;
+}
+
 /*
  * Returns: 1 on success, 0 on failure
  */
@@ -1499,6 +1603,21 @@
 		if (!r)
 			return_0;
 		break;
+	case SEG_REPLICATOR:
+		if ((r = _replicator_emit_segment_line(seg, params, paramsize,
+						       &pos)) <= 0) {
+			stack;
+			return r;
+		}
+		break;
+	case SEG_REPLICATOR_DEV:
+		if (!seg->replicator || !_build_dev_string(originbuf,
+							   sizeof(originbuf),
+							   seg->replicator))
+			return_0;
+
+		EMIT_PARAMS(pos, "%s %" PRIu64, originbuf, seg->rdevice_index);
+		break;
 	case SEG_SNAPSHOT:
 	case SEG_SNAPSHOT_MERGE:
 		if (!_build_dev_string(originbuf, sizeof(originbuf), seg->origin))
@@ -1527,6 +1646,7 @@
 
 	switch(seg->type) {
 	case SEG_ERROR:
+	case SEG_REPLICATOR:
 	case SEG_SNAPSHOT:
 	case SEG_SNAPSHOT_ORIGIN:
 	case SEG_SNAPSHOT_MERGE:
@@ -1534,6 +1654,7 @@
 		break;
 	case SEG_CRYPT:
 	case SEG_LINEAR:
+	case SEG_REPLICATOR_DEV:
 	case SEG_STRIPED:
 		if ((r = _emit_areas_line(dmt, seg, params, paramsize, &pos)) <= 0) {
 			stack;
@@ -1996,6 +2117,171 @@
 	return 1;
 }
 
+int dm_tree_node_add_replicator_target(struct dm_tree_node *node,
+				       uint64_t size,
+				       const char *rlog_uuid,
+				       const char *rlog_type,
+				       unsigned rsite_index,
+				       dm_replicator_mode_t mode,
+				       uint32_t async_timeout,
+				       uint64_t fall_behind_data,
+				       uint32_t fall_behind_ios)
+{
+	struct load_segment *rseg;
+	struct replicator_site *rsite;
+
+	/* Local site0 - adds replicator segment and links rlog device */
+	if (rsite_index == REPLICATOR_LOCAL_SITE) {
+		if (node->props.segment_count) {
+			log_error(INTERNAL_ERROR "Attempt to add replicator segment to already used node.");
+			return 0;
+		}
+
+		if (!(rseg = _add_segment(node, SEG_REPLICATOR, size)))
+			return_0;
+
+		if (!(rseg->log = dm_tree_find_node_by_uuid(node->dtree, rlog_uuid))) {
+			log_error("Missing replicator log uuid %s.", rlog_uuid);
+			return 0;
+		}
+
+		if (!_link_tree_nodes(node, rseg->log))
+			return_0;
+
+		if (strcmp(rlog_type, "ringbuffer") != 0) {
+			log_error("Unsupported replicator log type %s.", rlog_type);
+			return 0;
+		}
+
+		if (!(rseg->rlog_type = dm_pool_strdup(node->dtree->mem, rlog_type)))
+			return_0;
+
+		dm_list_init(&rseg->rsites);
+		rseg->rdevice_count = 0;
+		node->activation_priority = 1;
+	}
+
+	/* Add site to segment */
+	if (mode == DM_REPLICATOR_SYNC
+	    && (async_timeout || fall_behind_ios || fall_behind_data)) {
+		log_error("Async parameters passed for synchronnous replicator.");
+		return 0;
+	}
+
+	if (node->props.segment_count != 1) {
+		log_error(INTERNAL_ERROR "Attempt to add remote site area before setting replicator log.");
+		return 0;
+	}
+
+	rseg = dm_list_item(dm_list_last(&node->props.segs), struct load_segment);
+	if (rseg->type != SEG_REPLICATOR) {
+		log_error(INTERNAL_ERROR "Attempt to use non replicator segment %s.",
+			  dm_segtypes[rseg->type].target);
+		return 0;
+	}
+
+	if (!(rsite = dm_pool_zalloc(node->dtree->mem, sizeof(*rsite)))) {
+		log_error("Failed to allocate remote site segment.");
+		return 0;
+	}
+
+	dm_list_add(&rseg->rsites, &rsite->list);
+	rseg->rsite_count++;
+
+	rsite->mode = mode;
+	rsite->async_timeout = async_timeout;
+	rsite->fall_behind_data = fall_behind_data;
+	rsite->fall_behind_ios = fall_behind_ios;
+	rsite->rsite_index = rsite_index;
+
+	return 1;
+}
+
+/* Appends device node to Replicator */
+int dm_tree_node_add_replicator_dev_target(struct dm_tree_node *node,
+					   uint64_t size,
+					   const char *replicator_uuid,
+					   uint64_t rdevice_index,
+					   const char *rdev_uuid,
+					   unsigned rsite_index,
+					   const char *slog_uuid,
+					   uint32_t slog_flags,
+					   uint32_t slog_region_size)
+{
+	struct seg_area *area;
+	struct load_segment *rseg;
+	struct load_segment *rep_seg;
+
+	if (rsite_index == REPLICATOR_LOCAL_SITE) {
+		/* Site index for local target */
+		if (!(rseg = _add_segment(node, SEG_REPLICATOR_DEV, size)))
+			return_0;
+
+		if (!(rseg->replicator = dm_tree_find_node_by_uuid(node->dtree, replicator_uuid))) {
+			log_error("Missing replicator uuid %s.", replicator_uuid);
+			return 0;
+		}
+
+		/* Local slink0 for replicator must be always initialized first */
+		if (rseg->replicator->props.segment_count != 1) {
+			log_error(INTERNAL_ERROR "Attempt to use non replicator segment.");
+			return 0;
+		}
+
+		rep_seg = dm_list_item(dm_list_last(&rseg->replicator->props.segs), struct load_segment);
+		if (rep_seg->type != SEG_REPLICATOR) {
+			log_error(INTERNAL_ERROR "Attempt to use non replicator segment %s.",
+				  dm_segtypes[rep_seg->type].target);
+			return 0;
+		}
+		rep_seg->rdevice_count++;
+
+		if (!_link_tree_nodes(node, rseg->replicator))
+			return_0;
+
+		rseg->rdevice_index = rdevice_index;
+	} else {
+		/* Local slink0 for replicator must be always initialized first */
+		if (node->props.segment_count != 1) {
+			log_error(INTERNAL_ERROR "Attempt to use non replicator-dev segment.");
+			return 0;
+		}
+
+		rseg = dm_list_item(dm_list_last(&node->props.segs), struct load_segment);
+		if (rseg->type != SEG_REPLICATOR_DEV) {
+			log_error(INTERNAL_ERROR "Attempt to use non replicator-dev segment %s.",
+				  dm_segtypes[rseg->type].target);
+			return 0;
+		}
+	}
+
+	if (!(slog_flags & DM_CORELOG) && !slog_uuid) {
+		log_error("Unspecified sync log uuid.");
+		return 0;
+	}
+
+	if (!dm_tree_node_add_target_area(node, NULL, rdev_uuid, 0))
+		return_0;
+
+	area = dm_list_item(dm_list_last(&rseg->areas), struct seg_area);
+
+	if (!(slog_flags & DM_CORELOG)) {
+		if (!(area->slog = dm_tree_find_node_by_uuid(node->dtree, slog_uuid))) {
+			log_error("Couldn't find sync log uuid %s.", slog_uuid);
+			return 0;
+		}
+
+		if (!_link_tree_nodes(node, area->slog))
+			return_0;
+	}
+
+	area->flags = slog_flags;
+	area->region_size = slog_region_size;
+	area->rsite_index = rsite_index;
+
+	return 1;
+}
+
 static int _add_area(struct dm_tree_node *node, struct load_segment *seg, struct dm_tree_node *dev_node, uint64_t offset)
 {
 	struct seg_area *area;


^ permalink raw reply	[flat|nested] 5+ messages in thread

* LVM2 ./WHATS_NEW libdm/.exported_symbols libdm ...
@ 2010-05-21 12:27 zkabelac
  0 siblings, 0 replies; 5+ messages in thread
From: zkabelac @ 2010-05-21 12:27 UTC (permalink / raw)
  To: lvm-devel, lvm2-cvs

CVSROOT:	/cvs/lvm2
Module name:	LVM2
Changes by:	zkabelac@sourceware.org	2010-05-21 12:27:03

Modified files:
	.              : WHATS_NEW 
	libdm          : .exported_symbols libdevmapper.h 
	                 libdm-deptree.c 

Log message:
	Replicator: support deactivate of replicator-dev nodes
	
	Introducing dm_tree_node_set_presuspend_node() for presuspending child
	node (i.e. replicator control target) before deactivation of parent node
	(i.e. replicator-dev target).
	
	This patch presents no functional change to current dtree - only
	replicator target currently sets presuspend node for dev nodes.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1577&r2=1.1578
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/libdm/.exported_symbols.diff?cvsroot=lvm2&r1=1.53&r2=1.54
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/libdm/libdevmapper.h.diff?cvsroot=lvm2&r1=1.114&r2=1.115
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/libdm/libdm-deptree.c.diff?cvsroot=lvm2&r1=1.76&r2=1.77

--- LVM2/WHATS_NEW	2010/05/21 12:24:15	1.1577
+++ LVM2/WHATS_NEW	2010/05/21 12:27:02	1.1578
@@ -1,5 +1,6 @@
 Version 2.02.67 -
 ===============================
+  Added dm_tree_node_set_presuspend_node() to presuspend child in deactivate.
   Initial libdm support for Replicator target (API is not stable yet).
   Extend process_each_lv_in_vg() with support for list of failed lvnames.
   Return ECMD_FAILED for break in process_each_lv() and process_each_segment_in_lv().
--- LVM2/libdm/.exported_symbols	2010/05/21 12:24:15	1.53
+++ LVM2/libdm/.exported_symbols	2010/05/21 12:27:03	1.54
@@ -82,6 +82,7 @@
 dm_tree_node_add_target_area
 dm_tree_node_add_replicator_target
 dm_tree_node_add_replicator_dev_target
+dm_tree_node_set_presuspend_node
 dm_tree_node_set_read_ahead
 dm_tree_skip_lockfs
 dm_tree_use_no_flush_suspend
--- LVM2/libdm/libdevmapper.h	2010/05/21 12:24:15	1.114
+++ LVM2/libdm/libdevmapper.h	2010/05/21 12:27:03	1.115
@@ -474,6 +474,9 @@
 					   uint32_t slog_region_size);
 /* End of Replicator API */
 
+void dm_tree_node_set_presuspend_node(struct dm_tree_node *node,
+				      struct dm_tree_node *presuspend_node);
+
 int dm_tree_node_add_target_area(struct dm_tree_node *node,
 				    const char *dev_name,
 				    const char *dlid,
--- LVM2/libdm/libdm-deptree.c	2010/05/21 12:24:15	1.76
+++ LVM2/libdm/libdm-deptree.c	2010/05/21 12:27:03	1.77
@@ -168,6 +168,12 @@
 	void *context;			/* External supplied context */
 
 	struct load_properties props;	/* For creation/table (re)load */
+
+	/*
+	 * If presuspend of child node is needed
+	 * Note: only direct child is allowed
+	 */
+	struct dm_tree_node *presuspend_node;
 };
 
 struct dm_tree {
@@ -684,6 +690,12 @@
 	dnode->props.read_ahead_flags = read_ahead_flags;
 }
 
+void dm_tree_node_set_presuspend_node(struct dm_tree_node *node,
+				      struct dm_tree_node *presuspend_node)
+{
+	node->presuspend_node = presuspend_node;
+}
+
 int dm_tree_add_dev(struct dm_tree *dtree, uint32_t major, uint32_t minor)
 {
 	return _add_dev(dtree, &dtree->root, major, minor, 0) ? 1 : 0;
@@ -794,6 +806,10 @@
 		if (!_uuid_prefix_matches(uuid, uuid_prefix, uuid_prefix_len))
 			continue;
 
+		/* Ignore if parent node wants to presuspend this node */
+		if (dlink->node->presuspend_node == node)
+			continue;
+
 		if (!(dinfo = dm_tree_node_get_info(dlink->node))) {
 			stack;	/* FIXME Is this normal? */
 			return 0;
@@ -1095,6 +1111,11 @@
 			continue;
 		}
 
+		/* Suspend child node first if requested */
+		if (child->presuspend_node &&
+		    !dm_tree_suspend_children(child, uuid_prefix, uuid_prefix_len))
+			continue;
+
 		if (!_deactivate_node(name, info.major, info.minor,
 				      &child->dtree->cookie, child->udev_flags)) {
 			log_error("Unable to deactivate %s (%" PRIu32


^ permalink raw reply	[flat|nested] 5+ messages in thread

* LVM2 ./WHATS_NEW libdm/.exported_symbols libdm ...
@ 2010-05-06 10:10 zkabelac
  0 siblings, 0 replies; 5+ messages in thread
From: zkabelac @ 2010-05-06 10:10 UTC (permalink / raw)
  To: lvm-devel, lvm2-cvs

CVSROOT:	/cvs/lvm2
Module name:	LVM2
Changes by:	zkabelac@sourceware.org	2010-05-06 10:10:16

Modified files:
	.              : WHATS_NEW 
	libdm          : .exported_symbols libdevmapper.h 
	libdm/datastruct: list.c 

Log message:
	Add dm_list_splice() to join two lists.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1547&r2=1.1548
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/libdm/.exported_symbols.diff?cvsroot=lvm2&r1=1.51&r2=1.52
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/libdm/libdevmapper.h.diff?cvsroot=lvm2&r1=1.112&r2=1.113
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/libdm/datastruct/list.c.diff?cvsroot=lvm2&r1=1.6&r2=1.7

--- LVM2/WHATS_NEW	2010/05/05 22:38:31	1.1547
+++ LVM2/WHATS_NEW	2010/05/06 10:10:15	1.1548
@@ -1,6 +1,8 @@
 Version 2.02.65 - 
 =================================
   Suppress duplicate error messages about read failures and missing devices.
+  Install plugins to $(libdir)/device-mapper and $(libdir)/lvm2.
+  Add dm_list_splice() function to join two lists together.
 
 Version 2.02.64 - 30th April 2010
 =================================
--- LVM2/libdm/.exported_symbols	2010/04/20 13:58:22	1.51
+++ LVM2/libdm/.exported_symbols	2010/05/06 10:10:16	1.52
@@ -155,6 +155,7 @@
 dm_list_add_h
 dm_list_del
 dm_list_move
+dm_list_splice
 dm_list_empty
 dm_list_start
 dm_list_end
--- LVM2/libdm/libdevmapper.h	2010/04/28 13:37:36	1.112
+++ LVM2/libdm/libdevmapper.h	2010/05/06 10:10:16	1.113
@@ -718,6 +718,11 @@
 void dm_list_move(struct dm_list *head, struct dm_list *elem);
 
 /*
+ * Join 'head1' to the of 'head'.
+ */
+void dm_list_splice(struct dm_list *head, struct dm_list *head1);
+
+/*
  * Is the list empty?
  */
 int dm_list_empty(const struct dm_list *head);
--- LVM2/libdm/datastruct/list.c	2008/11/04 15:07:45	1.6
+++ LVM2/libdm/datastruct/list.c	2010/05/06 10:10:16	1.7
@@ -1,6 +1,6 @@
 /*
  * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
- * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2004-2010 Red Hat, Inc. All rights reserved.
  *
  * This file is part of LVM2.
  *
@@ -144,3 +144,25 @@
 
 	return s;
 }
+
+/*
+ * Join two lists together.
+ * This moves all the elements of the list 'head1' to the end of the list
+ * 'head', leaving 'head1' empty.
+ */
+void dm_list_splice(struct dm_list *head, struct dm_list *head1)
+{
+	assert(head->n);
+	assert(head1->n);
+
+	if (dm_list_empty(head1))
+	    return;
+
+	head1->p->n = head;
+	head1->n->p = head->p;
+
+	head->p->n = head1->n;
+	head->p = head1->p;
+
+	dm_list_init(head1);
+}


^ permalink raw reply	[flat|nested] 5+ messages in thread

* LVM2 ./WHATS_NEW libdm/.exported_symbols libdm ...
@ 2009-07-31 17:51 agk
  0 siblings, 0 replies; 5+ messages in thread
From: agk @ 2009-07-31 17:51 UTC (permalink / raw)
  To: lvm-devel, lvm2-cvs

CVSROOT:	/cvs/lvm2
Module name:	LVM2
Changes by:	agk@sourceware.org	2009-07-31 17:51:46

Modified files:
	.              : WHATS_NEW 
	libdm          : .exported_symbols libdevmapper.h libdm-common.c 
	man            : dmsetup.8.in 
	tools          : dmsetup.c 

Log message:
	Add udevcomplete and --noudevwait to dmsetup.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1221&r2=1.1222
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/libdm/.exported_symbols.diff?cvsroot=lvm2&r1=1.39&r2=1.40
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/libdm/libdevmapper.h.diff?cvsroot=lvm2&r1=1.92&r2=1.93
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/libdm/libdm-common.c.diff?cvsroot=lvm2&r1=1.68&r2=1.69
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/man/dmsetup.8.in.diff?cvsroot=lvm2&r1=1.23&r2=1.24
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/tools/dmsetup.c.diff?cvsroot=lvm2&r1=1.117&r2=1.118

--- LVM2/WHATS_NEW	2009/07/31 15:53:11	1.1221
+++ LVM2/WHATS_NEW	2009/07/31 17:51:45	1.1222
@@ -1,5 +1,6 @@
 Version 2.02.51 - 
 ================================
+  Add udevcomplete and --noudevwait to dmsetup.
   Add libdevmapper functions to support synchronisation with udev.
   Added configure --enable-udev_rules --enable-udev_sync.
   Added configure --with-udev-prefix --with-udevdir.
--- LVM2/libdm/.exported_symbols	2009/07/31 15:53:12	1.39
+++ LVM2/libdm/.exported_symbols	2009/07/31 17:51:46	1.40
@@ -157,6 +157,6 @@
 dm_list_size
 dm_udev_set_sync_support
 dm_udev_get_sync_support
-dm_udev_notify
+dm_udev_complete
 dm_udev_wait
 dm_udev_cleanup
--- LVM2/libdm/libdevmapper.h	2009/07/31 15:53:12	1.92
+++ LVM2/libdm/libdevmapper.h	2009/07/31 17:51:46	1.93
@@ -1018,7 +1018,7 @@
  */
 void dm_udev_set_sync_support(int sync_with_udev);
 int dm_udev_get_sync_support(void);
-int dm_udev_notify(uint32_t cookie);
+int dm_udev_complete(uint32_t cookie);
 int dm_udev_wait(uint32_t cookie);
 int dm_udev_cleanup(uint32_t cookie);
 
--- LVM2/libdm/libdm-common.c	2009/07/31 16:57:06	1.68
+++ LVM2/libdm/libdm-common.c	2009/07/31 17:51:46	1.69
@@ -789,7 +789,7 @@
 	return 1;
 }
 
-int dm_udev_notify(uint32_t cookie)
+int dm_udev_complete(uint32_t cookie)
 {
 	return 1;
 }
@@ -983,7 +983,7 @@
 	return 0;
 }
 
-int dm_udev_notify(uint32_t cookie)
+int dm_udev_complete(uint32_t cookie)
 {
 	int semid;
 
--- LVM2/man/dmsetup.8.in	2009/04/23 12:20:15	1.23
+++ LVM2/man/dmsetup.8.in	2009/07/31 17:51:46	1.24
@@ -64,6 +64,9 @@
 .B dmsetup mknodes
 .I [device_name]
 .br
+.B dmsetup udevcomplete
+.I cookie
+.br
 .B dmsetup targets
 .br
 .B dmsetup version
@@ -108,6 +111,9 @@
 .IP \fB--notable
 .br
 When creating a device, don't load any table.
+.IP \fB--noudevsync
+Do not synchronise with udev when creating, renaming or removing devices.
+.br
 .IP \fB-o|--options
 .br
 Specify which fields to display.
@@ -280,6 +286,11 @@
 .IP \fBtargets
 .br
 Displays the names and versions of the currently-loaded targets.
+.IP \fBudevcomplete
+.I cookie
+.br
+Wake any processes that are waiting for udev to complete processing the specified cookie.
+.br
 .IP \fBversion
 .br
 Outputs version information.
--- LVM2/tools/dmsetup.c	2009/07/13 21:26:42	1.117
+++ LVM2/tools/dmsetup.c	2009/07/31 17:51:46	1.118
@@ -119,6 +119,7 @@
 	NOLOCKFS_ARG,
 	NOOPENCOUNT_ARG,
 	NOTABLE_ARG,
+	NOUDEVSYNC_ARG,
 	OPTIONS_ARG,
 	READAHEAD_ARG,
 	ROWS_ARG,
@@ -540,6 +541,7 @@
 	int r = 0;
 	struct dm_task *dmt;
 	const char *file = NULL;
+	uint32_t cookie = 0;
 
 	if (argc == 3)
 		file = argv[2];
@@ -582,8 +584,16 @@
 				    _read_ahead_flags))
 		goto out;
 
-	if (!dm_task_run(dmt))
+	if (_switches[NOTABLE_ARG])
+		dm_udev_set_sync_support(0);
+
+	if (!dm_task_set_cookie(dmt, &cookie) ||
+	    !dm_task_run(dmt)) {
+		(void) dm_udev_cleanup(cookie);
 		goto out;
+	}
+
+	dm_udev_wait(cookie);
 
 	r = 1;
 
@@ -600,6 +610,7 @@
 {
 	int r = 0;
 	struct dm_task *dmt;
+	uint32_t cookie = 0;
 
 	if (!(dmt = dm_task_create(DM_DEVICE_RENAME)))
 		return 0;
@@ -614,8 +625,13 @@
 	if (_switches[NOOPENCOUNT_ARG] && !dm_task_no_open_count(dmt))
 		goto out;
 
-	if (!dm_task_run(dmt))
+	if (!dm_task_set_cookie(dmt, &cookie) ||
+	    !dm_task_run(dmt)) {
+		(void) dm_udev_cleanup(cookie);
 		goto out;
+	}
+
+	dm_udev_wait(cookie);
 
 	r = 1;
 
@@ -740,6 +756,19 @@
 	return r;
 }
 
+static int _udevcomplete(int argc, char **argv, void *data __attribute((unused)))
+{
+	uint32_t cookie;
+	char *p;
+
+	if (!(cookie = (uint32_t) strtoul(argv[1], &p, 0)) || *p) {
+		err("Incorrect cookie value");
+		return 0;
+	}
+
+	return dm_udev_complete(cookie);
+}
+
 static int _version(int argc __attribute((unused)), char **argv __attribute((unused)), void *data __attribute((unused)))
 {
 	char version[80];
@@ -757,6 +786,9 @@
 
 static int _simple(int task, const char *name, uint32_t event_nr, int display)
 {
+	uint32_t cookie = 0;
+	int udev_wait_flag = task == DM_DEVICE_RESUME ||
+			     task == DM_DEVICE_REMOVE;
 	int r = 0;
 
 	struct dm_task *dmt;
@@ -784,8 +816,20 @@
 				    _read_ahead_flags))
 		goto out;
 
+	if (udev_wait_flag && !dm_task_set_cookie(dmt, &cookie)) {
+		(void) dm_udev_cleanup(cookie);
+		goto out;
+	}
+
 	r = dm_task_run(dmt);
 
+	if (udev_wait_flag) {
+		if (r)
+			(void) dm_udev_wait(cookie);
+		else
+			(void) dm_udev_cleanup(cookie);
+	}
+
 	if (r && display && _switches[VERBOSE_ARG])
 		r = _display_info(dmt);
 
@@ -2261,6 +2305,7 @@
 	{"table", "[<device>] [--target <target_type>] [--showkeys]", 0, 1, _status},
 	{"wait", "<device> [<event_nr>]", 0, 2, _wait},
 	{"mknodes", "[<device>]", 0, 1, _mknodes},
+	{"udevcomplete", "<cookie>", 1, 1, _udevcomplete},
 	{"targets", "", 0, 0, _targets},
 	{"version", "", 0, 0, _version},
 	{"setgeometry", "<device> <cyl> <head> <sect> <start>", 5, 5, _setgeometry},
@@ -2275,7 +2320,7 @@
 	fprintf(out, "Usage:\n\n");
 	fprintf(out, "dmsetup [--version] [-v|--verbose [-v|--verbose ...]]\n"
 		"        [-r|--readonly] [--noopencount] [--nolockfs]\n"
-		"        [--readahead [+]<sectors>|auto|none]\n"
+		"        [--noudevsync] [--readahead [+]<sectors>|auto|none]\n"
 		"        [-c|-C|--columns] [-o <fields>] [-O|--sort <sort_fields>]\n"
 		"        [--nameprefixes] [--noheadings] [--separator <separator>]\n\n");
 	for (i = 0; _commands[i].name; i++)
@@ -2639,6 +2684,7 @@
 		{"nolockfs", 0, &ind, NOLOCKFS_ARG},
 		{"noopencount", 0, &ind, NOOPENCOUNT_ARG},
 		{"notable", 0, &ind, NOTABLE_ARG},
+		{"noudevsync", 0, &ind, NOUDEVSYNC_ARG},
 		{"options", 1, &ind, OPTIONS_ARG},
 		{"readahead", 1, &ind, READAHEAD_ARG},
 		{"rows", 0, &ind, ROWS_ARG},
@@ -2747,6 +2793,8 @@
 			_switches[UUID_ARG]++;
 			_uuid = optarg;
 		}
+		if (ind == NOUDEVSYNC_ARG)
+			_switches[NOUDEVSYNC_ARG]++;
 		if (c == 'G' || ind == GID_ARG) {
 			_switches[GID_ARG]++;
 			_int_args[GID_ARG] = atoi(optarg);
@@ -2888,6 +2936,9 @@
 	if (_switches[COLS_ARG] && !_report_init(c))
 		goto out;
 
+	if (_switches[NOUDEVSYNC_ARG])
+		dm_udev_set_sync_support(0);
+
       doit:
 	if (!c->fn(argc, argv, NULL)) {
 		fprintf(stderr, "Command failed\n");


^ permalink raw reply	[flat|nested] 5+ messages in thread

* LVM2 ./WHATS_NEW libdm/.exported_symbols libdm ...
@ 2009-07-31 15:53 agk
  0 siblings, 0 replies; 5+ messages in thread
From: agk @ 2009-07-31 15:53 UTC (permalink / raw)
  To: lvm-devel, lvm2-cvs

CVSROOT:	/cvs/lvm2
Module name:	LVM2
Changes by:	agk@sourceware.org	2009-07-31 15:53:12

Modified files:
	.              : WHATS_NEW 
	libdm          : .exported_symbols libdevmapper.h libdm-common.c 
	libdm/ioctl    : libdm-iface.c 

Log message:
	Add libdevmapper functions to support synchronisation with udev.

Patches:
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/WHATS_NEW.diff?cvsroot=lvm2&r1=1.1220&r2=1.1221
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/libdm/.exported_symbols.diff?cvsroot=lvm2&r1=1.38&r2=1.39
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/libdm/libdevmapper.h.diff?cvsroot=lvm2&r1=1.91&r2=1.92
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/libdm/libdm-common.c.diff?cvsroot=lvm2&r1=1.66&r2=1.67
http://sourceware.org/cgi-bin/cvsweb.cgi/LVM2/libdm/ioctl/libdm-iface.c.diff?cvsroot=lvm2&r1=1.58&r2=1.59

--- LVM2/WHATS_NEW	2009/07/31 13:31:53	1.1220
+++ LVM2/WHATS_NEW	2009/07/31 15:53:11	1.1221
@@ -1,5 +1,6 @@
 Version 2.02.51 - 
 ================================
+  Add libdevmapper functions to support synchronisation with udev.
   Added configure --enable-udev_rules --enable-udev_sync.
   Added configure --with-udev-prefix --with-udevdir.
   Added udev dir to hold udev rules.
--- LVM2/libdm/.exported_symbols	2009/07/10 09:59:38	1.38
+++ LVM2/libdm/.exported_symbols	2009/07/31 15:53:12	1.39
@@ -24,6 +24,7 @@
 dm_task_get_read_ahead
 dm_task_set_ro
 dm_task_set_newname
+dm_task_set_cookie
 dm_task_set_event_nr
 dm_task_set_major
 dm_task_set_minor
@@ -154,3 +155,8 @@
 dm_list_prev
 dm_list_next
 dm_list_size
+dm_udev_set_sync_support
+dm_udev_get_sync_support
+dm_udev_notify
+dm_udev_wait
+dm_udev_cleanup
--- LVM2/libdm/libdevmapper.h	2009/07/10 09:59:38	1.91
+++ LVM2/libdm/libdevmapper.h	2009/07/31 15:53:12	1.92
@@ -164,6 +164,7 @@
 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_cookie(struct dm_task *dmt, uint32_t *cookie);
 int dm_task_set_event_nr(struct dm_task *dmt, uint32_t event_nr);
 int dm_task_set_geometry(struct dm_task *dmt, const char *cylinders, const char *heads, const char *sectors, const char *start);
 int dm_task_set_message(struct dm_task *dmt, const char *message);
@@ -1010,4 +1011,15 @@
 void dm_report_field_set_value(struct dm_report_field *field, const void *value,
 			       const void *sortvalue);
 
+int dm_cookie_supported(void);
+
+/*
+ * Udev notification functions.
+ */
+void dm_udev_set_sync_support(int sync_with_udev);
+int dm_udev_get_sync_support(void);
+int dm_udev_notify(uint32_t cookie);
+int dm_udev_wait(uint32_t cookie);
+int dm_udev_cleanup(uint32_t cookie);
+
 #endif				/* LIB_DEVICE_MAPPER_H */
--- LVM2/libdm/libdm-common.c	2009/07/10 09:59:38	1.66
+++ LVM2/libdm/libdm-common.c	2009/07/31 15:53:12	1.67
@@ -24,6 +24,12 @@
 #include <sys/ioctl.h>
 #include <fcntl.h>
 
+#ifdef UDEV_SYNC_SUPPORT
+#  include <sys/types.h>
+#  include <sys/ipc.h>
+#  include <sys/sem.h>
+#endif
+
 #ifdef linux
 #  include <linux/fs.h>
 #endif
@@ -33,11 +39,16 @@
 #endif
 
 #define DEV_DIR "/dev/"
+#define COOKIE_MAGIC 0x0D4D
 
 static char _dm_dir[PATH_MAX] = DEV_DIR DM_DIR;
 
 static int _verbose = 0;
 
+#ifdef UDEV_SYNC_SUPPORT
+static int _sync_with_udev = 1;
+#endif
+
 /*
  * Library users can provide their own logging
  * function.
@@ -761,3 +772,281 @@
 	return r;
 }
 
+#ifndef UDEV_SYNC_SUPPORT
+void dm_udev_set_sync_support(int sync_with_udev)
+{
+}
+
+int dm_udev_get_sync_support(void)
+{
+	return 0;
+}
+
+int dm_task_set_cookie(struct dm_task *dmt, uint32_t *cookie)
+{
+	*cookie = 0;
+
+	return 1;
+}
+
+int dm_udev_notify(uint32_t cookie)
+{
+	return 1;
+}
+
+int dm_udev_wait(uint32_t cookie)
+{
+	return 1;
+}
+
+int dm_udev_cleanup(uint32_t cookie)
+{
+	return 1;
+}
+
+#else		/* UDEV_SYNC_SUPPORT */
+
+void dm_udev_set_sync_support(int sync_with_udev)
+{
+	_sync_with_udev = sync_with_udev;
+}
+
+int dm_udev_get_sync_support(void)
+{
+	return _sync_with_udev;
+}
+
+static int _get_cookie_sem(uint32_t cookie, int *semid)
+{
+	if ((*semid = semget((key_t) cookie, 1, 0)) >= 0)
+		return 1;
+
+	switch (errno) {
+		case ENOENT:
+			log_error("Could not find notification "
+				  "semaphore identified by cookie "
+				  "value %" PRIu32 " (0x%x)",
+				  cookie, cookie);
+			break;
+		case EACCES:
+			log_error("No permission to access "
+				  "notificaton semaphore identified "
+				  "by cookie value %" PRIu32 " (0x%x)",
+				  cookie, cookie);
+			break;
+		default:
+			/* FIXME errno use missing */
+			log_error("Failed to access notification "
+				   "semaphore identified by cookie "
+				   "value %" PRIu32 " (0x%x)",
+				  cookie, cookie);
+			break;
+	}
+
+	return 0;
+}
+
+static int _udev_notify_sem_inc(int semid)
+{
+	struct sembuf sb = {0, 1, 0};
+
+	/* FIXME errno use missing */
+	return semop(semid, &sb, 1) == 0;
+}
+
+static int _udev_notify_sem_dec(int semid)
+{
+	/* FIXME Think we should have IPC_NOWAIT here in case something went wrong and it's already 0 */
+	struct sembuf sb = {0, -1, 0};
+
+	/* FIXME errno use missing */
+	return semop(semid, &sb, 1) == 0;
+}
+
+static int _udev_notify_sem_destroy(int semid, uint32_t cookie)
+{
+	/* FIXME errno use missing */
+	if (semctl(semid, 0, IPC_RMID, 0) < 0) {
+		log_error("Could not cleanup notification semaphore "
+			  "identified by cookie value %" PRIu32 " (0x%x)",
+			  cookie, cookie);
+		return 0;
+	}
+
+	return 1;
+}
+
+static int _udev_notify_sem_create(uint32_t *cookie, int *semid)
+{
+	int fd;
+	int gen_semid;
+	uint16_t base_cookie;
+	uint32_t gen_cookie;
+
+	if ((fd = open("/dev/urandom", O_RDONLY)) < 0) {
+		log_error("Failed to open /dev/urandom "
+			  "to create random cookie value");
+		*cookie = 0;
+		return 0;
+	}
+
+	/* Generate random cookie value. Be sure it is unique and non-zero. */
+	do {
+		/* FIXME Handle non-error returns from read(). Move _io() into libdm? */
+		if (read(fd, &base_cookie, sizeof(base_cookie)) != sizeof(base_cookie)) {
+			log_error("Failed to initialize notification cookie");
+			goto bad;
+		}
+
+		gen_cookie = COOKIE_MAGIC << 16 | base_cookie;
+
+		if (base_cookie && (gen_semid = semget((key_t) gen_cookie,
+				    1, 0600 | IPC_CREAT | IPC_EXCL)) < 0) {
+			switch (errno) {
+				case EEXIST:
+					/* if the semaphore key exists, we
+					 * simply generate another random one */
+					base_cookie = 0;
+					break;
+				case ENOMEM:
+					log_error("Not enough memory to create "
+						  "notification semaphore");
+					goto bad;
+				case ENOSPC:
+					/* FIXME Suggest what to check & do */
+					log_error("Limit for the maximum number "
+						  "of semaphores reached");
+					goto bad;
+				default:
+					/* FIXME Use errno */
+					log_error("Failed to create "
+						  "notification semaphore");
+					goto bad;
+			}
+		}
+	} while (!base_cookie);
+
+	if (semctl(gen_semid, 0, SETVAL, 1) < 0) {
+		/* FIXME Use errno and give gen_semid */
+		log_error("Failed to initialize notification semaphore");
+		/* We have to destroy just created semaphore
+		 * so it won't stay in the system. */
+		_udev_notify_sem_destroy(gen_semid, gen_cookie);
+		goto bad;
+	}
+
+	if (close(fd))
+		stack;
+
+	*semid = gen_semid;
+	*cookie = gen_cookie;
+
+	return 1;
+
+bad:
+	if (close(fd))
+		stack;
+
+	*cookie = 0;
+
+	return 0;
+}
+
+int dm_task_set_cookie(struct dm_task *dmt, uint32_t *cookie)
+{
+	int semid;
+
+	if (!dm_udev_get_sync_support() || !dm_cookie_supported()) {
+		dmt->event_nr = *cookie = 0;
+		return 1;
+	}
+
+	if (*cookie) {
+		if (!_get_cookie_sem(*cookie, &semid))
+			goto_bad;
+	} else if (!_udev_notify_sem_create(cookie, &semid))
+		goto_bad;
+
+	if (!_udev_notify_sem_inc(semid)) {
+		log_error("Could not set notification semaphore "
+			  "identified by cookie value %" PRIu32 " (0x%x)",
+			  *cookie, *cookie);
+		goto bad;
+	}
+
+	dmt->event_nr = *cookie;
+	return 1;
+
+bad:
+	dmt->event_nr = 0;
+	return 0;
+}
+
+int dm_udev_notify(uint32_t cookie)
+{
+	int semid;
+
+	if (!cookie || !dm_udev_get_sync_support() || !dm_cookie_supported())
+		return 1;
+
+	if (!_get_cookie_sem(cookie, &semid))
+		return_0;
+
+	if (!_udev_notify_sem_dec(semid)) {
+		log_error("Could not signal waiting process using notification "
+			  "semaphore identified by cookie value %" PRIu32 " (0x%x)",
+			  cookie, cookie);
+		return 0;
+	}
+
+	return 1;
+}
+
+int dm_udev_wait(uint32_t cookie)
+{
+	int semid;
+	struct sembuf sb = {0, 0, 0};
+
+	if (!cookie || !dm_udev_get_sync_support() || !dm_cookie_supported())
+		return 1;
+
+	if (!_get_cookie_sem(cookie, &semid))
+		return_0;
+
+	if (!_udev_notify_sem_dec(semid)) {
+		log_error("Failed to set a proper state for notification "
+			  "semaphore identified by cookie value %" PRIu32 " (0x%x) "
+			  "to initialize waiting for incoming notifications.",
+			  cookie, cookie);
+		_udev_notify_sem_destroy(semid, cookie);
+		return 0;
+	}
+
+repeat_wait:
+	if (semop(semid, &sb, 1) < 0) {
+		if (errno == EINTR)
+			goto repeat_wait;
+		/* FIXME missing errno use */
+		log_error("Could not set wait state for notification semaphore "
+			  "identified by cookie value %" PRIu32 " (0x%x)",
+			  cookie, cookie);
+		_udev_notify_sem_destroy(semid, cookie);
+		return 0;
+	}
+
+	return _udev_notify_sem_destroy(semid, cookie);
+}
+
+int dm_udev_cleanup(uint32_t cookie)
+{
+	int semid;
+
+	if (!cookie || !dm_udev_get_sync_support() || !dm_cookie_supported())
+		return 1;
+
+	if (!_get_cookie_sem(cookie, &semid))
+		return 0;
+
+	return _udev_notify_sem_destroy(semid, cookie);
+}
+#endif		/* UDEV_SYNC_SUPPORT */
--- LVM2/libdm/ioctl/libdm-iface.c	2009/06/17 20:55:25	1.58
+++ LVM2/libdm/ioctl/libdm-iface.c	2009/07/31 15:53:12	1.59
@@ -864,6 +864,13 @@
 	return 0;
 }
 
+int dm_cookie_supported(void)
+{
+	return (dm_check_version() &&
+	        _dm_version >= 4 &&
+	        _dm_version_minor >= 15);
+}
+
 void *dm_get_next_target(struct dm_task *dmt, void *next,
 			 uint64_t *start, uint64_t *length,
 			 char **target_type, char **params)


^ permalink raw reply	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2010-05-21 12:27 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-05-21 12:24 LVM2 ./WHATS_NEW libdm/.exported_symbols libdm zkabelac
  -- strict thread matches above, loose matches on Subject: below --
2010-05-21 12:27 zkabelac
2010-05-06 10:10 zkabelac
2009-07-31 17:51 agk
2009-07-31 15:53 agk

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).