mirror of
git://sourceware.org/git/lvm2.git
synced 2025-03-31 14:50:37 +03:00
o sync laptop to test machine.
This commit is contained in:
parent
a11603ca6c
commit
8f37cadce8
@ -12,116 +12,83 @@
|
||||
#include "hash.h"
|
||||
|
||||
/*
|
||||
* The text format is a human readable metadata
|
||||
* format that will be used to store the metadata
|
||||
* backups from the LVM2 system. By being human
|
||||
* readable it is hoped that people will be able
|
||||
* to recieve a lot more support when things go
|
||||
* wrong.
|
||||
*
|
||||
* The format instance is given a directory path
|
||||
* upon creation. Each file in this directory
|
||||
* whose name is of the form '(.*)_[0-9]*.vg' is a config
|
||||
* file (see lib/config.[hc]), which contains a
|
||||
* description of a single volume group.
|
||||
*
|
||||
* The prefix ($1 from the above regex) of the
|
||||
* config file gives the volume group name.
|
||||
*
|
||||
* Backup files that have expired will be removed.
|
||||
* NOTE: Currently there can be only one vg per file.
|
||||
*/
|
||||
|
||||
struct text_c {
|
||||
uint32_t retain_days;
|
||||
uint32_t min_retains;
|
||||
|
||||
char *dir;
|
||||
};
|
||||
|
||||
/*
|
||||
* Returns a list of config files, one for each
|
||||
* .vg file in the given directory.
|
||||
*/
|
||||
struct config_list {
|
||||
struct list list;
|
||||
struct config_file *cf;
|
||||
};
|
||||
|
||||
struct list *_get_configs(struct pool *mem, const char *dir)
|
||||
static void _not_written(const char *cmd)
|
||||
{
|
||||
|
||||
log_err("The text format is lacking an implementation for '%s'", cmd);
|
||||
}
|
||||
|
||||
void _put_configs(struct pool *mem, struct list *configs)
|
||||
struct list *_get_vgs(struct format_instance *fi)
|
||||
{
|
||||
struct list *cfh;
|
||||
struct config_list *cl;
|
||||
_not_written("_get_vgs");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
list_iterate(cfh, configs) {
|
||||
cl = list_item(cfh, struct config_file);
|
||||
destroy_config_file(cl->cf);
|
||||
struct list *_get_pvs(struct format_instance *fi)
|
||||
{
|
||||
_not_written("_get_vgs");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct physical_volume *_pv_read(struct format_instance *fi,
|
||||
const char *pv_name)
|
||||
{
|
||||
_not_written("_get_vgs");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int _pv_setup(struct format_instance *fi, struct physical_volume *pv,
|
||||
struct volume_group *vg)
|
||||
{
|
||||
_not_written("_get_vgs");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int _pv_write(struct format_instance *fi, struct physical_volume *pv)
|
||||
{
|
||||
_not_written("_get_vgs");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int _vg_setup(struct format_instance *fi, struct volume_group *vg)
|
||||
{
|
||||
_not_written("_get_vgs");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
struct volume_group *_vg_read(struct format_instance *fi,
|
||||
const char *vg_name)
|
||||
{
|
||||
_not_written("_get_vgs");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int _vg_write(struct format_instance *fi, struct volume_group *vg)
|
||||
{
|
||||
FILE *fp;
|
||||
char *file = (char *) fi->private;
|
||||
|
||||
/* FIXME: should be opened exclusively */
|
||||
if (!(fp = fopen(file, "w"))) {
|
||||
log_err("Couldn't open text file '%s'.", file);
|
||||
return 0;
|
||||
}
|
||||
|
||||
pool_free(mem, configs);
|
||||
if (!text_vg_export(fp, vg)) {
|
||||
log_err("Couldn't write text format file.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Just returns the vg->name fields
|
||||
*/
|
||||
struct list *get_vgs(struct format_instance *fi)
|
||||
void _destroy(struct format_instance *fi)
|
||||
{
|
||||
struct text_c *tc = (struct text_c *) fi->private;
|
||||
|
||||
|
||||
pool_free(cmd->mem, fi);
|
||||
}
|
||||
|
||||
struct list *get_pvs(struct format_instance *fi)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
struct physical_volume *pv_read(struct format_instance *fi,
|
||||
const char *pv_name)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int pv_setup(struct format_instance *fi, struct physical_volume *pv,
|
||||
struct volume_group *vg)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int pv_write(struct format_instance *fi, struct physical_volume *pv)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int vg_setup(struct format_instance *fi, struct volume_group *vg)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
struct volume_group *vg_read(struct format_instance *fi, const char *vg_name)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
int vg_write(struct format_instance *fi, struct volume_group *vg)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
void destroy(struct format_instance *fi)
|
||||
{
|
||||
/*
|
||||
* We don't need to do anything here since
|
||||
* everything is allocated from the pool.
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
static struct format_handler _text_handler = {
|
||||
get_vgs: _get_vgs,
|
||||
get_pvs: _get_pvs,
|
||||
@ -134,37 +101,28 @@ static struct format_handler _text_handler = {
|
||||
destroy: _destroy
|
||||
};
|
||||
|
||||
|
||||
struct format_instance *text_format_create(struct cmd_context,
|
||||
const char *dir,
|
||||
uint32_t retain_days,
|
||||
uint32_t min_retains)
|
||||
struct format_instance *text_format_create(struct cmd_context *cmd,
|
||||
const char *file)
|
||||
{
|
||||
struct format_instance *fi;
|
||||
struct text_c *tc = NULL;
|
||||
const char *no_alloc = "Couldn't allocate text format object.";
|
||||
|
||||
if (!(tc = pool_zalloc(cmd->mem, sizeof(*tc)))) {
|
||||
stack;
|
||||
struct format_instance *fi;
|
||||
char *file;
|
||||
|
||||
if (!(fi = pool_alloc(cmd->mem, sizeof(*fi)))) {
|
||||
log_err(no_alloc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!(tc->dir = pool_strdup(cmd->mem, dir))) {
|
||||
stack;
|
||||
goto bad;
|
||||
}
|
||||
|
||||
if (!(fi = pool_alloc(cmd->mem, sizeof(*fi)))) {
|
||||
stack;
|
||||
goto bad;
|
||||
if (!(file = pool_strdup(cmd->mem, file))) {
|
||||
pool_free(fi);
|
||||
log_err(no_alloc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fi->cmd = cmd;
|
||||
fi->ops = _text_handler;
|
||||
fi->private = tc;
|
||||
fi->private = file;
|
||||
|
||||
return fi;
|
||||
|
||||
bad:
|
||||
pool_free(mem, tc);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -10,6 +10,14 @@
|
||||
#include "lvm-types.h"
|
||||
#include "metadata.h"
|
||||
|
||||
/*
|
||||
* The backup format is used to maintain a set of backup files.
|
||||
* 'retain_days' gives the minimum number of days that a backup must
|
||||
* be held for.
|
||||
*
|
||||
* 'min_backups' is the minimum number of backups required for each volume
|
||||
* group.
|
||||
*/
|
||||
struct format_instance *backup_format_create(struct cmd_context *cmd,
|
||||
const char *dir,
|
||||
uint32_t retain_days,
|
||||
@ -17,4 +25,10 @@ struct format_instance *backup_format_create(struct cmd_context *cmd,
|
||||
|
||||
void backup_expire(struct format_instance *fi);
|
||||
|
||||
/*
|
||||
* The text format can read and write a volume_group to a file.
|
||||
*/
|
||||
struct format_instance *text_format_create(struct cmd_context *cmd,
|
||||
const char *file);
|
||||
|
||||
#endif
|
||||
|
@ -35,14 +35,9 @@ void archive_exit(void)
|
||||
memset(&_archive_params, 0, sizeof(_archive_params));
|
||||
}
|
||||
|
||||
void archive_disable(void)
|
||||
void archive_enable(int flag)
|
||||
{
|
||||
_archive_params.enabled = 0;
|
||||
}
|
||||
|
||||
void archive_enable(void)
|
||||
{
|
||||
_archive_params.enabled = 1;
|
||||
_archive_params.enabled = flag;
|
||||
}
|
||||
|
||||
static int __archive(struct volume_group *vg)
|
||||
@ -108,6 +103,11 @@ void backup_exit(void)
|
||||
memset(&backup_params, 0, sizeof(_backup_params));
|
||||
}
|
||||
|
||||
void backup_enable(int flag)
|
||||
{
|
||||
_backup_params.enabled = flag;
|
||||
}
|
||||
|
||||
static int __backup(struct volume_group *vg)
|
||||
{
|
||||
int r;
|
||||
|
@ -25,8 +25,7 @@ int archive_init(const char *dir,
|
||||
unsigned int keep_days, unsigned int keep_min);
|
||||
void archive_exit(void);
|
||||
|
||||
void archive_disable(void);
|
||||
void archive_enable(void);
|
||||
void archive_enable(int flag);
|
||||
int archive(struct volume_group *vg);
|
||||
|
||||
int backup_init(const char *dir);
|
||||
|
@ -26,7 +26,7 @@ arg(debug_ARG, 'd', "debug", NULL)
|
||||
arg(disk_ARG, 'D', "disk", NULL)
|
||||
arg(exported_ARG, 'e', "exported", NULL)
|
||||
arg(physicalextent_ARG, 'E', "physicalextent", NULL)
|
||||
arg(file_ARG, 'f', "file", NULL)
|
||||
arg(file_ARG, 'f', "file", string_arg)
|
||||
arg(force_ARG, 'f', "force", NULL)
|
||||
arg(full_ARG, 'f', "full", NULL)
|
||||
arg(help_ARG, 'h', "help", NULL)
|
||||
|
@ -232,7 +232,7 @@ xx(lvscan,
|
||||
"lvscan " "\n"
|
||||
"\t[-b|--blockdevice] " "\n"
|
||||
"\t[-d|--debug] " "\n"
|
||||
"\t[-D|--disk]" "\n"
|
||||
"\t[-D|--disk]" "\n"
|
||||
"\t[-h|--help] " "\n"
|
||||
"\t[-v|--verbose] " "\n"
|
||||
"\t[--version]\n",
|
||||
@ -337,7 +337,7 @@ xx(vgcfgbackup,
|
||||
"\t[-v|--verbose]" "\n"
|
||||
"\t[-V|--version] " "\n"
|
||||
"\t[VolumeGroupName...]\n",
|
||||
autobackup_ARG)
|
||||
file_ARG)
|
||||
|
||||
xx(vgcfgrestore,
|
||||
"Restore volume group configuration",
|
||||
|
100
tools/lvm.c
100
tools/lvm.c
@ -52,21 +52,18 @@ static int _dump_filter;
|
||||
static int _interactive;
|
||||
static FILE *_log;
|
||||
|
||||
/*
|
||||
* Both verbose have a global setting which comes
|
||||
* from the command line that invoked the shell,
|
||||
* or the config file. These are the 'default'
|
||||
* variables. In addition people may set a level
|
||||
* for a single command.
|
||||
*/
|
||||
static int _default_debug;
|
||||
static int _debug;
|
||||
struct config_info {
|
||||
int debug;
|
||||
int verbose;
|
||||
int test;
|
||||
|
||||
static int _default_verbose;
|
||||
static int _verbose;
|
||||
int archive; /* should we archive ? */
|
||||
int backup; /* should we backup ? */
|
||||
};
|
||||
|
||||
static struct config_info _default_settings;
|
||||
static struct config_info _current_settings;
|
||||
|
||||
static int _default_test;
|
||||
static int _test;
|
||||
|
||||
/*
|
||||
* The lvm_sys_dir contains:
|
||||
@ -74,16 +71,11 @@ static int _test;
|
||||
* o The lvm configuration (lvm.conf)
|
||||
* o The persistent filter cache (.cache)
|
||||
* o Volume group backups (backup/)
|
||||
*
|
||||
*/
|
||||
static char _sys_dir[PATH_MAX] = "/etc/lvm";
|
||||
static char _backup_dir[PATH_MAX];
|
||||
static char _dev_dir[PATH_MAX];
|
||||
|
||||
static int _backup_days = 14; /* Keep at least 14 days */
|
||||
static int _backup_number = 10; /* Keep at least 10 backups */
|
||||
static int _backup_auto = 1; /* Autobackups enabled by default */
|
||||
|
||||
#define DEFAULT_DEV_DIR "/dev"
|
||||
|
||||
|
||||
@ -509,25 +501,24 @@ static int process_common_commands(struct command *com)
|
||||
{
|
||||
int l;
|
||||
|
||||
_current_settings = _default_settings;
|
||||
|
||||
if (arg_count(suspend_ARG))
|
||||
kill(getpid(), SIGSTOP);
|
||||
|
||||
_debug = _default_debug;
|
||||
if (arg_count(debug_ARG))
|
||||
_debug = arg_count(debug_ARG);
|
||||
_current_settings.debug = arg_count(debug_ARG);
|
||||
|
||||
_verbose = _default_verbose;
|
||||
if (arg_count(verbose_ARG))
|
||||
_verbose = arg_count(verbose_ARG);
|
||||
_current_settings.verbose = arg_count(verbose_ARG);
|
||||
|
||||
if (arg_count(quiet_ARG)) {
|
||||
_debug = 0;
|
||||
_verbose = 0;
|
||||
_current_settings.debug = 0;
|
||||
_current_settings.verbose = 0;
|
||||
}
|
||||
|
||||
_test = _default_test;
|
||||
if (arg_count(test_ARG))
|
||||
_test = arg_count(test_ARG);
|
||||
_current_settings.test = arg_count(test_ARG);
|
||||
|
||||
if (arg_count(help_ARG)) {
|
||||
usage(com->name);
|
||||
@ -542,10 +533,10 @@ 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 (!autobackup_init(_backup_dir, _backup_days,
|
||||
_backup_number, _backup_auto))
|
||||
return EINVALID_CMD_LINE;
|
||||
if (arg_count(autobackup_ARG)) {
|
||||
_current_settings.archive = 1;
|
||||
_current_settings.backup = 1;
|
||||
}
|
||||
|
||||
/* Zero indicates it's OK to continue processing this command */
|
||||
return 0;
|
||||
@ -579,6 +570,16 @@ static void display_help(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void _use_settings(struct config_info *settings)
|
||||
{
|
||||
init_debug(settings->debug);
|
||||
init_verbose(settings->verbose);
|
||||
init_test(settings->test);
|
||||
|
||||
archive_enable(settings->archive);
|
||||
backup_enable(settings->backup);
|
||||
}
|
||||
|
||||
static int run_command(int argc, char **argv)
|
||||
{
|
||||
int ret = 0;
|
||||
@ -594,19 +595,16 @@ static int run_command(int argc, char **argv)
|
||||
if ((ret = process_common_commands(the_command)))
|
||||
return ret;
|
||||
|
||||
init_debug(_debug);
|
||||
init_verbose(_verbose);
|
||||
init_test(_test);
|
||||
|
||||
_use_settings(&_current_settings);
|
||||
ret = the_command->fn(argc, argv);
|
||||
|
||||
/*
|
||||
* set the debug and verbose levels back
|
||||
* to the global default.
|
||||
* to the global default. We have to do
|
||||
* this so the logging levels get set
|
||||
* correctly for program exit.
|
||||
*/
|
||||
init_debug(_default_debug);
|
||||
init_verbose(_default_verbose);
|
||||
init_test(_default_test);
|
||||
_use_settings(&_default_settings);
|
||||
|
||||
/*
|
||||
* free off any memory the command used.
|
||||
@ -665,14 +663,13 @@ static void __init_log(struct config_file *cf)
|
||||
init_log(_log);
|
||||
}
|
||||
|
||||
_default_debug = find_config_int(cf->root, "log/level", '/', 0);
|
||||
init_debug(_default_debug);
|
||||
_default_settings.debug =
|
||||
find_config_int(cf->root, "log/level", '/', 0);
|
||||
|
||||
_default_verbose = find_config_int(cf->root, "log/verbose", '/', 0);
|
||||
init_verbose(_default_verbose);
|
||||
_default_settings.verbose =
|
||||
find_config_int(cf->root, "log/verbose", '/', 0);
|
||||
|
||||
_default_test = find_config_int(cf->root, "log/test", '/', 0);
|
||||
init_test(_default_test);
|
||||
_default_settings.test = find_config_int(cf->root, "log/test", '/', 0);
|
||||
}
|
||||
|
||||
static int dev_cache_setup(struct config_file *cf)
|
||||
@ -843,7 +840,7 @@ static int init(void)
|
||||
}
|
||||
|
||||
if (lvm_snprintf(_dev_dir, sizeof(_dev_dir), "%s/",
|
||||
find_config_str(cmd->cf->root, "devices/dir",
|
||||
find_config_str(cmd->cf->root, "devices/dir",
|
||||
'/', DEFAULT_DEV_DIR)) < 0) {
|
||||
log_error("Device directory given in config file too long");
|
||||
return 0;
|
||||
@ -854,8 +851,8 @@ static int init(void)
|
||||
|
||||
dm_log_init(print_log);
|
||||
|
||||
if (!*strncpy(_backup_dir,
|
||||
find_config_str(cmd->cf->root, "backup/dir", '/', ""),
|
||||
if (!*strncpy(_backup_dir,
|
||||
find_config_str(cmd->cf->root, "backup/dir", '/', ""),
|
||||
sizeof(_backup_dir)) &&
|
||||
*_sys_dir &&
|
||||
lvm_snprintf(_backup_dir, sizeof(_backup_dir), "%s/backup",
|
||||
@ -867,13 +864,13 @@ static int init(void)
|
||||
if (!create_dir(_backup_dir))
|
||||
return 0;
|
||||
|
||||
_backup_days = find_config_int(cmd->cf->root, "backup/days", '/',
|
||||
_backup_days = find_config_int(cmd->cf->root, "backup/days", '/',
|
||||
_backup_days);
|
||||
|
||||
_backup_number = find_config_int(cmd->cf->root, "backup/keep", '/',
|
||||
_backup_number = find_config_int(cmd->cf->root, "backup/keep", '/',
|
||||
_backup_number);
|
||||
|
||||
_backup_auto = find_config_int(cmd->cf->root, "backup/auto", '/',
|
||||
_backup_auto = find_config_int(cmd->cf->root, "backup/auto", '/',
|
||||
_backup_auto);
|
||||
|
||||
if (!dev_cache_setup(cmd->cf))
|
||||
@ -892,6 +889,7 @@ static int init(void)
|
||||
if (!(fid = create_lvm1_format(cmd)))
|
||||
return 0;
|
||||
|
||||
use_settings(_default_settings);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1103,7 +1101,7 @@ static void _read_history(void)
|
||||
if (read_history(hist_file))
|
||||
log_very_verbose("Couldn't read history from %s.", hist_file);
|
||||
|
||||
stifle_history(find_config_int(cmd->cf->root, "shell/history_size",
|
||||
stifle_history(find_config_int(cmd->cf->root, "shell/history_size",
|
||||
'/', MAX_HISTORY));
|
||||
|
||||
}
|
||||
|
@ -14,15 +14,15 @@ static int _keep_days; /* keep for at least this number of days */
|
||||
static int _keep_number; /* keep at least this number of backups */
|
||||
|
||||
/*
|
||||
* Determine whether or not to do autobackup.
|
||||
* Determine whether or not to do autobackup.
|
||||
* Cmd line overrides environment variable which in turn overrides config file
|
||||
*/
|
||||
int autobackup_init(const char *backup_dir, int keep_days, int keep_number,
|
||||
int autobackup)
|
||||
int archive_init(const char *backup_dir, int keep_days, int keep_number,
|
||||
int autobackup)
|
||||
{
|
||||
char *lvm_autobackup;
|
||||
|
||||
if (lvm_snprintf(_backup_dir, sizeof(_backup_dir),
|
||||
if (lvm_snprintf(_backup_dir, sizeof(_backup_dir),
|
||||
"%s", backup_dir) < 0) {
|
||||
log_error("Backup directory name too long.");
|
||||
return 0;
|
||||
@ -33,7 +33,7 @@ int autobackup_init(const char *backup_dir, int keep_days, int keep_number,
|
||||
_autobackup = autobackup; /* Config file setting */
|
||||
|
||||
if (arg_count(autobackup_ARG)) {
|
||||
_autobackup = !strcmp(arg_str_value(autobackup_ARG, "y"), "y");
|
||||
_autobackup = arg_int_value(autobackup_ARG, 0);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -53,7 +53,7 @@ int autobackup_init(const char *backup_dir, int keep_days, int keep_number,
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int __autobackup(struct volume_group *vg)
|
||||
static int __backup_old(struct volume_group *vg)
|
||||
{
|
||||
int r;
|
||||
struct pool *old;
|
||||
@ -62,7 +62,7 @@ static int __autobackup(struct volume_group *vg)
|
||||
old = vg->cmd->mem;
|
||||
|
||||
/*
|
||||
* Create a temprary pool for this, I
|
||||
* Create a temporary pool for this, I
|
||||
* doubt it's used but the backup code has
|
||||
* the right to expect it.
|
||||
*/
|
||||
@ -87,7 +87,10 @@ static int __autobackup(struct volume_group *vg)
|
||||
return r;
|
||||
}
|
||||
|
||||
int autobackup(struct volume_group *vg)
|
||||
/*
|
||||
* This backs up a volume group that is about to have it's .
|
||||
*/
|
||||
int auto_backup(struct volume_group *vg)
|
||||
{
|
||||
if (!_autobackup || !*_backup_dir) {
|
||||
log_print("WARNING: You don't have an automatic backup of %s",
|
||||
@ -111,6 +114,8 @@ int autobackup(struct volume_group *vg)
|
||||
return 1;
|
||||
}
|
||||
|
||||
int backup_new
|
||||
|
||||
|
||||
int create_dir(const char *dir)
|
||||
{
|
||||
|
@ -6,6 +6,25 @@
|
||||
|
||||
#include "tools.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
static int _backup_to_file(const char *file, struct volume_group *vg)
|
||||
{
|
||||
int r;
|
||||
struct format_instance *tf;
|
||||
|
||||
if (!(tf = text_format_create(vg->cmd, file))) {
|
||||
log_error("Couldn't create backup object.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!(r = tf->ops->vg_write(tf, vg)))
|
||||
stack;
|
||||
|
||||
tf->ops->destroy(tf);
|
||||
return r;
|
||||
}
|
||||
|
||||
static int vg_backup_single(const char *vg_name)
|
||||
{
|
||||
struct volume_group *vg;
|
||||
@ -19,9 +38,16 @@ static int vg_backup_single(const char *vg_name)
|
||||
log_print("Found %sactive volume group %s",
|
||||
(vg->status & ACTIVE) ? "" : "in", vg_name);
|
||||
|
||||
if (!autobackup(vg)) {
|
||||
stack;
|
||||
return ECMD_FAILED;
|
||||
if (arg_count(file_ARG)) {
|
||||
_backup_to_file(arg_value(file_ARG), vg);
|
||||
|
||||
} else {
|
||||
/* just use the normal backup code */
|
||||
backup_enable(); /* force a backup */
|
||||
if (!backup(vg)) {
|
||||
stack;
|
||||
return ECMD_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
log_print("Volume group %s successfully backed up.", vg_name);
|
||||
|
Loading…
x
Reference in New Issue
Block a user