1
0
mirror of git://sourceware.org/git/lvm2.git synced 2024-12-21 13:34:40 +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 -
=================================
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.
Fix uuid_from_num() buffer overrun.
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);
}
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;
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,
len >> SECTOR_SHIFT);
memset(buffer, 0, sizeof(buffer));
memset(buffer, value, sizeof(buffer));
while (1) {
s = len > sizeof(buffer) ? sizeof(buffer) : len;
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_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_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);
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;
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'",
dev_name(data->dev));
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,
mda_size1)) return 0;
if (!dev_zero((struct device *) pv->dev, start1,
if (!dev_set((struct device *) pv->dev, start1,
(size_t) (mda_size1 >
wipe_size ? : mda_size1))) {
wipe_size ? : mda_size1), 0)) {
log_error("Failed to wipe new metadata area");
return 0;
}
@ -1119,9 +1119,9 @@ static int _mda_setup(const struct format_type *fmt,
if (mda_size2) {
if (!add_mda(fmt, fmt->cmd->mem, mdas, pv->dev, start2,
mda_size2)) return 0;
if (!dev_zero(pv->dev, start2,
if (!dev_set(pv->dev, start2,
(size_t) (mda_size1 >
wipe_size ? : mda_size1))) {
wipe_size ? : mda_size1), 0)) {
log_error("Failed to wipe new metadata area");
return 0;
}

View File

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

View File

@ -73,6 +73,7 @@ void init_indent(int indent);
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 set_cmd_name(const char *cmd_name);
@ -85,6 +86,7 @@ int debug_level(void);
int ignorelockingfailure(void);
int lockingfailed(void);
int security_level(void);
int mirror_in_sync(void);
/* Suppress messages to stdout/stderr (1) or everywhere (2) */
/* Returns previous setting */

View File

@ -245,6 +245,9 @@ static int _add_log(struct dev_manager *dm, struct lv_segment *seg,
return 0;
}
if (mirror_in_sync() && !(seg->status & PVMOVE))
log_flags |= DM_NOSYNC;
if (_block_on_error_available && !(seg->status & PVMOVE))
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(separator_ARG, '\0', "separator", string_arg)
arg(mirrorsonly_ARG, '\0', "mirrorsonly", NULL)
arg(nosync_ARG, '\0', "nosync", NULL)
/* Allow some variations */
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,
lp->alloc,
lv->name))) {
lv->name, 0))) {
log_error("Failed to create mirror log.");
return 0;
}
@ -390,7 +390,7 @@ static int lvconvert_snapshot(struct cmd_context *cmd,
if (!lp->zero)
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 "
"exception store.");
return 0;

View File

@ -646,7 +646,7 @@ static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp)
lp->region_size);
if (!(log_lv = create_mirror_log(cmd, vg, ah, lp->alloc,
lv_name))) {
lv_name, 0))) {
log_error("Failed to create mirror log.");
return 0;
}
@ -730,7 +730,7 @@ static int _lvcreate(struct cmd_context *cmd, struct lvcreate_params *lp)
}
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 */
log_error("Aborting. Failed to wipe snapshot "
"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 "
"detected on %s. Wipe it? [y/n] ", name) == 'y'))) {
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",
name);
return 0;
@ -225,7 +225,7 @@ static int pvcreate_single(struct cmd_context *cmd, const char *pv_name,
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);
dev_close(dev);
goto error;

View File

@ -15,10 +15,15 @@
#include "tools.h"
#include "lv_alloc.h"
#include "xlate.h"
#include <sys/stat.h>
#include <sys/wait.h>
/* From linux/drivers/md/dm-log.c */
#define MIRROR_MAGIC 0x4D695272
#define MIRROR_DISK_VERSION 2
/* Command line args */
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;
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)
*/
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;
}
if (lvm_snprintf(name, PATH_MAX, "%s%s/%s", cmd->dev_dir,
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;
}
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))) {
log_error("%s: not found: device not zeroed", name);
log_error("%s: not found: device not cleared", name);
return 0;
}
if (!dev_open_quiet(dev))
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);
return 1;
@ -1156,7 +1214,8 @@ struct logical_volume *create_mirror_log(struct cmd_context *cmd,
struct volume_group *vg,
struct alloc_handle *ah,
alloc_policy_t alloc,
const char *lv_name)
const char *lv_name,
int in_sync)
{
struct logical_volume *log_lv;
char *log_name;
@ -1201,12 +1260,18 @@ struct logical_volume *create_mirror_log(struct cmd_context *cmd,
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. "
"Remove new LV and retry.");
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)) {
log_error("Aborting. Failed to deactivate mirror log. "
"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 alloc_handle *ah,
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