xref: /dragonfly/contrib/lvm2/dist/tools/pvcreate.c (revision cf89a63b)
1 /*	$NetBSD: pvcreate.c,v 1.1.1.2 2009/12/02 00:25:54 haad Exp $	*/
2 
3 /*
4  * Copyright (C) 2001-2004 Sistina Software, Inc. All rights reserved.
5  * Copyright (C) 2004-2009 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 #include "metadata-exported.h"
20 
21 /*
22  * Intial sanity checking of recovery-related command-line arguments.
23  * These args are: --restorefile, --uuid, and --physicalvolumesize
24  *
25  * Output arguments:
26  * pp: structure allocated by caller, fields written / validated here
27  */
28 static int pvcreate_restore_params_validate(struct cmd_context *cmd,
29 					    int argc, char **argv,
30 					    struct pvcreate_params *pp)
31 {
32 	const char *uuid = NULL;
33 	void *existing_pv;
34 	struct volume_group *vg;
35 
36 	if (arg_count(cmd, restorefile_ARG) && !arg_count(cmd, uuidstr_ARG)) {
37 		log_error("--uuid is required with --restorefile");
38 		return 0;
39 	}
40 
41 	if (arg_count(cmd, uuidstr_ARG) && argc != 1) {
42 		log_error("Can only set uuid on one volume at once");
43 		return 0;
44 	}
45 
46  	if (arg_count(cmd, uuidstr_ARG)) {
47 		uuid = arg_str_value(cmd, uuidstr_ARG, "");
48 		if (!id_read_format(&pp->id, uuid))
49 			return 0;
50 		pp->idp = &pp->id;
51 	}
52 
53 	if (arg_count(cmd, restorefile_ARG)) {
54 		pp->restorefile = arg_str_value(cmd, restorefile_ARG, "");
55 		/* The uuid won't already exist */
56 		if (!(vg = backup_read_vg(cmd, NULL, pp->restorefile))) {
57 			log_error("Unable to read volume group from %s",
58 				  pp->restorefile);
59 			return 0;
60 		}
61 		if (!(existing_pv = find_pv_in_vg_by_uuid(vg, pp->idp))) {
62 			log_error("Can't find uuid %s in backup file %s",
63 				  uuid, pp->restorefile);
64 			return 0;
65 		}
66 		pp->pe_start = pv_pe_start(existing_pv);
67 		pp->extent_size = pv_pe_size(existing_pv);
68 		pp->extent_count = pv_pe_count(existing_pv);
69 		vg_release(vg);
70 	}
71 
72 	if (arg_sign_value(cmd, physicalvolumesize_ARG, 0) == SIGN_MINUS) {
73 		log_error("Physical volume size may not be negative");
74 		return 0;
75 	}
76 	pp->size = arg_uint64_value(cmd, physicalvolumesize_ARG, UINT64_C(0));
77 
78 	if (arg_count(cmd, restorefile_ARG) || arg_count(cmd, uuidstr_ARG))
79 		pp->zero = 0;
80 	return 1;
81 }
82 
83 int pvcreate(struct cmd_context *cmd, int argc, char **argv)
84 {
85 	int i;
86 	int ret = ECMD_PROCESSED;
87 	struct pvcreate_params pp;
88 
89 	pvcreate_params_set_defaults(&pp);
90 
91 	if (!pvcreate_restore_params_validate(cmd, argc, argv, &pp)) {
92 		return EINVALID_CMD_LINE;
93 	}
94 	if (!pvcreate_params_validate(cmd, argc, argv, &pp)) {
95 		return EINVALID_CMD_LINE;
96 	}
97 
98 	for (i = 0; i < argc; i++) {
99 		if (!lock_vol(cmd, VG_ORPHANS, LCK_VG_WRITE)) {
100 			log_error("Can't get lock for orphan PVs");
101 			return ECMD_FAILED;
102 		}
103 
104 		if (!pvcreate_single(cmd, argv[i], &pp)) {
105 			stack;
106 			ret = ECMD_FAILED;
107 		}
108 
109 		unlock_vg(cmd, VG_ORPHANS);
110 		if (sigint_caught())
111 			return ret;
112 	}
113 
114 	return ret;
115 }
116