1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-12-31 12:32:49 +03:00

Compare commits

...

15 Commits

Author SHA1 Message Date
Alasdair Kergon
dcb8415b7a 1.02.01 2005-11-23 18:36:33 +00:00
Alasdair Kergon
699e1c75ce Fix lvdisplay cmdline to accept snapshots. 2005-11-23 16:16:39 +00:00
Alasdair Kergon
465b6e613e Fix open RO->RW promotions. 2005-11-23 16:07:40 +00:00
Alasdair Kergon
05fa105855 Resume snapshot-origins last. 2005-11-22 20:00:35 +00:00
Alasdair Kergon
d7a0cdebe5 Remove a resolved FIXME. 2005-11-22 19:37:14 +00:00
Alasdair Kergon
b049ab31eb Suppress unnecessary resumes. 2005-11-22 19:31:20 +00:00
Alasdair Kergon
6db4dcff7a Drop leading zeros from dm_format_dev.
Suppress attempt to reload identical table.
2005-11-22 18:43:12 +00:00
Alasdair Kergon
3eeaef00ec Additional LVM- prefix matching for transitional period. 2005-11-12 22:46:48 +00:00
Alasdair Kergon
8bf4c38a00 lvcreate vg_revert 2005-11-12 22:42:08 +00:00
Alasdair Kergon
3a32b09ad1 A missing vg_revert in an error path. 2005-11-12 22:00:50 +00:00
Alasdair Kergon
6315982752 more debug fixes 2005-11-11 16:16:37 +00:00
Alasdair Kergon
374a171e82 Fix selinux compile. 2005-11-10 18:31:17 +00:00
Alasdair Kergon
fc5d801f91 fix debug linking 2005-11-10 16:33:04 +00:00
Alasdair Kergon
5146641848 post-release 2005-11-10 16:06:29 +00:00
Alasdair Kergon
cdd0ac42cf pre-release 2005-11-10 15:27:19 +00:00
13 changed files with 200 additions and 75 deletions

View File

@@ -1 +1 @@
2.02.00-cvs (2005-10-16)
2.02.01-cvs (2005-11-10)

View File

@@ -1,5 +1,11 @@
Version 2.02.00 -
===================================
Version 2.02.01 -
====================================
Fix lvdisplay cmdline to accept snapshots.
Fix open RO->RW promotion.
Fix missing vg_revert in lvcreate error path.
Version 2.02.00 - 10th November 2005
====================================
Extend allocation areas to avoid overflow with contiguous with other PVs.
Stop lvcreate attempting to wipe zero or error segments.
Added new lvs table attributes.

View File

@@ -1,4 +1,10 @@
Version 1.02.00 -
Version 1.02.01 - 23 Nov 2005
=============================
Drop leading zeros from dm_format_dev.
Suppress attempt to reload identical table.
Additional LVM- prefix matching for transitional period.
Version 1.02.00 - 10 Nov 2005
=============================
Added activation functions to library.
Added return macros.

View File

