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