summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--WHATS_NEW1
-rw-r--r--lib/log/log.c11
-rw-r--r--lib/log/log.h3
-rw-r--r--man/vgcfgbackup.812
-rw-r--r--tools/archiver.c4
-rw-r--r--tools/vgcfgbackup.c44
6 files changed, 69 insertions, 6 deletions
diff --git a/WHATS_NEW b/WHATS_NEW
index 0f2d87c0..f6c5982e 100644
--- a/WHATS_NEW
+++ b/WHATS_NEW
@@ -1,5 +1,6 @@
Version 2.00.17 -
=============================
+ vgcfgbackup -f accepts template with %s for VG name.
Extend hash functions to handle non-null-terminated data.
Add local activation support.
Tidy relative paths in makefile includes.
diff --git a/lib/log/log.c b/lib/log/log.c
index 19fab7eb..55f939cb 100644
--- a/lib/log/log.c
+++ b/lib/log/log.c
@@ -38,6 +38,7 @@ static int _indent = 1;
static int _log_cmd_name = 0;
static int _log_suppress = 0;
static int _ignorelockingfailure = 0;
+static int _security_level = SECURITY_LEVEL;
static char _cmd_name[30] = "";
static char _msg_prefix[30] = " ";
static int _already_logging = 0;
@@ -147,6 +148,11 @@ void init_ignorelockingfailure(int level)
_ignorelockingfailure = level;
}
+void init_security_level(int level)
+{
+ _security_level = level;
+}
+
void init_cmd_name(int status)
{
_log_cmd_name = status;
@@ -191,6 +197,11 @@ int ignorelockingfailure()
return _ignorelockingfailure;
}
+int security_level()
+{
+ return _security_level;
+}
+
void init_debug(int level)
{
_debug_level = level;
diff --git a/lib/log/log.h b/lib/log/log.h
index dd500b9f..c241b275 100644
--- a/lib/log/log.h
+++ b/lib/log/log.h
@@ -49,6 +49,7 @@
#define _LOG_FATAL 2
#define VERBOSE_BASE_LEVEL _LOG_WARN
+#define SECURITY_LEVEL 0
void init_log_file(const char *log_file, int append);
void init_log_direct(const char *log_file, int append);
@@ -68,6 +69,7 @@ void init_cmd_name(int status);
void init_msg_prefix(const char *prefix);
void init_indent(int indent);
void init_ignorelockingfailure(int level);
+void init_security_level(int level);
void set_cmd_name(const char *cmd_name);
@@ -76,6 +78,7 @@ int partial_mode(void);
int pvmove_mode(void);
int debug_level(void);
int ignorelockingfailure(void);
+int security_level(void);
/* Suppress messages to stdout/stderr */
void log_suppress(int suppress);
diff --git a/man/vgcfgbackup.8 b/man/vgcfgbackup.8
index 8d44dad9..b072af6a 100644
--- a/man/vgcfgbackup.8
+++ b/man/vgcfgbackup.8
@@ -15,10 +15,18 @@ vgcfgbackup \- backup volume group descriptor area
allows you to backup the metadata
of your volume groups.
If you don't name any volume groups on the command line, all of them
-will be backed up. This DOESN'T backup user/system data in logical
+will be backed up.
+.sp
+In a default installation, each volume group gets backed up into a separate
+file bearing the name of the volume group in the directory /etc/lvm/backup.
+You can write the backup to an alternative file using -f. In this case
+if you are backing up more than one volume group the filename is
+treated as a template, and %s gets replaced by the volume group name.
+.sp
+NB. This DOESN'T backup user/system data in logical
volume(s)! Backup /etc/lvm regularly too.
.SH OPTIONS
See \fBlvm\fP for common options.
.SH SEE ALSO
.BR lvm (8),
-.BR vgcreate (8)
+.BR vgcfgrestore (8)
diff --git a/tools/archiver.c b/tools/archiver.c
index 72492225..acf48c96 100644
--- a/tools/archiver.c
+++ b/tools/archiver.c
@@ -174,8 +174,6 @@ static int __backup(struct volume_group *vg)
return 0;
}
- log_verbose("Creating volume group backup \"%s\"", name);
-
return backup_to_file(name, desc, vg);
}
@@ -332,6 +330,8 @@ int backup_to_file(const char *file, const char *desc, struct volume_group *vg)
cmd = vg->cmd;
+ log_verbose("Creating volume group backup \"%s\"", file);
+
if (!(context = create_text_context(cmd, file, desc)) ||
!(tf = cmd->fmt_backup->ops->create_instance(cmd->fmt_backup, NULL,
context))) {
diff --git a/tools/vgcfgbackup.c b/tools/vgcfgbackup.c
index e1221694..987896a3 100644
--- a/tools/vgcfgbackup.c
+++ b/tools/vgcfgbackup.c
@@ -15,10 +15,42 @@
#include "tools.h"
+static char *_expand_filename(const char *template, const char *vg_name,
+ char **last_filename)
+{
+ char *filename;
+
+ if (security_level())
+ return dbg_strdup(template);
+
+ filename = dbg_malloc(PATH_MAX);
+ if (snprintf(filename, PATH_MAX, template, vg_name) < 0) {
+ log_error("Error processing filename template %s",
+ template);
+ dbg_free(filename);
+ return NULL;
+ }
+ if (*last_filename && !strncmp(*last_filename, filename,
+ strlen(template))) {
+ log_error("VGs must be backed up into different files. "
+ "Use %%s in filename for VG name.");
+ dbg_free(filename);
+ return NULL;
+ }
+
+ dbg_free(*last_filename);
+ *last_filename = filename;
+
+ return filename;
+}
+
static int vg_backup_single(struct cmd_context *cmd, const char *vg_name,
struct volume_group *vg, int consistent,
void *handle)
{
+ char **last_filename = (char **)handle;
+ char *filename;
+
if (!vg) {
log_error("Volume group \"%s\" not found", vg_name);
return ECMD_FAILED;
@@ -28,8 +60,13 @@ static int vg_backup_single(struct cmd_context *cmd, const char *vg_name,
log_error("Warning: Volume group \"%s\" inconsistent", vg_name);
if (arg_count(cmd, file_ARG)) {
- backup_to_file(arg_value(cmd, file_ARG), vg->cmd->cmd_line, vg);
+ if (!(filename = _expand_filename(arg_value(cmd, file_ARG),
+ vg->name, last_filename))) {
+ stack;
+ return ECMD_FAILED;
+ }
+ backup_to_file(filename, vg->cmd->cmd_line, vg);
} else {
if (!consistent) {
log_error("No backup taken: specify filename with -f "
@@ -53,13 +90,16 @@ static int vg_backup_single(struct cmd_context *cmd, const char *vg_name,
int vgcfgbackup(struct cmd_context *cmd, int argc, char **argv)
{
int ret;
+ char *last_filename = NULL;
if (partial_mode())
init_pvmove(1);
- ret = process_each_vg(cmd, argc, argv, LCK_VG_READ, 0, NULL,
+ ret = process_each_vg(cmd, argc, argv, LCK_VG_READ, 0, &last_filename,
&vg_backup_single);
+ dbg_free(last_filename);
+
init_pvmove(0);
return ret;