diff --git a/WHATS_NEW_DM b/WHATS_NEW_DM index 3de28a71f..f05d2700c 100644 --- a/WHATS_NEW_DM +++ b/WHATS_NEW_DM @@ -1,5 +1,7 @@ Version 1.02.01 - ============================= + 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 diff --git a/libdm/.exported_symbols b/libdm/.exported_symbols index 23c3f708d..898c06e1c 100644 --- a/libdm/.exported_symbols +++ b/libdm/.exported_symbols @@ -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 diff --git a/libdm/ioctl/libdm-iface.c b/libdm/ioctl/libdm-iface.c index c915333b1..3f2e59211 100644 --- a/libdm/ioctl/libdm-iface.c +++ b/libdm/ioctl/libdm-iface.c @@ -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; diff --git a/libdm/ioctl/libdm-targets.h b/libdm/ioctl/libdm-targets.h index ce3ab8225..4eea595d4 100644 --- a/libdm/ioctl/libdm-targets.h +++ b/libdm/ioctl/libdm-targets.h @@ -53,6 +53,7 @@ struct dm_task { uint64_t sector; int no_open_count; int skip_lockfs; + int suppress_identical_reload; char *uuid; }; diff --git a/libdm/libdevmapper.h b/libdm/libdevmapper.h index a6c3db2fc..1a7710c45 100644 --- a/libdm/libdevmapper.h +++ b/libdm/libdevmapper.h @@ -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. diff --git a/libdm/libdm-deptree.c b/libdm/libdm-deptree.c index 30a1e6d4a..d60f8607d 100644 --- a/libdm/libdm-deptree.c +++ b/libdm/libdm-deptree.c @@ -1353,8 +1353,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; @@ -1362,7 +1369,6 @@ out: dm_task_destroy(dmt); return r; - } int dm_tree_preload_children(struct dm_tree_node *dnode,