* [PATCH 00/25] Replicator 100808
@ 2010-08-08 8:57 Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 01/25] Update libdm for replicator Zdenek Kabelac
` (24 more replies)
0 siblings, 25 replies; 26+ messages in thread
From: Zdenek Kabelac @ 2010-08-08 8:57 UTC (permalink / raw)
To: lvm-devel
This patchset enhances lvm with replicator metadata construction.
This version contains changes from Prague discussion.
Replicated-dev has been changed to replicated
(kernel driver though is still replicated-dev).
Sitemode has been renamed to sitepolicy.
Size and Extents are not needed when site argument is given.
Updated logic for specifying vg for lvcreate command.
Not yet finished:
HA LVM usage for activation of replicator.
Removal of replicator devices could be better.
Use case example:
# build remote devices
vgcreate vg_ny /dev/loop1
vgcreate vg_paris /dev/loop2
lvcreate -L10M -n L1 vg_ny
lvcreate -L10M -n L1 vg_paris
lvcreate -L20M -n L2 vg_ny
lvcreate -L20M -n L2 vg_paris
# build local replicator
vgcreate my /dev/loop0
lvcreate --replicator rep -L20M my
lvcreate --site Berlin --replicator my/rep
lvcreate --site NY --remotevg vg_ny --replicator my/rep
lvcreate --site Paris --remotevg vg_paris --replicator my/rep
lvcreate --replicated -L10M -n L1 my/rep
lvcreate --replicated -L20M -n L2 my/rep
lvremove my/L1
Note: after removing 'L1' LV 'L1_rimage' and '_slog' devices
are left in VG Ideally user should use own 'VG'
and for removal just run:
vgremove my
lvchange --site Berlin --replicator my/rep -ay
== lvchange --site Berlin my/L1 -ay
== lvchange --site Berlin my/rep -ay
Zdenek Kabelac (25):
Update libdm for replicator
SEG_REPLICATED dm-deptree
Skip check missing rem.VGs for non-activate locks
Replicator: check for active replicator
Replicator: add reserved names
Replicator: man page update for lvm
Replicator: add _replicator_in_sync
Replicator: add report for replicator/ed targets
Replicator: improve detection of replicated segment
Replicator: new defaults
Replicator: metadata update
Replicator: segtype.h - replicated
Replicator: replicator_manip changes
Replicator: replicator.c changes
Replicator: add new command option read functions
Replicator: new args
Replicator: update of dev_manager.c
Replicator: read site_params
Replicator: lv_manip - create replicator
Replicator: lvcreate implementation
Replicator: man page update for lvcreate
Replicator: lvchange implementation
Replicator: man page update for lvchange
Replicator: lvremove implementation
Replicator: initial simple replicator testcase
lib/activate/dev_manager.c | 38 +-
lib/config/defaults.h | 9 +
lib/locking/locking.h | 2 +-
lib/metadata/lv_manip.c | 124 ++++
lib/metadata/merge.c | 22 +-
lib/metadata/metadata-exported.h | 83 ++-
lib/metadata/replicator_manip.c | 1262 +++++++++++++++++++++++++++++++-------
lib/metadata/segtype.h | 4 +-
lib/misc/lvm-globals.c | 11 +
lib/misc/lvm-globals.h | 2 +
lib/misc/lvm-string.c | 18 +
lib/replicator/replicator.c | 363 +++++-------
lib/report/columns.h | 2 +
lib/report/report.c | 32 +
libdm/libdevmapper.h | 32 +-
libdm/libdm-deptree.c | 88 ++--
man/lvchange.8.in | 31 +
man/lvcreate.8.in | 75 +++
man/lvm.8.in | 3 +-
test/t-replicator-usage.sh | 47 ++
tools/args.h | 10 +
tools/commands.h | 20 +-
tools/lvchange.c | 195 ++++++-
tools/lvcreate.c | 138 ++++-
tools/lvmcmdline.c | 71 +++
tools/lvremove.c | 18 +-
tools/toollib.c | 103 +++-
tools/toollib.h | 3 +
tools/tools.h | 3 +
tools/vgchange.c | 6 +-
30 files changed, 2245 insertions(+), 570 deletions(-)
create mode 100755 test/t-replicator-usage.sh
--
1.7.2.1
^ permalink raw reply [flat|nested] 26+ messages in thread
* [PATCH 01/25] Update libdm for replicator
2010-08-08 8:57 [PATCH 00/25] Replicator 100808 Zdenek Kabelac
@ 2010-08-08 8:57 ` Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 02/25] SEG_REPLICATED dm-deptree Zdenek Kabelac
` (23 subsequent siblings)
24 siblings, 0 replies; 26+ messages in thread
From: Zdenek Kabelac @ 2010-08-08 8:57 UTC (permalink / raw)
To: lvm-devel
Add units to passed parameters data & timeout
Switch fall_behind_data->fall_behind_size
Switch async_timeout->fall_behind_timeout
Keep ordered as in lvm library.
Signed-off-by: Zdenek Kabelac <zkabelac@redhat.com>
---
libdm/libdevmapper.h | 12 ++++++------
libdm/libdm-deptree.c | 48 +++++++++++++++++++++++++-----------------------
2 files changed, 31 insertions(+), 29 deletions(-)
diff --git a/libdm/libdevmapper.h b/libdm/libdevmapper.h
index e535d2b..b1bfbf3 100644
--- a/libdm/libdevmapper.h
+++ b/libdm/libdevmapper.h
@@ -459,18 +459,18 @@ typedef enum {
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;
+ NUM_DM_REPLICATOR_POLICIES
+} dm_replicator_policy_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);
+ dm_replicator_policy_t policy,
+ uint32_t fall_behind_ios,
+ uint64_t fall_behind_size,
+ uint32_t fall_behind_timeout);
int dm_tree_node_add_replicator_dev_target(struct dm_tree_node *node,
uint64_t size,
diff --git a/libdm/libdm-deptree.c b/libdm/libdm-deptree.c
index 0e49127..5a12c5f 100644
--- a/libdm/libdm-deptree.c
+++ b/libdm/libdm-deptree.c
@@ -83,10 +83,10 @@ struct replicator_site {
struct dm_list list;
unsigned rsite_index;
- dm_replicator_mode_t mode;
- uint32_t async_timeout;
+ dm_replicator_policy_t policy;
uint32_t fall_behind_ios;
- uint64_t fall_behind_data;
+ uint64_t fall_behind_size;
+ uint32_t fall_behind_timeout;
};
/* Per-segment properties */
@@ -1512,19 +1512,19 @@ static int _replicator_emit_segment_line(const struct load_segment *seg, char *p
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;
+ parm_count = (rsite->fall_behind_ios ||
+ rsite->fall_behind_size ||
+ rsite->fall_behind_timeout) ? 4 : 2;
EMIT_PARAMS(*pos, " blockdev %u %u %s", parm_count, rsite->rsite_index,
- (rsite->mode == DM_REPLICATOR_SYNC) ? "synchronous" : "asynchronous");
+ (rsite->policy == 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)
+ 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);
+ else if (rsite->fall_behind_size)
+ EMIT_PARAMS(*pos, " size %" PRIu64 "s", rsite->fall_behind_size);
+ else if (rsite->fall_behind_timeout)
+ EMIT_PARAMS(*pos, " timeout %" PRIu32 "s", rsite->fall_behind_timeout);
}
return 1;
@@ -2214,10 +2214,10 @@ int dm_tree_node_add_replicator_target(struct dm_tree_node *node,
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)
+ dm_replicator_policy_t policy,
+ uint32_t fall_behind_ios,
+ uint64_t fall_behind_size,
+ uint32_t fall_behind_timeout)
{
struct load_segment *rseg;
struct replicator_site *rsite;
@@ -2245,8 +2245,10 @@ int dm_tree_node_add_replicator_target(struct dm_tree_node *node,
return 0;
}
- if (!(rseg->rlog_type = dm_pool_strdup(node->dtree->mem, rlog_type)))
- return_0;
+ if (!(rseg->rlog_type = dm_pool_strdup(node->dtree->mem, rlog_type))) {
+ log_error("Failed to allocate replicator log type.");
+ return 0;
+ }
dm_list_init(&rseg->rsites);
rseg->rdevice_count = 0;
@@ -2254,8 +2256,8 @@ int dm_tree_node_add_replicator_target(struct dm_tree_node *node,
}
/* Add site to segment */
- if (mode == DM_REPLICATOR_SYNC
- && (async_timeout || fall_behind_ios || fall_behind_data)) {
+ if ((policy == DM_REPLICATOR_SYNC) &&
+ (fall_behind_ios || fall_behind_size || fall_behind_timeout)) {
log_error("Async parameters passed for synchronnous replicator.");
return 0;
}
@@ -2280,10 +2282,10 @@ int dm_tree_node_add_replicator_target(struct dm_tree_node *node,
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->policy = policy;
rsite->fall_behind_ios = fall_behind_ios;
+ rsite->fall_behind_size = fall_behind_size;
+ rsite->fall_behind_timeout = fall_behind_timeout;
rsite->rsite_index = rsite_index;
return 1;
--
1.7.2.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 02/25] SEG_REPLICATED dm-deptree
2010-08-08 8:57 [PATCH 00/25] Replicator 100808 Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 01/25] Update libdm for replicator Zdenek Kabelac
@ 2010-08-08 8:57 ` Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 03/25] Skip check missing rem.VGs for non-activate locks Zdenek Kabelac
` (22 subsequent siblings)
24 siblings, 0 replies; 26+ messages in thread
From: Zdenek Kabelac @ 2010-08-08 8:57 UTC (permalink / raw)
To: lvm-devel
Signed-off-by: Zdenek Kabelac <zkabelac@redhat.com>
---
libdm/libdevmapper.h | 18 +++++++++---------
libdm/libdm-deptree.c | 40 ++++++++++++++++++++--------------------
2 files changed, 29 insertions(+), 29 deletions(-)
diff --git a/libdm/libdevmapper.h b/libdm/libdevmapper.h
index b1bfbf3..942a30a 100644
--- a/libdm/libdevmapper.h
+++ b/libdm/libdevmapper.h
@@ -472,15 +472,15 @@ int dm_tree_node_add_replicator_target(struct dm_tree_node *node,
uint64_t fall_behind_size,
uint32_t fall_behind_timeout);
-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);
+int dm_tree_node_add_replicated_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 */
void dm_tree_node_set_presuspend_node(struct dm_tree_node *node,
diff --git a/libdm/libdm-deptree.c b/libdm/libdm-deptree.c
index 5a12c5f..c009209 100644
--- a/libdm/libdm-deptree.c
+++ b/libdm/libdm-deptree.c
@@ -36,7 +36,7 @@ enum {
SEG_LINEAR,
SEG_MIRRORED,
SEG_REPLICATOR,
- SEG_REPLICATOR_DEV,
+ SEG_REPLICATED,
SEG_SNAPSHOT,
SEG_SNAPSHOT_ORIGIN,
SEG_SNAPSHOT_MERGE,
@@ -55,7 +55,7 @@ struct {
{ SEG_LINEAR, "linear" },
{ SEG_MIRRORED, "mirror" },
{ SEG_REPLICATOR, "replicator" },
- { SEG_REPLICATOR_DEV, "replicator-dev" },
+ { SEG_REPLICATED, "replicator-dev" },
{ SEG_SNAPSHOT, "snapshot" },
{ SEG_SNAPSHOT_ORIGIN, "snapshot-origin" },
{ SEG_SNAPSHOT_MERGE, "snapshot-merge" },
@@ -125,8 +125,8 @@ struct load_segment {
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 */
+ struct dm_tree_node *replicator;/* Replicated */
+ uint64_t rdevice_index; /* Replicated */
};
/* Per-device properties */
@@ -1450,7 +1450,7 @@ static int _emit_areas_line(struct dm_task *dmt __attribute__((unused)),
return_0;
switch (seg->type) {
- case SEG_REPLICATOR_DEV:
+ case SEG_REPLICATED:
EMIT_PARAMS(*pos, " %d 1 %s", area->rsite_index, devbuf);
if (first_time)
EMIT_PARAMS(*pos, " nolog 0");
@@ -1682,7 +1682,7 @@ static int _emit_segment_line(struct dm_task *dmt, uint32_t major,
return r;
}
break;
- case SEG_REPLICATOR_DEV:
+ case SEG_REPLICATED:
if (!seg->replicator || !_build_dev_string(originbuf,
sizeof(originbuf),
seg->replicator))
@@ -1726,7 +1726,7 @@ static int _emit_segment_line(struct dm_task *dmt, uint32_t major,
break;
case SEG_CRYPT:
case SEG_LINEAR:
- case SEG_REPLICATOR_DEV:
+ case SEG_REPLICATED:
case SEG_STRIPED:
if ((r = _emit_areas_line(dmt, seg, params, paramsize, &pos)) <= 0) {
stack;
@@ -2292,15 +2292,15 @@ int dm_tree_node_add_replicator_target(struct dm_tree_node *node,
}
/* 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)
+int dm_tree_node_add_replicated_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;
@@ -2308,7 +2308,7 @@ int dm_tree_node_add_replicator_dev_target(struct dm_tree_node *node,
if (rsite_index == REPLICATOR_LOCAL_SITE) {
/* Site index for local target */
- if (!(rseg = _add_segment(node, SEG_REPLICATOR_DEV, size)))
+ if (!(rseg = _add_segment(node, SEG_REPLICATED, size)))
return_0;
if (!(rseg->replicator = dm_tree_find_node_by_uuid(node->dtree, replicator_uuid))) {
@@ -2337,13 +2337,13 @@ int dm_tree_node_add_replicator_dev_target(struct dm_tree_node *node,
} 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.");
+ log_error(INTERNAL_ERROR "Attempt to use non replicated 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.",
+ if (rseg->type != SEG_REPLICATED) {
+ log_error(INTERNAL_ERROR "Attempt to use non replicated segment %s.",
dm_segtypes[rseg->type].target);
return 0;
}
--
1.7.2.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 03/25] Skip check missing rem.VGs for non-activate locks
2010-08-08 8:57 [PATCH 00/25] Replicator 100808 Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 01/25] Update libdm for replicator Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 02/25] SEG_REPLICATED dm-deptree Zdenek Kabelac
@ 2010-08-08 8:57 ` Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 04/25] Replicator: check for active replicator Zdenek Kabelac
` (21 subsequent siblings)
24 siblings, 0 replies; 26+ messages in thread
From: Zdenek Kabelac @ 2010-08-08 8:57 UTC (permalink / raw)
To: lvm-devel
Skip call for checking whether this LV needs to locks some
more remote VGs (applies to replicator_dev devices).
The effect is, that deactivation of replicator-dev devices does
not require to take a lock for remote VGs, so avoids repeated invoke
of deactivate_lv.
Signed-off-by: Zdenek Kabelac <zkabelac@redhat.com>
---
lib/locking/locking.h | 2 +-
lib/metadata/metadata-exported.h | 2 +-
lib/metadata/replicator_manip.c | 5 ++++-
3 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/lib/locking/locking.h b/lib/locking/locking.h
index 488d194..af02844 100644
--- a/lib/locking/locking.h
+++ b/lib/locking/locking.h
@@ -136,7 +136,7 @@ int check_lvm1_vg_inactive(struct cmd_context *cmd, const char *vgname);
(vg_is_clustered((lv)->vg) ? LCK_CLUSTER_VG : 0)
#define lock_lv_vol(cmd, lv, flags) \
- (find_replicator_vgs((lv)) ? \
+ ((find_replicator_vgs((lv), (flags))) ? \
lock_vol(cmd, (lv)->lvid.s, flags | LCK_LV_CLUSTERED(lv)) : \
0)
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index a72a6bf..41ef566 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -831,7 +831,7 @@ struct cmd_vg *cmd_vg_lookup(struct dm_list *cmd_vgs,
int cmd_vg_read(struct cmd_context *cmd, struct dm_list *cmd_vgs);
void cmd_vg_release(struct dm_list *cmd_vgs);
-int find_replicator_vgs(struct logical_volume *lv);
+int find_replicator_vgs(struct logical_volume *lv, uint32_t flags);
int lv_read_replicator_vgs(struct logical_volume *lv);
void lv_release_replicator_vgs(struct logical_volume *lv);
diff --git a/lib/metadata/replicator_manip.c b/lib/metadata/replicator_manip.c
index b3a2fff..272ceac 100644
--- a/lib/metadata/replicator_manip.c
+++ b/lib/metadata/replicator_manip.c
@@ -608,11 +608,14 @@ void cmd_vg_release(struct dm_list *cmd_vgs)
* Find all needed remote VGs for processing given LV.
* Missing VGs are added to VG's cmd_vg list and flag cmd_missing_vgs is set.
*/
-int find_replicator_vgs(struct logical_volume *lv)
+int find_replicator_vgs(struct logical_volume *lv, uint32_t flags)
{
struct replicator_site *rsite;
int ret = 1;
+ if ((flags & LCK_TYPE_MASK) == LCK_READ)
+ return 1; /* no need to check for remote vgs */
+
if (!lv_is_replicator_dev(lv))
return 1;
--
1.7.2.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 04/25] Replicator: check for active replicator
2010-08-08 8:57 [PATCH 00/25] Replicator 100808 Zdenek Kabelac
` (2 preceding siblings ...)
2010-08-08 8:57 ` [PATCH 03/25] Skip check missing rem.VGs for non-activate locks Zdenek Kabelac
@ 2010-08-08 8:57 ` Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 05/25] Replicator: add reserved names Zdenek Kabelac
` (20 subsequent siblings)
24 siblings, 0 replies; 26+ messages in thread
From: Zdenek Kabelac @ 2010-08-08 8:57 UTC (permalink / raw)
To: lvm-devel
Skip activation of other heads only for a active replicator.
For inactive active all heads with linear overlay mapping
Signed-off-by: Zdenek Kabelac <zkabelac@redhat.com>
---
tools/vgchange.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/tools/vgchange.c b/tools/vgchange.c
index 960d8dd..a3a0155 100644
--- a/tools/vgchange.c
+++ b/tools/vgchange.c
@@ -104,9 +104,9 @@ static int _activate_lvs_in_vg(struct cmd_context *cmd,
if ((lv->status & MIRROR_IMAGE) || (lv->status & MIRROR_LOG))
continue;
- /* Only request activation of the first replicator-dev LV */
- /* Avoids retry with all heads in case of failure */
- if (lv_is_replicator_dev(lv) && (lv != first_replicator_dev(lv)))
+ /* Only request activation of the first replicated LV */
+ /* Avoids retry with all heads in case of some failure */
+ if (lv_is_active_replicated(lv) && (lv != first_replicated(lv)))
continue;
/* Can't deactivate a pvmove LV */
--
1.7.2.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 05/25] Replicator: add reserved names
2010-08-08 8:57 [PATCH 00/25] Replicator 100808 Zdenek Kabelac
` (3 preceding siblings ...)
2010-08-08 8:57 ` [PATCH 04/25] Replicator: check for active replicator Zdenek Kabelac
@ 2010-08-08 8:57 ` Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 06/25] Replicator: man page update for lvm Zdenek Kabelac
` (19 subsequent siblings)
24 siblings, 0 replies; 26+ messages in thread
From: Zdenek Kabelac @ 2010-08-08 8:57 UTC (permalink / raw)
To: lvm-devel
Add new reserved names for replicator related devices.
Signed-off-by: Zdenek Kabelac <zkabelac@redhat.com>
---
lib/misc/lvm-string.c | 18 ++++++++++++++++++
1 files changed, 18 insertions(+), 0 deletions(-)
diff --git a/lib/misc/lvm-string.c b/lib/misc/lvm-string.c
index 7eed799..fb73674 100644
--- a/lib/misc/lvm-string.c
+++ b/lib/misc/lvm-string.c
@@ -275,6 +275,24 @@ int apply_lvname_restrictions(const char *name)
return 0;
}
+ if (strstr(name, "_slog")) {
+ log_error("Names including \"_slog\" are reserved. "
+ "Please choose a different LV name.");
+ return 0;
+ }
+
+ if (strstr(name, "_rlog")) {
+ log_error("Names including \"_rlog\" are reserved. "
+ "Please choose a different LV name.");
+ return 0;
+ }
+
+ if (strstr(name, "_rimage")) {
+ log_error("Names including \"_rimage\" are reserved. "
+ "Please choose a different LV name.");
+ return 0;
+ }
+
return 1;
}
--
1.7.2.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 06/25] Replicator: man page update for lvm
2010-08-08 8:57 [PATCH 00/25] Replicator 100808 Zdenek Kabelac
` (4 preceding siblings ...)
2010-08-08 8:57 ` [PATCH 05/25] Replicator: add reserved names Zdenek Kabelac
@ 2010-08-08 8:57 ` Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 07/25] Replicator: add _replicator_in_sync Zdenek Kabelac
` (18 subsequent siblings)
24 siblings, 0 replies; 26+ messages in thread
From: Zdenek Kabelac @ 2010-08-08 8:57 UTC (permalink / raw)
To: lvm-devel
Add new reserved names to lvm man page.
Signed-off-by: Zdenek Kabelac <zkabelac@redhat.com>
---
man/lvm.8.in | 3 ++-
1 files changed, 2 insertions(+), 1 deletions(-)
diff --git a/man/lvm.8.in b/man/lvm.8.in
index e38ce4f..7d070f7 100644
--- a/man/lvm.8.in
+++ b/man/lvm.8.in
@@ -271,7 +271,8 @@ The following characters are valid for VG and LV names:
VG and LV names cannot begin with a hyphen.
There are also various reserved names that are used internally by lvm that can not be used as LV or VG names.
A VG cannot be called anything that exists in /dev/ at the time of creation, nor can it be called '.' or '..'.
-A LV cannot be called '.' '..' 'snapshot' or 'pvmove'. The LV name may also not contain the strings '_mlog' or '_mimage'
+A LV cannot be called '.' '..' 'snapshot' or 'pvmove'. The LV name may also not contain the strings
+'_mlog', '_mimage', '_rlog', '_slog', '_rimage'.
.SH DIAGNOSTICS
--
1.7.2.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 07/25] Replicator: add _replicator_in_sync
2010-08-08 8:57 [PATCH 00/25] Replicator 100808 Zdenek Kabelac
` (5 preceding siblings ...)
2010-08-08 8:57 ` [PATCH 06/25] Replicator: man page update for lvm Zdenek Kabelac
@ 2010-08-08 8:57 ` Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 08/25] Replicator: add report for replicator/ed targets Zdenek Kabelac
` (17 subsequent siblings)
24 siblings, 0 replies; 26+ messages in thread
From: Zdenek Kabelac @ 2010-08-08 8:57 UTC (permalink / raw)
To: lvm-devel
Add function init_replicator_in_sync() to be similar as mirror.
For now this function is not functional.
Signed-off-by: Zdenek Kabelac <zkabelac@redhat.com>
---
lib/misc/lvm-globals.c | 11 +++++++++++
lib/misc/lvm-globals.h | 2 ++
2 files changed, 13 insertions(+), 0 deletions(-)
diff --git a/lib/misc/lvm-globals.c b/lib/misc/lvm-globals.c
index 8dc2b02..5334691 100644
--- a/lib/misc/lvm-globals.c
+++ b/lib/misc/lvm-globals.c
@@ -34,6 +34,7 @@ static int _ignorelockingfailure = 0;
static int _security_level = SECURITY_LEVEL;
static char _cmd_name[30] = "";
static int _mirror_in_sync = 0;
+static int _replicator_in_sync = 0;
static int _dmeventd_monitor = DEFAULT_DMEVENTD_MONITOR;
static int _background_polling = DEFAULT_BACKGROUND_POLLING;
static int _ignore_suspended_devices = 0;
@@ -88,6 +89,11 @@ void init_mirror_in_sync(int in_sync)
_mirror_in_sync = in_sync;
}
+void init_replicator_in_sync(int in_sync)
+{
+ _replicator_in_sync = in_sync;
+}
+
void init_dmeventd_monitor(int reg)
{
_dmeventd_monitor = reg;
@@ -190,6 +196,11 @@ int mirror_in_sync(void)
return _mirror_in_sync;
}
+int replicator_in_sync(void)
+{
+ return _replicator_in_sync;
+}
+
int dmeventd_monitor_mode(void)
{
return _dmeventd_monitor;
diff --git a/lib/misc/lvm-globals.h b/lib/misc/lvm-globals.h
index 0134c32..c08aa2e 100644
--- a/lib/misc/lvm-globals.h
+++ b/lib/misc/lvm-globals.h
@@ -31,6 +31,7 @@ void init_ignorelockingfailure(int level);
void init_lockingfailed(int level);
void init_security_level(int level);
void init_mirror_in_sync(int in_sync);
+void init_replicator_in_sync(int in_sync);
void init_dmeventd_monitor(int reg);
void init_background_polling(int polling);
void init_ignore_suspended_devices(int ignore);
@@ -51,6 +52,7 @@ int ignorelockingfailure(void);
int lockingfailed(void);
int security_level(void);
int mirror_in_sync(void);
+int replicator_in_sync(void);
int background_polling(void);
int ignore_suspended_devices(void);
const char *log_command_name(void);
--
1.7.2.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 08/25] Replicator: add report for replicator/ed targets
2010-08-08 8:57 [PATCH 00/25] Replicator 100808 Zdenek Kabelac
` (6 preceding siblings ...)
2010-08-08 8:57 ` [PATCH 07/25] Replicator: add _replicator_in_sync Zdenek Kabelac
@ 2010-08-08 8:57 ` Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 09/25] Replicator: improve detection of replicated segment Zdenek Kabelac
` (16 subsequent siblings)
24 siblings, 0 replies; 26+ messages in thread
From: Zdenek Kabelac @ 2010-08-08 8:57 UTC (permalink / raw)
To: lvm-devel
Elementary reporting tool for replicator and replicato-dev LVs.
Replicator uses free flag 'q'.
Replicated 'r' for normal, 'R' for unsynchronized replicated LV.
Note: unsychronized status not yet implemented.
Signed-off-by: Zdenek Kabelac <zkabelac@redhat.com>
---
lib/report/columns.h | 2 ++
lib/report/report.c | 32 ++++++++++++++++++++++++++++++++
2 files changed, 34 insertions(+), 0 deletions(-)
diff --git a/lib/report/columns.h b/lib/report/columns.h
index 9eca600..a48210e 100644
--- a/lib/report/columns.h
+++ b/lib/report/columns.h
@@ -76,6 +76,8 @@ FIELD(LVS, lv, STR, "Convert", lvid, 7, convertlv, "convert_lv", "For lvconvert,
FIELD(LVS, lv, STR, "LV Tags", tags, 7, tags, "lv_tags", "Tags, if any.")
FIELD(LVS, lv, STR, "Log", lvid, 3, loglv, "mirror_log", "For mirrors, the LV holding the synchronisation log.")
FIELD(LVS, lv, STR, "Modules", lvid, 7, modules, "modules", "Kernel device-mapper modules required for this LV.")
+FIELD(LVS, lv, STR, "RImage", lvid, 7, rimage, "rimage", "For replicators, the replicated image of this LV.")
+FIELD(LVS, lv, STR, "Replicator", lvid, 7, replicator, "replicator", "For replicators, the replicator control LV.")
FIELD(LABEL, pv, STR, "Fmt", id, 3, pvfmt, "pv_fmt", "Type of metadata.")
FIELD(LABEL, pv, STR, "PV UUID", id, 38, uuid, "pv_uuid", "Unique identifier.")
diff --git a/lib/report/report.c b/lib/report/report.c
index b3f6544..9a4d99f 100644
--- a/lib/report/report.c
+++ b/lib/report/report.c
@@ -303,6 +303,10 @@ static int _lvstatus_disp(struct dm_report *rh __attribute__((unused)), struct d
repstr[0] = 'p';
else if (lv->status & CONVERTING)
repstr[0] = 'c';
+ else if (lv_is_replicator(lv))
+ repstr[0] = 'q';
+ else if (lv_is_replicated(lv))
+ repstr[0] = (lv->status & REPLICATOR_NOTSYNCED) ? 'R' : 'r';
else if (lv->status & VIRTUAL)
repstr[0] = 'v';
/* Origin takes precedence over Mirror */
@@ -605,6 +609,34 @@ static int _convertlv_disp(struct dm_report *rh, struct dm_pool *mem __attribute
return 1;
}
+static int _rimage_disp(struct dm_report *rh, struct dm_pool *mem,
+ struct dm_report_field *field,
+ const void *data, void *private)
+{
+ const struct logical_volume *lv = (const struct logical_volume *) data;
+
+ if (lv_is_replicated(lv))
+ return _lvname_disp(rh, mem, field, lv->rdevice->lv, private);
+
+ dm_report_field_set_value(field, "", NULL);
+
+ return 1;
+}
+
+static int _replicator_disp(struct dm_report *rh, struct dm_pool *mem,
+ struct dm_report_field *field,
+ const void *data, void *private)
+{
+ const struct logical_volume *lv = (const struct logical_volume *) data;
+
+ if (lv_is_replicated(lv))
+ return _lvname_disp(rh, mem, field, lv->rdevice->rsite->replicator, private);
+
+ dm_report_field_set_value(field, "", NULL);
+
+ return 1;
+}
+
static int _size32_disp(struct dm_report *rh __attribute__((unused)), struct dm_pool *mem,
struct dm_report_field *field,
const void *data, void *private)
--
1.7.2.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 09/25] Replicator: improve detection of replicated segment
2010-08-08 8:57 [PATCH 00/25] Replicator 100808 Zdenek Kabelac
` (7 preceding siblings ...)
2010-08-08 8:57 ` [PATCH 08/25] Replicator: add report for replicator/ed targets Zdenek Kabelac
@ 2010-08-08 8:57 ` Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 10/25] Replicator: new defaults Zdenek Kabelac
` (15 subsequent siblings)
24 siblings, 0 replies; 26+ messages in thread
From: Zdenek Kabelac @ 2010-08-08 8:57 UTC (permalink / raw)
To: lvm-devel
Switch from replicator-dev to replicated.
Check for NULL replicator pointer in replicated segment.
Signed-off-by: Zdenek Kabelac <zkabelac@redhat.com>
---
lib/metadata/merge.c | 22 ++++++++++++++--------
1 files changed, 14 insertions(+), 8 deletions(-)
diff --git a/lib/metadata/merge.c b/lib/metadata/merge.c
index 3b8895c..314a7de 100644
--- a/lib/metadata/merge.c
+++ b/lib/metadata/merge.c
@@ -73,7 +73,7 @@ int check_lv_segments(struct logical_volume *lv, int complete_vg)
struct seg_list *sl;
int error_count = 0;
struct replicator_site *rsite;
- struct replicator_device *rdev;
+ struct replicated_device *rdev;
dm_list_iterate_items(seg, &lv->segments) {
seg_count++;
@@ -218,15 +218,21 @@ int check_lv_segments(struct logical_volume *lv, int complete_vg)
if (lv == seg_lv(seg, s))
seg_found++;
}
- if (seg_is_replicator_dev(seg)) {
- dm_list_iterate_items(rsite, &seg->replicator->rsites) {
- dm_list_iterate_items(rdev, &rsite->rdevices) {
- if (lv == rdev->lv || lv == rdev->slog)
- seg_found++;
+ if (seg_is_replicated(seg)) {
+ if (!seg->replicator) {
+ log_error("LV %s has replicated segment "
+ "without replicator", lv->name);
+ inc_error_count;
+ } else {
+ dm_list_iterate_items(rsite, &seg->replicator->rsites) {
+ dm_list_iterate_items(rdev, &rsite->rdevices) {
+ if (lv == rdev->lv || lv == rdev->slog)
+ seg_found++;
+ }
}
+ if (lv == seg->replicator)
+ seg_found++;
}
- if (lv == seg->replicator)
- seg_found++;
}
if (seg_is_replicator(seg) && lv == seg->rlog_lv)
seg_found++;
--
1.7.2.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 10/25] Replicator: new defaults
2010-08-08 8:57 [PATCH 00/25] Replicator 100808 Zdenek Kabelac
` (8 preceding siblings ...)
2010-08-08 8:57 ` [PATCH 09/25] Replicator: improve detection of replicated segment Zdenek Kabelac
@ 2010-08-08 8:57 ` Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 11/25] Replicator: metadata update Zdenek Kabelac
` (14 subsequent siblings)
24 siblings, 0 replies; 26+ messages in thread
From: Zdenek Kabelac @ 2010-08-08 8:57 UTC (permalink / raw)
To: lvm-devel
Signed-off-by: Zdenek Kabelac <zkabelac@redhat.com>
---
lib/config/defaults.h | 9 +++++++++
1 files changed, 9 insertions(+), 0 deletions(-)
diff --git a/lib/config/defaults.h b/lib/config/defaults.h
index 3d8881c..1c9ce54 100644
--- a/lib/config/defaults.h
+++ b/lib/config/defaults.h
@@ -48,6 +48,14 @@
#define DEFAULT_DMEVENTD_MONITOR 1
#define DEFAULT_BACKGROUND_POLLING 1
+#define DEFAULT_REPLICATOR_SYNCLOG "disk"
+#define DEFAULT_REPLICATOR_LOG_TYPE "ringbuffer"
+#define DEFAULT_REPLICATOR_LOCAL_SITE_NAME "local"
+#define DEFAULT_REPLICATOR_FALL_BEHIND_IOS 0
+#define DEFAULT_REPLICATOR_FALL_BEHIND_SIZE 0
+#define DEFAULT_REPLICATOR_FALL_BEHIND_TIMEOUT 0
+#define DEFAULT_REPLICATOR_SITE_POLICY (DM_REPLICATOR_ASYNC_WARN)
+
#define DEFAULT_UMASK 0077
#ifdef LVM1_FALLBACK
@@ -106,6 +114,7 @@
#define DEFAULT_STRIPE_FILLER "error"
#define DEFAULT_MIRROR_REGION_SIZE 512 /* KB */
+#define DEFAULT_REPLICATOR_REGION_SIZE 512 /* KB */
#define DEFAULT_INTERVAL 15
#ifdef READLINE_SUPPORT
--
1.7.2.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 11/25] Replicator: metadata update
2010-08-08 8:57 [PATCH 00/25] Replicator 100808 Zdenek Kabelac
` (9 preceding siblings ...)
2010-08-08 8:57 ` [PATCH 10/25] Replicator: new defaults Zdenek Kabelac
@ 2010-08-08 8:57 ` Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 12/25] Replicator: segtype.h - replicated Zdenek Kabelac
` (13 subsequent siblings)
24 siblings, 0 replies; 26+ messages in thread
From: Zdenek Kabelac @ 2010-08-08 8:57 UTC (permalink / raw)
To: lvm-devel
Signed-off-by: Zdenek Kabelac <zkabelac@redhat.com>
---
lib/metadata/metadata-exported.h | 81 +++++++++++++++++++++++++++-----------
1 files changed, 58 insertions(+), 23 deletions(-)
diff --git a/lib/metadata/metadata-exported.h b/lib/metadata/metadata-exported.h
index 41ef566..70a4c33 100644
--- a/lib/metadata/metadata-exported.h
+++ b/lib/metadata/metadata-exported.h
@@ -73,7 +73,8 @@
#define MERGING 0x10000000U /* LV SEG */
#define REPLICATOR 0x20000000U /* LV -internal use only for replicator */
-#define REPLICATOR_LOG 0x40000000U /* LV -internal use only for replicator-dev */
+#define REPLICATOR_LOG 0x40000000U /* LV -internal use only for replicated */
+#define REPLICATOR_NOTSYNCED 0x80000000U /* LV -internal use only for replicator */
#define LVM_READ 0x00000100U /* LV VG */
#define LVM_WRITE 0x00000200U /* LV VG */
@@ -327,7 +328,7 @@ typedef enum {
struct replicator_site {
struct dm_list list; /* Chained list of sites */
- struct dm_list rdevices; /* Device list */
+ struct dm_list rdevices; /* List of replicated devices */
struct logical_volume *replicator; /* Reference to replicator */
@@ -336,23 +337,23 @@ struct replicator_site {
struct volume_group *vg; /* resolved vg (activate/deactive) */
unsigned site_index;
replicator_state_t state; /* Active or pasive state of site */
- dm_replicator_mode_t op_mode; /* Operation mode sync or async fail|warn|drop|stall */
- uint64_t fall_behind_data; /* Bytes */
+ dm_replicator_policy_t policy; /* Policy sync or async fail|warn|drop|stall */
uint32_t fall_behind_ios; /* IO operations */
+ uint64_t fall_behind_size; /* Bytes */
uint32_t fall_behind_timeout; /* Seconds */
};
-struct replicator_device {
+struct replicated_device {
struct dm_list list; /* Chained list of devices from same site */
- struct lv_segment *replicator_dev; /* Reference to replicator-dev segment */
+ struct lv_segment *replicated_seg; /* Reference to replicated segment */
struct replicator_site *rsite; /* Reference to site parameters */
uint64_t device_index;
const char *name; /* Device LV name */
struct logical_volume *lv; /* LV from replicator site's VG */
struct logical_volume *slog; /* Synclog lv from VG */
- const char *slog_name; /* Debug - specify size of core synclog */
+ uint32_t slog_core; /* Corelog size */
};
/* -- Replicator datatypes */
@@ -384,7 +385,7 @@ struct lv_segment {
struct lv_segment_area *areas;
- struct logical_volume *replicator;/* For replicator-devs - link to replicator LV */
+ struct logical_volume *replicator;/* For replicated - link to replicator LV */
struct logical_volume *rlog_lv; /* For replicators */
const char *rlog_type; /* For replicators */
uint64_t rdevice_index_highest; /* For replicators */
@@ -414,7 +415,7 @@ struct logical_volume {
struct dm_list snapshot_segs;
struct lv_segment *snapshot;
- struct replicator_device *rdevice;/* For replicator-devs, rimages, slogs - reference to rdevice */
+ struct replicated_device *rdevice;/* For replicated, rimages, slogs - reference to rdevice */
struct dm_list rsites; /* For replicators - all sites */
struct dm_list segments;
@@ -623,6 +624,8 @@ uint64_t extents_from_size(struct cmd_context *cmd, uint64_t size,
struct lvcreate_params {
/* flags */
int snapshot; /* snap */
+ const char *replicator; /* replicator */
+ int replicated; /* replicated */
int zero; /* all */
int major; /* all */
int minor; /* all */
@@ -641,6 +644,9 @@ struct lvcreate_params {
uint32_t mirrors; /* mirror */
+ const char *rlog_type; /* replicator */
+ struct replicator_site rsite; /* replicator, use only parameters */
+
const struct segment_type *segtype; /* all */
/* size */
@@ -804,24 +810,53 @@ int collapse_mirrored_lv(struct logical_volume *lv);
int shift_mirror_images(struct lv_segment *mirrored_seg, unsigned mimage);
/* ++ metadata/replicator_manip.c */
-int replicator_add_replicator_dev(struct logical_volume *replicator_lv,
- struct lv_segment *rdev_seg);
-struct logical_volume *replicator_remove_replicator_dev(struct lv_segment *rdev_seg);
-int replicator_add_rlog(struct lv_segment *replicator_seg, struct logical_volume *rlog_lv);
-struct logical_volume *replicator_remove_rlog(struct lv_segment *replicator_seg);
-
-int replicator_dev_add_slog(struct replicator_device *rdev, struct logical_volume *slog_lv);
-struct logical_volume *replicator_dev_remove_slog(struct replicator_device *rdev);
-int replicator_dev_add_rimage(struct replicator_device *rdev, struct logical_volume *lv);
-struct logical_volume *replicator_dev_remove_rimage(struct replicator_device *rdev);
-
-int lv_is_active_replicator_dev(const struct logical_volume *lv);
+int lv_is_active_replicated(const struct logical_volume *lv);
int lv_is_replicator(const struct logical_volume *lv);
-int lv_is_replicator_dev(const struct logical_volume *lv);
+int lv_is_replicated(const struct logical_volume *lv);
int lv_is_rimage(const struct logical_volume *lv);
int lv_is_rlog(const struct logical_volume *lv);
int lv_is_slog(const struct logical_volume *lv);
-struct logical_volume *first_replicator_dev(const struct logical_volume *lv);
+struct replicator_site *find_site_in_replicator(const struct logical_volume *replicator,
+ const char *site_name);
+struct replicator_site *find_local_site_in_replicator(const struct logical_volume *replicator);
+struct logical_volume *first_replicated(const struct logical_volume *lv);
+int replicator_add_rlog(struct lv_segment *replicator_seg, struct logical_volume *rlog_lv);
+struct logical_volume *replicator_remove_rlog(struct lv_segment *replicator_seg);
+int replicator_site_add_device(struct replicator_site *rsite,
+ struct lv_segment *replicated_seg,
+ const char *name,
+ struct logical_volume *rimage,
+ uint32_t slog_core,
+ struct logical_volume *slog_lv,
+ uint64_t device_index);
+int replicator_site_set_policy(struct replicator_site *rsite, const char *sitepolicy);
+const char *replicator_site_get_policy(const struct replicator_site *rsite);
+struct replicator_site *replicator_add_site(struct logical_volume *replicator,
+ const char *site_name);
+void replicator_init(struct logical_volume *replicator);
+int replicator_add_replicated_seg(struct logical_volume *replicator,
+ struct lv_segment *rdev_seg);
+
+int lv_add_replicated(struct logical_volume *replicator,
+ struct logical_volume *lv);
+int lv_remove_replicated(struct logical_volume *replicated);
+
+int lv_add_replicator_site(struct logical_volume *replicator,
+ const struct replicator_site *rsite);
+int lv_remove_replicator_site(struct logical_volume *replicator, const char *site_name);
+
+int lv_add_sync_log(struct logical_volume *replicator,
+ unsigned site_index,
+ uint64_t device_index,
+ struct dm_list *allocatable_pvs,
+ alloc_policy_t alloc);
+
+int vg_prearrange_replicator(struct volume_group *vg,
+ const struct lvcreate_params *lp);
+int vg_add_replicator(struct logical_volume *replicator,
+ const char *rlog_type,
+ uint32_t region_size);
+int vg_remove_replicator(struct logical_volume *replicator);
/* -- metadata/replicator_manip.c */
struct cmd_vg *cmd_vg_add(struct dm_pool *mem, struct dm_list *cmd_vgs,
const char *vg_name, const char *vgid,
--
1.7.2.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 12/25] Replicator: segtype.h - replicated
2010-08-08 8:57 [PATCH 00/25] Replicator 100808 Zdenek Kabelac
` (10 preceding siblings ...)
2010-08-08 8:57 ` [PATCH 11/25] Replicator: metadata update Zdenek Kabelac
@ 2010-08-08 8:57 ` Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 13/25] Replicator: replicator_manip changes Zdenek Kabelac
` (12 subsequent siblings)
24 siblings, 0 replies; 26+ messages in thread
From: Zdenek Kabelac @ 2010-08-08 8:57 UTC (permalink / raw)
To: lvm-devel
Change REPLICATOR_DEV to REPLICATED
Signed-off-by: Zdenek Kabelac <zkabelac@redhat.com>
---
lib/metadata/segtype.h | 4 ++--
1 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/lib/metadata/segtype.h b/lib/metadata/segtype.h
index d15df8b..799d6be 100644
--- a/lib/metadata/segtype.h
+++ b/lib/metadata/segtype.h
@@ -36,12 +36,12 @@ struct dev_manager;
#define SEG_CANNOT_BE_ZEROED 0x00000040U
#define SEG_MONITORED 0x00000080U
#define SEG_REPLICATOR 0x00000100U
-#define SEG_REPLICATOR_DEV 0x00000200U
+#define SEG_REPLICATED 0x00000200U
#define SEG_UNKNOWN 0x80000000U
#define seg_is_mirrored(seg) ((seg)->segtype->flags & SEG_AREAS_MIRRORED ? 1 : 0)
#define seg_is_replicator(seg) ((seg)->segtype->flags & SEG_REPLICATOR ? 1 : 0)
-#define seg_is_replicator_dev(seg) ((seg)->segtype->flags & SEG_REPLICATOR_DEV ? 1 : 0)
+#define seg_is_replicated(seg) ((seg)->segtype->flags & SEG_REPLICATED ? 1 : 0)
#define seg_is_striped(seg) ((seg)->segtype->flags & SEG_AREAS_STRIPED ? 1 : 0)
#define seg_is_snapshot(seg) ((seg)->segtype->flags & SEG_SNAPSHOT ? 1 : 0)
#define seg_is_virtual(seg) ((seg)->segtype->flags & SEG_VIRTUAL ? 1 : 0)
--
1.7.2.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 13/25] Replicator: replicator_manip changes
2010-08-08 8:57 [PATCH 00/25] Replicator 100808 Zdenek Kabelac
` (11 preceding siblings ...)
2010-08-08 8:57 ` [PATCH 12/25] Replicator: segtype.h - replicated Zdenek Kabelac
@ 2010-08-08 8:57 ` Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 14/25] Replicator: replicator.c changes Zdenek Kabelac
` (11 subsequent siblings)
24 siblings, 0 replies; 26+ messages in thread
From: Zdenek Kabelac @ 2010-08-08 8:57 UTC (permalink / raw)
To: lvm-devel
Changes for replicator_manip.c source file.
Adding new API functions.
Lots of lines for log creation are copied from mirror code and then
are adapted for _slog. Code is done with hope we could share same
parametrized code later for both targets - mirror and replicator.
But with recent changes to mirrored logs it is a harder task.
Signed-off-by: Zdenek Kabelac <zkabelac@redhat.com>
---
lib/metadata/replicator_manip.c | 1257 +++++++++++++++++++++++++++++++--------
1 files changed, 1024 insertions(+), 233 deletions(-)
diff --git a/lib/metadata/replicator_manip.c b/lib/metadata/replicator_manip.c
index 272ceac..b690019 100644
--- a/lib/metadata/replicator_manip.c
+++ b/lib/metadata/replicator_manip.c
@@ -15,244 +15,741 @@
#include "lib.h"
#include "locking.h"
#include "metadata.h"
+#include "defaults.h"
#include "segtype.h"
#include "toolcontext.h"
+#include "activate.h"
+#include "archiver.h"
+#include "lv_alloc.h"
+#include "str_list.h"
+
+static const struct {
+ const char name[8];
+ int value;
+} policy_table[] = {
+ { "sync", DM_REPLICATOR_SYNC },
+ { "warn", DM_REPLICATOR_ASYNC_WARN },
+ { "stall", DM_REPLICATOR_ASYNC_STALL },
+ { "drop", DM_REPLICATOR_ASYNC_DROP },
+ { "fail", DM_REPLICATOR_ASYNC_FAIL }
+};
-/* Add lv as replicator_dev device */
-int replicator_dev_add_rimage(struct replicator_device *rdev,
- struct logical_volume *lv)
+/**
+ * Tests whether LV is member of an active replicator.
+ *
+ * \param lv Logical volume for testing
+ *
+ * \return Returns 1 if the lv is member of an active replicator,
+ * 0 otherwise.
+ */
+int lv_is_active_replicated(const struct logical_volume *lv)
{
- if (!lv || !rdev)
- return_0;
+ return (lv_is_replicated(lv) &&
+ lv->rdevice &&
+ lv->rdevice->rsite &&
+ lv->rdevice->rsite->state == REPLICATOR_STATE_ACTIVE);
+}
- if (lv_is_rimage(lv)) {
- log_error("Logical volume %s is already part of other "
+/**
+ * Tests whether LV is replicator control device.
+ * (Segment-less LV could be also replicator.)
+ *
+ * \param lv Logical volume for testing
+ *
+ * \return Returns 1 if the lv is replicator control device,
+ * 0 otherwise.
+ */
+int lv_is_replicator(const struct logical_volume *lv)
+{
+ return ((lv->status & REPLICATOR) &&
+ (dm_list_empty(&lv->segments) ||
+ seg_is_replicator(first_seg(lv))));
+}
+
+/**
+ * Tests whether LV is replicated device.
+ *
+ * \param lv Logical volume for testing
+ *
+ * \return Returns 1 if the lv is replicated device,
+ * 0 otherwise.
+ */
+int lv_is_replicated(const struct logical_volume *lv)
+{
+ return ((lv->status & REPLICATOR) &&
+ !dm_list_empty(&lv->segments) &&
+ seg_is_replicated(first_seg(lv)));
+}
+
+/**
+ * Tests whether LV is replicated rimage device.
+ *
+ * \param lv Logical volume for testing
+ *
+ * \return Returns 1 if the lv is replicated rimage device,
+ * 0 otherwise.
+ */
+int lv_is_rimage(const struct logical_volume *lv)
+{
+ return (!lv_is_replicated(lv) &&
+ (lv->rdevice && lv->rdevice->lv == lv));
+}
+
+/**
+ * Tests whether LV is replicator log device.
+ *
+ * \param lv Logical volume for testing
+ *
+ * \return Returns 1 if the lv is replicator log device,
+ * 0 otherwise.
+ */
+int lv_is_rlog(const struct logical_volume *lv)
+{
+ return (lv->status & REPLICATOR_LOG);
+}
+
+/**
+ * Tests whether LV is replicator sync log device.
+ *
+ * \param lv Logical volume for testing
+ *
+ * \return Returns 1 if the lv is replicator sync log device,
+ * 0 otherwise.
+ */
+int lv_is_slog(const struct logical_volume *lv)
+{
+ return (lv->rdevice && lv->rdevice->slog == lv);
+}
+
+/**
+ * Returns local site from replicator.
+ */
+struct replicator_site *find_local_site_in_replicator(const struct logical_volume *replicator)
+{
+ struct replicator_site *rsite;
+
+ dm_list_iterate_items(rsite, &replicator->rsites)
+ if (rsite->site_index == 0)
+ return rsite;
+
+ return NULL;
+}
+
+/**
+ * Returns site with name site_name from replicator.
+ */
+struct replicator_site *find_site_in_replicator(const struct logical_volume *replicator,
+ const char *site_name)
+{
+ struct replicator_site *rsite;
+
+ dm_list_iterate_items(rsite, &replicator->rsites)
+ if (strcmp(rsite->name, site_name) == 0)
+ return rsite;
+
+ return NULL;
+}
+
+/**
+ * Returns first replicated LV in site in case the LV is replicated
+ * or replicator, NULL otherwise
+ */
+struct logical_volume *first_replicated(const struct logical_volume *lv)
+{
+ struct replicated_device *rdev;
+ struct replicator_site *rsite;
+ const struct logical_volume *replicator;
+
+ if (lv_is_replicated(lv))
+ replicator = first_seg(lv)->replicator;
+ else if (lv_is_replicator(lv))
+ replicator = lv;
+ else {
+ log_error(INTERNAL_ERROR "Logical volume %s is not "
"replicator.", lv->name);
+ return NULL;
+ }
+
+ if ((rsite = find_local_site_in_replicator(replicator)))
+ dm_list_iterate_items(rdev, &rsite->rdevices)
+ return rdev->replicated_seg->lv;
+
+ return NULL;
+}
+
+/* Add lv as replicated device */
+static int _replicated_device_add_rimage(struct replicated_device *rdev,
+ struct logical_volume *lv)
+{
+ if (lv_is_rimage(lv)) {
+ log_error(INTERNAL_ERROR "Logical volume %s is used by replicator %s.",
+ lv->name, lv->rdevice->rsite->replicator->name);
return 0;
}
if (rdev->lv) {
- log_error("Logical volume %s can not be attached to an "
- "already defined replicator device", lv->name);
+ log_error(INTERNAL_ERROR "Logical volume %s cannot be attached to an "
+ "already defined replicated device.", lv->name);
return 0;
}
lv_set_hidden(lv);
lv->rdevice = rdev;
+ rdev->replicated_seg->lv->rdevice = rdev;
rdev->lv = lv;
- return add_seg_to_segs_using_this_lv(lv, rdev->replicator_dev);
+ return add_seg_to_segs_using_this_lv(lv, rdev->replicated_seg);
}
-/* Remove lv from replicator_dev device */
-struct logical_volume *replicator_dev_remove_rimage(struct replicator_device *rdev)
+/* Remove lv from replicated device */
+static struct logical_volume *_replicated_device_remove_rimage(struct replicated_device *rdev)
{
- struct logical_volume *lv;
+ struct logical_volume *rimage = rdev->lv;
- if (!rdev || !rdev->lv)
- return_NULL;
+ if (!rimage || !lv_is_rimage(rimage)) {
+ log_error(INTERNAL_ERROR "Replicated device in site %s "
+ "does not have rimage.", rdev->rsite->name);
+ return NULL;
+ }
- lv = rdev->lv;
- if (!remove_seg_from_segs_using_this_lv(lv, rdev->replicator_dev))
+ if (!remove_seg_from_segs_using_this_lv(rimage, rdev->replicated_seg))
return_NULL;
- /* FIXME: - check for site references */
rdev->lv = NULL;
- lv->rdevice = NULL;
- lv_set_visible(lv);
+ rimage->rdevice = NULL;
+ lv_set_visible(rimage);
- return lv;
+ return rimage;
}
-int replicator_dev_add_slog(struct replicator_device *rdev,
- struct logical_volume *slog)
+static int _replicated_device_add_slog(struct replicated_device *rdev,
+ struct logical_volume *slog)
{
- if (!slog || !rdev)
- return_0;
-
- if (rdev->slog) {
- log_error("Replicator device in site %s already has sync log.",
- rdev->rsite->name);
+ if (lv_is_slog(slog)) {
+ log_error(INTERNAL_ERROR "Logical volume %s cannot be used.",
+ slog->name);
return 0;
}
- if (slog->rdevice) {
- log_error("Sync log %s is already used by replicator %s.",
- slog->name, slog->rdevice->rsite->replicator->name);
+ if (rdev->slog) {
+ log_error(INTERNAL_ERROR "Replicated device in site %s has "
+ "sync log %s.", rdev->rsite->name, rdev->slog->name);
return 0;
}
+ if (!add_seg_to_segs_using_this_lv(slog, rdev->replicated_seg))
+ return_0;
+
lv_set_hidden(slog);
- slog->rdevice = rdev;
rdev->slog = slog;
+ slog->rdevice = rdev;
- return add_seg_to_segs_using_this_lv(slog, rdev->replicator_dev);
+ return 1;
}
-struct logical_volume *replicator_dev_remove_slog(struct replicator_device *rdev)
+static struct logical_volume *_replicated_device_remove_slog(struct replicated_device *rdev)
{
- struct logical_volume *lv;
+ struct logical_volume *slog = rdev->slog;
- if (!rdev)
+ if (!slog || !lv_is_slog(slog)) {
+ log_error(INTERNAL_ERROR "Replicated device in site %s "
+ "does not have sync log.", rdev->rsite->name);
+ return NULL;
+ }
+
+ slog->rdevice = NULL;
+ rdev->slog = NULL;
+ lv_set_visible(slog);
+
+ if (!remove_seg_from_segs_using_this_lv(slog, rdev->replicated_seg))
return_NULL;
- lv = rdev->slog;
- if (!lv) {
- log_error("Replicator device in site %s does not have sync log.",
- rdev->rsite->name);
+ return slog;
+}
+
+static char *_replicated_device_slog_name(struct logical_volume *replicator,
+ unsigned site_index,
+ uint64_t device_index)
+{
+ char *name;
+ size_t len = strlen(replicator->name) + 12 + 22 + 10;
+
+ if (!(name = dm_pool_zalloc(replicator->vg->vgmem, len))) {
+ log_error("Allocation of slog name failed.");
+ return NULL;
+ }
+
+ if (!dm_snprintf(name, len, "%s_%u_%" PRIu64 "_slog", replicator->name,
+ site_index, device_index) < 0) {
+ log_error("Error in name creation.");
+ return NULL;
+ }
+
+ return name;
+}
+
+int replicator_add_rlog(struct lv_segment *replicator_seg,
+ struct logical_volume *rlog_lv)
+{
+ if (lv_is_rlog(rlog_lv)) {
+ log_error(INTERNAL_ERROR "Logical volume %s cannot be used.",
+ rlog_lv->name);
+ return 0;
+ }
+
+ if (!add_seg_to_segs_using_this_lv(rlog_lv, replicator_seg))
+ return_0;
+
+ lv_set_hidden(rlog_lv);
+ rlog_lv->status |= REPLICATOR_LOG;
+ replicator_seg->rlog_lv = rlog_lv;
+
+ return 1;
+}
+
+struct logical_volume *replicator_remove_rlog(struct lv_segment *replicator_seg)
+{
+ struct logical_volume *rlog_lv = replicator_seg->rlog_lv;
+
+ if (!rlog_lv || !lv_is_rlog(rlog_lv)) {
+ log_error(INTERNAL_ERROR "Replicator %s does not have rlog.",
+ replicator_seg->lv->name);
return NULL;
}
- if (!remove_seg_from_segs_using_this_lv(lv, rdev->replicator_dev))
+ replicator_seg->rlog_lv = NULL;
+ rlog_lv->status &= ~REPLICATOR_LOG;
+ lv_set_visible(rlog_lv);
+
+ if (!remove_seg_from_segs_using_this_lv(rlog_lv, replicator_seg))
return_NULL;
- rdev->slog = NULL;
- lv->rdevice = NULL;
- lv_set_visible(lv);
+ return rlog_lv;
+}
+
+/**
+ *
+ */
+int replicator_site_add_device(struct replicator_site *rsite,
+ struct lv_segment *replicated_seg,
+ const char *name,
+ struct logical_volume *rimage,
+ uint32_t slog_core,
+ struct logical_volume *slog,
+ uint64_t device_index)
+{
+ struct dm_pool *mem = replicated_seg->lv->vg->vgmem;
+ struct replicated_device *rdev;
+
+ if (!(rdev = dm_pool_zalloc(mem, sizeof(*rdev)))) {
+ log_error("Allocation of replicated device failed.");
+ return 0;
+ }
+
+ if (!(rdev->name = dm_pool_strdup(mem, name))) {
+ log_error("Allocation of replicated device name failed.");
+ return 0;
+ }
+
+ log_very_verbose("Created %s/%s", rsite->name, rdev->name);
+
+ rdev->rsite = rsite;
+ rdev->replicated_seg = replicated_seg;
+ rdev->device_index = device_index;
+ rdev->slog_core = slog_core;
+
+ dm_list_add(&rsite->rdevices, &rdev->list);// linked site list
- return lv;
+ if (rimage && !_replicated_device_add_rimage(rdev, rimage))
+ return_0;
+
+ if (slog_core && slog) {
+ log_error("Either slog or corelog must be used.");
+ return 0;
+ }
+
+ if (slog && !_replicated_device_add_slog(rdev, slog))
+ return_0;
+
+ return 1;
}
-int replicator_add_replicator_dev(struct logical_volume *replicator_lv,
- struct lv_segment *replicator_dev_seg)
+static int _replicator_site_remove_device(struct replicated_device *rdev)
{
- if (!replicator_lv)
+ if (rdev->lv && !_replicated_device_remove_rimage(rdev))
return_0;
- if (!(replicator_lv->status & REPLICATOR)) {
- dm_list_init(&replicator_lv->rsites);
- lv_set_hidden(replicator_lv);
- replicator_lv->status |= REPLICATOR;
+ if (rdev->slog && !_replicated_device_remove_slog(rdev))
+ return_0;
+
+ dm_list_del(&rdev->list);
+
+ return 1;
+}
+
+struct replicator_site *replicator_add_site(struct logical_volume *replicator,
+ const char *site_name)
+{
+ struct replicator_site *rsite;
+
+ if (find_site_in_replicator(replicator, site_name)) {
+ log_error("Site name %s already exists.", site_name);
+ return NULL;
}
- if (!replicator_dev_seg)
- return 1;
+ if (!(rsite = dm_pool_zalloc(replicator->vg->vgmem,
+ sizeof(*rsite)))) {
+ log_error("Allocation of replicator site failed.");
+ return NULL;
+ }
- if (replicator_dev_seg->replicator) {
- log_error("Replicator device %s is already part of replicator.",
- replicator_dev_seg->lv->name);
- return 0;
+ if (!(rsite->name = dm_pool_strdup(replicator->vg->vgmem,
+ site_name))) {
+ log_error("Allocation of replicator site name failed.");
+ return NULL;
}
- replicator_dev_seg->replicator = replicator_lv;
+ rsite->replicator = replicator;
+ dm_list_init(&rsite->rdevices);
+ dm_list_add(&replicator->rsites, &rsite->list);
+
+ return rsite;
+}
+
+static int _replicator_remove_site(struct replicator_site *rsite)
+{
+ struct replicated_device *rdev, *trdev;
+
+ dm_list_iterate_items_safe(rdev, trdev, &rsite->rdevices)
+ if (!_replicator_site_remove_device(rdev))
+ return_0;
+
+ dm_list_del(&rsite->list);
+
+ return 1;
+}
- return add_seg_to_segs_using_this_lv(replicator_lv, replicator_dev_seg);
+
+void replicator_init(struct logical_volume *replicator)
+{
+ if (!lv_is_replicator(replicator)) {
+ dm_list_init(&replicator->rsites);
+ lv_set_hidden(replicator);
+ replicator->status |= REPLICATOR;
+ }
}
/**
- * Returns rimage ?? lv upon succeful detach of device
- * entire LV entry should be removed by this crootall ??
+ * Connects replicated segment to replicator.
+ *
+ * \param replicator
+ * \param replicated_seg
*/
-struct logical_volume *replicator_remove_replicator_dev(struct lv_segment *replicator_dev_seg)
+int replicator_add_replicated_seg(struct logical_volume *replicator,
+ struct lv_segment *replicated_seg)
{
- struct logical_volume *lv = NULL;
+ replicator_init(replicator);
- log_error("FIXME: not implemented.");
-#if 0
- /* FIXME: - this is going to be complex.... */
- if (!replicator_dev_seg)
- return_NULL;
+ if (replicated_seg->replicator) {
+ log_error(INTERNAL_ERROR "Replicated device %s is already "
+ "part of replicator.", replicated_seg->lv->name);
+ return 0;
+ }
- /* if slog or rimage - exit */
+ replicated_seg->replicator = replicator;
+ replicated_seg->rlog_lv = NULL;
+ replicated_seg->lv->status |= REPLICATOR;
- if (!remove_seg_from_segs_using_this_lv(lv, replicator_seg))
- return_NULL;
+ if (!add_seg_to_segs_using_this_lv(replicator, replicated_seg))
+ return_0;
- replicator_seg->rlog_lv = NULL;
- lv->status &= ~REPLICATOR_LOG;
- lv_set_visible(lv);
-#endif
+ return 1;
+}
- return lv;
+/**
+ * Returns rimage LV upon succeful detach of device
+ * entire LV entry should be removed by this call ??
+ */
+static int _replicator_remove_replicated_seg(struct lv_segment *replicated_seg)
+{
+ struct replicator_site *rsite;
+ struct replicated_device *rdev;
+ struct logical_volume *replicator = replicated_seg->replicator;
+ uint64_t device_index = replicated_seg->lv->rdevice->device_index;
+
+ dm_list_iterate_items(rsite, &replicator->rsites) {
+ dm_list_iterate_items(rdev, &rsite->rdevices) {
+ if (rdev->device_index != device_index)
+ continue;
+ if (!_replicator_site_remove_device(rdev))
+ return_0;
+ /* no need for iterate_items_safe - 1 device per site */
+ break;
+ }
+ }
+
+ if (!remove_seg_from_segs_using_this_lv(replicator, replicated_seg))
+ return_0;
+
+ replicated_seg->lv->status &= ~REPLICATOR;
+ replicated_seg->rlog_lv = NULL;
+ replicated_seg->replicator = NULL;
+
+ return 1;
}
-int replicator_add_rlog(struct lv_segment *replicator_seg,
- struct logical_volume *rlog_lv)
+/*
+ * Create new layered LV over the original LV
+ * this target will have a replicated segment
+ */
+int lv_add_replicated(struct logical_volume *replicator,
+ struct logical_volume *lv)
{
- if (!rlog_lv)
+ const struct segment_type *segtype;
+ struct logical_volume *rimage;
+ struct logical_volume *slog;
+ struct lv_segment *seg;
+ struct replicator_site *rsite;
+ const char *slog_name;
+ uint64_t dev_idx = first_seg(replicator)->rdevice_index_highest;
+
+ if (!(segtype = get_segtype_from_string(lv->vg->cmd, "replicated")))
return_0;
- if (rlog_lv->status & REPLICATOR_LOG) {
- log_error("Rlog device %s is already used.", rlog_lv->name);
+ if (activation() && segtype->ops->target_present &&
+ !segtype->ops->target_present(lv->vg->cmd, NULL, NULL)) {
+ log_error("%s: Required device-mapper target(s) not "
+ "detected in your kernel.", segtype->name);
return 0;
}
- lv_set_hidden(rlog_lv);
- rlog_lv->status |= REPLICATOR_LOG;
- replicator_seg->rlog_lv = rlog_lv;
+ /* If replicator does not have any site defined, add local default site */
+ if (dm_list_empty(&replicator->rsites)) {
+ if (!replicator_add_site(replicator, DEFAULT_REPLICATOR_LOCAL_SITE_NAME))
+ return_0;
+ first_seg(replicator)->rsite_index_highest++;
+ }
+
+ first_seg(replicator)->rdevice_index_highest++;
+ dm_list_iterate_items(rsite, &replicator->rsites) {
+ if (rsite->site_index == 0) {
+ if (!(rimage = insert_layer_for_lv(lv->vg->cmd, lv, 0, "_rimage")))
+ return_0;
+
+ seg = first_seg(lv);
+ seg->segtype = segtype; /* switch to replicated */
+
+ if (!replicator_add_replicated_seg(replicator, seg))
+ return_0;
+
+ if (!replicator_site_add_device(rsite, seg, rimage->name,
+ rimage, 0, NULL, dev_idx))
+ return_0;
+ } else {
+ // FIXME: corelog support missing
+ slog_name = _replicated_device_slog_name(replicator, rsite->site_index,
+ dev_idx);
+ if (!(slog = find_lv(lv->vg, slog_name))) {
+ log_error("Cannot find slog LV %s for %s/%s",
+ slog_name, rsite->name, lv->name);
+ return 0;
+ }
- return add_seg_to_segs_using_this_lv(rlog_lv, replicator_seg);
+ if (!replicator_site_add_device(rsite, seg, lv->name,
+ NULL, 0, slog, dev_idx))
+ return_0;
+ }
+ }
+
+ return 1;
}
-struct logical_volume *replicator_remove_rlog(struct lv_segment *replicator_seg)
+int lv_remove_replicated(struct logical_volume *lv)
{
- struct logical_volume *lv;
+ /* FIXME: collect all removed devices */
+ if (!_replicator_remove_replicated_seg(first_seg(lv)))
+ return_0;
- if (!replicator_seg)
+ return 1;
+}
+
+int lv_add_replicator_site(struct logical_volume *replicator,
+ const struct replicator_site *rsite)
+{
+ struct replicator_site *nrsite;
+
+ if (!lv_is_replicator(replicator)) {
+ log_error(INTERNAL_ERROR "Logical volume %s is not a "
+ "replicator.", replicator->name);
+ return 0;
+ }
+
+ if (!(nrsite = replicator_add_site(replicator, rsite->name)))
return_0;
- if (!(lv = replicator_seg->rlog_lv)) {
- log_error("Replog segment %s does not have rlog.",
- replicator_seg->lv->name);
- return NULL;
+ if (rsite->vg_name &&
+ !(nrsite->vg_name = dm_pool_strdup(replicator->vg->vgmem,
+ rsite->vg_name))) {
+ log_error("Allocation of replicator site vg_name failed.");
+ return 0;
}
- if (!remove_seg_from_segs_using_this_lv(lv, replicator_seg))
- return_NULL;
+ nrsite->site_index = first_seg(replicator)->rsite_index_highest++;
+ nrsite->policy = rsite->policy;
+ nrsite->fall_behind_ios = rsite->fall_behind_ios;
+ nrsite->fall_behind_size = rsite->fall_behind_size;
+ nrsite->fall_behind_timeout = rsite->fall_behind_timeout;
- replicator_seg->rlog_lv = NULL;
- lv->status &= ~REPLICATOR_LOG;
- lv_set_visible(lv);
+ return 1;
+}
+
+int lv_remove_replicator_site(struct logical_volume *replicator,
+ const char *site_name)
+{
+ struct replicator_site *rsite, *trsite;
- return lv;
+ if (!(rsite = find_site_in_replicator(replicator, site_name))) {
+ log_error(INTERNAL_ERROR "Replicator %s does not contain "
+ "site %s.", site_name, replicator->name);
+ return 0;
+ }
+
+ if (!_replicator_remove_site(rsite))
+ return_0;
+
+ /* When the local site is removed, all remote sites must be removed */
+ if (rsite->site_index == 0) {
+ dm_list_iterate_items_safe(rsite, trsite, &replicator->rsites)
+ if (!_replicator_remove_site(rsite))
+ return_0;
+ }
+
+ return 1;
}
+int vg_prearrange_replicator(struct volume_group *vg,
+ const struct lvcreate_params *lp)
+{
+ struct logical_volume *replicator = NULL;
+ struct replicator_site *rsite;
+ struct replicated_device *rdev;
+ unsigned site_index;
+ uint64_t device_index;
-#if 0
-/*
- * Create new LV to pretend the original LV
- * this target will have a 'replicator' segment
- */
-int lv_add_replicator(struct logical_volume *origin, const char *rep_suffix)
+ if (lp->replicated || lp->rsite.name)
+ if (!(replicator = find_lv(vg, lp->replicator))) {
+ log_error("Replicator %s not found.", lp->replicator);
+ return 0;
+ }
+
+ if (lp->replicated) {
+ device_index = first_seg(replicator)->rdevice_index_highest;
+ dm_list_iterate_items(rsite, &replicator->rsites) {
+ if (rsite->site_index != 0 &&
+ !lv_add_sync_log(replicator,
+ rsite->site_index,
+ device_index,
+ lp->pvh, lp->alloc))
+ return_0;
+ }
+ }
+
+ if (lp->rsite.name) {
+ site_index = first_seg(replicator)->rsite_index_highest;
+ dm_list_iterate_items(rsite, &replicator->rsites) {
+ if (rsite->site_index != 0)
+ continue;
+
+ dm_list_iterate_items(rdev, &rsite->rdevices) {
+ if (!lv_add_sync_log(replicator,
+ site_index,
+ rdev->device_index,
+ lp->pvh, lp->alloc))
+ return_0;
+ }
+ }
+
+ if (!lv_add_replicator_site(replicator, &lp->rsite))
+ return_0;
+
+ if (!archive(vg))
+ return_0;
+
+ /* store vg on disk(s) */
+ if (!vg_write(vg) || !vg_commit(vg))
+ return_0;
+
+ backup(vg);
+ }
+
+ return 1;
+}
+
+int vg_add_replicator(struct logical_volume *replicator,
+ const char *rlog_type,
+ uint32_t region_size)
{
- struct logical_volume *rep_lv;
- char *name;
- size_t slen;
+ const struct segment_type *segtype;
+ //float sync_percent;
+ //percent_range_t percent_range;
+ struct logical_volume *rlog_lv;
+ struct lv_segment *repseg;
+ struct lvinfo info;
+
+ /*
+ * We are unable to convert the log of inactive cluster replictors
+ */
+ if (vg_is_clustered(replicator->vg)
+ && !(lv_info(replicator->vg->cmd, replicator, &info, 0, 0) &&
+ info.exists)) {
+ log_error("Replicator in this VG is not supported.");
+ return 0;
+ }
+
+ if (!(segtype = get_segtype_from_string(replicator->vg->cmd,
+ "replicator")))
+ return_0;
- if (!(name = strstr(origin->name, rep_suffix))) {
- log_error("Failed to find replicator suffix %s in LV name %s",
- rep_suffix, origin->name);
+ if (activation() && segtype->ops->target_present &&
+ !segtype->ops->target_present(replicator->vg->cmd, NULL, NULL)) {
+ log_error("%s: Required device-mapper target(s) not "
+ "detected in your kernel.", segtype->name);
return 0;
}
- slen = (size_t)(name - origin->name);
- name = alloca(slen + 1);
- memcpy(name, origin->name, slen);
- name[slen] = 0;
- if ((rep_lv = find_lv(origin->vg, name))) {
- rep_lv->status |= VIRTUAL;
- return 1;
+ if (!(rlog_lv = insert_layer_for_lv(replicator->vg->cmd,
+ replicator, 0, "_rlog"))) {
+ log_error("Failed to insert replicator _rlog.");
+ return 0;
}
- if (!(rep_lv = lv_create_empty(name, &origin->lvid,
- LVM_READ | LVM_WRITE | VISIBLE_LV,
- ALLOC_INHERIT, origin->vg)))
- return_0;
+ repseg = first_seg(replicator);
+ repseg->segtype = segtype;
- if (!lv_add_virtual_segment(rep_lv, 0, origin->le_count,
- get_segtype_from_string(origin->vg->cmd,
- "error")))
+ repseg->rlog_type = rlog_type; //"ringbuffer";
+ repseg->rdevice_index_highest = 0;
+ repseg->rsite_index_highest = 0;
+ repseg->region_size = region_size;
+
+ replicator_init(replicator);
+
+ if (!replicator_add_rlog(repseg, rlog_lv))
return_0;
- rep_lv->status |= VIRTUAL;
return 1;
}
-int lv_remove_replicator(struct logical_volume *lv)
+int vg_remove_replicator(struct logical_volume *replicator)
{
+ /* FIXME: replace heads with error targets first */
+ if (!suspend_lv(replicator->vg->cmd, replicator)) {
+ log_error("Failed to suspend %s.",
+ replicator->name);
+ return 0;
+ }
+
return 1;
}
-#endif
/*
* Check all replicator structures:
@@ -265,8 +762,8 @@ int lv_remove_replicator(struct logical_volume *lv)
int check_replicator_segment(const struct lv_segment *rseg)
{
struct replicator_site *rsite, *rsiteb;
- struct replicator_device *rdev, *rdevb;
- struct logical_volume *lv = rseg->lv;
+ struct replicated_device *rdev, *rdevb;
+ struct logical_volume *lv = rseg->lv;
int r = 1;
if (vg_is_clustered(lv->vg)) {
@@ -282,51 +779,51 @@ int check_replicator_segment(const struct lv_segment *rseg)
}
dm_list_iterate_items(rsite, &lv->rsites) {
- if (rsite->op_mode == DM_REPLICATOR_SYNC) {
- if (rsite->fall_behind_timeout) {
- log_error("Defined fall_behind_timeout="
- "%d for sync replicator %s/%s.",
- rsite->fall_behind_timeout, lv->name,
- rsite->name);
- r = 0;
- }
+ if (rsite->policy == DM_REPLICATOR_SYNC) {
if (rsite->fall_behind_ios) {
log_error("Defined fall_behind_ios="
"%d for sync replicator %s/%s.",
rsite->fall_behind_ios, lv->name, rsite->name);
r = 0;
}
- if (rsite->fall_behind_data) {
- log_error("Defined fall_behind_data="
+ if (rsite->fall_behind_size) {
+ log_error("Defined fall_behind_size="
"%" PRIu64 " for sync replicator %s/%s.",
- rsite->fall_behind_data, lv->name, rsite->name);
+ rsite->fall_behind_size, lv->name, rsite->name);
+ r = 0;
+ }
+ if (rsite->fall_behind_timeout) {
+ log_error("Defined fall_behind_timeout="
+ "%d for sync replicator %s/%s.",
+ rsite->fall_behind_timeout, lv->name,
+ rsite->name);
r = 0;
}
} else {
- if (rsite->fall_behind_timeout && rsite->fall_behind_ios) {
- log_error("Defined fall_behind_timeout and"
- " fall_behind_ios for async replicator %s/%s.",
+ if (rsite->fall_behind_ios && rsite->fall_behind_size) {
+ log_error("Defined fall behind ios and size "
+ "for asynchronous replicator %s/%s.",
lv->name, rsite->name);
r = 0;
}
- if (rsite->fall_behind_timeout && rsite->fall_behind_data) {
- log_error("Defined fall_behind_timeout and"
- " fall_behind_data for async replicator %s/%s.",
+ if (rsite->fall_behind_ios && rsite->fall_behind_timeout) {
+ log_error("Defined fall behind ios and timeout "
+ "for asynchronous replicator %s/%s.",
lv->name, rsite->name);
r = 0;
}
- if (rsite->fall_behind_ios && rsite->fall_behind_data) {
- log_error("Defined fall_behind_ios and"
- " fall_behind_data for async replicator %s/%s.",
+ if (rsite->fall_behind_size && rsite->fall_behind_timeout) {
+ log_error("Defined fall behind size and timeout "
+ "for asynchronous replicator %s/%s.",
lv->name, rsite->name);
r = 0;
}
if (!rsite->fall_behind_ios &&
- !rsite->fall_behind_data &&
+ !rsite->fall_behind_size &&
!rsite->fall_behind_timeout) {
- log_error("fall_behind_timeout,"
- " fall_behind_ios and fall_behind_data are"
- " undefined for async replicator %s/%s.",
+ log_error("For asynchronous replicator %s/%s on of "
+ "fall_behind_ios, fall_behind_size "
+ "or fall_behind_timeout needs to be defined.",
lv->name, rsite->name);
r = 0;
}
@@ -335,16 +832,16 @@ int check_replicator_segment(const struct lv_segment *rseg)
if (rsite == rsiteb)
break;
if (strcasecmp(rsite->name, rsiteb->name) == 0) {
- log_error("Duplicate site name "
- "%s detected for replicator %s.",
+ log_error("Duplicate site name %s "
+ "detected for replicator %s.",
rsite->name, lv->name);
r = 0;
}
if ((rsite->vg_name && rsiteb->vg_name &&
strcasecmp(rsite->vg_name, rsiteb->vg_name) == 0) ||
(!rsite->vg_name && !rsiteb->vg_name)) {
- log_error("Duplicate VG name "
- "%s detected for replicator %s.",
+ log_error("Duplicate VG name %s "
+ "detected for replicator %s.",
(rsite->vg_name) ? rsite->vg_name : "<local>",
lv->name);
r = 0;
@@ -356,8 +853,8 @@ int check_replicator_segment(const struct lv_segment *rseg)
rsite->name);
r = 0;
}
- if (rsite->site_index > rseg->rsite_index_highest) {
- log_error("Site index %d > %d (too high) "
+ if (rsite->site_index >= rseg->rsite_index_highest) {
+ log_error("Site index %d >= %d (too high) "
"for replicator site %s/%s.",
rsite->site_index,
rseg->rsite_index_highest,
@@ -367,6 +864,20 @@ int check_replicator_segment(const struct lv_segment *rseg)
}
dm_list_iterate_items(rdev, &rsite->rdevices) {
+ if (rdev->rsite->site_index == 0) {
+ if (strcasecmp(rdev->name,
+ rdev->replicated_seg->lv->name) == 0) {
+ log_error("Self referenced device name "
+ "%s detected for replicator %s.",
+ rdev->name, lv->name);
+ r = 0;
+ }
+ } else if (!rdev->slog && !rdev->slog_core) {
+ log_error("Undefined slog for %s/%s "
+ " for replicator %s.",
+ rdev->rsite->name, rdev->name, lv->name);
+ r = 0;
+ }
dm_list_iterate_items(rdevb, &rsite->rdevices) {
if (rdev == rdevb)
break;
@@ -376,6 +887,13 @@ int check_replicator_segment(const struct lv_segment *rseg)
rdev->slog->name, lv->name);
r = 0;
}
+ if (strcasecmp(rdev->name,
+ rdevb->replicated_seg->lv->name) == 0) {
+ log_error("Internal self reference device "
+ "name %s detected for replicator %s.",
+ rdev->name, lv->name);
+ r = 0;
+ }
if (strcasecmp(rdev->name, rdevb->name) == 0) {
log_error("Duplicate device name %s "
"detected for replicator %s.",
@@ -390,9 +908,9 @@ int check_replicator_segment(const struct lv_segment *rseg)
lv->name, rsite->name);
r = 0;
}
- if (rdev->device_index > rseg->rdevice_index_highest) {
- log_error("Device index %" PRIu64
- " > %" PRIu64 " (too high) "
+ if (rdev->device_index >= rseg->rdevice_index_highest) {
+ log_error("Device index %" PRIu64 " >= %"
+ PRIu64 " (too high) "
"for replicator site %s/%s.",
rdev->device_index,
rseg->rdevice_index_highest,
@@ -406,78 +924,29 @@ int check_replicator_segment(const struct lv_segment *rseg)
return r;
}
-/**
- * Is this segment part of active replicator
- */
-int lv_is_active_replicator_dev(const struct logical_volume *lv)
+int replicator_site_set_policy(struct replicator_site *rsite, const char *policy)
{
- return ((lv->status & REPLICATOR) &&
- lv->rdevice &&
- lv->rdevice->rsite &&
- lv->rdevice->rsite->state == REPLICATOR_STATE_ACTIVE);
-}
+ int i;
-/**
- * Is this LV replicator control device
- */
-int lv_is_replicator(const struct logical_volume *lv)
-{
- return ((lv->status & REPLICATOR) &&
- !dm_list_empty(&lv->segments) &&
- seg_is_replicator(first_seg(lv)));
-}
-
-/**
- * Is this LV replicator device
- */
-int lv_is_replicator_dev(const struct logical_volume *lv)
-{
- return ((lv->status & REPLICATOR) &&
- !dm_list_empty(&lv->segments) &&
- seg_is_replicator_dev(first_seg(lv)));
-}
-
-/**
- * Is this LV replicated origin lv
- */
-int lv_is_rimage(const struct logical_volume *lv)
-{
- return (lv->rdevice && lv->rdevice->lv == lv);
-}
-
-/**
- * Is this LV rlog
- */
-int lv_is_rlog(const struct logical_volume *lv)
-{
- return (lv->status & REPLICATOR_LOG);
-}
+ for (i = 0; i < sizeof(policy_table) / sizeof(policy_table[0]); ++i)
+ if (strcasecmp(policy, policy_table[i].name) == 0) {
+ rsite->policy = policy_table[i].value;
+ return 1;
+ }
-/**
- * Is this LV sync log
- */
-int lv_is_slog(const struct logical_volume *lv)
-{
- return (lv->rdevice && lv->rdevice->slog == lv);
+ log_error("Unknown policy: %s", policy);
+ return 0;
}
-/**
- * Returns first replicator-dev in site in case the LV is replicator-dev,
- * NULL otherwise
- */
-struct logical_volume *first_replicator_dev(const struct logical_volume *lv)
+const char *replicator_site_get_policy(const struct replicator_site *rsite)
{
- struct replicator_device *rdev;
- struct replicator_site *rsite;
+ int i;
- if (lv_is_replicator_dev(lv))
- dm_list_iterate_items(rsite, &first_seg(lv)->replicator->rsites) {
- dm_list_iterate_items(rdev, &rsite->rdevices)
- return rdev->replicator_dev->lv;
- break;
- }
+ for (i = 0; i < sizeof(policy_table) / sizeof(policy_table[0]); ++i)
+ if (rsite->policy == policy_table[i].value)
+ return policy_table[i].name;
- return NULL;
+ return NULL;
}
/**
@@ -616,7 +1085,7 @@ int find_replicator_vgs(struct logical_volume *lv, uint32_t flags)
if ((flags & LCK_TYPE_MASK) == LCK_READ)
return 1; /* no need to check for remote vgs */
- if (!lv_is_replicator_dev(lv))
+ if (!lv_is_replicated(lv))
return 1;
dm_list_iterate_items(rsite, &first_seg(lv)->replicator->rsites) {
@@ -645,17 +1114,17 @@ int find_replicator_vgs(struct logical_volume *lv, uint32_t flags)
*/
int lv_read_replicator_vgs(struct logical_volume *lv)
{
- struct replicator_device *rdev;
struct replicator_site *rsite;
+ struct replicated_device *rdev;
struct volume_group *vg;
- if (!lv_is_replicator_dev(lv))
+ if (!lv_is_active_replicated(lv))
return 1;
dm_list_iterate_items(rsite, &first_seg(lv)->replicator->rsites) {
if (!rsite->vg_name)
continue;
- vg = vg_read(lv->vg->cmd, rsite->vg_name, 0, 0); // READ_WITHOUT_LOCK
+ vg = vg_read(lv->vg->cmd, rsite->vg_name, 0, READ_WITHOUT_LOCK);
if (vg_read_error(vg)) {
log_error("Unable to read volume group %s",
rsite->vg_name);
@@ -685,7 +1154,7 @@ void lv_release_replicator_vgs(struct logical_volume *lv)
{
struct replicator_site *rsite;
- if (!lv_is_replicator_dev(lv))
+ if (!lv_is_replicated(lv))
return;
dm_list_iterate_back_items(rsite, &first_seg(lv)->replicator->rsites)
@@ -694,3 +1163,325 @@ void lv_release_replicator_vgs(struct logical_volume *lv)
rsite->vg = NULL;
}
}
+
+static int _write_replicator_header(struct cmd_context *cmd, struct logical_volume *lv)
+{
+ return 1;
+}
+
+/*
+ * Initialize log contents
+ *
+ * log_name = "mirror log", "replicator sync log"
+ */
+static int _init_log(struct cmd_context *cmd,
+ struct logical_volume *log_lv, int in_sync,
+ struct dm_list *tags, int remove_on_failure,
+ const char *log_name,
+ int (*write_header) (struct cmd_context *cmd,
+ struct logical_volume *lv))
+{
+ struct str_list *sl;
+ struct lvinfo info;
+ uint64_t orig_status = log_lv->status;
+ int was_active = 0;
+
+ if (!activation() && in_sync) {
+ log_error("Aborting. Unable to create in-sync %s "
+ "while activation is disabled.", log_name);
+ return 0;
+ }
+
+ /* If the LV is active, deactivate it first. */
+ if (lv_info(cmd, log_lv, &info, 0, 0) && info.exists) {
+ (void)deactivate_lv(cmd, log_lv);
+ /*
+ * FIXME: workaround to fail early
+ * Ensure that log is really deactivated because deactivate_lv
+ * on cluster do not fail if there is log_lv with different UUID.
+ */
+ if (lv_info(cmd, log_lv, &info, 0, 0) && info.exists) {
+ log_error("Aborting. Unable to deactivate %s.",
+ log_name);
+ goto revert_new_lv;
+ }
+ was_active = 1;
+ }
+
+ /* Temporary make it visible for set_lv() */
+ lv_set_visible(log_lv);
+
+ /* Temporary tag mirror log for activation */
+ dm_list_iterate_items(sl, tags)
+ if (!str_list_add(cmd->mem, &log_lv->tags, sl->str)) {
+ log_error("Aborting. Unable to tag %s.", log_name);
+ goto activate_lv;
+ }
+
+ /* store mirror log on disk(s) */
+ if (!vg_write(log_lv->vg) || !vg_commit(log_lv->vg))
+ goto activate_lv;
+
+ backup(log_lv->vg);
+
+ if (!activate_lv(cmd, log_lv)) {
+ log_error("Aborting. Failed to activate %s.", log_name);
+ goto revert_new_lv;
+ }
+
+ /* Remove the temporary tags */
+ dm_list_iterate_items(sl, tags)
+ if (!str_list_del(&log_lv->tags, sl->str))
+ log_error("Failed to remove tag %s from %s.",
+ log_name, sl->str);
+
+ if (activation() && !set_lv(cmd, log_lv, log_lv->size,
+ in_sync ? -1 : 0)) {
+ log_error("Aborting. Failed to wipe %s.", log_name);
+ goto deactivate_and_revert_new_lv;
+ }
+
+ if (activation() && !write_header(cmd, log_lv)) { /* FIXME */
+ log_error("Aborting. Failed to write %s header.", log_name);
+ goto deactivate_and_revert_new_lv;
+ }
+
+ if (!deactivate_lv(cmd, log_lv)) {
+ log_error("Aborting. Failed to deactivate %s. "
+ "Manual intervention required.", log_name);
+ return 0;
+ }
+
+ lv_set_hidden(log_lv);
+
+ if (was_active && !activate_lv(cmd, log_lv))
+ return_0;
+
+ return 1;
+
+deactivate_and_revert_new_lv:
+ if (!deactivate_lv(cmd, log_lv)) {
+ log_error("Unable to deactivate %s LV. "
+ "Manual intervention required.", log_name);
+ return 0;
+ }
+
+revert_new_lv:
+ log_lv->status = orig_status;
+
+ dm_list_iterate_items(sl, tags)
+ if (!str_list_del(&log_lv->tags, sl->str))
+ log_error("Failed to remove tag %s from %s.",
+ log_name, sl->str);
+
+ if (remove_on_failure && !lv_remove(log_lv)) {
+ log_error("Manual intervention may be required to remove "
+ "abandoned log LV before retrying.");
+ return 0;
+ }
+
+ if (!vg_write(log_lv->vg) || !vg_commit(log_lv->vg))
+ log_error("Manual intervention may be required to "
+ "remove/restore abandoned log LV before retrying.");
+ else
+ backup(log_lv->vg);
+
+activate_lv:
+ if (was_active && !remove_on_failure && !activate_lv(cmd, log_lv))
+ return_0;
+
+ return 0;
+}
+
+#if 0
+static int _init_replicator_log(struct cmd_context *cmd,
+ struct logical_volume *log_lv, int in_sync,
+ struct dm_list *tags, int remove_on_failure)
+{
+ if (!_init_log(cmd, log_lv, in_sync, tags, remove_on_failure,
+ "replicator log", _write_replicator_header))
+ return_0;
+
+ return 1;
+}
+#endif
+
+static int _init_replicator_sync_log(struct cmd_context *cmd,
+ struct logical_volume *log_lv, int in_sync,
+ struct dm_list *tags, int remove_on_failure)
+{
+ if (!_init_log(cmd, log_lv, in_sync, tags, remove_on_failure,
+ "sync log", _write_replicator_header))
+ return_0;
+
+ return 1;
+}
+
+/* Could be shared with mirror */
+static struct logical_volume *_create_log(struct logical_volume *lv,
+ struct alloc_handle *ah,
+ alloc_policy_t alloc,
+ const char *lv_name,
+ const char *suffix,
+ uint64_t status)
+{
+ struct logical_volume *log_lv;
+ char *log_name;
+ size_t len;
+
+ len = strlen(lv_name) + 32;
+ if (!(log_name = alloca(len))) {
+ log_error("log_name allocation failed.");
+ return NULL;
+ }
+
+ if (dm_snprintf(log_name, len, "%s%s", lv_name, suffix) < 0) {
+ log_error("log_name allocation failed.");
+ return NULL;
+ }
+
+ if (!(log_lv = lv_create_empty(log_name, NULL,
+ VISIBLE_LV | LVM_READ | LVM_WRITE,
+ alloc, lv->vg)))
+ return_NULL;
+
+ if (!lv_add_log_segment(ah, 0, log_lv, status))
+ return_NULL;
+
+ return log_lv;
+}
+
+#if 0
+static struct logical_volume *_set_up_replicator_log(struct cmd_context *cmd,
+ struct alloc_handle *ah,
+ struct logical_volume *lv,
+ uint32_t log_size __attribute((unused)),
+ alloc_policy_t alloc,
+ int in_sync)
+{
+ struct logical_volume *log_lv;
+ const char *suffix, *c;
+ char *lv_name;
+ size_t len;
+ struct lv_segment *seg;
+
+ //init_mirror_in_sync(in_sync);
+
+ /* Replicator log name is lv_name + suffix, determined as the following:
+ * 1. suffix is:
+ * o "_rlog" for the original replicator LV.
+ * o "_rlogtmp_%d" for temporary mirror LV,
+ * 2. lv_name is:
+ * o lv->name, if the log is temporary
+ * o otherwise, the top-level LV name
+ */
+ seg = first_seg(lv);
+ if (seg_type(seg, 0) == AREA_LV &&
+ strstr(seg_lv(seg, 0)->name, MIRROR_SYNC_LAYER)) {
+ lv_name = lv->name;
+ suffix = "_rlogtmp_%d";
+ } else if ((c = strstr(lv->name, MIRROR_SYNC_LAYER))) {
+ len = (size_t)(c - lv->name + 1);
+ if (!(lv_name = alloca(len)) ||
+ !dm_snprintf(lv_name, len, "%s", lv->name)) {
+ log_error("replicator log name allocation failed");
+ return 0;
+ }
+ suffix = "_rlog";
+ } else {
+ lv_name = lv->name;
+ suffix = "_rlog";
+ }
+
+ if (!(log_lv = _create_log(lv, ah, alloc, lv_name, suffix, REPLICATOR_LOG))) {
+ log_error("Failed to create replicator log.");
+ return NULL;
+ }
+
+ if (!_init_replicator_log(cmd, log_lv, in_sync, &lv->tags, 1)) {
+ log_error("Failed to initialise replicator log.");
+ return NULL;
+ }
+
+ return log_lv;
+}
+#endif
+
+static struct logical_volume *_set_up_sync_log(struct cmd_context *cmd,
+ struct alloc_handle *ah,
+ struct logical_volume *replicator,
+ unsigned site_index,
+ uint64_t device_index,
+ alloc_policy_t alloc,
+ int in_sync)
+{
+ struct logical_volume *log_lv;
+ const char *suffix = "";
+ char *lv_name;
+
+ if (!(lv_name = _replicated_device_slog_name(replicator, site_index, device_index)))
+ return_NULL;
+
+ if (!(log_lv = _create_log(replicator, ah, alloc, lv_name, suffix,
+ REPLICATOR_LOG))) {
+ log_error("Failed to create replicator sync log.");
+ return NULL;
+ }
+
+ if (!_init_replicator_sync_log(cmd, log_lv, in_sync, &replicator->tags, 1)) {
+ log_error("Failed to initialise replicator sync log.");
+ return NULL;
+ }
+
+ return log_lv;
+}
+
+int lv_add_sync_log(struct logical_volume *replicator,
+ unsigned site_index,
+ uint64_t device_index,
+ struct dm_list *allocatable_pvs,
+ alloc_policy_t alloc)
+{
+ struct cmd_context *cmd = replicator->vg->cmd;
+ const struct segment_type *segtype;
+ struct alloc_handle *ah;
+ uint32_t region_size;
+ int in_sync;
+ int r = 1;
+
+ if (!(segtype = get_segtype_from_string(cmd, "striped")))
+ return_0;
+
+ if (activation() && segtype->ops->target_present &&
+ !segtype->ops->target_present(cmd, NULL, NULL)) {
+ log_error("%s: Required device-mapper target(s) not "
+ "detected in your kernel", segtype->name);
+ return 0;
+ }
+
+ region_size = adjusted_mirror_region_size(replicator->vg->extent_size,
+ replicator->le_count,
+ first_seg(replicator)->region_size);
+
+ /* allocate destination extents */
+ ah = allocate_extents(replicator->vg, NULL, segtype,
+ 0, 0, 1, region_size, 0,
+ allocatable_pvs, alloc, NULL);
+ if (!ah) {
+ log_error("Unable to allocate extents for replicator sync log.");
+ return 0;
+ }
+
+ /* check sync status */
+ in_sync = 0;
+
+ if (!_set_up_sync_log(cmd, ah, replicator, site_index, device_index,
+ alloc, in_sync)) {
+ stack;
+ r = 0;
+ }
+
+ alloc_destroy(ah);
+
+ return r;
+}
--
1.7.2.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 14/25] Replicator: replicator.c changes
2010-08-08 8:57 [PATCH 00/25] Replicator 100808 Zdenek Kabelac
` (12 preceding siblings ...)
2010-08-08 8:57 ` [PATCH 13/25] Replicator: replicator_manip changes Zdenek Kabelac
@ 2010-08-08 8:57 ` Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 15/25] Replicator: add new command option read functions Zdenek Kabelac
` (10 subsequent siblings)
24 siblings, 0 replies; 26+ messages in thread
From: Zdenek Kabelac @ 2010-08-08 8:57 UTC (permalink / raw)
To: lvm-devel
Changes for replicator.c source file.
Reusing few new API functions from replicator_manip.c for replicator.
Add few missing log_error() diagnostic messages instead of <backtrace>.
Segment for replicator has now SEG_VIRTUAL and SEG_CANNOT_BE_ZEROED
flags. (Not really sure about logic here).
Signed-off-by: Zdenek Kabelac <zkabelac@redhat.com>
---
lib/replicator/replicator.c | 363 ++++++++++++++++++------------------------
1 files changed, 156 insertions(+), 207 deletions(-)
diff --git a/lib/replicator/replicator.c b/lib/replicator/replicator.c
index 2c58d16..360aa7f 100644
--- a/lib/replicator/replicator.c
+++ b/lib/replicator/replicator.c
@@ -28,7 +28,7 @@
/* Dm kernel module name for replicator */
#define REPLICATOR_MODULE "replicator"
-#define REPLICATOR_DEV_MODULE "replicator-dev"
+#define REPLICATED_MODULE "replicated"
/*
* Macro used as return argument - returns 0.
@@ -104,61 +104,17 @@ static replicator_state_t _get_state(const struct config_node *sn,
return def;
}
-/* Strings for replicator_action_t enum */
-static const char _op_mode_txt[NUM_DM_REPLICATOR_MODES][8] = {
- "sync",
- "warn",
- "stall",
- "drop",
- "fail"
-};
-
-
-/* Parse action string */
-static dm_replicator_mode_t _get_op_mode(const struct config_node *sn,
- const char *path, dm_replicator_mode_t def)
-{
- char *str;
- unsigned i;
-
- if (get_config_str(sn, path, &str)) {
- for (i = 0; i < sizeof(_op_mode_txt)/sizeof(_op_mode_txt[0]); ++i)
- if (strcasecmp(str, _op_mode_txt[i]) == 0) {
- log_very_verbose("Setting %s to %s",
- path, _op_mode_txt[i]);
- return (dm_replicator_mode_t) i;
- }
- log_warn("%s: unknown value '%s', using default '%s' operation mode",
- path, str, _op_mode_txt[def]);
- }
-
- return def;
-}
-
static struct replicator_site *_get_site(struct logical_volume *replicator,
const char *key)
{
- struct dm_pool *mem = replicator->vg->vgmem;
struct replicator_site *rsite;
- dm_list_iterate_items(rsite, &replicator->rsites)
- if (strcasecmp(rsite->name, key) == 0)
- return rsite;
-
- if (!(rsite = dm_pool_zalloc(mem, sizeof(*rsite))))
- return_NULL;
-
- if (!(rsite->name = dm_pool_strdup(mem, key)))
- return_NULL;
+ if ((rsite = find_site_in_replicator(replicator, key)))
+ return rsite;
- rsite->replicator = replicator;
- dm_list_init(&rsite->rdevices);
- dm_list_add(&replicator->rsites, &rsite->list);
-
- return rsite;
+ return replicator_add_site(replicator, key);
}
-
/* Parse replicator site element */
static int _add_site(struct lv_segment *seg,
const char *key,
@@ -167,6 +123,7 @@ static int _add_site(struct lv_segment *seg,
struct dm_pool *mem = seg->lv->vg->vgmem;
const struct config_node *cn;
struct replicator_site *rsite;
+ char *op_mode;
if (!(rsite = _get_site(seg->lv, key)))
return_0;
@@ -180,36 +137,41 @@ static int _add_site(struct lv_segment *seg,
return SEG_LOG_ERROR("site_index=%d > highest_site_index=%d for",
rsite->site_index, seg->rsite_index_highest);
- rsite->fall_behind_data = _get_config_uint64(sn, "fall_behind_data", 0);
rsite->fall_behind_ios = _get_config_uint32(sn, "fall_behind_ios", 0);
+ rsite->fall_behind_size = _get_config_uint64(sn, "fall_behind_size", 0);
rsite->fall_behind_timeout = _get_config_uint32(sn, "fall_behind_timeout", 0);
- rsite->op_mode = DM_REPLICATOR_SYNC;
+ rsite->policy = DM_REPLICATOR_SYNC;
- if (rsite->fall_behind_data ||
- rsite->fall_behind_ios ||
+ if (rsite->fall_behind_ios ||
+ rsite->fall_behind_size ||
rsite->fall_behind_timeout) {
- if (rsite->fall_behind_data && rsite->fall_behind_ios)
- return SEG_LOG_ERROR("Defined both fall_behind_data "
- "and fall_behind_ios in");
-
- if (rsite->fall_behind_data && rsite->fall_behind_timeout)
- return SEG_LOG_ERROR("Defined both fall_behind_data "
- "and fall_behind_timeout in");
+ if (rsite->fall_behind_ios && rsite->fall_behind_size)
+ return SEG_LOG_ERROR("Defined both fall behind ios "
+ "and size in");
if (rsite->fall_behind_ios && rsite->fall_behind_timeout)
- return SEG_LOG_ERROR("Defined both fall_behind_ios "
- "and fall_behind_timeout in");
+ return SEG_LOG_ERROR("Defined both fall behind ios "
+ "and timeout in");
+
+ if (rsite->fall_behind_size && rsite->fall_behind_timeout)
+ return SEG_LOG_ERROR("Defined both fall behind size "
+ "and timeout in");
+
+ if (!get_config_str(sn, "operation_mode", &op_mode))
+ return SEG_LOG_ERROR("Operation mode undefined in");
- rsite->op_mode = _get_op_mode(sn, "operation_mode",
- rsite->op_mode);
+ if (!replicator_site_set_policy(rsite, op_mode))
+ return SEG_LOG_ERROR("Unknown value for operation mode in");
}
if ((cn = find_config_node(sn, "volume_group"))) {
if (!cn->v || cn->v->type != CFG_STRING)
return SEG_LOG_ERROR("volume_group must be a string in");
- if (!(rsite->vg_name = dm_pool_strdup(mem, cn->v->v.str)))
- return_0;
+ if (!(rsite->vg_name = dm_pool_strdup(mem, cn->v->v.str))) {
+ log_error("Failed to duplicate volume group name.");
+ return 0;
+ }
} else if (rsite->site_index != 0)
return SEG_LOG_ERROR("volume_group is mandatory for remote site in");
@@ -226,12 +188,11 @@ static int _replicator_text_import(struct lv_segment *seg,
const struct config_node *cn;
struct logical_volume *rlog_lv;
- if (!replicator_add_replicator_dev(seg->lv, NULL))
- return_0;
+ replicator_init(seg->lv);
if (!(cn = find_config_node(sn, "replicator_log")) ||
!cn->v || cn->v->type != CFG_STRING)
- return SEG_LOG_ERROR("Replicator log type must be a string in");
+ return SEG_LOG_ERROR("Replicator log must be a string in");
if (!(rlog_lv = find_lv(seg->lv->vg, cn->v->v.str)))
return SEG_LOG_ERROR("Unknown replicator log %s in",
@@ -239,13 +200,15 @@ static int _replicator_text_import(struct lv_segment *seg,
if (!(cn = find_config_node(sn, "replicator_log_type")) ||
!cn->v || cn->v->type != CFG_STRING)
- return SEG_LOG_ERROR("Replicator log's type must be a string in");
+ return SEG_LOG_ERROR("Replicator log type must be a string in");
+
if (strcasecmp(cn->v->v.str, "ringbuffer"))
return SEG_LOG_ERROR("Only ringbuffer replicator log type is supported in");
- if (!(seg->rlog_type = dm_pool_strdup(seg->lv->vg->vgmem, cn->v->v.str)))
- return_0;
-
+ if (!(seg->rlog_type = dm_pool_strdup(seg->lv->vg->vgmem, cn->v->v.str))) {
+ log_error("Failed to duplicate replicator log type.");
+ return 0;
+ }
log_very_verbose("replicator_log = %s", rlog_lv->name);
log_very_verbose("replicator_log_type = %s", seg->rlog_type);
@@ -267,6 +230,7 @@ static int _replicator_text_import(struct lv_segment *seg,
if (!_add_site(seg, sn->key, sn->child))
return_0;
}
+
return 1;
}
@@ -275,9 +239,10 @@ static int _replicator_text_export(const struct lv_segment *seg,
struct formatter *f)
{
struct replicator_site *rsite;
+ const char *policy;
if (!seg->rlog_lv)
- return_0;
+ return_0;
outf(f, "replicator_log = \"%s\"", seg->rlog_lv->name);
outf(f, "replicator_log_type = \"%s\"", seg->rlog_type);
@@ -299,18 +264,22 @@ static int _replicator_text_export(const struct lv_segment *seg,
outf(f, "site_index = %d", rsite->site_index);
/* Only non-default parameters are written */
- if (rsite->op_mode != DM_REPLICATOR_SYNC)
- outf(f, "operation_mode = \"%s\"",
- _op_mode_txt[rsite->op_mode]);
- if (rsite->fall_behind_timeout)
- outfc(f, "# seconds", "fall_behind_timeout = %u",
- rsite->fall_behind_timeout);
+ if (rsite->policy != DM_REPLICATOR_SYNC) {
+ if (!(policy = replicator_site_get_policy(rsite))) {
+ log_error("Unknown operation mode.");
+ return 0;
+ }
+ outf(f, "operation_mode = \"%s\"", policy);
+ }
if (rsite->fall_behind_ios)
outfc(f, "# io operations", "fall_behind_ios = %u",
rsite->fall_behind_ios);
- if (rsite->fall_behind_data)
- outsize(f, rsite->fall_behind_data, "fall_behind_data = %" PRIu64,
- rsite->fall_behind_data);
+ if (rsite->fall_behind_size)
+ outsize(f, rsite->fall_behind_size, "fall_behind_size = %" PRIu64,
+ rsite->fall_behind_size);
+ if (rsite->fall_behind_timeout)
+ outfc(f, "# seconds", "fall_behind_timeout = %u",
+ rsite->fall_behind_timeout);
if (rsite->state != REPLICATOR_STATE_ACTIVE && rsite->vg_name)
outf(f, "volume_group = \"%s\"", rsite->vg_name);
@@ -346,10 +315,10 @@ static int _replicator_add_target_line(struct dev_manager *dm,
rlog_dlid,
seg->rlog_type,
rsite->site_index,
- rsite->op_mode,
- rsite->fall_behind_timeout,
- rsite->fall_behind_data,
- rsite->fall_behind_ios)) {
+ rsite->policy,
+ rsite->fall_behind_ios,
+ rsite->fall_behind_size,
+ rsite->fall_behind_timeout)) {
if (rsite->site_index == 0) {
log_error("Failed to add replicator log '%s' "
"to replicator '%s'.",
@@ -400,7 +369,7 @@ static int _replicator_modules_needed(struct dm_pool *mem,
if (!str_list_add(mem, modules, REPLICATOR_MODULE))
return_0;
- if (!str_list_add(mem, modules, REPLICATOR_DEV_MODULE))
+ if (!str_list_add(mem, modules, REPLICATED_MODULE))
return_0;
return 1;
@@ -426,9 +395,9 @@ static struct segtype_handler _replicator_ops = {
};
/*
- * Replicator-dev target
+ * Replicated target
*/
-static void _replicator_dev_display(const struct lv_segment *seg)
+static void _replicated_display(const struct lv_segment *seg)
{
//const char *size;
//uint32_t s;
@@ -445,82 +414,63 @@ static int _add_device(struct lv_segment *seg,
const struct config_node *sn,
uint64_t devidx)
{
- struct dm_pool *mem = seg->lv->vg->vgmem;
- struct logical_volume *lv = NULL;
- struct logical_volume *slog_lv = NULL;
+ struct logical_volume *rimage = NULL;
+ struct logical_volume *slog = NULL;
struct replicator_site *rsite = _get_site(seg->replicator, site_name);
- struct replicator_device *rdev;
- const char *dev_str = NULL;
+ struct replicated_device *rdev;
+ const char *lv_name = NULL;
const char *slog_str = NULL;
+ uint32_t slog_core = 0;
const struct config_node *cn;
dm_list_iterate_items(rdev, &rsite->rdevices)
- if (rdev->replicator_dev == seg)
+ if (rdev->replicated_seg == seg)
return SEG_LOG_ERROR("Duplicate site found in");
if ((cn = find_config_node(sn, "sync_log"))) {
- if (!cn->v || !cn->v->v.str)
- return SEG_LOG_ERROR("Sync log must be a string in");
- slog_str = cn->v->v.str;
+ if (cn->v && cn->v->v.str)
+ slog_str = cn->v->v.str;
+ else if (!get_config_uint32(sn, "sync_log", &slog_core))
+ return SEG_LOG_ERROR("Could not read 'sync_log' for");
}
if (!(cn = find_config_node(sn, "logical_volume")) ||
!cn->v || !cn->v->v.str)
return SEG_LOG_ERROR("Logical volume must be a string in");
- dev_str = cn->v->v.str;
+ lv_name = cn->v->v.str;
if (!seg->lv->rdevice) {
if (slog_str)
return SEG_LOG_ERROR("Sync log %s defined for local "
- "device in", slog_str);
+ "site device in", slog_str);
/* Check for device in current VG */
- if (!(lv = find_lv(seg->lv->vg, dev_str)))
+ if (!(rimage = find_lv(seg->lv->vg, lv_name)))
return SEG_LOG_ERROR("Logical volume %s not found in",
- dev_str);
+ lv_name);
} else {
- if (!slog_str)
+ if (!slog_str && !slog_core)
return SEG_LOG_ERROR("Sync log is missing for remote "
- "device in");
+ "site device in");
/* Check for slog device in current VG */
- if (!(slog_lv = find_lv(seg->lv->vg, slog_str)))
+ if (!slog_core &&
+ !(slog = find_lv(seg->lv->vg, slog_str)))
return SEG_LOG_ERROR("Sync log %s not found in",
slog_str);
}
- if (!(rdev = dm_pool_zalloc(mem, sizeof(*rdev))))
- return_0;
-
- if (!(rdev->name = dm_pool_strdup(mem, dev_str)))
+ if (!replicator_site_add_device(rsite, seg, lv_name, rimage,
+ slog_core, slog, devidx))
return_0;
- rdev->replicator_dev = seg;
- rdev->rsite = rsite;
- rdev->device_index = devidx;
-
- if (!seg->lv->rdevice) {
- if (!replicator_dev_add_rimage(rdev, lv))
- return SEG_LOG_ERROR("LV inconsistency found in");
- seg->lv->rdevice = rdev;
- } else {
- if (!slog_str ||
- !(rdev->slog_name = dm_pool_strdup(mem, slog_str)))
- return_0;
-
- if (!replicator_dev_add_slog(rdev, slog_lv))
- return SEG_LOG_ERROR("Sync log inconsistency found in");
- }
-
- dm_list_add(&rsite->rdevices, &rdev->list);// linked site list
-
return 1;
}
/* Import replicator segment */
-static int _replicator_dev_text_import(struct lv_segment *seg,
- const struct config_node *sn,
- struct dm_hash_table *pv_hash __attribute__((unused)))
+static int _replicated_text_import(struct lv_segment *seg,
+ const struct config_node *sn,
+ struct dm_hash_table *pv_hash __attribute__((unused)))
{
const struct config_node *cn;
struct logical_volume *replicator;
@@ -535,7 +485,7 @@ static int _replicator_dev_text_import(struct lv_segment *seg,
if (!(replicator = find_lv(seg->lv->vg, cn->v->v.str)))
return SEG_LOG_ERROR("Unknown replicator %s for", cn->v->v.str);
- if (!replicator_add_replicator_dev(replicator, seg))
+ if (!replicator_add_replicated_seg(replicator, seg))
return_0;
log_very_verbose("replicator=%s", replicator->name);
@@ -551,20 +501,17 @@ static int _replicator_dev_text_import(struct lv_segment *seg,
return_0;
if (!seg->lv->rdevice)
- return SEG_LOG_ERROR("Replicator device without site in");
-
- seg->rlog_lv = NULL;
- seg->lv->status |= REPLICATOR;
+ return SEG_LOG_ERROR("Replicated device without site in");
return 1;
}
-/* Export replicator-dev segment */
-static int _replicator_dev_text_export(const struct lv_segment *seg,
- struct formatter *f)
+/* Export replicated segment */
+static int _replicated_text_export(const struct lv_segment *seg,
+ struct formatter *f)
{
struct replicator_site *rsite;
- struct replicator_device *rdev;
+ struct replicated_device *rdev;
if (!seg->replicator || !seg->lv->rdevice)
return_0;
@@ -576,7 +523,7 @@ static int _replicator_dev_text_export(const struct lv_segment *seg,
dm_list_iterate_items(rsite, &seg->replicator->rsites) {
dm_list_iterate_items(rdev, &rsite->rdevices) {
- if (rdev->replicator_dev != seg)
+ if (rdev->replicated_seg != seg)
continue;
outf(f, "%s {", rdev->rsite->name);
@@ -586,10 +533,12 @@ static int _replicator_dev_text_export(const struct lv_segment *seg,
outf(f, "logical_volume = \"%s\"",
rdev->name ? rdev->name : rdev->lv->name);
- if (rdev->slog)
- outf(f, "sync_log = \"%s\"", rdev->slog->name);
- else if (rdev->slog_name)
- outf(f, "sync_log = \"%s\"", rdev->slog_name);
+ if (rsite->site_index != 0) {
+ if (rdev->slog)
+ outf(f, "sync_log = \"%s\"", rdev->slog->name);
+ else
+ outf(f, "sync_log = %d", rdev->slog_core);
+ }
out_dec_indent(f);
@@ -604,29 +553,31 @@ static int _replicator_dev_text_export(const struct lv_segment *seg,
/*
* Add target for passive site matching the device index
*/
-static int _replicator_dev_add_target_line(struct dev_manager *dm,
- struct dm_pool *mem,
- struct cmd_context *cmd,
- void **target_state,
- struct lv_segment *seg,
- struct dm_tree_node *node,
- uint64_t len,
- uint32_t *pvmove_mirror_count)
+static int _replicated_add_target_line(struct dev_manager *dm,
+ struct dm_pool *mem,
+ struct cmd_context *cmd,
+ void **target_state,
+ struct lv_segment *seg,
+ struct dm_tree_node *node,
+ uint64_t len,
+ uint32_t *pvmove_mirror_count)
{
const char *replicator_dlid, *rdev_dlid, *slog_dlid;
- struct replicator_device *rdev, *rdev_search;
+ struct replicated_device *rdev, *rdev_search;
struct replicator_site *rsite;
uint32_t slog_size;
uint32_t slog_flags;
- if (!lv_is_active_replicator_dev(seg->lv)) {
+ if (!lv_is_active_replicated(seg->lv)) {
/* Create passive linear mapping */
log_very_verbose("Inactive replicator %s using %s.",
seg->lv->name, seg->lv->rdevice->lv->name);
if (!dm_tree_node_add_linear_target(node, seg->lv->size))
return_0;
- if (!(rdev_dlid = build_dm_uuid(mem, seg->lv->rdevice->lv->lvid.s, NULL)))
- return_0;
+ if (!(rdev_dlid = build_dm_uuid(mem, seg->lv->rdevice->lv->lvid.s, NULL))) {
+ log_error("Failed to build replicated uuid.");
+ return 0;
+ }
return dm_tree_node_add_target_area(node, NULL, rdev_dlid, 0);
} else if (seg->lv->rdevice->rsite->site_index) {
log_error("Active site with site_index != 0 (%s, %d)",
@@ -639,9 +590,11 @@ static int _replicator_dev_add_target_line(struct dev_manager *dm,
* At this point all devices that have some connection with replicator
* must be present in dm_tree
*/
- if (!seg_is_replicator_dev(seg) ||
- !(replicator_dlid = build_dm_uuid(mem, seg->replicator->lvid.s, NULL)))
- return_0;
+ if (!seg_is_replicated(seg) ||
+ !(replicator_dlid = build_dm_uuid(mem, seg->replicator->lvid.s, NULL))) {
+ log_error("Failed to build replicator dlid.");
+ return 0;
+ }
/* Select remote devices with the same device index */
dm_list_iterate_items(rsite, &seg->replicator->rsites) {
@@ -651,7 +604,7 @@ static int _replicator_dev_add_target_line(struct dev_manager *dm,
} else {
rdev = NULL;
dm_list_iterate_items(rdev_search, &rsite->rdevices) {
- if (rdev_search->replicator_dev == seg) {
+ if (rdev_search->replicated_seg == seg) {
rdev = rdev_search;
break;
}
@@ -664,8 +617,10 @@ static int _replicator_dev_add_target_line(struct dev_manager *dm,
}
if (!rdev->lv ||
- !(rdev_dlid = build_dm_uuid(mem, rdev->lv->lvid.s, NULL)))
- return_0;
+ !(rdev_dlid = build_dm_uuid(mem, rdev->lv->lvid.s, NULL))) {
+ log_error("Failed UUID allocation.");
+ return 0;
+ }
slog_dlid = NULL;
@@ -675,29 +630,23 @@ static int _replicator_dev_add_target_line(struct dev_manager *dm,
slog_size = (uint32_t) rdev->slog->size;
if (!(slog_dlid = build_dm_uuid(mem, rdev->slog->lvid.s, NULL)))
return_0;
- } else if (rdev->slog_name &&
- sscanf(rdev->slog_name, "%" PRIu32, &slog_size) == 1) {
- slog_flags = DM_CORELOG | DM_FORCESYNC;
- if (slog_size == 0) {
- log_error("Failed to use empty corelog size "
- "in replicator '%s'.",
- rsite->replicator->name);
- return 0;
- }
- } else {
+ } else if (rdev->slog_core || (rsite->site_index == 0)) {
slog_flags = DM_CORELOG | DM_FORCESYNC;
slog_size = 0; /* NOLOG */
+ } else {
+ log_error(INTERNAL_ERROR "Either slog or corelog must be used.");
+ return 0;
}
- if (!dm_tree_node_add_replicator_dev_target(node,
- seg->lv->size,
- replicator_dlid,
- seg->lv->rdevice->device_index,
- rdev_dlid,
- rsite->site_index,
- slog_dlid,
- slog_flags,
- slog_size)) {
+ if (!dm_tree_node_add_replicated_target(node,
+ seg->lv->size,
+ replicator_dlid,
+ seg->lv->rdevice->device_index,
+ rdev_dlid,
+ rsite->site_index,
+ slog_dlid,
+ slog_flags,
+ slog_size)) {
return_0;
/* FIXME: handle 'state = dropped' in future */
}
@@ -706,29 +655,29 @@ static int _replicator_dev_add_target_line(struct dev_manager *dm,
return 1;
}
-/* FIXME: write something useful for replicator-dev here */
-static int _replicator_dev_target_percent(void **target_state,
- percent_range_t *percent_range,
- struct dm_pool *mem,
- struct cmd_context *cmd,
- struct lv_segment *seg,
- char *params,
- uint64_t *total_numerator,
- uint64_t *total_denominator)
+/* FIXME: write something useful for replicated target here */
+static int _replicated_target_percent(void **target_state,
+ percent_range_t *percent_range,
+ struct dm_pool *mem,
+ struct cmd_context *cmd,
+ struct lv_segment *seg,
+ char *params,
+ uint64_t *total_numerator,
+ uint64_t *total_denominator)
{
return 1;
}
/* Check for module presence */
-static int _replicator_dev_target_present(struct cmd_context *cmd,
- const struct lv_segment *seg __attribute__((unused)),
- unsigned *attributes __attribute__((unused)))
+static int _replicated_target_present(struct cmd_context *cmd,
+ const struct lv_segment *seg __attribute__((unused)),
+ unsigned *attributes __attribute__((unused)))
{
static int _checked = 0;
static int _present = 0;
if (!_checked) {
- _present = target_present(cmd, REPLICATOR_DEV_MODULE, 1);
+ _present = target_present(cmd, "replicator-dev", 1);
_checked = 1;
}
@@ -737,15 +686,15 @@ static int _replicator_dev_target_present(struct cmd_context *cmd,
#endif
-static struct segtype_handler _replicator_dev_ops = {
+static struct segtype_handler _replicated_ops = {
.name = _replicator_name,
- .display = _replicator_dev_display,
- .text_import = _replicator_dev_text_import,
- .text_export = _replicator_dev_text_export,
+ .display = _replicated_display,
+ .text_import = _replicated_text_import,
+ .text_export = _replicated_text_export,
#ifdef DEVMAPPER_SUPPORT
- .add_target_line = _replicator_dev_add_target_line,
- .target_percent = _replicator_dev_target_percent,
- .target_present = _replicator_dev_target_present,
+ .add_target_line = _replicated_add_target_line,
+ .target_percent = _replicated_target_percent,
+ .target_present = _replicated_target_present,
#endif
.modules_needed = _replicator_modules_needed,
.destroy = _replicator_destroy,
@@ -766,7 +715,7 @@ int init_multiple_segtype(struct segtype_library *seglib)
segtype->ops = &_replicator_ops;
segtype->name = REPLICATOR_MODULE;
segtype->private = NULL;
- segtype->flags = SEG_REPLICATOR;
+ segtype->flags = SEG_REPLICATOR | SEG_VIRTUAL | SEG_CANNOT_BE_ZEROED;
if (!lvm_register_segtype(seglib, segtype))
return_0;
@@ -776,15 +725,15 @@ int init_multiple_segtype(struct segtype_library *seglib)
if (!(segtype = dm_malloc(sizeof(*segtype))))
return_0;
- segtype->ops = &_replicator_dev_ops;
- segtype->name = REPLICATOR_DEV_MODULE;
+ segtype->ops = &_replicated_ops;
+ segtype->name = REPLICATED_MODULE;
segtype->private = NULL;
- segtype->flags = SEG_REPLICATOR_DEV;
+ segtype->flags = SEG_REPLICATED;
if (!lvm_register_segtype(seglib, segtype))
return_0;
- log_very_verbose("Initialised segtype: " REPLICATOR_DEV_MODULE);
+ log_very_verbose("Initialised segtype: " REPLICATED_MODULE);
return 1;
}
--
1.7.2.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 15/25] Replicator: add new command option read functions
2010-08-08 8:57 [PATCH 00/25] Replicator 100808 Zdenek Kabelac
` (13 preceding siblings ...)
2010-08-08 8:57 ` [PATCH 14/25] Replicator: replicator.c changes Zdenek Kabelac
@ 2010-08-08 8:57 ` Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 16/25] Replicator: new args Zdenek Kabelac
` (9 subsequent siblings)
24 siblings, 0 replies; 26+ messages in thread
From: Zdenek Kabelac @ 2010-08-08 8:57 UTC (permalink / raw)
To: lvm-devel
site_arg - reads name of the site.
sitepolicy_arg - reads site policy.
timeout_arg - reads timeout parameter for fall_hind_timeout.
Signed-off-by: Zdenek Kabelac <zkabelac@redhat.com>
---
tools/lvmcmdline.c | 71 ++++++++++++++++++++++++++++++++++++++++++++++++++++
tools/tools.h | 3 ++
2 files changed, 74 insertions(+), 0 deletions(-)
diff --git a/tools/lvmcmdline.c b/tools/lvmcmdline.c
index 54169ad..fa63fa0 100644
--- a/tools/lvmcmdline.c
+++ b/tools/lvmcmdline.c
@@ -473,6 +473,77 @@ int readahead_arg(struct cmd_context *cmd __attribute__((unused)), struct arg *a
return 1;
}
+int site_arg(struct cmd_context *cmd __attribute__((unused)), struct arg *a)
+{
+ if (!validate_name(a->value)) {
+ log_error("Invalid site name.");
+ return 0;
+ }
+
+ return 1;
+}
+
+int sitepolicy_arg(struct cmd_context *cmd __attribute__((unused)), struct arg *a)
+{
+ struct replicator_site rsite;
+
+ if (!replicator_site_set_policy(&rsite, a->value)) {
+ log_error("Invalid site policy %s.", a->value);
+ return 0;
+ }
+
+ a->ui_value = rsite.policy;
+
+ return 1;
+}
+
+/**
+ * Parsing time string in form: hh:mm:sec
+ * Supported is also format like 3245:34 -> 3245 minutes and 34 seconds
+ * Max supported time value is less then 10000h
+ */
+int timeout_arg(struct cmd_context *cmd __attribute__((unused)), struct arg *a)
+{
+ const char *p = a->value;
+ unsigned hours = 0, mins = 0, secs = 0;
+ unsigned idx = 0;
+
+ while (*p) {
+ if (isdigit(*p)) {
+ secs = secs * 10 + *p - '0';
+ if (idx > 0 && secs > 59)
+ goto err;
+ if (secs > 35999999)
+ goto high;
+ } else if (*p == ':') {
+ if (idx++ > 1)
+ goto err;
+ if (idx == 1) {
+ hours = mins;
+ if (hours > 9999)
+ goto high;
+ }
+ mins = secs;
+ if (mins > 599999)
+ goto high;
+ secs = 0;
+ } else
+ goto err;
+ p++;
+ }
+
+ a->ui_value = hours * 3600 + mins * 60 + secs;
+
+ return 1;
+err:
+ log_error("Invalid time string.");
+ return 0;
+
+high:
+ log_error("Parsed time is too high.");
+ return 0;
+}
+
/*
* Non-zero, positive integer, "all", or "unmanaged"
*/
diff --git a/tools/tools.h b/tools/tools.h
index e9bc850..ac42276 100644
--- a/tools/tools.h
+++ b/tools/tools.h
@@ -153,6 +153,9 @@ int segtype_arg(struct cmd_context *cmd, struct arg *a);
int alloc_arg(struct cmd_context *cmd, struct arg *a);
int readahead_arg(struct cmd_context *cmd, struct arg *a);
int metadatacopies_arg(struct cmd_context *cmd __attribute__((unused)), struct arg *a);
+int site_arg(struct cmd_context *cmd, struct arg *a);
+int sitepolicy_arg(struct cmd_context *cmd, struct arg *a);
+int timeout_arg(struct cmd_context *cmd, struct arg *a);
/* we use the enums to access the switches */
unsigned arg_count(const struct cmd_context *cmd, int a);
--
1.7.2.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 16/25] Replicator: new args
2010-08-08 8:57 [PATCH 00/25] Replicator 100808 Zdenek Kabelac
` (14 preceding siblings ...)
2010-08-08 8:57 ` [PATCH 15/25] Replicator: add new command option read functions Zdenek Kabelac
@ 2010-08-08 8:57 ` Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 17/25] Replicator: update of dev_manager.c Zdenek Kabelac
` (8 subsequent siblings)
24 siblings, 0 replies; 26+ messages in thread
From: Zdenek Kabelac @ 2010-08-08 8:57 UTC (permalink / raw)
To: lvm-devel
Signed-off-by: Zdenek Kabelac <zkabelac@redhat.com>
---
tools/args.h | 10 ++++++++++
1 files changed, 10 insertions(+), 0 deletions(-)
diff --git a/tools/args.h b/tools/args.h
index a23c46c..0b8f436 100644
--- a/tools/args.h
+++ b/tools/args.h
@@ -69,6 +69,16 @@ arg(noudevsync_ARG, '\0', "noudevsync", NULL, 0)
arg(poll_ARG, '\0', "poll", yes_no_arg, 0)
arg(stripes_long_ARG, '\0', "stripes", int_arg, 0)
arg(sysinit_ARG, '\0', "sysinit", NULL, 0)
+arg(fallbehindios_ARG, '\0', "fallbehindios", int_arg, 0)
+arg(fallbehindsize_ARG, '\0', "fallbehindsize", size_mb_arg, 0)
+arg(fallbehindtimeout_ARG, '\0', "fallbehindtimeout", timeout_arg, 0)
+arg(remotevg_ARG, '\0', "remotevg", string_arg, 0)
+arg(replicated_ARG, '\0', "replicated", NULL, 0)
+arg(replicator_ARG, '\0', "replicator", NULL, 0)
+arg(replicatorlogtype_ARG, '\0', "replicatorlogtype", string_arg, 0)
+arg(replicatorsynclog_ARG, '\0', "replicatorsynclog", string_arg, 0)
+arg(site_ARG, '\0', "site", site_arg, 0)
+arg(sitepolicy_ARG, '\0', "sitepolicy", sitepolicy_arg, 0)
/* Allow some variations */
arg(resizable_ARG, '\0', "resizable", yes_no_arg, 0)
--
1.7.2.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 17/25] Replicator: update of dev_manager.c
2010-08-08 8:57 [PATCH 00/25] Replicator 100808 Zdenek Kabelac
` (15 preceding siblings ...)
2010-08-08 8:57 ` [PATCH 16/25] Replicator: new args Zdenek Kabelac
@ 2010-08-08 8:57 ` Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 18/25] Replicator: read site_params Zdenek Kabelac
` (7 subsequent siblings)
24 siblings, 0 replies; 26+ messages in thread
From: Zdenek Kabelac @ 2010-08-08 8:57 UTC (permalink / raw)
To: lvm-devel
Change related to replicator-dev to replicated switch.
Signed-off-by: Zdenek Kabelac <zkabelac@redhat.com>
---
lib/activate/dev_manager.c | 38 +++++++++++++++++++-------------------
1 files changed, 19 insertions(+), 19 deletions(-)
diff --git a/lib/activate/dev_manager.c b/lib/activate/dev_manager.c
index 9b27616..a4dc651 100644
--- a/lib/activate/dev_manager.c
+++ b/lib/activate/dev_manager.c
@@ -927,7 +927,7 @@ static int _add_dev_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
}
/*
- * Add replicator devices
+ * Add replicated devices
*
* Using _add_dev_to_dtree() directly instead of _add_lv_to_dtree()
* to avoid extra checks with extensions.
@@ -937,19 +937,19 @@ static int _add_partial_replicator_to_dtree(struct dev_manager *dm,
struct logical_volume *lv)
{
struct logical_volume *rlv = first_seg(lv)->replicator;
- struct replicator_device *rdev;
+ struct replicated_device *rdev;
struct replicator_site *rsite;
struct dm_tree_node *rep_node, *rdev_node;
const char *uuid;
- if (!lv_is_active_replicator_dev(lv)) {
+ if (!lv_is_active_replicated(lv)) {
if (!_add_dev_to_dtree(dm, dtree, lv->rdevice->lv,
NULL))
return_0;
return 1;
}
- /* Add _rlog and replicator device */
+ /* Add _rlog and replicated device */
if (!_add_dev_to_dtree(dm, dtree, first_seg(rlv)->rlog_lv, NULL))
return_0;
@@ -969,16 +969,16 @@ static int _add_partial_replicator_to_dtree(struct dev_manager *dm,
if (!_add_dev_to_dtree(dm, dtree, rdev->lv, NULL))
return_0;
- /* Add replicator-dev LV, except of the already added one */
- if ((lv != rdev->replicator_dev->lv) &&
+ /* Add replicated LV, except of the already added one */
+ if ((lv != rdev->replicated_seg->lv) &&
!_add_dev_to_dtree(dm, dtree,
- rdev->replicator_dev->lv, NULL))
+ rdev->replicated_seg->lv, NULL))
return_0;
/* If replicator exists - try connect existing heads */
if (rep_node) {
uuid = build_dm_uuid(dm->mem,
- rdev->replicator_dev->lv->lvid.s,
+ rdev->replicated_seg->lv->lvid.s,
NULL);
if (!uuid)
return_0;
@@ -1024,7 +1024,7 @@ static int _add_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree, struc
return_0;
/* Adding LV head of replicator adds all other related devs */
- if (lv_is_replicator_dev(lv) &&
+ if (lv_is_replicated(lv) &&
!_add_partial_replicator_to_dtree(dm, dtree, lv))
return_0;
@@ -1263,15 +1263,15 @@ static int _add_new_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
struct logical_volume *lv, const char *layer);
/* Add all replicators' LVs */
-static int _add_replicator_dev_target_to_dtree(struct dev_manager *dm,
+static int _add_replicated_seg_target_to_dtree(struct dev_manager *dm,
struct dm_tree *dtree,
struct lv_segment *seg)
{
- struct replicator_device *rdev;
+ struct replicated_device *rdev;
struct replicator_site *rsite;
/* For inactive replicator add linear mapping */
- if (!lv_is_active_replicator_dev(seg->lv)) {
+ if (!lv_is_active_replicated(seg->lv)) {
if (!_add_new_lv_to_dtree(dm, dtree, seg->lv->rdevice->lv, NULL))
return_0;
return 1;
@@ -1285,7 +1285,7 @@ static int _add_replicator_dev_target_to_dtree(struct dev_manager *dm,
!_add_new_lv_to_dtree(dm, dtree, seg->replicator, NULL))
return_0;
- /* Activation of one replicator_dev node activates all other nodes */
+ /* Activation of one replicated node activates all other nodes */
dm_list_iterate_items(rsite, &seg->replicator->rsites) {
dm_list_iterate_items(rdev, &rsite->rdevices) {
if (rdev->lv &&
@@ -1298,17 +1298,17 @@ static int _add_replicator_dev_target_to_dtree(struct dev_manager *dm,
return_0;
}
}
- /* Add remaining replicator-dev nodes in the second loop
+ /* Add remaining replicated nodes in the second loop
* to avoid multiple retries for inserting all elements */
dm_list_iterate_items(rsite, &seg->replicator->rsites) {
if (rsite->state != REPLICATOR_STATE_ACTIVE)
continue;
dm_list_iterate_items(rdev, &rsite->rdevices) {
- if (rdev->replicator_dev->lv == seg->lv)
+ if (rdev->replicated_seg->lv == seg->lv)
continue;
- if (!rdev->replicator_dev->lv ||
+ if (!rdev->replicated_seg->lv ||
!_add_new_lv_to_dtree(dm, dtree,
- rdev->replicator_dev->lv,
+ rdev->replicated_seg->lv,
NULL))
return_0;
}
@@ -1347,8 +1347,8 @@ static int _add_segment_to_dtree(struct dev_manager *dm,
!_add_new_lv_to_dtree(dm, dtree, seg->log_lv, NULL))
return_0;
- if (seg_is_replicator_dev(seg)) {
- if (!_add_replicator_dev_target_to_dtree(dm, dtree, seg))
+ if (seg_is_replicated(seg)) {
+ if (!_add_replicated_seg_target_to_dtree(dm, dtree, seg))
return_0;
/* If this is a snapshot origin, add real LV */
/* If this is a snapshot origin + merging snapshot, add cow + real LV */
--
1.7.2.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 18/25] Replicator: read site_params
2010-08-08 8:57 [PATCH 00/25] Replicator 100808 Zdenek Kabelac
` (16 preceding siblings ...)
2010-08-08 8:57 ` [PATCH 17/25] Replicator: update of dev_manager.c Zdenek Kabelac
@ 2010-08-08 8:57 ` Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 19/25] Replicator: lv_manip - create replicator Zdenek Kabelac
` (6 subsequent siblings)
24 siblings, 0 replies; 26+ messages in thread
From: Zdenek Kabelac @ 2010-08-08 8:57 UTC (permalink / raw)
To: lvm-devel
Common function for parsing replicator site parameters.
It's used by lvcreate and lvchange commands.
Signed-off-by: Zdenek Kabelac <zkabelac@redhat.com>
---
tools/toollib.c | 103 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-
tools/toollib.h | 3 ++
2 files changed, 105 insertions(+), 1 deletions(-)
diff --git a/tools/toollib.c b/tools/toollib.c
index bdb52d5..6205c2f 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -1,6 +1,6 @@
/*
* Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
- * Copyright (C) 2004-2009 Red Hat, Inc. All rights reserved.
+ * Copyright (C) 2004-2010 Red Hat, Inc. All rights reserved.
*
* This file is part of LVM2.
*
@@ -1551,3 +1551,104 @@ int get_stripe_params(struct cmd_context *cmd, uint32_t *stripes, uint32_t *stri
return _validate_stripe_params(cmd, stripes, stripe_size);
}
+/**
+ * Parse parameters for replicator site
+ *
+ * \param cmd
+ * \param rsite
+ * \param changed
+ */
+int get_replicator_site_params(struct cmd_context *cmd,
+ struct replicator_site *rsite,
+ int *changed)
+{
+ struct replicator_site nrsite;
+
+ if (((arg_count(cmd, fallbehindios_ARG) > 0) +
+ (arg_count(cmd, fallbehindsize_ARG) > 0) +
+ (arg_count(cmd, fallbehindtimeout_ARG) > 0)) > 1) {
+ log_error("Only one asynchronous parameter can be used.");
+ return 0;
+ }
+
+ if (arg_count(cmd, fallbehindios_ARG)) {
+ nrsite.fall_behind_ios =
+ arg_uint_value(cmd, fallbehindios_ARG,
+ DEFAULT_REPLICATOR_FALL_BEHIND_IOS);
+
+ if (rsite->fall_behind_ios != nrsite.fall_behind_ios) {
+ rsite->fall_behind_ios = nrsite.fall_behind_ios;
+ rsite->fall_behind_size = 0;
+ rsite->fall_behind_timeout = 0;
+ (*changed)++;
+ }
+ } else if (arg_count(cmd, fallbehindsize_ARG)) {
+ nrsite.fall_behind_size =
+ arg_uint64_value(cmd, fallbehindsize_ARG,
+ DEFAULT_REPLICATOR_FALL_BEHIND_SIZE);
+
+ if (rsite->fall_behind_size != nrsite.fall_behind_size) {
+ rsite->fall_behind_ios = 0;
+ rsite->fall_behind_size = nrsite.fall_behind_size;
+ rsite->fall_behind_timeout = 0;
+ (*changed)++;
+ }
+ } else if (arg_count(cmd, fallbehindtimeout_ARG)) {
+ nrsite.fall_behind_timeout =
+ arg_uint_value(cmd, fallbehindtimeout_ARG,
+ DEFAULT_REPLICATOR_FALL_BEHIND_TIMEOUT);
+
+ if (rsite->fall_behind_timeout != nrsite.fall_behind_timeout) {
+ rsite->fall_behind_ios = 0;
+ rsite->fall_behind_size = 0;
+ rsite->fall_behind_timeout = nrsite.fall_behind_timeout;
+ (*changed)++;
+ }
+ }
+
+ nrsite.policy = NUM_DM_REPLICATOR_POLICIES;
+ if (arg_count(cmd, sitepolicy_ARG)) {
+ nrsite.policy = arg_uint_value(cmd, sitepolicy_ARG,
+ DEFAULT_REPLICATOR_SITE_POLICY);
+ if ((nrsite.policy == DM_REPLICATOR_SYNC) &&
+ !arg_count(cmd, fallbehindios_ARG) &&
+ !arg_count(cmd, fallbehindsize_ARG) &&
+ !arg_count(cmd, fallbehindtimeout_ARG) &&
+ (rsite->fall_behind_ios ||
+ rsite->fall_behind_size ||
+ rsite->fall_behind_timeout)) {
+ rsite->fall_behind_ios = 0;
+ rsite->fall_behind_size = 0;
+ rsite->fall_behind_timeout = 0;
+ (*changed)++;
+ log_debug("Clearing asynchronous parameters synchronous site.");
+ }
+ }
+
+ if (rsite->fall_behind_ios ||
+ rsite->fall_behind_size ||
+ rsite->fall_behind_timeout) {
+ if (nrsite.policy == DM_REPLICATOR_SYNC) {
+ log_error("For synchronous site policy all asynchronous "
+ "parameters must be deleted.");
+ return 0;
+ } else if (nrsite.policy == NUM_DM_REPLICATOR_POLICIES)
+ nrsite.policy = (rsite->policy == DM_REPLICATOR_SYNC) ?
+ DEFAULT_REPLICATOR_SITE_POLICY : rsite->policy;
+ } else {
+ if (nrsite.policy != NUM_DM_REPLICATOR_POLICIES &&
+ nrsite.policy != DM_REPLICATOR_SYNC) {
+ log_error("For asynchronous site policy an asynchronous "
+ "non-zero parameter must be specified.");
+ return 0;
+ }
+ nrsite.policy = DM_REPLICATOR_SYNC;
+ }
+
+ if (rsite->policy != nrsite.policy) {
+ rsite->policy = nrsite.policy;
+ (*changed)++;
+ }
+
+ return 1;
+}
diff --git a/tools/toollib.h b/tools/toollib.h
index 71e516f..47f1d4d 100644
--- a/tools/toollib.h
+++ b/tools/toollib.h
@@ -115,4 +115,7 @@ int get_activation_monitoring_mode(struct cmd_context *cmd,
int get_stripe_params(struct cmd_context *cmd, uint32_t *stripes,
uint32_t *stripe_size);
+int get_replicator_site_params(struct cmd_context *cmd,
+ struct replicator_site *rsite,
+ int *changed);
#endif
--
1.7.2.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 19/25] Replicator: lv_manip - create replicator
2010-08-08 8:57 [PATCH 00/25] Replicator 100808 Zdenek Kabelac
` (17 preceding siblings ...)
2010-08-08 8:57 ` [PATCH 18/25] Replicator: read site_params Zdenek Kabelac
@ 2010-08-08 8:57 ` Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 20/25] Replicator: lvcreate implementation Zdenek Kabelac
` (5 subsequent siblings)
24 siblings, 0 replies; 26+ messages in thread
From: Zdenek Kabelac @ 2010-08-08 8:57 UTC (permalink / raw)
To: lvm-devel
Signed-off-by: Zdenek Kabelac <zkabelac@redhat.com>
---
lib/metadata/lv_manip.c | 124 +++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 124 insertions(+), 0 deletions(-)
diff --git a/lib/metadata/lv_manip.c b/lib/metadata/lv_manip.c
index 52c80c4..8375fb6 100644
--- a/lib/metadata/lv_manip.c
+++ b/lib/metadata/lv_manip.c
@@ -418,6 +418,8 @@ static int _lv_reduce(struct logical_volume *lv, uint32_t extents, int delete)
/* FIXME Check this is safe */
if (seg->log_lv && !lv_remove(seg->log_lv))
return_0;
+ if (seg->rlog_lv && !lv_remove(seg->rlog_lv))
+ return_0;
dm_list_del(&seg->list);
reduction = seg->len;
} else
@@ -2205,6 +2207,7 @@ int lv_remove_single(struct cmd_context *cmd, struct logical_volume *lv,
struct volume_group *vg;
struct lvinfo info;
struct logical_volume *origin = NULL;
+ struct logical_volume *replicator = NULL;
int was_merging = 0;
vg = lv->vg;
@@ -2230,6 +2233,12 @@ int lv_remove_single(struct cmd_context *cmd, struct logical_volume *lv,
return 0;
}
+ if (lv_is_rimage(lv) || lv_is_rlog(lv) || lv_is_slog(lv)) {
+ log_error("Can't remove logical volume %s used by a "
+ "replicator.", lv->name);
+ return 0;
+ }
+
if (lv->status & LOCKED) {
log_error("Can't remove locked LV %s", lv->name);
return 0;
@@ -2267,6 +2276,14 @@ int lv_remove_single(struct cmd_context *cmd, struct logical_volume *lv,
return_0;
}
+ if (lv_is_replicated(lv)) {
+ replicator = first_seg(lv)->replicator;
+ if (!lv_remove_replicated(lv)) {
+ log_error("Unable to remove replicated logical volume \"%s\"", lv->name);
+ return 0;
+ }
+ }
+
if (!deactivate_lv(cmd, lv)) {
log_error("Unable to deactivate logical volume \"%s\"",
lv->name);
@@ -2295,6 +2312,17 @@ int lv_remove_single(struct cmd_context *cmd, struct logical_volume *lv,
}
}
+ if (replicator) {
+ if (!suspend_lv(cmd, replicator)) {
+ log_error("Failed to refresh replicator %s.", replicator->name);
+ return 0;
+ }
+ if (!resume_lv(cmd, replicator)) {
+ log_error("Failed to resume replicator %s.", replicator->name);
+ return 0;
+ }
+ }
+
backup(vg);
if (lv_is_visible(lv))
@@ -2310,6 +2338,8 @@ int lv_remove_with_dependencies(struct cmd_context *cmd, struct logical_volume *
const force_t force, unsigned level)
{
struct dm_list *snh, *snht;
+ struct replicator_site *rsite;
+ struct replicated_device *rdev;
if (lv_is_cow(lv)) {
/* A merging snapshot cannot be removed directly */
@@ -2320,6 +2350,18 @@ int lv_remove_with_dependencies(struct cmd_context *cmd, struct logical_volume *
}
}
+ if (lv_is_replicator(lv)) {
+ /* Remove replicators' head LVs first */
+ dm_list_iterate_items(rsite, &lv->rsites) {
+ if (rsite->site_index != 0)
+ continue;
+ dm_list_iterate_items(rdev, &rsite->rdevices)
+ if (!lv_remove_with_dependencies(cmd, rdev->lv,
+ force, level + 1))
+ return_0;
+ }
+ }
+
if (lv_is_origin(lv)) {
/* remove snapshot LVs first */
dm_list_iterate_safe(snh, snht, &lv->snapshot_segs) {
@@ -2998,6 +3040,7 @@ int lv_create_single(struct volume_group *vg,
struct logical_volume *lv, *org = NULL;
int origin_active = 0;
struct lvinfo info;
+ struct logical_volume *replicator;
if (lp->lv_name && find_lv_in_vg(vg, lp->lv_name)) {
log_error("Logical volume \"%s\" already exists in "
@@ -3118,6 +3161,13 @@ int lv_create_single(struct volume_group *vg,
}
}
+ if (lp->replicator) {
+ if (!vg_prearrange_replicator(vg, lp))
+ return_0;
+ if (lp->rsite.name && !lp->replicated)
+ return 1; /* Do not create any LV this time */
+ }
+
if (!lp->extents) {
log_error("Unable to create new logical volume with no extents");
return 0;
@@ -3169,6 +3219,19 @@ int lv_create_single(struct volume_group *vg,
}
}
+ if (lp->replicated) {
+ init_replicator_in_sync(lp->nosync);
+
+ if (lp->nosync) {
+ log_error("FIXME: Unsupported.");
+ return 0;
+
+ log_warn("WARNING: New replicator won't be synchronised. "
+ "Don't read what you didn't write!");
+ status |= REPLICATOR_NOTSYNCED;
+ }
+ }
+
if (!(lv = lv_create_empty(lp->lv_name ? lp->lv_name : "lvol%d", NULL,
status, lp->alloc, vg)))
return_0;
@@ -3225,6 +3288,12 @@ int lv_create_single(struct volume_group *vg,
"exception store.");
goto revert_new_lv;
}
+ } else if (lp->replicated || lp->replicator) {
+ if (!activate_lv_excl(cmd, lv)) {
+ log_error("Aborting. Failed to activate replicator "
+ "device.");
+ goto revert_new_lv;
+ }
} else if (!activate_lv(cmd, lv)) {
if (lp->zero) {
log_error("Aborting. Failed to activate new LV to wipe "
@@ -3239,11 +3308,66 @@ int lv_create_single(struct volume_group *vg,
log_warn("WARNING: \"%s\" not zeroed", lv->name);
else if (!set_lv(cmd, lv, UINT64_C(0), 0)) {
log_error("Aborting. Failed to wipe %s.",
+ lp->replicator ? "replicator backing store" :
lp->snapshot ? "snapshot exception store" :
"start of new LV");
goto deactivate_and_revert_new_lv;
}
+ if (!lp->replicated && lp->replicator) {
+ if (!deactivate_lv(cmd, lv)) {
+ log_error("Aborting. Couldn't deactivate replicator log."
+ " Manual intervention required.");
+ return 0;
+ }
+ if (!vg_add_replicator(lv, lp->rlog_type, lp->region_size)) {
+ log_error("Could not create replicator.");
+ goto revert_new_lv;
+ }
+ /* store vg on disk(s) */
+ if (!vg_write(vg) || !vg_commit(vg))
+ return_0;
+ }
+
+ if (lp->replicated) {
+ if (!lp->replicator) {
+ log_error("Replicator is not specified.");
+ return 0;
+ }
+ if (!deactivate_lv(cmd, lv)) {
+ log_error("Aborting. Could not deactivate new LV.");
+ return 0;
+ }
+
+ if (!(replicator = find_lv(vg, lp->replicator))) {
+ log_error("Could not find replicator.");
+ goto revert_new_lv;
+ }
+
+ if (!lv_add_replicated(replicator, lv)) {
+ log_error("Could not add replicated device to replicator.");
+ goto revert_new_lv;
+ }
+
+ /* store vg on disk(s) */
+ if (!vg_write(vg))
+ return_0;
+
+ if (!suspend_lv(cmd, replicator)) {
+ log_error("Failed to suspend replicator %s", replicator->name);
+ vg_revert(vg);
+ return 0;
+ }
+
+ if (!vg_commit(vg))
+ return_0;
+
+ if (!resume_lv(cmd, replicator)) {
+ log_error("Problem reactivating replicator %s", replicator->name);
+ return 0;
+ }
+ }
+
if (lp->snapshot) {
/* Reset permission after zeroing */
if (!(lp->permission & LVM_WRITE))
--
1.7.2.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 20/25] Replicator: lvcreate implementation
2010-08-08 8:57 [PATCH 00/25] Replicator 100808 Zdenek Kabelac
` (18 preceding siblings ...)
2010-08-08 8:57 ` [PATCH 19/25] Replicator: lv_manip - create replicator Zdenek Kabelac
@ 2010-08-08 8:57 ` Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 21/25] Replicator: man page update for lvcreate Zdenek Kabelac
` (4 subsequent siblings)
24 siblings, 0 replies; 26+ messages in thread
From: Zdenek Kabelac @ 2010-08-08 8:57 UTC (permalink / raw)
To: lvm-devel
Signed-off-by: Zdenek Kabelac <zkabelac@redhat.com>
---
tools/commands.h | 11 ++++-
tools/lvcreate.c | 138 ++++++++++++++++++++++++++++++++++++++++++++++++++++-
2 files changed, 145 insertions(+), 4 deletions(-)
diff --git a/tools/commands.h b/tools/commands.h
index d9e13f4..595da54 100644
--- a/tools/commands.h
+++ b/tools/commands.h
@@ -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.
*
@@ -165,6 +165,12 @@ xx(lvcreate,
"\t[-p|--permission {r|rw}]\n"
"\t[-r|--readahead ReadAheadSectors|auto|none]\n"
"\t[-R|--regionsize MirrorLogRegionSize]\n"
+ "\t[--replicator [ReplicatorName] [--replicatorlogtype ringbuffer]\n"
+ "\t[{--replicatorsynclog {disk|core}|--corelog}]\n"
+ "\t[--site LocalSiteName [--sitepolicy {sync|warn|stall|drop|fail}]\n"
+ "\t [--remotevg RemoteVGName] [{--fallbehindsize Size[bBsSkKmMgG]|\n"
+ "\t --fallbehindios IOCount|--fallbehindtimeout Secs}]]\n"
+ "\t[--replicatordev]\n"
"\t[-t|--test]\n"
"\t[--type VolumeType]\n"
"\t[-v|--verbose]\n"
@@ -203,6 +209,9 @@ xx(lvcreate,
mirrorlog_ARG, mirrors_ARG, monitor_ARG, name_ARG, nosync_ARG, noudevsync_ARG,
permission_ARG, persistent_ARG, readahead_ARG, regionsize_ARG, size_ARG,
snapshot_ARG, stripes_ARG, stripesize_ARG, test_ARG, type_ARG,
+ fallbehindios_ARG, fallbehindsize_ARG, fallbehindtimeout_ARG,
+ remotevg_ARG, replicated_ARG, replicator_ARG, replicatorlogtype_ARG,
+ site_ARG, sitepolicy_ARG,
virtualoriginsize_ARG, virtualsize_ARG, zero_ARG)
xx(lvdisplay,
diff --git a/tools/lvcreate.c b/tools/lvcreate.c
index de5b59c..d89678f 100644
--- a/tools/lvcreate.c
+++ b/tools/lvcreate.c
@@ -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.
*
@@ -64,9 +64,33 @@ static int _lvcreate_name_params(struct lvcreate_params *lp,
log_error("Please provide a volume group name");
return 0;
}
-
} else {
vg_name = skip_dev_dir(cmd, argv[0], NULL);
+ if (lp->replicator || lp->replicated) {
+ /*
+ * support with following combinations
+ * --replicator -n lv ... vg
+ * --replicator ... vg/rep_lv
+ * --site site --replicator ... vg/rep_lv
+ * --replicated -n lv --replicator ... vg/rep_lv
+ */
+ if (!(ptr = strrchr(vg_name, '/'))) {
+ if (!lp->lv_name || lp->replicated) {
+ log_error("Replicator logical volume name "
+ "expected with volume group name.");
+ return 0;
+ }
+ } else {
+ ptr[0] = '\0';
+ lp->replicator = ptr + 1;
+ }
+
+ if (!lp->lv_name &&
+ !lp->replicated &&
+ lp->replicator[0])
+ lp->lv_name = lp->replicator;
+ }
+
if (strrchr(vg_name, '/')) {
log_error("Volume group name expected "
"(no slash)");
@@ -311,7 +335,84 @@ static int _read_mirror_params(struct lvcreate_params *lp,
}
if (!_validate_mirror_params(cmd, lp))
+ return_0;
+
+ return 1;
+}
+
+static int _read_replicator_params(struct lvcreate_params *lp,
+ struct cmd_context *cmd)
+{
+ int region_size;
+ const char *replicatorsynclog;
+ int corelog = arg_count(cmd, corelog_ARG);
+ int changed;
+
+ if (arg_count(cmd, sitepolicy_ARG)) {
+ log_error("FIXME: Sorry, site policy parameter is not yet supported.");
return 0;
+ }
+
+ replicatorsynclog = arg_str_value(cmd, replicatorsynclog_ARG,
+ corelog ? "core" : DEFAULT_REPLICATOR_SYNCLOG);
+
+ if (strcmp("core", replicatorsynclog) && corelog) {
+ log_error("Please use only one of --replicatorlog or --corelog.");
+ return 0;
+ }
+
+ if (!strcmp("disk", replicatorsynclog))
+ lp->log_count = 1;
+ else if (!strcmp("core", replicatorsynclog))
+ lp->log_count = 0;
+ else {
+ log_error("Unknown replicatorsynclog type: %s.", replicatorsynclog);
+ return 0;
+ }
+
+ log_verbose("Setting sync logging type to %s", replicatorsynclog);
+ if (arg_count(cmd, regionsize_ARG)) {
+ if (arg_sign_value(cmd, regionsize_ARG, 0) == SIGN_MINUS) {
+ log_error("Negative regionsize is invalid.");
+ return 0;
+ }
+ lp->region_size = arg_uint_value(cmd, regionsize_ARG, 0);
+ } else {
+ region_size = 2 * find_config_tree_int(cmd,
+ "activation/replicator_region_size",
+ DEFAULT_REPLICATOR_REGION_SIZE);
+ if (region_size < 0) {
+ log_error("Negative replicator_region_size in configuration "
+ "file is invalid.");
+ return 0;
+ }
+ lp->region_size = region_size;
+ }
+
+ if (!_validate_mirror_params(cmd, lp)) /* reuse for mirror's region_size */
+ return 0;
+
+ lp->rlog_type = arg_str_value(cmd, replicatorlogtype_ARG,
+ DEFAULT_REPLICATOR_LOG_TYPE);
+
+ if (strcmp(lp->rlog_type, DEFAULT_REPLICATOR_LOG_TYPE)) {
+ log_error("Unsupported replicator log type %s.", lp->rlog_type);
+ return 0;
+ }
+
+ if (arg_count(cmd, remotevg_ARG))
+ lp->rsite.vg_name = arg_str_value(cmd, remotevg_ARG, NULL);
+
+ if (arg_count(cmd, site_ARG)) {
+ lp->rsite.name = arg_str_value(cmd, site_ARG,
+ DEFAULT_REPLICATOR_LOCAL_SITE_NAME);
+ lp->lv_name = NULL; /* cannot create LV when creating site */
+ /* FIXME: improve lv_create_single to handle --site case */
+ }
+
+ lp->rsite.policy = DM_REPLICATOR_SYNC;
+ if (!get_replicator_site_params(cmd, &lp->rsite, &changed))
+ return_0;
return 1;
}
@@ -323,6 +424,7 @@ static int _lvcreate_params(struct lvcreate_params *lp,
{
int contiguous;
unsigned pagesize;
+ int i;
memset(lp, 0, sizeof(*lp));
memset(lcp, 0, sizeof(*lcp));
@@ -342,6 +444,12 @@ static int _lvcreate_params(struct lvcreate_params *lp,
if (seg_is_mirrored(lp))
lp->mirrors = 2;
+ if (seg_is_replicator(lp) || arg_count(cmd, replicator_ARG))
+ lp->replicator = ""; /* later set replicator name */
+
+ if (seg_is_replicated(lp) || arg_count(cmd, replicated_ARG))
+ lp->replicated = 1;
+
if (arg_count(cmd, mirrors_ARG)) {
lp->mirrors = arg_uint_value(cmd, mirrors_ARG, 0) + 1;
if (lp->mirrors == 1)
@@ -379,7 +487,7 @@ static int _lvcreate_params(struct lvcreate_params *lp,
}
}
- if (lp->mirrors > 1) {
+ if (lp->mirrors > 1 || lp->replicator) {
if (lp->snapshot) {
log_error("mirrors and snapshots are currently "
"incompatible");
@@ -405,6 +513,29 @@ static int _lvcreate_params(struct lvcreate_params *lp,
}
}
+ if (!lp->replicator) {
+ static const struct {
+ const char str[20]; // carefull
+ int argname;
+ } repargs[] = {
+ { "fallbehindsize", fallbehindsize_ARG },
+ { "fallbehindios", fallbehindios_ARG },
+ { "fallbehindtimeout", fallbehindtimeout_ARG },
+ { "remotevg", remotevg_ARG },
+ { "replicatorlogtype", replicatorlogtype_ARG },
+ { "replicatorsynclog", replicatorsynclog_ARG },
+ { "site", site_ARG },
+ { "sitepolicy", sitepolicy_ARG }
+ };
+
+ for (i = 0; i < sizeof(repargs)/sizeof(repargs[0]); ++i)
+ if (arg_count(cmd, repargs[i].argname)) {
+ log_error("--%s is only available "
+ "with replicators.", repargs[i].str);
+ return 0;
+ }
+ }
+
if (activation() && lp->segtype->ops->target_present &&
!lp->segtype->ops->target_present(cmd, NULL, NULL)) {
log_error("%s: Required device-mapper target(s) not "
@@ -419,6 +550,7 @@ static int _lvcreate_params(struct lvcreate_params *lp,
if (!_lvcreate_name_params(lp, cmd, &argc, &argv) ||
!_read_size_params(lp, lcp, cmd) ||
!get_stripe_params(cmd, &lp->stripes, &lp->stripe_size) ||
+ !_read_replicator_params(lp, cmd) ||
!_read_mirror_params(lp, cmd))
return_0;
--
1.7.2.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 21/25] Replicator: man page update for lvcreate
2010-08-08 8:57 [PATCH 00/25] Replicator 100808 Zdenek Kabelac
` (19 preceding siblings ...)
2010-08-08 8:57 ` [PATCH 20/25] Replicator: lvcreate implementation Zdenek Kabelac
@ 2010-08-08 8:57 ` Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 22/25] Replicator: lvchange implementation Zdenek Kabelac
` (3 subsequent siblings)
24 siblings, 0 replies; 26+ messages in thread
From: Zdenek Kabelac @ 2010-08-08 8:57 UTC (permalink / raw)
To: lvm-devel
Update man page to cover basic usage of lvcreate
Current descriptions shows how to create replicator,
add site, add replicated device.
Signed-off-by: Zdenek Kabelac <zkabelac@redhat.com>
---
man/lvcreate.8.in | 75 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 75 insertions(+), 0 deletions(-)
diff --git a/man/lvcreate.8.in b/man/lvcreate.8.in
index 0d0976f..9b33414 100644
--- a/man/lvcreate.8.in
+++ b/man/lvcreate.8.in
@@ -36,6 +36,26 @@ VolumeGroupName [PhysicalVolumePath[:PE[-PE]]...]
OriginalLogicalVolumePath |
[\-s|\-\-snapshot]
VolumeGroupName \-\-virtualsize VirtualSize}
+.br
+
+.br
+.B lvcreate
+[\-\-replicator] [\-\-replicated]
+{\-l|\-\-extents LogicalExtentsNumber[%{VG|FREE|ORIGIN}] |
+ \-L|\-\-size LogicalVolumeSize[bBsSkKmMgGtTpPeE]}
+[\-\-nosync]
+[\-\-replicatorlogtype ReplicatorLogType]
+{[\-\-replicatorsynclog {disk|core}] | [\-\-corelog]}
+[\-R|\-\-regionsize ReplicatorSyncLogRegionSize]]
+[\-\-site SiteName [\-\-sitepolicy {sync|warn|stall|drop|fail}]
+{[\-\-fallbehindios IOS] |
+[\-\-fallbehindsize Size[bBsSkKmMgGtTpPeE]] |
+[\-\-fallbehindtimeout timeout]}
+[\-\-remotevg RemoteVolumeGroupName]]
+\-n|\-\-name ReplicatorName
+VolumeGroupName/ReplicatorNamePath
+.br
+
.SH DESCRIPTION
lvcreate creates a new logical volume in a volume group ( see
.B vgcreate(8), vgchange(8)
@@ -52,6 +72,8 @@ extents will be restricted to these volumes.
.br
The second form supports the creation of snapshot logical volumes which
keep the contents of the original logical volume for backup purposes.
+.br
+The third form supports the creation of replicated devices.
.SH OPTIONS
See \fBlvm\fP for common options.
.TP
@@ -120,6 +142,40 @@ device is activated, for example, after every reboot. Using "mirrored"
will create a persistent log that is itself mirrored.
The optional argument --corelog is equivalent to --mirrorlog core.
+.TP
+.I \-\-replicator
+Creates empty replicator logical volume. (see \fBlvchange\fP(8)) for
+options, how to customize created replicator LV.
+Specifying optional argument --nosync will cause the creation
+of the replicator to skip the initial resynchronization. Any data written
+afterwards will be replicated, but the original content will not be
+copied. This is useful for skipping a potentially long and resource
+intensive initial sync of an empty device. Currrently this flag is not
+supported.
+
+The optional argument --replicatorsynclog specifies the type of synclog to be
+used. The default is disk, which is persistent and requires a small amount of
+storage space. Using core means the replicator is regenerated by copying the
+data from the first device again each time the device is activated, for
+example, after every reboot.
+
+The optional argument --replicatorlogtype specifies type of the backing store
+log. The default and currently the only valid and supported type is
+\fBringbuffer\fP.
+
+The optional argument --site creates \fIsite\fP in replicator. Site has policy
+{sync|warn|stall|drop|fail}. For asynchronous modes one
+of the following fall behind parameters must be specified: --fallbehindios,
+--fallbehindsize, --fallbehindtimeout (see \fBlvchange\fP(8)).
+For remote sites --remotevg specifies the name of
+the remote volume group. Note: current implementation expects
+that any remote volume group contains prepared logical volumes
+with the same size and name as the local replicated logical volumes.
+
+.TP
+.I \-\-replicated
+Creates empty replicated logical volume in the local site
+of given Replicator.
.TP
.I \-n, \-\-name LogicalVolumeName
@@ -246,10 +302,29 @@ under 100MB of actual data on it.
creates a linear logical volume "vg00/lvol1" using physical extents
/dev/sda:0-7 and /dev/sdb:0-7 for allocation of extents.
+"lvcreate --replicator -L 1G -n rep0 vg00"
+.br
+creates a replicator "vg00/rep0" and hidden replicator backing store device
+"vg00/rep0_rlog" of size 1G.
+
+"lvcreate --site Remote --remotevg remotevg00 --fallbehindsize 100M
+--replicator vg00/rep0"
+.br
+creates the remote site named Remote in replicator "vg00/rep0"
+that uses remote volume group "remotevg00" and could get upto 100MiB
+asynchronous behind replicated volume.
+Current implementation needs remote LVs created by hand
+in the remote volume group "remotevg00".
+
+"lvcreate --replicated -n lvol1 -L 64M vg00/rep0"
+.br
+creates a replicated device named "vg00/lvol1" of size 64M attached to
+the local site in the replicator "vg00/rep0".
.SH SEE ALSO
.BR lvm (8),
.BR vgcreate (8),
+.BR lvchange (8),
.BR lvremove (8),
.BR lvrename (8)
.BR lvextend (8),
--
1.7.2.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 22/25] Replicator: lvchange implementation
2010-08-08 8:57 [PATCH 00/25] Replicator 100808 Zdenek Kabelac
` (20 preceding siblings ...)
2010-08-08 8:57 ` [PATCH 21/25] Replicator: man page update for lvcreate Zdenek Kabelac
@ 2010-08-08 8:57 ` Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 23/25] Replicator: man page update for lvchange Zdenek Kabelac
` (2 subsequent siblings)
24 siblings, 0 replies; 26+ messages in thread
From: Zdenek Kabelac @ 2010-08-08 8:57 UTC (permalink / raw)
To: lvm-devel
Signed-off-by: Zdenek Kabelac <zkabelac@redhat.com>
---
tools/commands.h | 6 ++
tools/lvchange.c | 195 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
2 files changed, 196 insertions(+), 5 deletions(-)
diff --git a/tools/commands.h b/tools/commands.h
index 595da54..a2b6690 100644
--- a/tools/commands.h
+++ b/tools/commands.h
@@ -80,6 +80,10 @@ xx(lvchange,
"\t[-r|--readahead ReadAheadSectors|auto|none]\n"
"\t[--refresh]\n"
"\t[--resync]\n"
+ "\t[--replicator ReplicatorName]\n"
+ "\t[--site SiteName [--sitepolicy {sync|warn|stall|drop|fail}]\n"
+ "\t [{--fallbehindios IOCount|--fallbehindsize Size[bBsSkKmMgG]|\n"
+ "\t --fallbehindtimeout Secs}]]]\n"
"\t[--sysinit]\n"
"\t[-t|--test]\n"
"\t[-v|--verbose]\n"
@@ -91,6 +95,8 @@ xx(lvchange,
ignorelockingfailure_ARG, ignoremonitoring_ARG, major_ARG, minor_ARG,
monitor_ARG, noudevsync_ARG, partial_ARG, permission_ARG, persistent_ARG,
poll_ARG, readahead_ARG, resync_ARG, refresh_ARG, addtag_ARG, deltag_ARG,
+ fallbehindios_ARG, fallbehindsize_ARG, fallbehindtimeout_ARG,
+ remotevg_ARG, replicator_ARG, replicatorlogtype_ARG, site_ARG, sitepolicy_ARG,
sysinit_ARG, test_ARG, yes_ARG)
xx(lvconvert,
diff --git a/tools/lvchange.c b/tools/lvchange.c
index 4186b53..f3b5f67 100644
--- a/tools/lvchange.c
+++ b/tools/lvchange.c
@@ -15,6 +15,11 @@
#include "tools.h"
+/* Internal data storage used for process_each_lv callbacks */
+struct lvchange_data {
+ struct dm_list activate_names;
+};
+
static int lvchange_permission(struct cmd_context *cmd,
struct logical_volume *lv)
{
@@ -514,12 +519,153 @@ static int lvchange_tag(struct cmd_context *cmd, struct logical_volume *lv,
return 1;
}
+static int lvchange_site(struct cmd_context *cmd, struct logical_volume *lv,
+ int *skip_available, int *changed)
+{
+ struct lvinfo info;
+ struct replicator_site nrsite;
+ struct logical_volume *replicator;
+ struct replicator_site *rsite;
+ const char *replicator_name, *trname;
+ int active;
+
+ *changed = 0;
+ replicator = (lv_is_replicator(lv)) ? lv : first_seg(lv)->replicator;
+ rsite = find_local_site_in_replicator(replicator);
+
+ if (arg_count(cmd, replicator_ARG)) {
+ if (lv == replicator) {
+ log_error("Replicator specified twice.");
+ return 0;
+ }
+ replicator_name = arg_str_value(cmd, replicator_ARG, "");
+ /* Strip the volume group from the replicator */
+ if ((trname = strrchr(replicator_name, (int)'/')))
+ replicator_name = trname + 1;
+ /* Skip different replicator */
+ if (strcmp(replicator->name, replicator_name)) {
+ log_debug("Replicator %s/%s name does not match %s.",
+ replicator->name, lv->name, replicator_name);
+ return 1;
+ }
+ }
+
+ if (arg_count(cmd, site_ARG)) {
+ nrsite.name = arg_str_value(cmd, site_ARG,
+ DEFAULT_REPLICATOR_LOCAL_SITE_NAME);
+
+ /* Skip different replicator */
+ if (!(rsite = find_site_in_replicator(replicator, nrsite.name))) {
+ log_debug("Replicator %s/%s does not have site %s.",
+ replicator->name, lv->name, nrsite.name);
+ return 1;
+ }
+ }
+
+ if (arg_count(cmd, remotevg_ARG)) {
+ log_error("Cannot change remotevg.");
+ return 0;
+ }
+
+ if (arg_count(cmd, replicatorlogtype_ARG)) {
+ log_error("Cannot change replicator log type.");
+ return 0;
+ }
+
+ memset(&nrsite, 0, sizeof(nrsite));
+ nrsite.state = NUM_REPLICATOR_STATE; /* invalid state */
+ if (arg_count(cmd, available_ARG)) {
+ if (rsite->site_index != 0) {
+ log_error("Cannot change state of remote site %s/%s.",
+ replicator->name, rsite->name);
+ return 0;
+ }
+ switch (arg_uint_value(cmd, available_ARG, 0)) {
+ case CHANGE_ALY:
+ case CHANGE_AE:
+ case CHANGE_AY:
+ nrsite.state = REPLICATOR_STATE_ACTIVE;
+ break;
+ default:
+ nrsite.state = REPLICATOR_STATE_PASSIVE;
+ }
+
+ if (rsite->state != nrsite.state) {
+ rsite->state = nrsite.state;
+ (*changed)++;
+ }
+ }
+
+ if (!get_replicator_site_params(cmd, rsite, changed))
+ return_0;
+
+ if (!*changed)
+ return 1;
+
+ /* Replicator heads needs to be updated */
+ if (lv == replicator)
+ lv = first_replicated(replicator);
+
+ active = (lv_info(cmd, lv, &info, 0, 0) && info.exists);
+
+ if (active && !arg_count(cmd, force_ARG) &&
+ yes_no_prompt("Replicator LVs %s will be deactivated. "
+ "Continue? [y/n]: ",
+ replicator->name) == 'n') {
+ log_error("%s site not changed.", rsite->name);
+ return 0;
+ }
+
+ if (active) {
+ /* FIXME: some cases may require synchronization of data from log */
+ if (arg_count(cmd, available_ARG) &&
+ (nrsite.state == REPLICATOR_STATE_PASSIVE)) {
+ if (!lvchange_availability(cmd, lv))
+ return_0;
+ *skip_available = 1; /* skip later change of available */
+ } else if (!deactivate_lv(cmd, lv)) {
+ log_error("Unable to deactivate replicator %s.",
+ replicator->name);
+ return 0;
+ }
+ }
+
+ if (!vg_write(lv->vg) || !vg_commit(lv->vg))
+ return_0;
+
+ backup(lv->vg);
+
+ if (active && !arg_count(cmd, available_ARG) &&
+ !activate_lv(cmd, lv)) {
+ log_debug("Retry to activate replicator %s.",
+ replicator->name);
+ return 0;
+ }
+
+ return 1;
+}
+
static int lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
- void *handle __attribute__((unused)))
+ void *handle)
{
int doit = 0, docmds = 0;
int dmeventd_mode, archived = 0;
struct logical_volume *origin;
+ struct lvchange_data *lvc_data = handle;
+ int site_changed;
+ int skip_available = 0;
+
+ if (str_list_match_item(&lvc_data->activate_names, lv->name)) {
+ if (lv_is_replicator(lv))
+ lv = first_replicated(lv);
+
+ if (!activate_lv(cmd, lv)) {
+ log_error("Reactivation of replicator %s failed.",
+ lv->rdevice->rsite->replicator->name);
+ return ECMD_FAILED;
+ }
+ return ECMD_PROCESSED;
+ }
if (!(lv->vg->status & LVM_WRITE) &&
(arg_count(cmd, contiguous_ARG) || arg_count(cmd, permission_ARG) ||
@@ -569,7 +715,8 @@ static int lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
lv_is_virtual_origin(origin = origin_from_cow(lv)))
lv = origin;
- if (!(lv_is_visible(lv)) && !lv_is_virtual_origin(lv)) {
+ if (!lv_is_visible(lv) && !lv_is_virtual_origin(lv) &&
+ !lv_is_replicator(lv)) {
log_error("Unable to change internal LV %s directly",
lv->name);
return ECMD_FAILED;
@@ -663,6 +810,23 @@ static int lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
docmds++;
}
+ /* Update replicator paramaters */
+ if ((lv_is_replicator(lv) || lv_is_replicated(lv)) &&
+ (arg_count(cmd, site_ARG) || arg_count(cmd, replicator_ARG))) {
+ if (!archived && !archive(lv->vg)) {
+ stack;
+ return ECMD_FAILED;
+ }
+ archived = 1;
+ site_changed = 0;
+ if (!lvchange_site(cmd, lv, &skip_available, &site_changed))
+ docmds++;
+ else if (site_changed) {
+ doit++;
+ docmds++;
+ }
+ }
+
if (doit)
log_print("Logical volume \"%s\" changed", lv->name);
@@ -673,7 +837,7 @@ static int lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
}
/* availability change */
- if (arg_count(cmd, available_ARG)) {
+ if (!skip_available && arg_count(cmd, available_ARG)) {
if (!lvchange_availability(cmd, lv)) {
stack;
return ECMD_FAILED;
@@ -705,7 +869,18 @@ static int lvchange_single(struct cmd_context *cmd, struct logical_volume *lv,
}
if (doit != docmds) {
- stack;
+ if (lv->vg->cmd_missing_vgs) {
+ /* Note: using cmd mempool to live across VG lifetime. */
+ if (!str_list_add(lv->vg->cmd->mem,
+ &lvc_data->activate_names,
+ lv->name)) {
+ log_error("Allocation of lv name failed.");
+ lv->vg->cmd_missing_vgs = 0;
+ }
+ /* Returns ECMD_FAILED for reprocessing. */
+ } else
+ stack;
+
return ECMD_FAILED;
}
@@ -718,8 +893,18 @@ int lvchange(struct cmd_context *cmd, int argc, char **argv)
arg_count(cmd, contiguous_ARG) || arg_count(cmd, permission_ARG) ||
arg_count(cmd, readahead_ARG) || arg_count(cmd, persistent_ARG) ||
arg_count(cmd, addtag_ARG) || arg_count(cmd, deltag_ARG) ||
+ arg_count(cmd, fallbehindios_ARG) ||
+ arg_count(cmd, fallbehindsize_ARG) ||
+ arg_count(cmd, fallbehindtimeout_ARG) ||
+ arg_count(cmd, remotevg_ARG) || arg_count(cmd, replicator_ARG) ||
+ arg_count(cmd, replicatorlogtype_ARG) ||
+ arg_count(cmd, site_ARG) || arg_count(cmd, sitepolicy_ARG) ||
arg_count(cmd, resync_ARG) || arg_count(cmd, alloc_ARG);
+ struct lvchange_data lvc_data;
+
+ dm_list_init(&lvc_data.activate_names);
+
if (!update &&
!arg_count(cmd, available_ARG) && !arg_count(cmd, refresh_ARG) &&
!arg_count(cmd, monitor_ARG) && !arg_count(cmd, poll_ARG) &&
@@ -768,6 +953,6 @@ int lvchange(struct cmd_context *cmd, int argc, char **argv)
}
return process_each_lv(cmd, argc, argv,
- update ? READ_FOR_UPDATE : 0, NULL,
+ update ? READ_FOR_UPDATE : 0, &lvc_data,
&lvchange_single);
}
--
1.7.2.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 23/25] Replicator: man page update for lvchange
2010-08-08 8:57 [PATCH 00/25] Replicator 100808 Zdenek Kabelac
` (21 preceding siblings ...)
2010-08-08 8:57 ` [PATCH 22/25] Replicator: lvchange implementation Zdenek Kabelac
@ 2010-08-08 8:57 ` Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 24/25] Replicator: lvremove implementation Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 25/25] Replicator: initial simple replicator testcase Zdenek Kabelac
24 siblings, 0 replies; 26+ messages in thread
From: Zdenek Kabelac @ 2010-08-08 8:57 UTC (permalink / raw)
To: lvm-devel
Update lvchange man page to cover basic command usage.
Signed-off-by: Zdenek Kabelac <zkabelac@redhat.com>
---
man/lvchange.8.in | 31 +++++++++++++++++++++++++++++++
1 files changed, 31 insertions(+), 0 deletions(-)
diff --git a/man/lvchange.8.in b/man/lvchange.8.in
index e269802..3003442 100644
--- a/man/lvchange.8.in
+++ b/man/lvchange.8.in
@@ -7,6 +7,11 @@ lvchange \- change attributes of a logical volume
[\-A|\-\-autobackup y|n] [\-a|\-\-available y|n|ey|en|ly|ln]
[\-\-alloc AllocationPolicy]
[\-C|\-\-contiguous y|n] [\-d|\-\-debug] [\-\-deltag Tag]
+[[\-\-site Site]
+[\-\-sitepolicy [sync|warn|stall|drop|fail]
+{[\-\-fallbehindios IOS] |
+[\-\-fallbehindsize Size[bBsSkKmMgGtTpPeE]] |
+[\-\-fallbehindtimeout [{[hh:mm:]|[mm:]}]ss]}]
[\-\-resync]
[\-h|\-?|\-\-help]
[\-\-ignorelockingfailure]
@@ -112,10 +117,36 @@ If the logical volume is active, reload its metadata.
This is not necessary in normal operation, but may be useful
if something has gone wrong or if you're doing clustering
manually without a clustered lock manager.
+.TP
+.I \-\-fallbehindios
+How many pending io operations are allowed.
+Cannot be mixed with --fallbehindsize or --fallbehindtimeout.
+.TP
+.I \-\-fallbehindsize
+How many pending data are allowed.
+Cannot be mixed with --fallbehindios or --fallbehindtimeout.
+.TP
+.I \-\-fallbehindtimeout
+How much time of outstanding data are allowed.
+Cannot be mixed with --fallbehindios or --fallbehindsize.
+.TP
+.I \-\-sitepolicy
+Selects replication policy. Default is Warn.
+Use sync for synchronous policy. Warn,Stall,Drop,Fail are asynchronous policies.
+Warn issues warning when site is switched to sync log.
+Stall stalls replicator until remote site is back in range.
+Drop drops whole site, if it gets too behind.
+Fail whole replicator fails is remote sites gets too behind.
+Local site works usually in stall mode. There is no synclog for local
+replicated volumes.
+.TP
.SH Examples
"lvchange -pr vg00/lvol1" changes the permission on
volume lvol1 in volume group vg00 to be read-only.
+"lvchange --site Berlin -ay vg00/L1"
+marks the local site Berlin for LV "vg00/L1" as active.
+
.SH SEE ALSO
.BR lvm (8),
.BR lvcreate (8),
--
1.7.2.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 24/25] Replicator: lvremove implementation
2010-08-08 8:57 [PATCH 00/25] Replicator 100808 Zdenek Kabelac
` (22 preceding siblings ...)
2010-08-08 8:57 ` [PATCH 23/25] Replicator: man page update for lvchange Zdenek Kabelac
@ 2010-08-08 8:57 ` Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 25/25] Replicator: initial simple replicator testcase Zdenek Kabelac
24 siblings, 0 replies; 26+ messages in thread
From: Zdenek Kabelac @ 2010-08-08 8:57 UTC (permalink / raw)
To: lvm-devel
Signed-off-by: Zdenek Kabelac <zkabelac@redhat.com>
---
tools/commands.h | 3 ++-
tools/lvremove.c | 18 +++++++++++++++++-
2 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/tools/commands.h b/tools/commands.h
index a2b6690..1387eda 100644
--- a/tools/commands.h
+++ b/tools/commands.h
@@ -365,12 +365,13 @@ xx(lvremove,
"\t[-f|--force]\n"
"\t[-h|--help]\n"
"\t[--noudevsync]\n"
+ "\t[--site SiteName]\n"
"\t[-t|--test]\n"
"\t[-v|--verbose]\n"
"\t[--version]" "\n"
"\tLogicalVolume[Path] [LogicalVolume[Path]...]\n",
- autobackup_ARG, force_ARG, noudevsync_ARG, test_ARG)
+ autobackup_ARG, force_ARG, noudevsync_ARG, site_ARG, test_ARG)
xx(lvrename,
"Rename a logical volume",
diff --git a/tools/lvremove.c b/tools/lvremove.c
index 0252149..8060146 100644
--- a/tools/lvremove.c
+++ b/tools/lvremove.c
@@ -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.
*
@@ -19,6 +19,8 @@ static int lvremove_single(struct cmd_context *cmd, struct logical_volume *lv,
void *handle __attribute__((unused)))
{
struct logical_volume *origin;
+ struct logical_volume *replicator;
+ const char *site_name;
/*
* If this is a sparse device, remove its origin too.
@@ -26,6 +28,20 @@ static int lvremove_single(struct cmd_context *cmd, struct logical_volume *lv,
if (lv_is_cow(lv) && lv_is_virtual_origin(origin = origin_from_cow(lv)))
lv = origin;
+ if ((lv_is_replicated(lv) || lv_is_replicator(lv)) &&
+ arg_count(cmd, site_ARG)) {
+ replicator = lv_is_replicator(lv) ? lv : first_seg(lv)->replicator;
+ site_name = arg_str_value(cmd, site_ARG,
+ DEFAULT_REPLICATOR_LOCAL_SITE_NAME);
+
+ if (!lv_remove_replicator_site(replicator, site_name)) {
+ stack;
+ return ECMD_FAILED;
+ }
+
+ return ECMD_PROCESSED;
+ }
+
if (!lv_remove_with_dependencies(cmd, lv, arg_count(cmd, force_ARG), 0)) {
stack;
return ECMD_FAILED;
--
1.7.2.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
* [PATCH 25/25] Replicator: initial simple replicator testcase
2010-08-08 8:57 [PATCH 00/25] Replicator 100808 Zdenek Kabelac
` (23 preceding siblings ...)
2010-08-08 8:57 ` [PATCH 24/25] Replicator: lvremove implementation Zdenek Kabelac
@ 2010-08-08 8:57 ` Zdenek Kabelac
24 siblings, 0 replies; 26+ messages in thread
From: Zdenek Kabelac @ 2010-08-08 8:57 UTC (permalink / raw)
To: lvm-devel
Signed-off-by: Zdenek Kabelac <zkabelac@redhat.com>
---
test/t-replicator-usage.sh | 47 ++++++++++++++++++++++++++++++++++++++++++++
1 files changed, 47 insertions(+), 0 deletions(-)
create mode 100755 test/t-replicator-usage.sh
diff --git a/test/t-replicator-usage.sh b/test/t-replicator-usage.sh
new file mode 100755
index 0000000..7abcc4f
--- /dev/null
+++ b/test/t-replicator-usage.sh
@@ -0,0 +1,47 @@
+#!/bin/sh
+# Copyright (C) 2010 Red Hat, Inc. All rights reserved.
+#
+# This copyrighted material is made available to anyone wishing to use,
+# modify, copy, or redistribute it subject to the terms and conditions
+# of the GNU General Public License v.2.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+
+test_description='Exercise some vgcreate diagnostics'
+
+. ./test-utils.sh
+
+aux prepare_pvs 3
+
+vgl=${PREFIX}vgl
+vgn=${PREFIX}vgn
+vgp=${PREFIX}vgp
+rep=${vgl}/rep
+
+#COMM create 3 VGs'
+vgcreate -c n $vgl $dev1
+vgcreate -c n $vgn $dev2
+vgcreate -c n $vgp $dev3
+
+#COMM remote site N
+lvcreate -l1 -n $lv1 $vgn
+lvcreate -l2 -n $lv2 $vgn
+
+#COMM remote site P
+lvcreate -l1 -n $lv1 $vgp
+lvcreate -l2 -n $lv2 $vgp
+
+lvcreate --replicator -l1 -n rep $vgl
+
+lvcreate --site Berlin --replicator $rep
+
+lvcreate --site NY --remotevg $vgn --replicator $rep
+lvcreate --site Paris --remotevg $vgp --replicator $rep
+
+lvcreate --replicated -l1 -n $lv1 $rep
+lvcreate --replicated -l2 -n $lv2 $rep
+
+# active site Berlin - using any replicated LV
+lvchange -ay --site Berlin $vgl/$lv1
--
1.7.2.1
^ permalink raw reply related [flat|nested] 26+ messages in thread
end of thread, other threads:[~2010-08-08 8:57 UTC | newest]
Thread overview: 26+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2010-08-08 8:57 [PATCH 00/25] Replicator 100808 Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 01/25] Update libdm for replicator Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 02/25] SEG_REPLICATED dm-deptree Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 03/25] Skip check missing rem.VGs for non-activate locks Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 04/25] Replicator: check for active replicator Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 05/25] Replicator: add reserved names Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 06/25] Replicator: man page update for lvm Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 07/25] Replicator: add _replicator_in_sync Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 08/25] Replicator: add report for replicator/ed targets Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 09/25] Replicator: improve detection of replicated segment Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 10/25] Replicator: new defaults Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 11/25] Replicator: metadata update Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 12/25] Replicator: segtype.h - replicated Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 13/25] Replicator: replicator_manip changes Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 14/25] Replicator: replicator.c changes Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 15/25] Replicator: add new command option read functions Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 16/25] Replicator: new args Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 17/25] Replicator: update of dev_manager.c Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 18/25] Replicator: read site_params Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 19/25] Replicator: lv_manip - create replicator Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 20/25] Replicator: lvcreate implementation Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 21/25] Replicator: man page update for lvcreate Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 22/25] Replicator: lvchange implementation Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 23/25] Replicator: man page update for lvchange Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 24/25] Replicator: lvremove implementation Zdenek Kabelac
2010-08-08 8:57 ` [PATCH 25/25] Replicator: initial simple replicator testcase Zdenek Kabelac
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.