mirror of
git://sourceware.org/git/lvm2.git
synced 2025-03-24 14:50:34 +03:00
o Added a quick vgcfgbackup, needs parameters as yet.
This commit is contained in:
parent
493793dcbc
commit
2041d905a9
@ -289,7 +289,7 @@ static int _vg_write(struct format_instance *fi, struct volume_group *vg)
|
||||
/*
|
||||
* Write the backup, to a temporary file.
|
||||
*/
|
||||
if ((fd = mkstemp(backup_name))) {
|
||||
if ((fd = mkstemp(backup_name)) == -1) {
|
||||
log_err("Couldn't create temporary file for backup.");
|
||||
return 0;
|
||||
}
|
||||
@ -327,7 +327,7 @@ static int _vg_write(struct format_instance *fi, struct volume_group *vg)
|
||||
log_err("backup file name too long.");
|
||||
goto out;
|
||||
}
|
||||
|
||||
#if 0
|
||||
if (rename(tmp_name, backup_name) < 0) {
|
||||
log_err("couldn't rename backup file to %s.",
|
||||
backup_name);
|
||||
@ -335,6 +335,10 @@ static int _vg_write(struct format_instance *fi, struct volume_group *vg)
|
||||
r = 1;
|
||||
break;
|
||||
}
|
||||
#else
|
||||
r = 1;
|
||||
break;
|
||||
#endif
|
||||
|
||||
index++;
|
||||
}
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include "hash.h"
|
||||
#include "pool.h"
|
||||
#include "dbg_malloc.h"
|
||||
#include "lvm-string.h"
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
@ -26,8 +27,24 @@ struct formatter {
|
||||
|
||||
FILE *fp; /* where we're writing to */
|
||||
int indent; /* current level of indentation */
|
||||
|
||||
int error;
|
||||
};
|
||||
|
||||
/*
|
||||
* Formatting functions.
|
||||
*/
|
||||
static void _out_size(struct formatter *f, uint64_t size,
|
||||
const char *fmt, ...)
|
||||
__attribute__ (( format (printf, 3, 4) ));
|
||||
|
||||
static void _out_hint(struct formatter *f, const char *fmt, ...)
|
||||
__attribute__ (( format (printf, 2, 3) ));
|
||||
|
||||
static void _out(struct formatter *f, const char *fmt, ...)
|
||||
__attribute__ (( format (printf, 2, 3) ));
|
||||
|
||||
|
||||
#define MAX_INDENT 5
|
||||
static void _inc_indent(struct formatter *f)
|
||||
{
|
||||
@ -37,7 +54,7 @@ static void _inc_indent(struct formatter *f)
|
||||
|
||||
static void _dec_indent(struct formatter *f)
|
||||
{
|
||||
if (--f->indent) {
|
||||
if (!f->indent--) {
|
||||
log_debug("Indenting seems to have messed up\n");
|
||||
f->indent = 0;
|
||||
}
|
||||
@ -58,6 +75,9 @@ static void _out_with_comment(struct formatter *f, const char *comment,
|
||||
int i;
|
||||
char white_space[MAX_INDENT + 1];
|
||||
|
||||
if (ferror(f->fp))
|
||||
return;
|
||||
|
||||
for (i = 0; i < f->indent; i++)
|
||||
white_space[i] = '\t';
|
||||
white_space[i] = '\0';
|
||||
@ -165,7 +185,7 @@ static int _print_header(struct formatter *f, struct volume_group *vg)
|
||||
_out(f,
|
||||
"# This file was originally generated by the LVM2 library\n"
|
||||
"# It is inadvisable for people to edit this by hand unless\n"
|
||||
"# they *really* know what they're doing.\n"
|
||||
"# they know what they're doing.\n"
|
||||
"# Generated: %s\n", ctime(&t));
|
||||
return 1;
|
||||
}
|
||||
@ -180,22 +200,16 @@ static int _print_vg(struct formatter *f, struct volume_group *vg)
|
||||
}
|
||||
|
||||
_out(f, "id = \"%s\"", buffer);
|
||||
_nl(f);
|
||||
|
||||
if (!print_flags(vg->status, VG_FLAGS, buffer, sizeof(buffer))) {
|
||||
stack;
|
||||
return 0;
|
||||
}
|
||||
|
||||
_out(f, "status = %s");
|
||||
_nl(f);
|
||||
|
||||
_out(f, "status = %s", buffer);
|
||||
_out_size(f, vg->extent_size, "extent_size = %u", vg->extent_size);
|
||||
_nl(f);
|
||||
|
||||
_out(f, "max_lv = %u", vg->max_lv);
|
||||
_out(f, "max_pv = %u", vg->max_pv);
|
||||
_nl(f);
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -223,6 +237,8 @@ static int _print_pvs(struct formatter *f, struct volume_group *vg)
|
||||
|
||||
list_iterate (pvh, &vg->pvs) {
|
||||
|
||||
pv = &(list_item(pvh, struct pv_list)->pv);
|
||||
|
||||
if (!(name = _get_pv_name(f, pv))) {
|
||||
stack;
|
||||
return 0;
|
||||
@ -238,7 +254,7 @@ static int _print_pvs(struct formatter *f, struct volume_group *vg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
_out(f, "tid = \"%s\"", buffer);
|
||||
_out(f, "id = \"%s\"", buffer);
|
||||
_out_hint(f, "device = %s", dev_name(pv->dev));
|
||||
_nl(f);
|
||||
|
||||
@ -249,7 +265,7 @@ static int _print_pvs(struct formatter *f, struct volume_group *vg)
|
||||
}
|
||||
|
||||
_out(f, "status = %s", buffer);
|
||||
_out(f, "pe_start = %u", pv->pe_start);
|
||||
_out(f, "pe_start = %llu", pv->pe_start);
|
||||
_out_size(f, vg->extent_size * (uint64_t) pv->pe_count,
|
||||
"pe_count = %u", pv->pe_count);
|
||||
|
||||
@ -272,7 +288,7 @@ static int _print_segment(struct formatter *f, struct volume_group *vg,
|
||||
_out(f, "segment%u {", count);
|
||||
_inc_indent(f);
|
||||
|
||||
_out(f, "start_entent = %u", seg->le);
|
||||
_out(f, "start_extent = %u", seg->le);
|
||||
_out_size(f, seg->len * vg->extent_size, "extent_count = %u", seg->len);
|
||||
_out(f, "stripes = %u", seg->stripes);
|
||||
|
||||
@ -338,9 +354,8 @@ static int _print_lvs(struct formatter *f, struct volume_group *vg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
_out(f, "status = %s", buffer);
|
||||
_out(f, "read_ahead = %u", lv->read_ahead);
|
||||
_nl(f);
|
||||
|
||||
_out(f, "segment_count = %u", _count_segments(lv));
|
||||
_nl(f);
|
||||
|
||||
@ -354,13 +369,12 @@ static int _print_lvs(struct formatter *f, struct volume_group *vg)
|
||||
}
|
||||
}
|
||||
|
||||
_out(f, "}");
|
||||
_dec_indent(f);
|
||||
_out(f, "}");
|
||||
}
|
||||
|
||||
_out(f, "}");
|
||||
_nl(f);
|
||||
_dec_indent(f);
|
||||
_out(f, "}");
|
||||
|
||||
return 1;
|
||||
}
|
||||
@ -391,7 +405,8 @@ static int _build_pv_names(struct formatter *f,
|
||||
list_iterate (pvh, &vg->pvs) {
|
||||
pv = &list_item(pvh, struct pv_list)->pv;
|
||||
|
||||
if (snprintf(buffer, sizeof(buffer), "pv%d", count++) < 0) {
|
||||
if (lvm_snprintf(buffer, sizeof(buffer),
|
||||
"pv%d", count++) < 0) {
|
||||
stack;
|
||||
goto bad;
|
||||
}
|
||||
@ -401,7 +416,7 @@ static int _build_pv_names(struct formatter *f,
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (!hash_insert(f->pv_names, dev_name(pv->dev), buffer)) {
|
||||
if (!hash_insert(f->pv_names, dev_name(pv->dev), name)) {
|
||||
stack;
|
||||
goto bad;
|
||||
}
|
||||
@ -449,9 +464,13 @@ int text_vg_export(FILE *fp, struct volume_group *vg)
|
||||
if (!_print_vg(f, vg))
|
||||
fail;
|
||||
|
||||
_nl(f):
|
||||
|
||||
if (!_print_pvs(f, vg))
|
||||
fail;
|
||||
|
||||
_nl(f);
|
||||
|
||||
if (!_print_lvs(f, vg))
|
||||
fail;
|
||||
|
||||
@ -459,8 +478,7 @@ int text_vg_export(FILE *fp, struct volume_group *vg)
|
||||
|
||||
_dec_indent(f);
|
||||
_out(f, "}");
|
||||
|
||||
r = 1;
|
||||
r = !ferror(f->fp);
|
||||
|
||||
out:
|
||||
if (f->mem)
|
||||
|
@ -62,6 +62,23 @@ static struct flag *_get_flags(int type)
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int _emit(char **buffer, size_t *size, const char *fmt, ...)
|
||||
{
|
||||
size_t n;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, fmt);
|
||||
n = vsnprintf(*buffer, *size, fmt, ap);
|
||||
va_end(ap);
|
||||
|
||||
if (n < 0 || (n == size))
|
||||
return 0;
|
||||
|
||||
*buffer += n;
|
||||
*size -= n;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* Converts a bitset to an array of string values,
|
||||
* using one of the tables defined at the top of
|
||||
@ -77,31 +94,27 @@ int print_flags(uint32_t status, int type, char *buffer, size_t size)
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((n = lvm_snprintf(buffer, size, "[")) < 0)
|
||||
if (!_emit(&buffer, &size, "["))
|
||||
return 0;
|
||||
size -= n;
|
||||
|
||||
for (f = 0; flags[f].mask; f++) {
|
||||
if (status & flags[f].mask) {
|
||||
if (!first) {
|
||||
if ((n = lvm_snprintf(buffer, size, ", ")) < 0)
|
||||
if (!_emit(&buffer, &size, ", "))
|
||||
return 0;
|
||||
size -= n;
|
||||
|
||||
} else
|
||||
first = 0;
|
||||
|
||||
n = lvm_snprintf(buffer, size, "\"%s\"",
|
||||
flags[f].description);
|
||||
if (n < 0)
|
||||
if (!_emit(&buffer, &size, "\"%s\"",
|
||||
flags[f].description))
|
||||
return 0;
|
||||
size -= n;
|
||||
|
||||
status &= ~flags[f].mask;
|
||||
}
|
||||
}
|
||||
|
||||
if ((n = lvm_snprintf(buffer, size, "]")) < 0)
|
||||
if (!_emit(&buffer, &size, "]"))
|
||||
return 0;
|
||||
|
||||
if (status)
|
||||
|
@ -79,6 +79,7 @@ int id_cmp(struct id *lhs, struct id *rhs)
|
||||
}
|
||||
|
||||
#define GROUPS (ID_LEN / 4)
|
||||
|
||||
int id_write_format(struct id *id, char *buffer, size_t size)
|
||||
{
|
||||
int i;
|
||||
@ -92,7 +93,7 @@ int id_write_format(struct id *id, char *buffer, size_t size)
|
||||
buffer[(i * 5) + 4] = '-';
|
||||
}
|
||||
|
||||
buffer[GROUPS * 5] = '\0';
|
||||
buffer[(GROUPS * 5) - 1] = '\0';
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -37,8 +37,9 @@ SOURCES=\
|
||||
pvdisplay.c \
|
||||
pvscan.c \
|
||||
toollib.c \
|
||||
vgck.c \
|
||||
vgcfgbackup.c \
|
||||
vgchange.c \
|
||||
vgck.c \
|
||||
vgcreate.c \
|
||||
vgdisplay.c \
|
||||
vgextend.c \
|
||||
|
@ -336,7 +336,8 @@ xx(vgcfgbackup,
|
||||
"\t[-h|--help] " "\n"
|
||||
"\t[-v|--verbose]" "\n"
|
||||
"\t[-V|--version] " "\n"
|
||||
"\t[VolumeGroupName...]\n" )
|
||||
"\t[VolumeGroupName...]\n",
|
||||
autobackup_ARG)
|
||||
|
||||
xx(vgcfgrestore,
|
||||
"Restore volume group configuration",
|
||||
|
13
tools/lvm.c
13
tools/lvm.c
@ -543,18 +543,9 @@ static int process_common_commands(struct command *com)
|
||||
|
||||
/* Set autobackup if command takes this option */
|
||||
for (l = 0; l < com->num_args; l++)
|
||||
if (com->valid_args[l] == autobackup_ARG) {
|
||||
if (snprintf(backup_dir, sizeof(backup_dir),
|
||||
"%s/backup", _system_dir) < 0) {
|
||||
log_err("Backup path too long.");
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
|
||||
if (autobackup_init("/etc/lvm/backup"))
|
||||
if (com->valid_args[l] == autobackup_ARG)
|
||||
if (!autobackup_init(_system_dir))
|
||||
return EINVALID_CMD_LINE;
|
||||
else
|
||||
break;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -23,7 +23,6 @@ int lvmdiskscan(int argc, char **argv) {return 1;}
|
||||
int lvmsadc(int argc, char **argv) {return 1;}
|
||||
int lvmsar(int argc, char **argv) {return 1;}
|
||||
int pvdata(int argc, char **argv) {return 1;}
|
||||
int vgcfgbackup(int argc, char **argv) {return 1;}
|
||||
int vgcfgrestore(int argc, char **argv) {return 1;}
|
||||
int vgexport(int argc, char **argv) {return 1;}
|
||||
int vgimport(int argc, char **argv) {return 1;}
|
||||
|
@ -7,6 +7,7 @@
|
||||
#include "tools.h"
|
||||
#include "format-text.h"
|
||||
#include "metadata.h"
|
||||
#include "lvm-string.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
@ -15,24 +16,23 @@ static int _autobackup = 1;
|
||||
static char _backup_dir[PATH_MAX];
|
||||
static int _period = 7; /* backups will be kept for at least 7 days */
|
||||
static int _min_backups = 10; /* always have at least ten backups, even
|
||||
* if they're old than the period */
|
||||
* if they're older than the period */
|
||||
|
||||
/*
|
||||
* Work out by looking at command line, config
|
||||
* file and environment variable whether we should
|
||||
* do an autobackup.
|
||||
*/
|
||||
int autobackup_init(const char *dir)
|
||||
int autobackup_init(const char *system_dir)
|
||||
{
|
||||
char *lvm_autobackup;
|
||||
|
||||
if (strlen(dir) > sizeof(_backup_dir) - 1) {
|
||||
log_err("Backup directory (%s) too long.", dir);
|
||||
if (lvm_snprintf(_backup_dir, sizeof(_backup_dir),
|
||||
"%s/backup", system_dir) < 0) {
|
||||
log_err("Backup directory (%s/backup) too long.", system_dir);
|
||||
return 0;
|
||||
}
|
||||
|
||||
strcpy(_backup_dir, dir);
|
||||
|
||||
if (arg_count(autobackup_ARG)) {
|
||||
_autobackup = !strcmp(arg_str_value(autobackup_ARG, "y"), "y");
|
||||
return 1;
|
||||
@ -94,7 +94,7 @@ static int __autobackup(struct volume_group *vg)
|
||||
|
||||
int autobackup(struct volume_group *vg)
|
||||
{
|
||||
if (!__autobackup) {
|
||||
if (!_autobackup) {
|
||||
log_print("WARNING: You don't have an automatic backup of %s",
|
||||
vg->name);
|
||||
return 1;
|
||||
|
@ -22,7 +22,7 @@
|
||||
#define _LVM_TOOLLIB_H
|
||||
|
||||
int autobackup_set(void);
|
||||
int autobackup_init(const char *dir);
|
||||
int autobackup_init(const char *system_dir);
|
||||
int autobackup(struct volume_group *vg);
|
||||
|
||||
int process_each_vg(int argc, char **argv,
|
||||
|
35
tools/vgcfgbackup.c
Normal file
35
tools/vgcfgbackup.c
Normal file
@ -0,0 +1,35 @@
|
||||
/*
|
||||
* Copyright (C) 2001 Sistina Software (UK) Limited.
|
||||
*
|
||||
* This file is released under the GPL.
|
||||
*/
|
||||
|
||||
#include "tools.h"
|
||||
|
||||
static int vg_backup_single(const char *vg_name)
|
||||
{
|
||||
struct volume_group *vg;
|
||||
|
||||
log_verbose("Checking for volume group %s", vg_name);
|
||||
if (!(vg = fid->ops->vg_read(fid, vg_name))) {
|
||||
log_error("Volume group %s not found", vg_name);
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
|
||||
log_print("Found %sactive volume group %s",
|
||||
(vg->status & ACTIVE) ? "" : "in", vg_name);
|
||||
|
||||
if (!autobackup(vg)) {
|
||||
stack;
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
|
||||
log_print("Volume group %s successfully backed up.", vg_name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int vgcfgbackup(int argc, char **argv)
|
||||
{
|
||||
return process_each_vg(argc, argv, &vg_backup_single);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user