xref: /netbsd/external/gpl2/lvm2/dist/tools/pvdisplay.c (revision 7c604eea)
1 /*	$NetBSD: pvdisplay.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-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 
_pvdisplay_single(struct cmd_context * cmd,struct volume_group * vg,struct physical_volume * pv,void * handle)20 static int _pvdisplay_single(struct cmd_context *cmd,
21 			     struct volume_group *vg,
22 			     struct physical_volume *pv, void *handle)
23 {
24 	struct pv_list *pvl;
25 	int ret = ECMD_PROCESSED;
26 	uint64_t size;
27 	struct volume_group *old_vg = vg;
28 
29 	const char *pv_name = pv_dev_name(pv);
30 	const char *vg_name = NULL;
31 
32 	if (!is_orphan(pv) && !vg) {
33 		vg_name = pv_vg_name(pv);
34 		vg = vg_read(cmd, vg_name, (char *)&pv->vgid, 0);
35 		if (vg_read_error(vg)) {
36 			log_error("Skipping volume group %s", vg_name);
37 			vg_release(vg);
38 			/* FIXME If CLUSTERED should return ECMD_PROCESSED here */
39 			return ECMD_FAILED;
40 		}
41 
42 	 	/*
43 		 * Replace possibly incomplete PV structure with new one
44 		 * allocated in vg_read_internal() path.
45 		 */
46 		 if (!(pvl = find_pv_in_vg(vg, pv_name))) {
47 			 log_error("Unable to find \"%s\" in volume group \"%s\"",
48 				   pv_name, vg->name);
49 			 ret = ECMD_FAILED;
50 			 goto out;
51 		 }
52 
53 		 pv = pvl->pv;
54 	}
55 
56 	if (is_orphan(pv))
57 		size = pv_size(pv);
58 	else
59 		size = (pv_pe_count(pv) - pv_pe_alloc_count(pv)) *
60 			pv_pe_size(pv);
61 
62 	if (arg_count(cmd, short_ARG)) {
63 		log_print("Device \"%s\" has a capacity of %s", pv_name,
64 			  display_size(cmd, size));
65 		goto out;
66 	}
67 
68 	if (pv_status(pv) & EXPORTED_VG)
69 		log_print("Physical volume \"%s\" of volume group \"%s\" "
70 			  "is exported", pv_name, pv_vg_name(pv));
71 
72 	if (is_orphan(pv))
73 		log_print("\"%s\" is a new physical volume of \"%s\"",
74 			  pv_name, display_size(cmd, size));
75 
76 	if (arg_count(cmd, colon_ARG)) {
77 		pvdisplay_colons(pv);
78 		goto out;
79 	}
80 
81 	pvdisplay_full(cmd, pv, handle);
82 
83 	if (arg_count(cmd, maps_ARG))
84 		pvdisplay_segments(pv);
85 
86 out:
87 	if (vg_name)
88 		unlock_vg(cmd, vg_name);
89 	if (!old_vg)
90 		vg_release(vg);
91 
92 	return ret;
93 }
94 
pvdisplay(struct cmd_context * cmd,int argc,char ** argv)95 int pvdisplay(struct cmd_context *cmd, int argc, char **argv)
96 {
97 	if (arg_count(cmd, columns_ARG)) {
98 		if (arg_count(cmd, colon_ARG) || arg_count(cmd, maps_ARG) ||
99 		    arg_count(cmd, short_ARG)) {
100 			log_error("Incompatible options selected");
101 			return EINVALID_CMD_LINE;
102 		}
103 		return pvs(cmd, argc, argv);
104 	} else if (arg_count(cmd, aligned_ARG) ||
105 		   arg_count(cmd, all_ARG) ||
106 		   arg_count(cmd, noheadings_ARG) ||
107 		   arg_count(cmd, options_ARG) ||
108 		   arg_count(cmd, separator_ARG) ||
109 		   arg_count(cmd, sort_ARG) || arg_count(cmd, unbuffered_ARG)) {
110 		log_error("Incompatible options selected");
111 		return EINVALID_CMD_LINE;
112 	}
113 
114 	if (arg_count(cmd, colon_ARG) && arg_count(cmd, maps_ARG)) {
115 		log_error("Option -v not allowed with option -c");
116 		return EINVALID_CMD_LINE;
117 	}
118 
119 	return process_each_pv(cmd, argc, argv, NULL, 0, 0, NULL,
120 			       _pvdisplay_single);
121 }
122