]> sourceware.org Git - lvm2.git/blame - tools/dumpconfig.c
dev-type: detect mixed dos partition with gpt's PMBR
[lvm2.git] / tools / dumpconfig.c
CommitLineData
dcc31da5 1/*
67cdbd7e 2 * Copyright (C) 2003-2004 Sistina Software, Inc. All rights reserved.
ec647f1d 3 * Copyright (C) 2004-2015 Red Hat, Inc. All rights reserved.
dcc31da5 4 *
6606c3ae 5 * This file is part of LVM2.
dcc31da5 6 *
6606c3ae
AK
7 * This copyrighted material is made available to anyone wishing to use,
8 * modify, copy, or redistribute it subject to the terms and conditions
be684599 9 * of the GNU Lesser General Public License v.2.1.
dcc31da5 10 *
be684599 11 * You should have received a copy of the GNU Lesser General Public License
6606c3ae 12 * along with this program; if not, write to the Free Software Foundation,
fcbef05a 13 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
dcc31da5
AK
14 */
15
16#include "tools.h"
17
5ed7d0cf 18static int _get_vsn(struct cmd_context *cmd, uint16_t *version_int)
34350963 19{
ec647f1d 20 const char *vsn;
f5584d42 21 unsigned int major, minor, patchlevel;
34350963 22
bbf574ab
ZK
23 if (!(vsn = arg_str_value(cmd, atversion_ARG, NULL)) &&
24 !(vsn = arg_str_value(cmd, sinceversion_ARG, NULL)))
ec647f1d 25 vsn = LVM_VERSION;
1ea8afd3 26
ec647f1d 27 if (sscanf(vsn, "%u.%u.%u", &major, &minor, &patchlevel) != 3) {
34350963
PR
28 log_error("Incorrect version format.");
29 return 0;
30 }
31
5ed7d0cf 32 *version_int = vsn(major, minor, patchlevel);
34350963
PR
33 return 1;
34}
35
5dcec173
PR
36static int _do_def_check(struct config_def_tree_spec *spec,
37 struct dm_config_tree *cft,
5ed7d0cf 38 struct cft_check_handle **cft_check_handle)
661406a4
PR
39{
40 struct cft_check_handle *handle;
41
c42f7286 42 if (!(handle = get_config_tree_check_handle(spec->cmd, cft)))
661406a4
PR
43 return 0;
44
45 handle->force_check = 1;
661406a4
PR
46 handle->suppress_messages = 1;
47
24f32721
PR
48 if (spec->type == CFG_DEF_TREE_DIFF) {
49 if (!handle->check_diff)
50 handle->skip_if_checked = 0;
5dcec173 51 handle->check_diff = 1;
24f32721 52 } else {
5dcec173 53 handle->skip_if_checked = 1;
24f32721
PR
54 handle->check_diff = 0;
55 }
5dcec173 56
8b6b90b0
PR
57 handle->ignoreunsupported = spec->ignoreunsupported;
58 handle->ignoreadvanced = spec->ignoreadvanced;
59
000e81a9 60 config_def_check(handle);
661406a4
PR
61 *cft_check_handle = handle;
62
63 return 1;
64}
65
5ed7d0cf
PR
66static int _merge_config_cascade(struct cmd_context *cmd, struct dm_config_tree *cft_cascaded,
67 struct dm_config_tree **cft_merged)
68{
69 if (!cft_cascaded)
70 return 1;
71
72 if (!*cft_merged && !(*cft_merged = config_open(CONFIG_MERGED_FILES, NULL, 0)))
73 return_0;
74
75 if (!_merge_config_cascade(cmd, cft_cascaded->cascade, cft_merged))
76 return_0;
77
78 return merge_config_tree(cmd, *cft_merged, cft_cascaded, CONFIG_MERGE_TYPE_RAW);
79}
80
c42f7286
PR
81static int _config_validate(struct cmd_context *cmd, struct dm_config_tree *cft)
82{
83 struct cft_check_handle *handle;
84
85 if (!(handle = get_config_tree_check_handle(cmd, cft)))
86 return 1;
87
88 handle->force_check = 1;
89 handle->skip_if_checked = 1;
90 handle->suppress_messages = 0;
91
92 return config_def_check(handle);
93}
94
dcc31da5
AK
95int dumpconfig(struct cmd_context *cmd, int argc, char **argv)
96{
a8fb89ad 97 const char *file = arg_str_value(cmd, file_ARG, NULL);
7e671e5d 98 const char *type = arg_str_value(cmd, configtype_ARG, arg_is_set(cmd, list_ARG) ? "list" : "current");
34350963 99 struct config_def_tree_spec tree_spec = {0};
f5584d42 100 struct dm_config_tree *cft = NULL;
661406a4 101 struct cft_check_handle *cft_check_handle = NULL;
9c937e7d 102 struct profile *profile = NULL;
34350963
PR
103 int r = ECMD_PROCESSED;
104
b53ec372
PR
105 tree_spec.cmd = cmd;
106
7e671e5d 107 if (arg_is_set(cmd, configtype_ARG) && arg_is_set(cmd, validate_ARG)) {
34350963
PR
108 log_error("Only one of --type and --validate permitted.");
109 return EINVALID_CMD_LINE;
110 }
111
7e671e5d 112 if (arg_is_set(cmd, configtype_ARG) && arg_is_set(cmd, list_ARG)) {
3be3eb29
PR
113 log_error("Only one of --type and --list permitted.");
114 return EINVALID_CMD_LINE;
115 }
116
7e671e5d
AK
117 if (arg_is_set(cmd, atversion_ARG)) {
118 if (arg_is_set(cmd, sinceversion_ARG)) {
1ea8afd3
PR
119 log_error("Only one of --atversion and --sinceversion permitted.");
120 return EINVALID_CMD_LINE;
121 }
122
7e671e5d 123 if (!arg_is_set(cmd, configtype_ARG) && !arg_is_set(cmd, list_ARG)) {
1ea8afd3
PR
124 log_error("--atversion requires --type or --list");
125 return EINVALID_CMD_LINE;
126 }
7e671e5d
AK
127 } else if (arg_is_set(cmd, sinceversion_ARG)) {
128 if (!arg_is_set(cmd, configtype_ARG) || strcmp(type, "new")) {
1ea8afd3
PR
129 log_error("--sinceversion requires --type new");
130 return EINVALID_CMD_LINE;
131 }
34350963
PR
132 }
133
7e671e5d 134 if (arg_is_set(cmd, ignoreadvanced_ARG))
7d6991e9
PR
135 tree_spec.ignoreadvanced = 1;
136
7e671e5d
AK
137 if (arg_is_set(cmd, ignoreunsupported_ARG)) {
138 if (arg_is_set(cmd, showunsupported_ARG)) {
8b6b90b0
PR
139 log_error("Only one of --ignoreunsupported and --showunsupported permitted.");
140 return EINVALID_CMD_LINE;
141 }
7d6991e9 142 tree_spec.ignoreunsupported = 1;
7e671e5d 143 } else if (arg_is_set(cmd, showunsupported_ARG)) {
8b6b90b0
PR
144 tree_spec.ignoreunsupported = 0;
145 } else if (strcmp(type, "current") && strcmp(type, "diff")) {
146 /*
147 * By default hide unsupported settings
148 * for all display types except "current"
149 * and "diff".
150 */
151 tree_spec.ignoreunsupported = 1;
152 }
7d6991e9 153
fc65269d
PR
154 if (strcmp(type, "current") && strcmp(type, "diff")) {
155 /*
156 * By default hide deprecated settings
157 * for all display types except "current"
158 * and "diff" unless --showdeprecated is set.
159 *
160 * N.B. Deprecated settings are visible if
161 * --atversion is used with a version that
162 * is lower than the version in which the
163 * setting was deprecated.
164 */
7e671e5d 165 if (!arg_is_set(cmd, showdeprecated_ARG))
fc65269d
PR
166 tree_spec.ignoredeprecated = 1;
167 }
168
7e671e5d 169 if (arg_is_set(cmd, ignorelocal_ARG))
9b86e8e8
DT
170 tree_spec.ignorelocal = 1;
171
c794c163 172 if (!strcmp(type, "current") || !strcmp(type, "full")) {
7e671e5d 173 if (arg_is_set(cmd, atversion_ARG)) {
c794c163 174 log_error("--atversion has no effect with --type %s", type);
f5584d42
PR
175 return EINVALID_CMD_LINE;
176 }
177
7e671e5d
AK
178 if ((arg_is_set(cmd, ignoreunsupported_ARG) ||
179 arg_is_set(cmd, ignoreadvanced_ARG)) &&
c794c163 180 !strcmp(type, "current")) {
8b6b90b0 181 /* FIXME: allow these even for --type current */
f5584d42
PR
182 log_error("--ignoreadvanced and --ignoreunsupported has "
183 "no effect with --type current");
184 return EINVALID_CMD_LINE;
185 }
7e671e5d 186 } else if (arg_is_set(cmd, mergedconfig_ARG)) {
c794c163 187 log_error("--mergedconfig has no effect without --type current or --type full");
25f5e2da 188 return EINVALID_CMD_LINE;
f5584d42
PR
189 }
190
191 if (!_get_vsn(cmd, &tree_spec.version))
192 return EINVALID_CMD_LINE;
193
9c937e7d
PR
194 /*
195 * The profile specified by --profile cmd arg is like --commandprofile,
196 * but it is used just for dumping the profile content and not for
197 * application.
198 */
7e671e5d 199 if (arg_is_set(cmd, profile_ARG) &&
9c937e7d
PR
200 (!(profile = add_profile(cmd, arg_str_value(cmd, profile_ARG, NULL), CONFIG_PROFILE_COMMAND)) ||
201 !override_config_tree_from_profile(cmd, profile))) {
202 log_error("Failed to load profile %s.", arg_str_value(cmd, profile_ARG, NULL));
203 return ECMD_FAILED;
204 }
205
5ed7d0cf
PR
206 /*
207 * Set the 'cft' to work with based on whether we need the plain
208 * config tree or merged config tree cascade if --mergedconfig is used.
209 */
7e671e5d 210 if ((arg_is_set(cmd, mergedconfig_ARG) || !strcmp(type, "full") || !strcmp(type, "diff")) && cmd->cft->cascade) {
5ed7d0cf
PR
211 if (!_merge_config_cascade(cmd, cmd->cft, &cft)) {
212 log_error("Failed to merge configuration.");
213 r = ECMD_FAILED;
214 goto out;
215 }
216 } else
217 cft = cmd->cft;
c794c163 218 tree_spec.current_cft = cft;
5ed7d0cf 219
7e671e5d 220 if (arg_is_set(cmd, validate_ARG)) {
c42f7286 221 if (_config_validate(cmd, cft)) {
34350963 222 log_print("LVM configuration valid.");
5ed7d0cf 223 goto out;
34350963
PR
224 } else {
225 log_error("LVM configuration invalid.");
5ed7d0cf
PR
226 r = ECMD_FAILED;
227 goto out;
34350963
PR
228 }
229 }
230
7e671e5d 231 if (!strcmp(type, "list") || arg_is_set(cmd, list_ARG)) {
3be3eb29 232 tree_spec.type = CFG_DEF_TREE_LIST;
7e671e5d 233 if (arg_is_set(cmd, withcomments_ARG)) {
3be3eb29
PR
234 log_error("--withcomments has no effect with --type list");
235 return EINVALID_CMD_LINE;
236 }
fe423ef5
AK
237 if (arg_is_set(cmd, withlocalpreamble_ARG)) {
238 log_error("--withlocalpreamble has no effect with --type list");
239 return EINVALID_CMD_LINE;
240 }
241 if (arg_is_set(cmd, withgeneralpreamble_ARG)) {
242 log_error("--withgeneralpreamble has no effect with --type list");
243 return EINVALID_CMD_LINE;
244 }
b4cc28c2
PR
245 if (arg_is_set(cmd, valuesonly_ARG)) {
246 log_err("--valuesonly has no effect with --type list");
247 return EINVALID_CMD_LINE;
248 }
3be3eb29 249 /* list type does not require status check */
c794c163
PR
250 } else if (!strcmp(type, "full")) {
251 tree_spec.type = CFG_DEF_TREE_FULL;
252 if (!_do_def_check(&tree_spec, cft, &cft_check_handle)) {
253 r = ECMD_FAILED;
254 goto_out;
255 }
3be3eb29 256 } else if (!strcmp(type, "current")) {
34350963 257 tree_spec.type = CFG_DEF_TREE_CURRENT;
5dcec173 258 if (!_do_def_check(&tree_spec, cft, &cft_check_handle)) {
5ed7d0cf
PR
259 r = ECMD_FAILED;
260 goto_out;
261 }
34350963 262 }
661406a4 263 else if (!strcmp(type, "missing")) {
34350963 264 tree_spec.type = CFG_DEF_TREE_MISSING;
5dcec173 265 if (!_do_def_check(&tree_spec, cft, &cft_check_handle)) {
5ed7d0cf
PR
266 r = ECMD_FAILED;
267 goto_out;
268 }
661406a4
PR
269 }
270 else if (!strcmp(type, "default")) {
271 tree_spec.type = CFG_DEF_TREE_DEFAULT;
272 /* default type does not require check status */
273 }
5dcec173
PR
274 else if (!strcmp(type, "diff")) {
275 tree_spec.type = CFG_DEF_TREE_DIFF;
276 if (!_do_def_check(&tree_spec, cft, &cft_check_handle)) {
277 r = ECMD_FAILED;
278 goto_out;
279 }
280 }
661406a4 281 else if (!strcmp(type, "new")) {
7e671e5d 282 tree_spec.type = arg_is_set(cmd, sinceversion_ARG) ? CFG_DEF_TREE_NEW_SINCE
1ea8afd3 283 : CFG_DEF_TREE_NEW;
661406a4
PR
284 /* new type does not require check status */
285 }
953a438e
PR
286 else if (!strcmp(type, "profilable")) {
287 tree_spec.type = CFG_DEF_TREE_PROFILABLE;
288 /* profilable type does not require check status */
289 }
9c937e7d
PR
290 else if (!strcmp(type, "profilable-command")) {
291 tree_spec.type = CFG_DEF_TREE_PROFILABLE_CMD;
292 /* profilable-command type does not require check status */
293 }
294 else if (!strcmp(type, "profilable-metadata")) {
295 tree_spec.type = CFG_DEF_TREE_PROFILABLE_MDA;
296 /* profilable-metadata type does not require check status */
297 }
34350963
PR
298 else {
299 log_error("Incorrect type of configuration specified. "
c794c163
PR
300 "Expected one of: current, default, diff, full, list, missing, "
301 "new, profilable, profilable-command, profilable-metadata.");
5ed7d0cf
PR
302 r = EINVALID_CMD_LINE;
303 goto out;
34350963
PR
304 }
305
7e671e5d 306 if (arg_is_set(cmd, withsummary_ARG) || arg_is_set(cmd, list_ARG))
0ba332e8 307 tree_spec.withsummary = 1;
fe423ef5 308
7e671e5d 309 if (arg_is_set(cmd, withcomments_ARG))
558c9324 310 tree_spec.withcomments = 1;
fe423ef5 311
7e671e5d 312 if (arg_is_set(cmd, unconfigured_ARG))
5cd63817 313 tree_spec.unconfigured = 1;
558c9324 314
7e671e5d 315 if (arg_is_set(cmd, withversions_ARG))
558c9324
PR
316 tree_spec.withversions = 1;
317
fe423ef5
AK
318 if (arg_is_set(cmd, withgeneralpreamble_ARG))
319 tree_spec.withgeneralpreamble = 1;
320
321 if (arg_is_set(cmd, withlocalpreamble_ARG))
322 tree_spec.withlocalpreamble = 1;
323
7e671e5d 324 if (arg_is_set(cmd, withspaces_ARG))
a4724350
PR
325 tree_spec.withspaces = 1;
326
b4cc28c2
PR
327 if (arg_is_set(cmd, valuesonly_ARG))
328 tree_spec.valuesonly = 1;
329
661406a4
PR
330 if (cft_check_handle)
331 tree_spec.check_status = cft_check_handle->status;
332
c394c2a6 333 if ((tree_spec.type != CFG_DEF_TREE_CURRENT) &&
5dcec173 334 (tree_spec.type != CFG_DEF_TREE_DIFF) &&
c394c2a6
ZK
335 !(cft = config_def_create_tree(&tree_spec))) {
336 r = ECMD_FAILED;
337 goto_out;
338 }
34350963 339
558c9324 340 if (!config_write(cft, &tree_spec, file, argc, argv)) {
651ff9b3 341 stack;
34350963 342 r = ECMD_FAILED;
651ff9b3 343 }
5ed7d0cf 344out:
c794c163
PR
345 if (tree_spec.current_cft && (tree_spec.current_cft != cft) &&
346 (tree_spec.current_cft != cmd->cft))
347 /*
348 * This happens in case of CFG_DEF_TREE_FULL where we
349 * have merged explicitly defined config trees and also
350 * we have used default tree.
351 */
352 dm_config_destroy(tree_spec.current_cft);
353
5ed7d0cf 354 if (cft && (cft != cmd->cft))
c794c163 355 dm_config_destroy(cft);
9c937e7d
PR
356 else if (profile)
357 remove_config_tree_by_source(cmd, CONFIG_PROFILE_COMMAND);
34350963 358
f5584d42
PR
359 /*
360 * The cmd->cft (the "current" tree) is destroyed
361 * together with cmd context destroy...
362 */
363
34350963 364 return r;
dcc31da5 365}
3f043405
AK
366
367int config(struct cmd_context *cmd, int argc, char **argv)
368{
369 return dumpconfig(cmd, argc, argv);
370}
371
372int lvmconfig(struct cmd_context *cmd, int argc, char **argv)
373{
374 return dumpconfig(cmd, argc, argv);
375}
This page took 0.284613 seconds and 6 git commands to generate.