1
0
mirror of git://sourceware.org/git/lvm2.git synced 2025-03-10 16:58:47 +03:00

o Add cmd_line field to struct cmd_context

o  Text format now has a description and time field at the top level.

o  archiving and backup set the description appropriately. eg,

   for an archive:

     description = "Created *before* executing 'lvextend test_vg/lvol0 -l +1'."
     creation_time = 1013166332

   for a backup:

     description = "Created *after* executing 'lvextend test_vg/lvol0 -l +1'."
     creation_time = 1013166332

This is preparing the way for a simple vgcfgundo command.
This commit is contained in:
Joe Thornber 2002-02-08 11:13:47 +00:00
parent af7bbe5a6c
commit e74999af51
9 changed files with 147 additions and 44 deletions

View File

@ -39,6 +39,7 @@ struct archive_c {
uint32_t min_retains;
char *dir;
char *desc;
/*
* An ordered list of previous archives. Each list
@ -296,9 +297,10 @@ static int _scan_archives(struct archive_c *bc)
static int _vg_write(struct format_instance *fi, struct volume_group *vg)
{
struct archive_c *bc = (struct archive_c *) fi->private;
int r = 0, i, fd;
unsigned int index = 0;
struct archive_c *bc = (struct archive_c *) fi->private;
struct archive_file *last;
FILE *fp = NULL;
char temp_file[PATH_MAX], archive_name[PATH_MAX];
@ -314,7 +316,7 @@ static int _vg_write(struct format_instance *fi, struct volume_group *vg)
return 0;
}
if (!text_vg_export(fp, vg)) {
if (!text_vg_export(fp, vg, bc->desc)) {
stack;
fclose(fp);
return 0;
@ -374,10 +376,14 @@ static struct format_handler _archive_handler = {
destroy: _destroy
};
/*
* FIXME: format_instances shouldn't be allocated from the pool.
*/
struct format_instance *archive_format_create(struct cmd_context *cmd,
const char *dir,
uint32_t retain_days,
uint32_t min_retains)
const char *dir,
uint32_t retain_days,
uint32_t min_retains,
const char *desc)
{
struct format_instance *fi;
struct archive_c *bc = NULL;
@ -398,6 +404,11 @@ struct format_instance *archive_format_create(struct cmd_context *cmd,
goto bad;
}
if (!(bc->desc = pool_strdup(mem, desc))) {
stack;
goto bad;
}
bc->retain_days = retain_days;
bc->min_retains = min_retains;

View File

@ -172,7 +172,8 @@ static void _out(struct formatter *f, const char *fmt, ...)
va_end(ap);
}
static int _print_header(struct formatter *f, struct volume_group *vg)
static int _print_header(struct formatter *f,
struct volume_group *vg, const char *desc)
{
time_t t;
@ -181,6 +182,10 @@ static int _print_header(struct formatter *f, struct volume_group *vg)
_out(f,
"# This file was originally generated by the LVM2 library\n"
"# Generated: %s\n", ctime(&t));
_out(f, "description = \"%s\"", desc);
_out(f, "creation_time = %lu\n", t);
return 1;
}
@ -217,7 +222,7 @@ static int _print_vg(struct formatter *f, struct volume_group *vg)
static inline const char *
_get_pv_name(struct formatter *f, struct physical_volume *pv)
{
return (pv) ? (const char *)
return (pv) ? (const char *)
hash_lookup(f->pv_names, dev_name(pv->dev)) :
"Missing";
}
@ -431,7 +436,7 @@ static int _build_pv_names(struct formatter *f,
return 0;
}
int text_vg_export(FILE *fp, struct volume_group *vg)
int text_vg_export(FILE *fp, struct volume_group *vg, const char *desc)
{
int r = 0;
struct formatter *f;
@ -452,7 +457,7 @@ int text_vg_export(FILE *fp, struct volume_group *vg)
#define fail do {stack; goto out;} while(0)
if (!_print_header(f, vg))
if (!_print_header(f, vg, desc))
fail;
_out(f, "%s {", vg->name);

View File

@ -25,6 +25,7 @@
struct text_c {
char *path;
char *desc;
struct uuid_map *um;
};
@ -130,7 +131,7 @@ static int _vg_write(struct format_instance *fi, struct volume_group *vg)
return 0;
}
if (!text_vg_export(fp, vg)) {
if (!text_vg_export(fp, vg, tc->desc)) {
log_error("Failed to write metadata to %s.", temp_file);
fclose(fp);
return 0;
@ -173,33 +174,35 @@ static struct format_handler _text_handler = {
struct format_instance *text_format_create(struct cmd_context *cmd,
const char *file,
struct uuid_map *um)
struct uuid_map *um,
const char *desc)
{
const char *no_alloc = "Couldn't allocate text format object.";
struct format_instance *fi;
char *path;
char *path, *d;
struct text_c *tc;
if (!(fi = dbg_malloc(sizeof(*fi)))) {
log_err(no_alloc);
return NULL;
stack;
goto no_mem;
}
if (!(path = dbg_strdup(file))) {
dbg_free(fi);
log_err(no_alloc);
return NULL;
stack;
goto no_mem;
}
if (!(d = dbg_strdup(desc))) {
stack;
goto no_mem;
}
if (!(tc = dbg_malloc(sizeof(*tc)))) {
dbg_free(fi);
dbg_free(path);
log_err(no_alloc);
return NULL;
stack;
goto no_mem;
}
tc->path = path;
tc->desc = d;
tc->um = um;
fi->cmd = cmd;
@ -207,4 +210,17 @@ struct format_instance *text_format_create(struct cmd_context *cmd,
fi->private = tc;
return fi;
no_mem:
if (fi)
dbg_free(fi);
if (path)
dbg_free(path);
if (d)
dbg_free(path);
log_err("Couldn't allocate text format object.");
return NULL;
}

View File

@ -12,18 +12,17 @@
#include "uuid-map.h"
/*
* The archive format is used to maintain a set of metadata backup files
* in an archive directory.
* 'retain_days' is the minimum number of days that an archive file must
* be held for.
*
* 'min_archives' is the minimum number of archives required to be kept
* for each volume group.
* The archive format is used to maintain a set of metadata
* backup files in an archive directory. 'retain_days' is the
* minimum number of days that an archive file must be held for.
* 'min_archives' is the minimum number of archives required to
* be kept for each volume group.
*/
struct format_instance *archive_format_create(struct cmd_context *cmd,
const char *dir,
uint32_t retain_days,
uint32_t min_archives);
const char *dir,
uint32_t retain_days,
uint32_t min_archives,
const char *desc);
void backup_expire(struct format_instance *fi);
@ -32,6 +31,7 @@ void backup_expire(struct format_instance *fi);
*/
struct format_instance *text_format_create(struct cmd_context *cmd,
const char *file,
struct uuid_map *um);
struct uuid_map *um,
const char *desc);
#endif

View File

@ -24,7 +24,7 @@ int print_flags(uint32_t status, int type, char *buffer, size_t size);
int read_flags(uint32_t *status, int type, struct config_value *cv);
int text_vg_export(FILE *fp, struct volume_group *vg);
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);

