1 /* Copyright (c) 2008, XenSource Inc.
2  * All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are met:
6  *     * Redistributions of source code must retain the above copyright
7  *       notice, this list of conditions and the following disclaimer.
8  *     * Redistributions in binary form must reproduce the above copyright
9  *       notice, this list of conditions and the following disclaimer in the
10  *       documentation and/or other materials provided with the distribution.
11  *     * Neither the name of XenSource Inc. nor the names of its contributors
12  *       may be used to endorse or promote products derived from this software
13  *       without specific prior written permission.
14  *
15  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
19  * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
20  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
21  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
22  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
23  * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
24  * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
25  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27 #include <errno.h>
28 #include <fcntl.h>
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <unistd.h>
32 
33 #include "libvhd.h"
34 
35 int
vhd_util_query(int argc,char ** argv)36 vhd_util_query(int argc, char **argv)
37 {
38 	char *name;
39 	vhd_context_t vhd;
40 	off_t currsize;
41 	int ret, err, c, size, physize, parent, fields, depth;
42 
43 	name    = NULL;
44 	size    = 0;
45 	physize = 0;
46 	parent  = 0;
47 	fields  = 0;
48 	depth   = 0;
49 
50 	if (!argc || !argv) {
51 		err = -EINVAL;
52 		goto usage;
53 	}
54 
55 	optind = 0;
56 	while ((c = getopt(argc, argv, "n:vspfdh")) != -1) {
57 		switch (c) {
58 		case 'n':
59 			name = optarg;
60 			break;
61 		case 'v':
62 			size = 1;
63 			break;
64 		case 's':
65 			physize = 1;
66 			break;
67 		case 'p':
68 			parent = 1;
69 			break;
70 		case 'f':
71 			fields = 1;
72 			break;
73 		case 'd':
74 			depth = 1;
75 			break;
76 		case 'h':
77 			err = 0;
78 			goto usage;
79 		default:
80 			err = -EINVAL;
81 			goto usage;
82 		}
83 	}
84 
85 	if (!name || optind != argc) {
86 		err = -EINVAL;
87 		goto usage;
88 	}
89 
90 	err = vhd_open(&vhd, name, VHD_OPEN_RDONLY | VHD_OPEN_IGNORE_DISABLED);
91 	if (err) {
92 		printf("error opening %s: %d\n", name, err);
93 		return err;
94 	}
95 
96 	if (size)
97 		printf("%"PRIu64"\n", vhd.footer.curr_size >> 20);
98 
99 	if (physize) {
100 		err = vhd_get_phys_size(&vhd, &currsize);
101 		if (err)
102 			printf("failed to get physical size: %d\n", err);
103 		else
104 			printf("%"PRIu64"\n", currsize);
105 	}
106 
107 	if (parent) {
108 		ret = 0;
109 
110 		if (vhd.footer.type != HD_TYPE_DIFF)
111 			printf("%s has no parent\n", name);
112 		else {
113 			char *pname;
114 
115 			ret = vhd_parent_locator_get(&vhd, &pname);
116 			if (ret)
117 				printf("query failed\n");
118 			else {
119 				printf("%s\n", pname);
120 				free(pname);
121 			}
122 		}
123 
124 		err = (err ? : ret);
125 	}
126 
127 	if (fields) {
128 		int hidden;
129 
130 		ret = vhd_hidden(&vhd, &hidden);
131 		if (ret)
132 			printf("error checking 'hidden' field: %d\n", ret);
133 		else
134 			printf("hidden: %d\n", hidden);
135 
136 		err = (err ? : ret);
137 	}
138 
139 	if (depth) {
140 		int length;
141 
142 		ret = vhd_chain_depth(&vhd, &length);
143 		if (ret)
144 			printf("error checking chain depth: %d\n", ret);
145 		else
146 			printf("chain depth: %d\n", length);
147 
148 		err = (err ? : ret);
149 	}
150 
151 	vhd_close(&vhd);
152 	return err;
153 
154 usage:
155 	printf("options: <-n name> [-v print virtual size (in MB)] "
156 	       "[-s print physical utilization (bytes)] [-p print parent] "
157 	       "[-f print fields] [-d print chain depth] [-h help]\n");
158 	return err;
159 }
160