public inbox for lvm2-cvs@sourceware.org
help / color / mirror / Atom feed
* 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 ...
@ 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-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 ...
@ 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-06 10:10 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-21 12:24 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).