@@ -845,7 +845,6 @@ static int _add_new_lv_to_dtree(struct dev_manager *dm, struct dm_tree *dtree,
dm_tree_node_get_context(dnode))
return 1;
/* FIXME How do we determine whether a pre-existing node need reloading or not? */
if (!(lvlayer = dm_pool_alloc(dm->mem, sizeof(*lvlayer)))) {
log_error("_add_new_lv_to_dtree: pool alloc failed for %s %s.", lv->name, layer);
return 0;

View File

@@ -418,7 +418,6 @@ int dev_open_flags(struct device *dev, int flags, int direct, int quiet)
((fstat(dev->fd, &buf) < 0) || (buf.st_rdev != dev->dev))) {
log_error("%s: fstat failed: Has device name changed?", name);
dev_close_immediate(dev);
dev->open_count = 0;
return 0;
}
@@ -509,11 +508,9 @@ static int _dev_close(struct device *dev, int immediate)
if (dev->open_count > 0)
dev->open_count--;
if (immediate && dev->open_count) {
if (immediate && dev->open_count)
log_debug("%s: Immediate close attempt while still referenced",
dev_name(dev));
dev->open_count = 0;
}
/* Close unless device is known to belong to a locked VG */
if (immediate ||

View File

@@ -22,6 +22,7 @@ dm_task_set_major
dm_task_set_minor
dm_task_set_sector
dm_task_set_message
dm_task_suppress_identical_reload
dm_task_add_target
dm_task_no_open_count
dm_task_skip_lockfs
@@ -61,11 +62,12 @@ dm_tree_node_add_target_area
dm_is_dm_major
dm_mknodes
dm_malloc_aux
dm_malloc_aux_debug
dm_strdup
dm_free_aux
dm_realloc_aux
dm_dump_memory
dm_bounds_check
dm_dump_memory_debug
dm_bounds_check_debug
dm_pool_create
dm_pool_destroy
dm_pool_alloc

View File

@@ -236,7 +236,7 @@ static int _create_control(const char *control, uint32_t major, uint32_t minor)
}
#ifdef HAVE_SELINUX
if (!set_selinux_context(control, S_IFCHR)) {
if (!dm_set_selinux_context(control, S_IFCHR)) {
stack;
return 0;
}
@@ -875,7 +875,7 @@ int dm_format_dev(char *buf, int bufsize, uint32_t dev_major,
if (bufsize < 8)
return 0;
r = snprintf(buf, bufsize, "%03u:%03u", dev_major, dev_minor);
r = snprintf(buf, bufsize, "%u:%u", dev_major, dev_minor);
if (r < 0 || r > bufsize - 1)
return 0;
@@ -966,6 +966,12 @@ int dm_task_set_ro(struct dm_task *dmt)
return 1;
}
int dm_task_suppress_identical_reload(struct dm_task *dmt)
{
dmt->suppress_identical_reload = 1;
return 1;
}
int dm_task_set_newname(struct dm_task *dmt, const char *newname)
{
if (!(dmt->newname = dm_strdup(newname))) {
@@ -1342,6 +1348,71 @@ static int _create_and_load_v4(struct dm_task *dmt)
return r;
}
static int _reload_with_suppression_v4(struct dm_task *dmt)
{
struct dm_task *task;
struct target *t1, *t2;
int matches = 1;
int r;
/* New task to get existing table information */
if (!(task = dm_task_create(DM_DEVICE_TABLE))) {
log_error("Failed to create device-mapper task struct");
return 0;
}
/* Copy across relevant fields */
if (dmt->dev_name && !dm_task_set_name(task, dmt->dev_name)) {
dm_task_destroy(task);
return 0;
}
if (dmt->uuid && !dm_task_set_uuid(task, dmt->uuid)) {
dm_task_destroy(task);
return 0;
}
task->major = dmt->major;
task->minor = dmt->minor;
r = dm_task_run(task);
if (!r) {
dm_task_destroy(task);
return r;
}
t1 = dmt->head;
t2 = task->head;
while (t1 && t2) {
if ((t1->start != t2->start) ||
(t1->length != t2->length) ||
(strcmp(t1->type, t2->type)) ||
(strcmp(t1->params, t2->params))) {
matches = 0;
break;
}
t1 = t1->next;
t2 = t2->next;
}
if (matches && !t1 && !t2) {
dmt->dmi.v4 = task->dmi.v4;
task->dmi.v4 = NULL;
dm_task_destroy(task);
return 1;
}
dm_task_destroy(task);
/* Now do the original reload */
dmt->suppress_identical_reload = 0;
r = dm_task_run(dmt);
return r;
}
static struct dm_ioctl *_do_dm_ioctl(struct dm_task *dmt, unsigned command,
unsigned repeat_count)
{
@@ -1426,6 +1497,9 @@ int dm_task_run(struct dm_task *dmt)
!dmt->uuid && dmt->major <= 0)
return _mknodes_v4(dmt);
if ((dmt->type == DM_DEVICE_RELOAD) && dmt->suppress_identical_reload)
return _reload_with_suppression_v4(dmt);
if (!_open_control())
return 0;

View File

@@ -53,6 +53,7 @@ struct dm_task {
uint64_t sector;
int no_open_count;
int skip_lockfs;
int suppress_identical_reload;
char *uuid;
};

View File

@@ -145,6 +145,7 @@ int dm_task_set_message(struct dm_task *dmt, const char *message);
int dm_task_set_sector(struct dm_task *dmt, uint64_t sector);
int dm_task_no_open_count(struct dm_task *dmt);
int dm_task_skip_lockfs(struct dm_task *dmt);
int dm_task_suppress_identical_reload(struct dm_task *dmt);
/*
* Use these to prepare for a create or reload.
@@ -342,30 +343,34 @@ int dm_tree_node_add_target_area(struct dm_tree_node *node,
* Memory management
*******************/
void *dm_malloc_aux(size_t s, const char *file, int line);
#define dm_malloc(s) dm_malloc_aux((s), __FILE__, __LINE__)
char *dm_strdup(const char *str);
void *dm_malloc_aux(size_t s, const char *file, int line);
void *dm_malloc_aux_debug(size_t s, const char *file, int line);
void dm_free_aux(void *p);
void *dm_realloc_aux(void *p, unsigned int s, const char *file, int line);
int dm_dump_memory_debug(void);
void dm_bounds_check_debug(void);
#ifdef DEBUG_MEM
void dm_free_aux(void *p);
void *dm_realloc_aux(void *p, unsigned int s, const char *file, int line);
int dm_dump_memory(void);
void dm_bounds_check(void);
# define dm_malloc(s) dm_malloc_aux_debug((s), __FILE__, __LINE__)
# define dm_free(p) dm_free_aux(p)
# define dm_realloc(p, s) dm_realloc_aux(p, s, __FILE__, __LINE__)
# define dm_dump_memory() dm_dump_memory_debug()
# define dm_bounds_check() dm_bounds_check_debug()
#else
# define dm_malloc(s) dm_malloc_aux((s), __FILE__, __LINE__)
# define dm_free(p) free(p)
# define dm_realloc(p, s) realloc(p, s)
# define dm_dump_memory()
# define dm_bounds_check()
# define dm_dump_memory() {}
# define dm_bounds_check() {}
#endif
/*
* The pool allocator is useful when you are going to allocate
* lots of memory, use the memory for a bit, and then free the

View File

@@ -25,6 +25,9 @@
#define MAX_TARGET_PARAMSIZE 500000
/* FIXME Fix interface so this is used only by LVM */
#define UUID_PREFIX "LVM-"
/* Supported segment types */
enum {
SEG_ERROR,
@@ -112,6 +115,8 @@ struct dm_tree_node {
struct list uses; /* Nodes this node uses */
struct list used_by; /* Nodes that use this node */
int activation_priority; /* 0 gets activated first */
void *context; /* External supplied context */
struct load_properties props; /* For creation/table (re)load */
@@ -310,6 +315,7 @@ static struct dm_tree_node *_create_dm_tree_node(struct dm_tree *dtree,
node->uuid = uuid;
node->info = *info;
node->context = context;
node->activation_priority = 0;
list_init(&node->uses);
list_init(&node->used_by);
@@ -348,8 +354,15 @@ static struct dm_tree_node *_find_dm_tree_node(struct dm_tree *dtree,
static struct dm_tree_node *_find_dm_tree_node_by_uuid(struct dm_tree *dtree,
const char *uuid)
{
/* FIXME Do we need to cope with missing LVM- prefix too? */
return dm_hash_lookup(dtree->uuids, uuid);
struct dm_tree_node *node;
if ((node = dm_hash_lookup(dtree->uuids, uuid)))
return node;
if (strncmp(uuid, UUID_PREFIX, sizeof(UUID_PREFIX) - 1))
return NULL;
return dm_hash_lookup(dtree->uuids, uuid + sizeof(UUID_PREFIX) - 1);
}
static int _deps(struct dm_task **dmt, struct dm_pool *mem, uint32_t major, uint32_t minor,
@@ -653,13 +666,13 @@ static int _uuid_prefix_matches(const char *uuid, const char *uuid_prefix, size_
if (uuid_prefix_len <= 4)
return 0;
if (!strncmp(uuid, "LVM-", 4))
if (!strncmp(uuid, UUID_PREFIX, sizeof(UUID_PREFIX) - 1))
return 0;
if (strncmp(uuid_prefix, "LVM-", 4))
if (strncmp(uuid_prefix, UUID_PREFIX, sizeof(UUID_PREFIX) - 1))
return 0;
if (!strncmp(uuid, uuid_prefix + 4, uuid_prefix_len - 4))
if (!strncmp(uuid, uuid_prefix + sizeof(UUID_PREFIX) - 1, uuid_prefix_len - (sizeof(UUID_PREFIX) - 1)))
return 1;
return 0;
@@ -1026,7 +1039,7 @@ int dm_tree_suspend_children(struct dm_tree_node *dnode,
}
/* Ignore if it doesn't belong to this VG */
if (uuid_prefix && strncmp(uuid, uuid_prefix, uuid_prefix_len))
if (!_uuid_prefix_matches(uuid, uuid_prefix, uuid_prefix_len))
continue;
if (dm_tree_node_num_children(child, 0))
@@ -1045,6 +1058,7 @@ int dm_tree_activate_children(struct dm_tree_node *dnode,
struct dm_info newinfo;
const char *name;
const char *uuid;
int priority;
/* Activate children first */
while ((child = dm_tree_next_child(&handle, dnode, 0))) {
@@ -1058,36 +1072,53 @@ int dm_tree_activate_children(struct dm_tree_node *dnode,
if (dm_tree_node_num_children(child, 0))
dm_tree_activate_children(child, uuid_prefix, uuid_prefix_len);
}
if (!(name = dm_tree_node_get_name(child))) {
stack;
continue;
}
handle = NULL;
/* Rename? */
if (child->props.new_name) {
if (!_rename_node(name, child->props.new_name, child->info.major, child->info.minor)) {
log_error("Failed to rename %s (%" PRIu32
":%" PRIu32 ") to %s", name, child->info.major,
child->info.minor, child->props.new_name);
return 0;
for (priority = 0; priority < 2; priority++) {
while ((child = dm_tree_next_child(&handle, dnode, 0))) {
if (!(uuid = dm_tree_node_get_uuid(child))) {
stack;
continue;
}
child->name = child->props.new_name;
child->props.new_name = NULL;
if (!_uuid_prefix_matches(uuid, uuid_prefix, uuid_prefix_len))
continue;
if (priority != child->activation_priority)
continue;
if (!(name = dm_tree_node_get_name(child))) {
stack;
continue;
}
/* Rename? */
if (child->props.new_name) {
if (!_rename_node(name, child->props.new_name, child->info.major, child->info.minor)) {
log_error("Failed to rename %s (%" PRIu32
":%" PRIu32 ") to %s", name, child->info.major,
child->info.minor, child->props.new_name);
return 0;
}
child->name = child->props.new_name;
child->props.new_name = NULL;
}
if (!child->info.inactive_table && !child->info.suspended)
continue;
if (!_resume_node(name, child->info.major, child->info.minor, &newinfo)) {
log_error("Unable to resume %s (%" PRIu32
":%" PRIu32 ")", name, child->info.major,
child->info.minor);
continue;
}
/* Update cached info */
child->info = newinfo;
}
if (!child->info.inactive_table && !child->info.suspended)
continue;
if (!_resume_node(name, child->info.major, child->info.minor, &newinfo)) {
log_error("Unable to resume %s (%" PRIu32
":%" PRIu32 ")", name, child->info.major,
child->info.minor);
continue;
}
/* Update cached info */
child->info = newinfo;
}
handle = NULL;
@@ -1343,8 +1374,15 @@ static int _load_node(struct dm_tree_node *dnode)
if (!_emit_segment(dmt, seg, &seg_start))
goto_out;
if ((r = dm_task_run(dmt)))
if (!dm_task_suppress_identical_reload(dmt))
log_error("Failed to suppress reload of identical tables.");
if ((r = dm_task_run(dmt))) {
r = dm_task_get_info(dmt, &dnode->info);
if (r && !dnode->info.inactive_table)
log_verbose("Suppressed %s identical table reload.",
dnode->name);
}
dnode->props.segment_count = 0;
@@ -1352,7 +1390,6 @@ out:
dm_task_destroy(dmt);
return r;
}
int dm_tree_preload_children(struct dm_tree_node *dnode,
@@ -1371,8 +1408,8 @@ int dm_tree_preload_children(struct dm_tree_node *dnode,
continue;
/* Ignore if it doesn't belong to this VG */
if (uuid_prefix && child->info.exists &&
strncmp(child->uuid, uuid_prefix, uuid_prefix_len))
if (child->info.exists &&
!_uuid_prefix_matches(child->uuid, uuid_prefix, uuid_prefix_len))
continue;
if (dm_tree_node_num_children(child, 0))
@@ -1402,6 +1439,9 @@ int dm_tree_preload_children(struct dm_tree_node *dnode,
if (!dm_tree_node_num_children(child, 1))
continue;
if (!child->info.inactive_table && !child->info.suspended)
continue;
if (!_resume_node(name, child->info.major, child->info.minor, &newinfo)) {
log_error("Unable to resume %s (%" PRIu32
":%" PRIu32 ")", name, child->info.major,
@@ -1435,7 +1475,7 @@ int dm_tree_children_use_uuid(struct dm_tree_node *dnode,
return 1;
}
if (!strncmp(uuid, uuid_prefix, uuid_prefix_len))
if (_uuid_prefix_matches(uuid, uuid_prefix, uuid_prefix_len))
return 1;
if (dm_tree_node_num_children(child, 0))
@@ -1492,6 +1532,9 @@ int dm_tree_node_add_snapshot_origin_target(struct dm_tree_node *dnode,
if (!_link_tree_nodes(dnode, origin_node))
return_0;
/* Resume snapshot origins after new snapshots */
dnode->activation_priority = 1;
return 1;
}

View File

@@ -28,8 +28,6 @@ char *dm_strdup(const char *str)
return ret;
}
#ifdef DEBUG_MEM
struct memblock {
struct memblock *prev, *next; /* All allocated blocks are linked */
size_t length; /* Size of the requested block */
@@ -51,7 +49,7 @@ static struct {
static struct memblock *_head = 0;
static struct memblock *_tail = 0;
void *dm_malloc_aux(size_t s, const char *file, int line)
void *dm_malloc_aux_debug(size_t s, const char *file, int line)
{
struct memblock *nb;
size_t tsize = s + sizeof(*nb) + sizeof(unsigned long);
@@ -72,9 +70,7 @@ void *dm_malloc_aux(size_t s, const char *file, int line)
nb->file = file;
nb->line = line;
#ifdef BOUNDS_CHECK
dm_bounds_check();
#endif
/* setup fields */
nb->magic = nb + 1;
@@ -125,9 +121,7 @@ void dm_free_aux(void *p)
if (!p)
return;
#ifdef BOUNDS_CHECK
dm_bounds_check();
#endif
/* sanity check */
assert(mb->magic == p);
@@ -171,7 +165,7 @@ void *dm_realloc_aux(void *p, unsigned int s, const char *file, int line)
void *r;
struct memblock *mb = ((struct memblock *) p) - 1;
r = dm_malloc_aux(s, file, line);
r = dm_malloc_aux_debug(s, file, line);
if (p) {
memcpy(r, p, mb->length);
@@ -181,7 +175,7 @@ void *dm_realloc_aux(void *p, unsigned int s, const char *file, int line)
return r;
}
int dm_dump_memory(void)
int dm_dump_memory_debug(void)
{
unsigned long tot = 0;
struct memblock *mb;
@@ -216,7 +210,7 @@ int dm_dump_memory(void)
return 1;
}
void dm_bounds_check(void)
void dm_bounds_check_debug(void)
{
struct memblock *mb = _head;
while (mb) {
@@ -230,8 +224,6 @@ void dm_bounds_check(void)
}
}
#else
void *dm_malloc_aux(size_t s, const char *file, int line)
{
if (s > 50000000) {
@@ -242,5 +234,3 @@ void *dm_malloc_aux(size_t s, const char *file, int line)
return malloc(s);
}
#endif

View File

@@ -761,6 +761,7 @@ static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp)
if (!suspend_lv(cmd, org)) {
log_error("Failed to suspend origin %s", org->name);
vg_revert(vg);
return 0;
}

View File

@@ -18,7 +18,8 @@
static int _lvdisplay_single(struct cmd_context *cmd, struct logical_volume *lv,
void *handle)
{
if (!arg_count(cmd, all_ARG) && !(lv->status & VISIBLE_LV))
if (!arg_count(cmd, all_ARG) && !(lv->status & VISIBLE_LV) &&
!(lv_is_cow(lv)))
return ECMD_PROCESSED;
if (arg_count(cmd, colon_ARG))