1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-01-03 05:18:29 +03:00

Create a log header for replacement in-sync mirror log.

Use set_lv() and dev_set() to wipe sections of devices.
Add mirror_in_sync() flag to avoid unnecessary resync on activation.
This commit is contained in:
Alasdair Kergon 2006-05-11 18:39:24 +00:00
parent 898e6f8e41
commit 5c9d70c955
14 changed files with 113 additions and 27 deletions

View File

@ -1,5 +1,8 @@
Version 2.02.06 - Version 2.02.06 -
================================= =================================
Create a log header for replacement in-sync mirror log.
Use set_lv() and dev_set() to wipe sections of devices.
Add mirror_in_sync() flag to avoid unnecessary resync on activation.
Add mirror_library description to example.conf. Add mirror_library description to example.conf.
Fix uuid_from_num() buffer overrun. Fix uuid_from_num() buffer overrun.
Make SIZE_SHORT the default for display_size(). Make SIZE_SHORT the default for display_size().

View File

@ -602,7 +602,7 @@ int dev_write(struct device *dev, uint64_t offset, size_t len, void *buffer)
return _aligned_io(&where, buffer, 1); return _aligned_io(&where, buffer, 1);
} }
int dev_zero(struct device *dev, uint64_t offset, size_t len) int dev_set(struct device *dev, uint64_t offset, size_t len, int value)
{ {
size_t s; size_t s;
char buffer[4096]; char buffer[4096];
@ -620,7 +620,7 @@ int dev_zero(struct device *dev, uint64_t offset, size_t len)
" sectors", dev_name(dev), offset >> SECTOR_SHIFT, " sectors", dev_name(dev), offset >> SECTOR_SHIFT,
len >> SECTOR_SHIFT); len >> SECTOR_SHIFT);
memset(buffer, 0, sizeof(buffer)); memset(buffer, value, sizeof(buffer));
while (1) { while (1) {
s = len > sizeof(buffer) ? sizeof(buffer) : len; s = len > sizeof(buffer) ? sizeof(buffer) : len;
if (!dev_write(dev, offset, s, buffer)) if (!dev_write(dev, offset, s, buffer))

View File

@ -80,7 +80,7 @@ const char *dev_name(const struct device *dev);
int dev_read(struct device *dev, uint64_t offset, size_t len, void *buffer); int dev_read(struct device *dev, uint64_t offset, size_t len, void *buffer);
int dev_write(struct device *dev, uint64_t offset, size_t len, void *buffer); int dev_write(struct device *dev, uint64_t offset, size_t len, void *buffer);
int dev_append(struct device *dev, size_t len, void *buffer); int dev_append(struct device *dev, size_t len, void *buffer);
int dev_zero(struct device *dev, uint64_t offset, size_t len); int dev_set(struct device *dev, uint64_t offset, size_t len, int value);
void dev_flush(struct device *dev); void dev_flush(struct device *dev);
struct device *dev_create_file(const char *filename, struct device *dev, struct device *dev_create_file(const char *filename, struct device *dev,

View File

@ -576,7 +576,7 @@ static int _write_lvs(struct disk_list *data)
pos = data->pvd.lv_on_disk.base; pos = data->pvd.lv_on_disk.base;
if (!dev_zero(data->dev, pos, data->pvd.lv_on_disk.size)) { if (!dev_set(data->dev, pos, data->pvd.lv_on_disk.size, 0)) {
log_error("Couldn't zero lv area on device '%s'", log_error("Couldn't zero lv area on device '%s'",
dev_name(data->dev)); dev_name(data->dev));
return 0; return 0;

View File

@ -1073,9 +1073,9 @@ static int _mda_setup(const struct format_type *fmt,
if (!add_mda(fmt, fmt->cmd->mem, mdas, pv->dev, start1, if (!add_mda(fmt, fmt->cmd->mem, mdas, pv->dev, start1,
mda_size1)) return 0; mda_size1)) return 0;
if (!dev_zero((struct device *) pv->dev, start1, if (!dev_set((struct device *) pv->dev, start1,
(size_t) (mda_size1 > (size_t) (mda_size1 >
wipe_size ? : mda_size1))) { wipe_size ? : mda_size1), 0)) {
log_error("Failed to wipe new metadata area"); log_error("Failed to wipe new metadata area");
return 0; return 0;
} }
@ -1119,9 +1119,9 @@ static int _mda_setup(const struct format_type *fmt,
if (mda_size2) { if (mda_size2) {
if (!add_mda(fmt, fmt->cmd->mem, mdas, pv->dev, start2, if (!add_mda(fmt, fmt->cmd->mem, mdas, pv->dev, start2,
mda_size2)) return 0; mda_size2)) return 0;
if (!dev_zero(pv->dev, start2, if (!dev_set(pv->dev, start2,
(size_t) (mda_size1 > (size_t) (mda_size1 >
wipe_size ? : mda_size1))) { wipe_size ? : mda_size1), 0)) {
log_error("Failed to wipe new metadata area"); log_error("Failed to wipe new metadata area");
return 0; return 0;
} }

View File

@ -45,6 +45,7 @@ static int _security_level = SECURITY_LEVEL;
static char _cmd_name[30] = ""; static char _cmd_name[30] = "";
static char _msg_prefix[30] = " "; static char _msg_prefix[30] = " ";
static int _already_logging = 0; static int _already_logging = 0;
static int _mirror_in_sync = 0;
static lvm2_log_fn_t _lvm2_log_fn = NULL; static lvm2_log_fn_t _lvm2_log_fn = NULL;
@ -175,6 +176,11 @@ void init_security_level(int level)
_security_level = level; _security_level = level;
} }
void init_mirror_in_sync(int in_sync)
{
_mirror_in_sync = in_sync;
}
void init_cmd_name(int status) void init_cmd_name(int status)
{ {
_log_cmd_name = status; _log_cmd_name = status;
@ -239,6 +245,11 @@ int security_level()
return _security_level; return _security_level;
} }
int mirror_in_sync(void)
{
return _mirror_in_sync;
}
void init_debug(int level) void init_debug(int level)
{ {
_debug_level = level; _debug_level = level;

View File

@ -73,6 +73,7 @@ void init_indent(int indent);
void init_ignorelockingfailure(int level); void init_ignorelockingfailure(int level);
void init_lockingfailed(int level); void init_lockingfailed(int level);
void init_security_level(int level); void init_security_level(int level);
void init_mirror_in_sync(int in_sync);
void set_cmd_name(const char *cmd_name); void set_cmd_name(const char *cmd_name);
@ -85,6 +86,7 @@ int debug_level(void);
int ignorelockingfailure(void); int ignorelockingfailure(void);
int lockingfailed(void); int lockingfailed(void);
int security_level(void); int security_level(void);
int mirror_in_sync(void);
/* Suppress messages to stdout/stderr (1) or everywhere (2) */ /* Suppress messages to stdout/stderr (1) or everywhere (2) */
/* Returns previous setting */ /* Returns previous setting */

View File

@ -245,6 +245,9 @@ static int _add_log(struct dev_manager *dm, struct lv_segment *seg,
return 0; return 0;
} }
if (mirror_in_sync() && !(seg->status & PVMOVE))
log_flags |= DM_NOSYNC;
if (_block_on_error_available && !(seg->status & PVMOVE)) if (_block_on_error_available && !(seg->status & PVMOVE))
log_flags |= DM_BLOCK_ON_ERROR; log_flags |= DM_BLOCK_ON_ERROR;

View File

@ -45,6 +45,7 @@ arg(type_ARG, '\0', "type", segtype_arg)
arg(alloc_ARG, '\0', "alloc", alloc_arg) arg(alloc_ARG, '\0', "alloc", alloc_arg)
arg(separator_ARG, '\0', "separator", string_arg) arg(separator_ARG, '\0', "separator", string_arg)
arg(mirrorsonly_ARG, '\0', "mirrorsonly", NULL) arg(mirrorsonly_ARG, '\0', "mirrorsonly", NULL)
arg(nosync_ARG, '\0', "nosync", NULL)
/* Allow some variations */ /* Allow some variations */
arg(resizable_ARG, '\0', "resizable", yes_no_arg) arg(resizable_ARG, '\0', "resizable", yes_no_arg)

View File

@ -327,7 +327,7 @@ static int lvconvert_mirrors(struct cmd_context * cmd, struct logical_volume * l
if (!(log_lv = create_mirror_log(cmd, lv->vg, ah, if (!(log_lv = create_mirror_log(cmd, lv->vg, ah,
lp->alloc, lp->alloc,
lv->name))) { lv->name, 0))) {
log_error("Failed to create mirror log."); log_error("Failed to create mirror log.");
return 0; return 0;
} }
@ -390,7 +390,7 @@ static int lvconvert_snapshot(struct cmd_context *cmd,
if (!lp->zero) if (!lp->zero)
log_error("WARNING: \"%s\" not zeroed", lv->name); log_error("WARNING: \"%s\" not zeroed", lv->name);
else if (!zero_lv(cmd, lv)) { else if (!set_lv(cmd, lv, 0)) {
log_error("Aborting. Failed to wipe snapshot " log_error("Aborting. Failed to wipe snapshot "
"exception store."); "exception store.");
return 0; return 0;

View File

@ -646,7 +646,7 @@ static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp)
lp->region_size); lp->region_size);
if (!(log_lv = create_mirror_log(cmd, vg, ah, lp->alloc, if (!(log_lv = create_mirror_log(cmd, vg, ah, lp->alloc,
lv_name))) { lv_name, 0))) {
log_error("Failed to create mirror log."); log_error("Failed to create mirror log.");
return 0; return 0;
} }
@ -730,7 +730,7 @@ static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp)
} }
if ((lp->zero || lp->snapshot) && activation()) { if ((lp->zero || lp->snapshot) && activation()) {
if (!zero_lv(cmd, lv) && lp->snapshot) { if (!set_lv(cmd, lv, 0) && lp->snapshot) {
/* FIXME Remove the failed lv we just added */ /* FIXME Remove the failed lv we just added */
log_error("Aborting. Failed to wipe snapshot " log_error("Aborting. Failed to wipe snapshot "
"exception store. Remove new LV and retry."); "exception store. Remove new LV and retry.");

View File

@ -96,7 +96,7 @@ static int pvcreate_check(struct cmd_context *cmd, const char *name)
(yes_no_prompt("Software RAID md superblock " (yes_no_prompt("Software RAID md superblock "
"detected on %s. Wipe it? [y/n] ", name) == 'y'))) { "detected on %s. Wipe it? [y/n] ", name) == 'y'))) {
log_print("Wiping software RAID md superblock on %s", name); log_print("Wiping software RAID md superblock on %s", name);
if (!dev_zero(dev, md_superblock, 4)) { if (!dev_set(dev, md_superblock, 4, 0)) {
log_error("Failed to wipe RAID md superblock on %s", log_error("Failed to wipe RAID md superblock on %s",
name); name);
return 0; return 0;
@ -225,7 +225,7 @@ static int pvcreate_single(struct cmd_context *cmd, const char *pv_name,
goto error; goto error;
} }
if (!dev_zero(dev, UINT64_C(0), (size_t) 2048)) { if (!dev_set(dev, UINT64_C(0), (size_t) 2048, 0)) {
log_error("%s not wiped: aborting", pv_name); log_error("%s not wiped: aborting", pv_name);
dev_close(dev); dev_close(dev);
goto error; goto error;

View File

@ -15,10 +15,15 @@
#include "tools.h" #include "tools.h"
#include "lv_alloc.h" #include "lv_alloc.h"
#include "xlate.h"
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/wait.h> #include <sys/wait.h>
/* From linux/drivers/md/dm-log.c */
#define MIRROR_MAGIC 0x4D695272
#define MIRROR_DISK_VERSION 2
/* Command line args */ /* Command line args */
unsigned arg_count(struct cmd_context *cmd, int a) unsigned arg_count(struct cmd_context *cmd, int a)
{ {
@ -1111,9 +1116,9 @@ int generate_log_name_format(struct volume_group *vg __attribute((unused)),
} }
/* /*
* Volumes may be zeroed to remove old application data. * Initialize the LV with 'value'.
*/ */
int zero_lv(struct cmd_context *cmd, struct logical_volume *lv) int set_lv(struct cmd_context *cmd, struct logical_volume *lv, int value)
{ {
struct device *dev; struct device *dev;
char *name; char *name;
@ -1126,27 +1131,80 @@ int zero_lv(struct cmd_context *cmd, struct logical_volume *lv)
* (I know the device is at least 4k, but not 32k) * (I know the device is at least 4k, but not 32k)
*/ */
if (!(name = dm_pool_alloc(cmd->mem, PATH_MAX))) { if (!(name = dm_pool_alloc(cmd->mem, PATH_MAX))) {
log_error("Name allocation failed - device not zeroed"); log_error("Name allocation failed - device not cleared");
return 0; return 0;
} }
if (lvm_snprintf(name, PATH_MAX, "%s%s/%s", cmd->dev_dir, if (lvm_snprintf(name, PATH_MAX, "%s%s/%s", cmd->dev_dir,
lv->vg->name, lv->name) < 0) { lv->vg->name, lv->name) < 0) {
log_error("Name too long - device not zeroed (%s)", lv->name); log_error("Name too long - device not cleared (%s)", lv->name);
return 0; return 0;
} }
log_verbose("Zeroing start of logical volume \"%s\"", lv->name); log_verbose("Clearing start of logical volume \"%s\"", lv->name);
if (!(dev = dev_cache_get(name, NULL))) { if (!(dev = dev_cache_get(name, NULL))) {
log_error("%s: not found: device not zeroed", name); log_error("%s: not found: device not cleared", name);
return 0; return 0;
} }
if (!dev_open_quiet(dev)) if (!dev_open_quiet(dev))
return 0; return 0;
dev_zero(dev, UINT64_C(0), (size_t) 4096); dev_set(dev, UINT64_C(0), (size_t) 4096, value);
dev_close_immediate(dev);
return 1;
}
/*
* This function writes a new header to the mirror log header to the lv
*
* Returns: 1 on success, 0 on failure
*/
static int _write_log_header(struct cmd_context *cmd, struct logical_volume *lv)
{
struct device *dev;
char *name;
struct { /* The mirror log header */
uint32_t magic;
uint32_t version;
uint64_t nr_regions;
} log_header;
log_header.magic = xlate32(MIRROR_MAGIC);
log_header.version = xlate32(MIRROR_DISK_VERSION);
log_header.nr_regions = xlate64((uint64_t)-1);
if (!(name = dm_pool_alloc(cmd->mem, PATH_MAX))) {
log_error("Name allocation failed - log header not written (%s)",
lv->name);
return 0;
}
if (lvm_snprintf(name, PATH_MAX, "%s%s/%s", cmd->dev_dir,
lv->vg->name, lv->name) < 0) {
log_error("Name too long - log header not written (%s)", lv->name);
return 0;
}
log_verbose("Writing log header to device, %s", lv->name);
if (!(dev = dev_cache_get(name, NULL))) {
log_error("%s: not found: log header not written", name);
return 0;
}
if (!dev_open_quiet(dev))
return 0;
if (!dev_write(dev, UINT64_C(0), sizeof(log_header), &log_header)) {
log_error("Failed to write log header to %s", name);
dev_close_immediate(dev);
return 0;
}
dev_close_immediate(dev); dev_close_immediate(dev);
return 1; return 1;
@ -1156,7 +1214,8 @@ struct logical_volume *create_mirror_log(struct cmd_context *cmd,
struct volume_group *vg, struct volume_group *vg,
struct alloc_handle *ah, struct alloc_handle *ah,
alloc_policy_t alloc, alloc_policy_t alloc,
const char *lv_name) const char *lv_name,
int in_sync)
{ {
struct logical_volume *log_lv; struct logical_volume *log_lv;
char *log_name; char *log_name;
@ -1201,12 +1260,18 @@ struct logical_volume *create_mirror_log(struct cmd_context *cmd,
goto error; goto error;
} }
if (activation() && !zero_lv(cmd, log_lv)) { if (activation() && !set_lv(cmd, log_lv, in_sync)) {
log_error("Aborting. Failed to wipe mirror log. " log_error("Aborting. Failed to wipe mirror log. "
"Remove new LV and retry."); "Remove new LV and retry.");
goto error; goto error;
} }
if (!_write_log_header(cmd, log_lv)) {
log_error("Aborting. Failed to write mirror log header. "
"Remove new LV and retry.");
goto error;
}
if (!deactivate_lv(cmd, log_lv)) { if (!deactivate_lv(cmd, log_lv)) {
log_error("Aborting. Failed to deactivate mirror log. " log_error("Aborting. Failed to deactivate mirror log. "
"Remove new LV and retry."); "Remove new LV and retry.");

View File

@ -97,8 +97,9 @@ struct logical_volume *create_mirror_log(struct cmd_context *cmd,
struct volume_group *vg, struct volume_group *vg,
struct alloc_handle *ah, struct alloc_handle *ah,
alloc_policy_t alloc, alloc_policy_t alloc,
const char *lv_name); const char *lv_name,
int in_sync);
int zero_lv(struct cmd_context *cmd, struct logical_volume *lv); int set_lv(struct cmd_context *cmd, struct logical_volume *lv, int value);
#endif #endif