/*
* 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;
}
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);
r = 1;
break;
}
+#else
+ r = 1;
+ break;
+#endif
index++;
}
#include "hash.h"
#include "pool.h"
#include "dbg_malloc.h"
+#include "lvm-string.h"
#include <stdio.h>
#include <stdarg.h>
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)
{
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;
}
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';
_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;
}
}
_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;
}
list_iterate (pvh, &vg->pvs) {
+ pv = &(list_item(pvh, struct pv_list)->pv);
+
if (!(name = _get_pv_name(f, pv))) {
stack;
return 0;
return 0;
}
- _out(f, "tid = \"%s\"", buffer);
+ _out(f, "id = \"%s\"", buffer);
_out_hint(f, "device = %s", dev_name(pv->dev));
_nl(f);
}
_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);
_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);
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);
}
}
- _out(f, "}");
_dec_indent(f);
+ _out(f, "}");
}
- _out(f, "}");
- _nl(f);
_dec_indent(f);
+ _out(f, "}");
return 1;
}
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;
}
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;
}
if (!_print_vg(f, vg))
fail;
+ _nl(f):
+
if (!_print_pvs(f, vg))
fail;
+ _nl(f);
+
if (!_print_lvs(f, vg))
fail;
_dec_indent(f);
_out(f, "}");
-
- r = 1;
+ r = !ferror(f->fp);
out:
if (f->mem)
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
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)
}
#define GROUPS (ID_LEN / 4)
+
int id_write_format(struct id *id, char *buffer, size_t size)
{
int i;
buffer[(i * 5) + 4] = '-';
}
- buffer[GROUPS * 5] = '\0';
+ buffer[(GROUPS * 5) - 1] = '\0';
return 1;
}
pvdisplay.c \
pvscan.c \
toollib.c \
- vgck.c \
+ vgcfgbackup.c \
vgchange.c \
+ vgck.c \
vgcreate.c \
vgdisplay.c \
vgextend.c \
"\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",
/* 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;
}
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;}
#include "tools.h"
#include "format-text.h"
#include "metadata.h"
+#include "lvm-string.h"
#include <ctype.h>
#include <limits.h>
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;
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;
#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,
--- /dev/null
+/*
+ * 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);
+}
+