import source from lvm2 2.02.79
[external/device-mapper.git] / tools / vgcfgbackup.c
1 /*
2  * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
3  * Copyright (C) 2004-2007 Red Hat, Inc. All rights reserved.
4  *
5  * This file is part of LVM2.
6  *
7  * This copyrighted material is made available to anyone wishing to use,
8  * modify, copy, or redistribute it subject to the terms and conditions
9  * of the GNU Lesser General Public License v.2.1.
10  *
11  * You should have received a copy of the GNU Lesser General Public License
12  * along with this program; if not, write to the Free Software Foundation,
13  * Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
14  */
15
16 #include "tools.h"
17
18 static char *_expand_filename(const char *template, const char *vg_name,
19                               char **last_filename)
20 {
21         char *filename;
22
23         if (security_level())
24                 return dm_strdup(template);
25
26         if (!(filename = dm_malloc(PATH_MAX))) {
27                 log_error("Failed to allocate filename.");
28                 return NULL;
29         }
30
31         if (snprintf(filename, PATH_MAX, template, vg_name) < 0) {
32                 log_error("Error processing filename template %s",
33                            template);
34                 dm_free(filename);      
35                 return NULL;
36         }
37         if (*last_filename && !strncmp(*last_filename, filename, PATH_MAX)) {
38                 log_error("VGs must be backed up into different files. "
39                           "Use %%s in filename for VG name.");
40                 dm_free(filename);
41                 return NULL;
42         }
43
44         dm_free(*last_filename);
45         *last_filename = filename;
46
47         return filename;
48 }
49
50 static int vg_backup_single(struct cmd_context *cmd, const char *vg_name,
51                             struct volume_group *vg,
52                             void *handle)
53 {
54         char **last_filename = (char **)handle;
55         char *filename;
56
57         if (arg_count(cmd, file_ARG)) {
58                 if (!(filename = _expand_filename(arg_value(cmd, file_ARG),
59                                                   vg->name, last_filename))) {
60                         stack;
61                         return ECMD_FAILED;
62                 }
63
64                 if (!backup_to_file(filename, vg->cmd->cmd_line, vg)) {
65                         stack;
66                         return ECMD_FAILED;
67                 }
68         } else {
69                 if (vg_read_error(vg) == FAILED_INCONSISTENT) {
70                         log_error("No backup taken: specify filename with -f "
71                                   "to backup an inconsistent VG");
72                         stack;
73                         return ECMD_FAILED;
74                 }
75
76                 /* just use the normal backup code */
77                 backup_enable(cmd, 1);  /* force a backup */
78                 if (!backup(vg)) {
79                         stack;
80                         return ECMD_FAILED;
81                 }
82         }
83
84         log_print("Volume group \"%s\" successfully backed up.", vg_name);
85         return ECMD_PROCESSED;
86 }
87
88 int vgcfgbackup(struct cmd_context *cmd, int argc, char **argv)
89 {
90         int ret;
91         char *last_filename = NULL;
92
93         init_pvmove(1);
94
95         ret = process_each_vg(cmd, argc, argv, READ_ALLOW_INCONSISTENT,
96                               &last_filename, &vg_backup_single);
97
98         dm_free(last_filename);
99
100         init_pvmove(0);
101
102         return ret;
103 }