From 03888774a5aa7978ff69c9434ab48a589f1b8851 Mon Sep 17 00:00:00 2001 From: Joe Thornber Date: Mon, 11 Feb 2002 11:43:17 +0000 Subject: [PATCH] o Added functions to display what's in the archive. o For now vgcfgrestore -l displays this list. A bit hacky, but it'll get better. --- lib/format_text/archive.c | 51 +++++++++++++++++++++++++++++++++ lib/format_text/format-text.c | 4 ++- lib/format_text/format-text.h | 5 ++++ lib/format_text/import-export.h | 3 +- lib/format_text/import.c | 36 +++++++++++++++++------ lib/locking/locking.h | 4 +-- tools/archive.c | 5 ++++ tools/archive.h | 27 +++++++++-------- tools/commands.h | 14 ++++----- tools/vgcfgrestore.c | 11 +++++++ 10 files changed, 128 insertions(+), 32 deletions(-) diff --git a/lib/format_text/archive.c b/lib/format_text/archive.c index bf5e20ede..dda145fda 100644 --- a/lib/format_text/archive.c +++ b/lib/format_text/archive.c @@ -20,6 +20,7 @@ #include #include #include +#include /* @@ -251,3 +252,53 @@ int archive_vg(struct volume_group *vg, return 1; } + +static void _display_archive(struct cmd_context *cmd, struct uuid_map *um, + struct archive_file *af) +{ + struct volume_group *vg; + time_t when; + char *desc; + + log_print("path:\t\t%s", af->path); + + /* + * Read the archive file to ensure that it is valid, and + * retrieve the archive time and description. + */ + if (!(vg = text_vg_import(cmd, af->path, um, &when, &desc))) { + log_print("Unable to read archive file."); + return; + } + + log_print("description:\t%s", desc ? desc : ""); + log_print("time:\t\t%s", ctime(&when)); + + pool_free(cmd->mem, vg); +} + +int archive_list(struct cmd_context *cmd, struct uuid_map *um, + const char *dir, const char *vg) +{ + struct list *archives, *ah; + struct archive_file *af; + + if (!(archives = _scan_archive(cmd->mem, vg, dir))) { + log_err("Couldn't scan the archive directory (%s).", dir); + return 0; + } + + if (list_empty(archives)) + log_print("No archives found."); + + list_iterate (ah, archives) { + af = list_item(ah, struct archive_file); + + _display_archive(cmd, um, af); + log_print(" "); + } + + pool_free(cmd->mem, archives); + + return 1; +} diff --git a/lib/format_text/format-text.c b/lib/format_text/format-text.c index 351be046e..bbfeb4a56 100644 --- a/lib/format_text/format-text.c +++ b/lib/format_text/format-text.c @@ -77,8 +77,10 @@ static struct volume_group *_vg_read(struct format_instance *fi, { struct text_c *tc = (struct text_c *) fi->private; struct volume_group *vg; + time_t when; + char *desc; - if (!(vg = text_vg_import(fi->cmd, tc->path, tc->um))) { + if (!(vg = text_vg_import(fi->cmd, tc->path, tc->um, &when, &desc))) { stack; return NULL; } diff --git a/lib/format_text/format-text.h b/lib/format_text/format-text.h index 223e47c74..6dbd1844e 100644 --- a/lib/format_text/format-text.h +++ b/lib/format_text/format-text.h @@ -23,6 +23,11 @@ int archive_vg(struct volume_group *vg, uint32_t retain_days, uint32_t min_archive); +/* + * Displays a list of vg backups in a particular archive directory. + */ +int archive_list(struct cmd_context *cmd, struct uuid_map *um, + const char *dir, const char *vg); /* * The text format can read and write a volume_group to a file. diff --git a/lib/format_text/import-export.h b/lib/format_text/import-export.h index 015995a01..ed56e7c38 100644 --- a/lib/format_text/import-export.h +++ b/lib/format_text/import-export.h @@ -26,6 +26,7 @@ int read_flags(uint32_t *status, int type, struct config_value *cv); int text_vg_export(FILE *fp, struct volume_group *vg, const char *desc); struct volume_group *text_vg_import(struct cmd_context *cmd, const char *file, - struct uuid_map *um); + struct uuid_map *um, + time_t *when, char **desc); #endif diff --git a/lib/format_text/import.c b/lib/format_text/import.c index 4623419b5..e9ff6146f 100644 --- a/lib/format_text/import.c +++ b/lib/format_text/import.c @@ -372,7 +372,7 @@ static int _read_lv(struct pool *mem, } lv->minor = -1; - if ((lv->status & FIXED_MINOR) && + if ((lv->status & FIXED_MINOR) && !_read_int32(lvn, "minor", &lv->minor)) { log_error("Couldn't read 'minor' value for logical volume."); return 0; @@ -423,16 +423,15 @@ static int _read_sections(const char *section, section_fn fn, static struct volume_group *_read_vg(struct pool *mem, struct config_file *cf, struct uuid_map *um) { - struct config_node *vgn = cf->root, *cn; + struct config_node *vgn, *cn; struct volume_group *vg; struct hash_table *pv_hash = NULL; - if (!vgn) { - log_err("Couldn't find volume group."); - return NULL; - } + /* skip any top-level values */ + for (vgn = cf->root; (vgn && vgn->v); vgn = vgn->sib) + ; - if (!(vgn = cf->root)) { + if (!vgn) { log_err("Couldn't find volume group in file."); return NULL; } @@ -453,7 +452,7 @@ static struct volume_group *_read_vg(struct pool *mem, struct config_file *cf, } vgn = vgn->child; - + if ((cn = find_config_node(vgn, "system_id", '/')) && cn->v) { if (!cn->v->v.str) { log_error("system_id must be a string"); @@ -543,13 +542,30 @@ static struct volume_group *_read_vg(struct pool *mem, struct config_file *cf, return NULL; } +static void _read_desc(struct pool *mem, + struct config_file *cf, time_t *when, char **desc) +{ + const char *d; + unsigned int u = 0u; + + d = find_config_str(cf->root, "description", '/', ""); + *desc = pool_strdup(mem, d); + + get_config_uint32(cf->root, "creation_time", '/', &u); + *when = u; +} + struct volume_group *text_vg_import(struct cmd_context *cmd, const char *file, - struct uuid_map *um) + struct uuid_map *um, + time_t *when, char **desc) { struct volume_group *vg = NULL; struct config_file *cf; + *desc = NULL; + *when = 0; + if (!(cf = create_config_file())) { stack; goto out; @@ -567,6 +583,8 @@ struct volume_group *text_vg_import(struct cmd_context *cmd, vg->cmd = cmd; + _read_desc(cmd->mem, cf, when, desc); + out: destroy_config_file(cf); return vg; diff --git a/lib/locking/locking.h b/lib/locking/locking.h index 08233c96b..37d0c1498 100644 --- a/lib/locking/locking.h +++ b/lib/locking/locking.h @@ -13,12 +13,12 @@ int init_locking(int type, struct config_file *cf); void fin_locking(void); /* - * LCK_VG: + * LCK_VG: * Lock/unlock on-disk volume group data * Use "" to lock orphan PVs * char *vol holds volume group name * - * LCK_LV: + * LCK_LV: * Lock/unlock an individual logical volume * Also suspends/resumes the LV if it's active. * struct logical_volume *vol diff --git a/tools/archive.c b/tools/archive.c index f156bc53f..451c17d56 100644 --- a/tools/archive.c +++ b/tools/archive.c @@ -113,6 +113,11 @@ int archive(struct volume_group *vg) return 1; } +int archive_display(const char *vg_name) +{ + return archive_list(fid->cmd, the_um, _archive_params.dir, vg_name); +} + static struct { diff --git a/tools/archive.h b/tools/archive.h index 61b05c7c0..e10eca764 100644 --- a/tools/archive.h +++ b/tools/archive.h @@ -10,19 +10,21 @@ #include "metadata.h" /* - * There are two operations that come under the - * general area of backups. 'Archiving' occurs - * just before a volume group configuration is - * changed. The user may configure when archived - * files are expired. Typically archives will be - * stored in /etc/lvm/archive. + * FIXME: This file is going to merge with the archiving code in + * lib/format_text at some point. + */ + +/* + * There are two operations that come under the general area of + * backups. 'Archiving' occurs just before a volume group + * configuration is changed. The user may configure when + * archived files are expired. Typically archives will be stored + * in /etc/lvm/archive. * - * A 'backup' is a redundant copy of the *current* - * volume group configuration. As such it should - * be taken just after the volume group is - * changed. Only 1 backup file will exist. - * Typically backups will be stored in - * /etc/lvm/backups. + * A 'backup' is a redundant copy of the *current* volume group + * configuration. As such it should be taken just after the + * volume group is changed. Only 1 backup file will exist. + * Typically backups will be stored in /etc/lvm/backups. */ int archive_init(const char *dir, @@ -31,6 +33,7 @@ void archive_exit(void); void archive_enable(int flag); int archive(struct volume_group *vg); +int archive_display(const char *vg_name); int backup_init(const char *dir); void backup_exit(void); diff --git a/tools/commands.h b/tools/commands.h index 3c8acea24..a5274f28d 100644 --- a/tools/commands.h +++ b/tools/commands.h @@ -61,13 +61,13 @@ xx(lvchange, "\t[-v/--verbose]\n" "\tLogicalVolume[Path] [LogicalVolume[Path]...]\n", - autobackup_ARG, available_ARG, contiguous_ARG, + autobackup_ARG, available_ARG, contiguous_ARG, minor_ARG, persistent_ARG, partial_ARG, permission_ARG, readahead_ARG, test_ARG) xx(lvcreate, "Create a logical volume", - "lvcreate " "\n" + "lvcreate " "\n" "\t[-A|--autobackup {y|n}] " "\n" "\t[-C|--contiguous {y|n}] " "\n" "\t[-d|--debug]" "\n" @@ -95,12 +95,12 @@ xx(lvcreate, "\t-n|--name SnapshotLogicalVolumeName" "\n" "\t[-t|--test]" "\n" "\tLogicalVolume[Path] [PhysicalVolumePath...]" "\n", -chunksize_ARG, -snapshot_ARG, +chunksize_ARG, +snapshot_ARG, */ autobackup_ARG, contiguous_ARG, stripes_ARG, stripesize_ARG, - extents_ARG, size_ARG, name_ARG, permission_ARG, readahead_ARG, + extents_ARG, size_ARG, name_ARG, permission_ARG, readahead_ARG, minor_ARG, persistent_ARG, test_ARG, zero_ARG) @@ -136,7 +136,7 @@ xx(lvextend, xx(lvmchange, "With the device mapper, this is obsolete and does nothing.", - "lvmchange\n" + "lvmchange\n" "\t[-d/--debug]\n" "\t[-h/-?/--help]\n" "\t[-R/--reset]\n" @@ -375,7 +375,7 @@ xx(vgchange, "\t[VolumeGroupName...]\n", autobackup_ARG, available_ARG, logicalvolume_ARG, partial_ARG, - resizeable_ARG, resizable_ARG, allocation_ARG, + resizeable_ARG, resizable_ARG, allocation_ARG, test_ARG) xx(vgck, diff --git a/tools/vgcfgrestore.c b/tools/vgcfgrestore.c index 0d8e2d5c6..19e456711 100644 --- a/tools/vgcfgrestore.c +++ b/tools/vgcfgrestore.c @@ -15,6 +15,17 @@ int vgcfgrestore(int argc, char **argv) return ECMD_FAILED; } + /* + * FIXME: overloading the -l arg for now to display a + * list of archive files for a particular vg + */ + if (arg_count(list_ARG)) { + if (!archive_display(argv[0])) + return ECMD_FAILED; + + return 0; + } + if (!(arg_count(file_ARG) ? backup_restore_from_file(argv[0], arg_str_value(file_ARG, "")) : backup_restore(argv[0]))) {