mirror of
git://sourceware.org/git/lvm2.git
synced 2025-01-18 10:04:20 +03:00
o Added functions to display what's in the archive.
o For now vgcfgrestore -l <vg> displays this list. A bit hacky, but it'll get better.
This commit is contained in:
parent
d1ad45cc41
commit
03888774a5
@ -20,6 +20,7 @@
|
||||
#include <sys/stat.h>
|
||||
#include <sys/file.h>
|
||||
#include <fcntl.h>
|
||||
#include <time.h>
|
||||
|
||||
|
||||
/*
|
||||
@ -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 : "<No description>");
|
||||
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;
|
||||
}
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
@ -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;
|
||||
|
@ -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 {
|
||||
|
@ -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);
|
||||
|
@ -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]))) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user