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