diff --git a/lib/format_text/format-text.c b/lib/format_text/format-text.c index 2b0c3bc06..9a58e80f4 100644 --- a/lib/format_text/format-text.c +++ b/lib/format_text/format-text.c @@ -68,14 +68,33 @@ static int _vg_setup(struct format_instance *fi, struct volume_group *vg) static struct volume_group *_vg_read(struct format_instance *fi, const char *vg_name) { - _not_written("_get_vgs"); - return NULL; + char *file = (char *) fi->private; + struct volume_group *vg; + + if (!(vg = text_vg_import(fi->cmd, file))) { + stack; + return NULL; + } + + /* + * Currently you can only have a single volume group per + * text file (this restriction may remain). We need to + * check that it contains the correct volume group. + */ + if (strcmp(vg_name, vg->name)) { + pool_free(fi->cmd->mem, vg); + log_err("'%s' does not contain volume group '%s'.", + file, vg_name); + return NULL; + } + + return vg; } static int _vg_write(struct format_instance *fi, struct volume_group *vg) { FILE *fp; - int fd; + int fd; char *slash; char *file = (char *) fi->private; char temp_file[PATH_MAX], temp_dir[PATH_MAX]; @@ -87,6 +106,7 @@ static int _vg_write(struct format_instance *fi, struct volume_group *vg) else if (slash - file < PATH_MAX) { strncpy(temp_dir, file, slash - file); temp_dir[slash - file] = '\0'; + } else { log_error("Text format failed to determine directory."); return 0; @@ -125,7 +145,8 @@ static int _vg_write(struct format_instance *fi, struct volume_group *vg) static void _destroy(struct format_instance *fi) { - pool_free(fi->cmd->mem, fi); + dbg_free(fi->private); + dbg_free(fi); } static struct format_handler _text_handler = { @@ -148,13 +169,13 @@ struct format_instance *text_format_create(struct cmd_context *cmd, struct format_instance *fi; char *path; - if (!(fi = pool_alloc(cmd->mem, sizeof(*fi)))) { + if (!(fi = dbg_malloc(sizeof(*fi)))) { log_err(no_alloc); return NULL; } - if (!(path = pool_strdup(cmd->mem, file))) { - pool_free(fi->cmd->mem, fi); + if (!(path = dbg_strdup(file))) { + dbg_free(fi); log_err(no_alloc); return NULL; } diff --git a/tools/archive.c b/tools/archive.c index 2f40c1bb6..42d4117f5 100644 --- a/tools/archive.c +++ b/tools/archive.c @@ -198,3 +198,64 @@ int backup_remove(const char *vg_name) return 1; } +static int _read_vg(struct command_context *cmd, + const char *vg_name, const char *file) +{ + int r; + struct format_instance *tf; + + if (!(tf = text_format_create(cmd, file))) { + log_error("Couldn't create text format object."); + return 0; + } + + if (!(r = tf->ops->vg_read(tf, vg_name))) + stack; + + tf->ops->destroy(tf); + return r; +} + +int backup_restore_from_file(const char *vg_name, const char *file) +{ + struct volume_group *vg; + + /* + * Read in the volume group. + */ + if (!(vg = _read_vg(vg_name, file))) { + stack; + return 0; + } + + /* + * Check that those pv's referenced in the backup are + * currently orphans or members of the vg.s + */ + /* + * FIXME: waiting for label code. + */ + + /* + * Write the vg. + */ + if (!fid->ops->vg_write(fid, vg)) { + stack; + return 0; + } + + return 1; +} + +int backup_restore(const char *vg_name) +{ + char path[PATH_MAX]; + + if (lvm_snprintf(path, sizeof(path), "%s/%s", + _backup_params.dir, vg_name) < 0) { + log_err("Failed to generate backup filename (for restore)."); + return 0; + } + + return backup_restore_from_file(vg_name, path); +} diff --git a/tools/archive.h b/tools/archive.h index 505d045ac..61b05c7c0 100644 --- a/tools/archive.h +++ b/tools/archive.h @@ -39,4 +39,7 @@ void backup_enable(int flag); int backup(struct volume_group *vg); int backup_remove(const char *vg_name); +int backup_restore_from_file(const char *vg_name, const char *file); +int backup_restore(const char *vg_name); + #endif diff --git a/tools/stub.h b/tools/stub.h index 591347161..5bf2e78d0 100644 --- a/tools/stub.h +++ b/tools/stub.h @@ -1,21 +1,7 @@ /* - * Copyright (C) 2001 Sistina Software - * - * LVM is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; either version 2, or (at your option) - * any later version. - * - * LVM is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with LVM; see the file COPYING. If not, write to - * the Free Software Foundation, 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * Copyright (C) 2001 Sistina Software (UK) Limited. * + * This file is released under the GPL. */ int e2fsadm(int argc, char **argv) {return 1;} @@ -23,7 +9,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 vgcfgrestore(int argc, char **argv) {return 1;} int vgexport(int argc, char **argv) {return 1;} int vgimport(int argc, char **argv) {return 1;} int vgmknodes(int argc, char **argv) {return 1;} diff --git a/tools/vgcreate.c b/tools/vgcreate.c index 58ce6ab7b..4efee30c6 100644 --- a/tools/vgcreate.c +++ b/tools/vgcreate.c @@ -55,12 +55,12 @@ int vgcreate(int argc, char **argv) log_error("maxlogicalvolumes too low"); return EINVALID_CMD_LINE; } - + if (max_pv < 1) { log_error("maxphysicalvolumes too low"); return EINVALID_CMD_LINE; } - + /* Strip dev_dir if present */ if (!strncmp(vg_name, fid->cmd->dev_dir, strlen(fid->cmd->dev_dir))) vg_name += strlen(fid->cmd->dev_dir); @@ -72,16 +72,16 @@ int vgcreate(int argc, char **argv) } /* Create the new VG */ - if (!(vg = vg_create(fid, vg_name, extent_size, max_pv, max_lv, + if (!(vg = vg_create(fid, vg_name, extent_size, max_pv, max_lv, argc - 1, argv + 1))) return ECMD_FAILED; - if (max_lv != vg->max_lv) - log_error("Warning: Setting maxlogicalvolumes to %d", + if (max_lv != vg->max_lv) + log_error("Warning: Setting maxlogicalvolumes to %d", vg->max_lv); - if (max_pv != vg->max_pv) - log_error("Warning: Setting maxphysicalvolumes to %d", + if (max_pv != vg->max_pv) + log_error("Warning: Setting maxphysicalvolumes to %d", vg->max_pv); if (!archive(vg))