View File

@ -148,6 +148,7 @@ struct cmd_context {
struct pool *mem;
/* misc. vars needed by format handler */
char *cmd_line;
char *dev_dir;
struct dev_filter *filter;
struct config_file *cf;
@ -267,7 +268,7 @@ struct logical_volume *lv_create(struct format_instance *fi,
struct volume_group *vg,
struct list *acceptable_pvs);
int lv_reduce(struct format_instance *fi,
int lv_reduce(struct format_instance *fi,
struct logical_volume *lv, uint32_t extents);
int lv_extend(struct format_instance *fi,

View File

@ -59,15 +59,42 @@ void archive_enable(int flag)
_archive_params.enabled = flag;
}
static char *_build_desc(struct pool *mem, const char *line, int before)
{
size_t len = strlen(line) + 32;
char *buffer;
if (!(buffer = pool_zalloc(mem, strlen(line) + 32))) {
stack;
return NULL;
}
if (snprintf(buffer, len,
"Created %s executing '%s'",
before ? "*before*" : "*after*", line) < 0) {
stack;
return NULL;
}
return buffer;
}
static int __archive(struct volume_group *vg)
{
int r;
struct format_instance *archiver;
char *desc;
if (!(desc = _build_desc(vg->cmd->mem, vg->cmd->cmd_line, 1))) {
stack;
return 0;
}
if (!(archiver = archive_format_create(vg->cmd,
_archive_params.dir,
_archive_params.keep_days,
_archive_params.keep_number))) {
_archive_params.dir,
_archive_params.keep_days,
_archive_params.keep_number,
desc))) {
log_error("Couldn't create archiver object.");
return 0;
}
@ -141,6 +168,12 @@ static int __backup(struct volume_group *vg)
int r;
struct format_instance *tf;
char name[PATH_MAX];
char *desc;
if (!(desc = _build_desc(vg->cmd->mem, vg->cmd->cmd_line, 0))) {
stack;
return 0;
}
if (lvm_snprintf(name, sizeof(name), "%s/%s",
_backup_params.dir, vg->name) < 0) {
@ -151,7 +184,7 @@ static int __backup(struct volume_group *vg)
log_verbose("Creating volume group backup \"%s\"", name);
if (!(tf = text_format_create(vg->cmd, name, the_um))) {
if (!(tf = text_format_create(vg->cmd, name, the_um, desc))) {
stack;
return 0;
}
@ -207,9 +240,9 @@ static struct volume_group *_read_vg(struct cmd_context *cmd,
struct volume_group *vg;
struct format_instance *tf;
if (!(tf = text_format_create(cmd, file, the_um))) {
if (!(tf = text_format_create(cmd, file, the_um, cmd->cmd_line))) {
log_error("Couldn't create text format object.");
return 0;
return NULL;
}
if (!(vg = tf->ops->vg_read(tf, vg_name)))

View File

@ -684,10 +684,46 @@ static void _use_settings(struct config_info *settings)
backup_enable(settings->backup);
}
static char *_copy_command_line(struct pool *mem, int argc, char **argv)
{
int i;
/*
* Build up the complete command line, used as a
* description for backups.
*/
if (!pool_begin_object(cmd->mem, 128))
goto bad;
for (i = 0; i < argc; i++) {
if (!pool_grow_object(cmd->mem, argv[i], strlen(argv[i])))
goto bad;
if (i < (argc - 1))
if (!pool_grow_object(cmd->mem, " ", 1));
}
/*
* Terminate.
*/
if (!pool_grow_object(mem, "\0", 1))
goto bad;
return pool_end_object(mem);
bad:
log_err("Couldn't copy command line.");
pool_abandon_object(mem);
return NULL;
}
static int run_command(int argc, char **argv)
{
int ret = 0;
if (!(cmd->cmd_line = _copy_command_line(cmd->mem, argc, argv)))
return ECMD_FAILED;
if (!(the_command = find_command(argv[0])))
return ENO_SUCH_CMD;
@ -787,7 +823,7 @@ static void __init_log(struct config_file *cf)
init_cmd_name(find_config_int(cf->root, "log/command_names", '/', 0));
_default_settings.test = find_config_int(cf->root, "global/test",
_default_settings.test = find_config_int(cf->root, "global/test",
'/', 0);
if (find_config_int(cf->root, "log/overwrite", '/', 0))
open_mode = "w";

View File

@ -13,7 +13,8 @@ static int _backup_to_file(const char *file, struct volume_group *vg)
int r;
struct format_instance *tf;
if (!(tf = text_format_create(vg->cmd, file, the_um))) {
if (!(tf = text_format_create(vg->cmd, file, the_um,
vg->cmd->cmd_line))) {
log_error("Couldn't create backup object.");
return 0;
}