mirror of
git://sourceware.org/git/lvm2.git
synced 2024-12-21 13:34:40 +03:00
vgscan/change/display/vgs automatically create metadata backup if out-of-date or missing.
This commit is contained in:
parent
b7c70050d6
commit
24e654645f
@ -1,5 +1,6 @@
|
|||||||
Version 2.01.11 -
|
Version 2.01.11 -
|
||||||
==============================
|
==============================
|
||||||
|
vgscan/change/display/vgs automatically create metadata backups if needed.
|
||||||
Fix contiguous allocation policy with linear.
|
Fix contiguous allocation policy with linear.
|
||||||
Cope with missing format1 PVs again.
|
Cope with missing format1 PVs again.
|
||||||
Remove lists of free PV segments.
|
Remove lists of free PV segments.
|
||||||
|
@ -152,7 +152,8 @@ static int _create_dir_recursive(const char *dir)
|
|||||||
if (*orig) {
|
if (*orig) {
|
||||||
rc = mkdir(orig, 0777);
|
rc = mkdir(orig, 0777);
|
||||||
if (rc < 0 && errno != EEXIST) {
|
if (rc < 0 && errno != EEXIST) {
|
||||||
log_sys_error("mkdir", orig);
|
if (errno != EROFS)
|
||||||
|
log_sys_error("mkdir", orig);
|
||||||
dbg_free(orig);
|
dbg_free(orig);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -164,7 +165,8 @@ static int _create_dir_recursive(const char *dir)
|
|||||||
/* Create final directory */
|
/* Create final directory */
|
||||||
rc = mkdir(dir, 0777);
|
rc = mkdir(dir, 0777);
|
||||||
if (rc < 0 && errno != EEXIST) {
|
if (rc < 0 && errno != EEXIST) {
|
||||||
log_sys_error("mkdir", dir);
|
if (errno != EROFS)
|
||||||
|
log_sys_error("mkdir", dir);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -106,7 +106,13 @@ int archive(struct volume_group *vg)
|
|||||||
if (!create_dir(_archive_params.dir))
|
if (!create_dir(_archive_params.dir))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
log_verbose("Archiving volume group \"%s\" metadata.", vg->name);
|
/* Trap a read-only file system */
|
||||||
|
if ((access(_archive_params.dir, R_OK | W_OK | X_OK) == -1) &&
|
||||||
|
(errno == EROFS))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
log_verbose("Archiving volume group \"%s\" metadata (seqno %u).", vg->name,
|
||||||
|
vg->seqno);
|
||||||
if (!__archive(vg)) {
|
if (!__archive(vg)) {
|
||||||
log_error("Volume group \"%s\" metadata archive failed.",
|
log_error("Volume group \"%s\" metadata archive failed.",
|
||||||
vg->name);
|
vg->name);
|
||||||
@ -189,6 +195,11 @@ int backup(struct volume_group *vg)
|
|||||||
if (!create_dir(_backup_params.dir))
|
if (!create_dir(_backup_params.dir))
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
/* Trap a read-only file system */
|
||||||
|
if ((access(_backup_params.dir, R_OK | W_OK | X_OK) == -1) &&
|
||||||
|
(errno == EROFS))
|
||||||
|
return 0;
|
||||||
|
|
||||||
if (!__backup(vg)) {
|
if (!__backup(vg)) {
|
||||||
log_error("Backup of volume group %s metadata failed.",
|
log_error("Backup of volume group %s metadata failed.",
|
||||||
vg->name);
|
vg->name);
|
||||||
@ -269,7 +280,7 @@ int backup_restore_vg(struct cmd_context *cmd, struct volume_group *vg)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
if (cmd->fmt != info->fmt) {
|
if (cmd->fmt != info->fmt) {
|
||||||
log_error("PV %s is a different format (%s)",
|
log_error("PV %s is a different format (seqno %s)",
|
||||||
dev_name(pv->dev), info->fmt->name);
|
dev_name(pv->dev), info->fmt->name);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -330,7 +341,7 @@ int backup_to_file(const char *file, const char *desc, struct volume_group *vg)
|
|||||||
|
|
||||||
cmd = vg->cmd;
|
cmd = vg->cmd;
|
||||||
|
|
||||||
log_verbose("Creating volume group backup \"%s\"", file);
|
log_verbose("Creating volume group backup \"%s\" (seqno %u).", file, vg->seqno);
|
||||||
|
|
||||||
if (!(context = create_text_context(cmd, file, desc)) ||
|
if (!(context = create_text_context(cmd, file, desc)) ||
|
||||||
!(tf = cmd->fmt_backup->ops->create_instance(cmd->fmt_backup, NULL,
|
!(tf = cmd->fmt_backup->ops->create_instance(cmd->fmt_backup, NULL,
|
||||||
@ -354,3 +365,34 @@ int backup_to_file(const char *file, const char *desc, struct volume_group *vg)
|
|||||||
tf->fmt->ops->destroy_instance(tf);
|
tf->fmt->ops->destroy_instance(tf);
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Update backup (and archive) if they're out-of-date or don't exist.
|
||||||
|
*/
|
||||||
|
void check_current_backup(struct volume_group *vg)
|
||||||
|
{
|
||||||
|
char path[PATH_MAX];
|
||||||
|
struct volume_group *vg_backup;
|
||||||
|
|
||||||
|
if ((vg->status & PARTIAL_VG) || (vg->status & EXPORTED_VG))
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (lvm_snprintf(path, sizeof(path), "%s/%s",
|
||||||
|
_backup_params.dir, vg->name) < 0) {
|
||||||
|
log_debug("Failed to generate backup filename.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
log_suppress(1);
|
||||||
|
/* Up-to-date backup exists? */
|
||||||
|
if ((vg_backup = backup_read_vg(vg->cmd, vg->name, path)) &&
|
||||||
|
(vg->seqno == vg_backup->seqno) &&
|
||||||
|
(id_equal(&vg->id, &vg_backup->id)))
|
||||||
|
return;
|
||||||
|
log_suppress(0);
|
||||||
|
|
||||||
|
if (vg_backup)
|
||||||
|
archive(vg_backup);
|
||||||
|
archive(vg);
|
||||||
|
backup(vg);
|
||||||
|
}
|
||||||
|
@ -60,4 +60,6 @@ int backup_restore(struct cmd_context *cmd, const char *vg_name);
|
|||||||
|
|
||||||
int backup_to_file(const char *file, const char *desc, struct volume_group *vg);
|
int backup_to_file(const char *file, const char *desc, struct volume_group *vg);
|
||||||
|
|
||||||
|
void check_current_backup(struct volume_group *vg);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -27,6 +27,8 @@ static int _vgs_single(struct cmd_context *cmd, const char *vg_name,
|
|||||||
if (!report_object(handle, vg, NULL, NULL, NULL, NULL))
|
if (!report_object(handle, vg, NULL, NULL, NULL, NULL))
|
||||||
return ECMD_FAILED;
|
return ECMD_FAILED;
|
||||||
|
|
||||||
|
check_current_backup(vg);
|
||||||
|
|
||||||
return ECMD_PROCESSED;
|
return ECMD_PROCESSED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -89,6 +89,10 @@ static int _vgchange_available(struct cmd_context *cmd, struct volume_group *vg)
|
|||||||
return ECMD_FAILED;
|
return ECMD_FAILED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* FIXME Move into library where clvmd can use it */
|
||||||
|
if (activate && !lockingfailed())
|
||||||
|
check_current_backup(vg);
|
||||||
|
|
||||||
if (activate && (active = lvs_in_vg_activated(vg)))
|
if (activate && (active = lvs_in_vg_activated(vg)))
|
||||||
log_verbose("%d logical volume(s) in volume group \"%s\" "
|
log_verbose("%d logical volume(s) in volume group \"%s\" "
|
||||||
"already active", active, vg->name);
|
"already active", active, vg->name);
|
||||||
|
@ -53,6 +53,8 @@ static int vgdisplay_single(struct cmd_context *cmd, const char *vg_name,
|
|||||||
process_each_pv_in_vg(cmd, vg, NULL, NULL, &pvdisplay_short);
|
process_each_pv_in_vg(cmd, vg, NULL, NULL, &pvdisplay_short);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
check_current_backup(vg);
|
||||||
|
|
||||||
return ECMD_PROCESSED;
|
return ECMD_PROCESSED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -36,6 +36,8 @@ static int vgscan_single(struct cmd_context *cmd, const char *vg_name,
|
|||||||
(vg->status & EXPORTED_VG) ? "exported " : "", vg_name,
|
(vg->status & EXPORTED_VG) ? "exported " : "", vg_name,
|
||||||
vg->fid->fmt->name);
|
vg->fid->fmt->name);
|
||||||
|
|
||||||
|
check_current_backup(vg);
|
||||||
|
|
||||||
return ECMD_PROCESSED;
|
return ECMD_PROCESSED;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user