summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/format_text/backup.c8
-rw-r--r--lib/format_text/export.c60
-rw-r--r--lib/format_text/flags.c31
-rw-r--r--lib/uuid/uuid.c3
-rw-r--r--tools/Makefile.in3
-rw-r--r--tools/commands.h3
-rw-r--r--tools/lvm.c13
-rw-r--r--tools/stub.h1
-rw-r--r--tools/toollib.c14
-rw-r--r--tools/toollib.h2
-rw-r--r--tools/vgcfgbackup.c35
11 files changed, 118 insertions, 55 deletions
diff --git a/lib/format_text/backup.c b/lib/format_text/backup.c
index d33a470a..ded809c6 100644
--- a/lib/format_text/backup.c
+++ b/lib/format_text/backup.c
@@ -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++;
}
diff --git a/lib/format_text/export.c b/lib/format_text/export.c
index bdb055b9..dbd90b45 100644
--- a/lib/format_text/export.c
+++ b/lib/format_text/export.c
@@ -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)
diff --git a/lib/format_text/flags.c b/lib/format_text/flags.c
index 8fd0ed7b..de96ef2d 100644
--- a/lib/format_text/flags.c
+++ b/lib/format_text/flags.c
@@ -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)
diff --git a/lib/uuid/uuid.c b/lib/uuid/uuid.c
index 2904e0b4..92b85d93 100644
--- a/lib/uuid/uuid.c
+++ b/lib/uuid/uuid.c
@@ -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;
}
diff --git a/tools/Makefile.in b/tools/Makefile.in
index fe4fa12b..2c4790bf 100644
--- a/tools/Makefile.in
+++ b/tools/Makefile.in
@@ -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 \
diff --git a/tools/commands.h b/tools/commands.h
index 46aa976b..647f9c79 100644
--- a/tools/commands.h
+++ b/tools/commands.h
@@ -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",
diff --git a/tools/lvm.c b/tools/lvm.c
index 334fda5a..8db5ff3f 100644
--- a/tools/lvm.c
+++ b/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;
}
diff --git a/tools/stub.h b/tools/stub.h
index d2e2ef02..59134716 100644
--- a/tools/stub.h
+++ b/tools/stub.h
@@ -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;}
diff --git a/tools/toollib.c b/tools/toollib.c
index bf9c562a..2581265c 100644
--- a/tools/toollib.c
+++ b/tools/toollib.c
@@ -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;
diff --git a/tools/toollib.h b/tools/toollib.h
index ce81dcba..559ee36a 100644
--- a/tools/toollib.h
+++ b/tools/toollib.h
@@ -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,
diff --git a/tools/vgcfgbackup.c b/tools/vgcfgbackup.c
new file mode 100644
index 00000000..9c79e8e8
--- /dev/null
+++ b/tools/vgcfgbackup.c
@@ -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);
+}
+