root / vhd / lib / vhd-util-scan.c @ abdb293f
History | View | Annotate | Download (27.6 kB)
1 | abdb293f | Chrysostomos Nanakos | /*
|
---|---|---|---|
2 | abdb293f | Chrysostomos Nanakos | * Copyright (c) 2007, XenSource Inc.
|
3 | abdb293f | Chrysostomos Nanakos | * Copyright (c) 2010, Citrix Systems, Inc.
|
4 | abdb293f | Chrysostomos Nanakos | *
|
5 | abdb293f | Chrysostomos Nanakos | * All rights reserved.
|
6 | abdb293f | Chrysostomos Nanakos | *
|
7 | abdb293f | Chrysostomos Nanakos | * Redistribution and use in source and binary forms, with or without
|
8 | abdb293f | Chrysostomos Nanakos | * modification, are permitted provided that the following conditions are met:
|
9 | abdb293f | Chrysostomos Nanakos | * * Redistributions of source code must retain the above copyright
|
10 | abdb293f | Chrysostomos Nanakos | * notice, this list of conditions and the following disclaimer.
|
11 | abdb293f | Chrysostomos Nanakos | * * Redistributions in binary form must reproduce the above copyright
|
12 | abdb293f | Chrysostomos Nanakos | * notice, this list of conditions and the following disclaimer in the
|
13 | abdb293f | Chrysostomos Nanakos | * documentation and/or other materials provided with the distribution.
|
14 | abdb293f | Chrysostomos Nanakos | * * Neither the name of XenSource Inc. nor the names of its contributors
|
15 | abdb293f | Chrysostomos Nanakos | * may be used to endorse or promote products derived from this software
|
16 | abdb293f | Chrysostomos Nanakos | * without specific prior written permission.
|
17 | abdb293f | Chrysostomos Nanakos | *
|
18 | abdb293f | Chrysostomos Nanakos | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
19 | abdb293f | Chrysostomos Nanakos | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
20 | abdb293f | Chrysostomos Nanakos | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
21 | abdb293f | Chrysostomos Nanakos | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
|
22 | abdb293f | Chrysostomos Nanakos | * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
23 | abdb293f | Chrysostomos Nanakos | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
24 | abdb293f | Chrysostomos Nanakos | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
|
25 | abdb293f | Chrysostomos Nanakos | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
|
26 | abdb293f | Chrysostomos Nanakos | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
27 | abdb293f | Chrysostomos Nanakos | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
28 | abdb293f | Chrysostomos Nanakos | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
29 | abdb293f | Chrysostomos Nanakos | */
|
30 | abdb293f | Chrysostomos Nanakos | |
31 | abdb293f | Chrysostomos Nanakos | #ifdef HAVE_CONFIG_H
|
32 | abdb293f | Chrysostomos Nanakos | #include "config.h" |
33 | abdb293f | Chrysostomos Nanakos | #endif
|
34 | abdb293f | Chrysostomos Nanakos | |
35 | abdb293f | Chrysostomos Nanakos | #include <glob.h> |
36 | abdb293f | Chrysostomos Nanakos | #include <errno.h> |
37 | abdb293f | Chrysostomos Nanakos | #include <fcntl.h> |
38 | abdb293f | Chrysostomos Nanakos | #include <stdio.h> |
39 | abdb293f | Chrysostomos Nanakos | #include <string.h> |
40 | abdb293f | Chrysostomos Nanakos | #include <stdlib.h> |
41 | abdb293f | Chrysostomos Nanakos | #include <unistd.h> |
42 | abdb293f | Chrysostomos Nanakos | #include <fnmatch.h> |
43 | abdb293f | Chrysostomos Nanakos | #include <limits.h> |
44 | abdb293f | Chrysostomos Nanakos | #include <libgen.h> |
45 | abdb293f | Chrysostomos Nanakos | #include <syslog.h> |
46 | abdb293f | Chrysostomos Nanakos | #include <sys/stat.h> |
47 | abdb293f | Chrysostomos Nanakos | #include <sys/types.h> |
48 | abdb293f | Chrysostomos Nanakos | |
49 | abdb293f | Chrysostomos Nanakos | #include "list.h" |
50 | abdb293f | Chrysostomos Nanakos | #include "libvhd.h" |
51 | abdb293f | Chrysostomos Nanakos | #include "lvm-util.h" |
52 | abdb293f | Chrysostomos Nanakos | |
53 | abdb293f | Chrysostomos Nanakos | #define VHD_SCAN_FAST 0x01 |
54 | abdb293f | Chrysostomos Nanakos | #define VHD_SCAN_PRETTY 0x02 |
55 | abdb293f | Chrysostomos Nanakos | #define VHD_SCAN_VOLUME 0x04 |
56 | abdb293f | Chrysostomos Nanakos | #define VHD_SCAN_NOFAIL 0x08 |
57 | abdb293f | Chrysostomos Nanakos | #define VHD_SCAN_VERBOSE 0x10 |
58 | abdb293f | Chrysostomos Nanakos | #define VHD_SCAN_PARENTS 0x20 |
59 | abdb293f | Chrysostomos Nanakos | #define VHD_SCAN_MARKERS 0x40 |
60 | abdb293f | Chrysostomos Nanakos | |
61 | abdb293f | Chrysostomos Nanakos | #define VHD_TYPE_RAW_FILE 0x01 |
62 | abdb293f | Chrysostomos Nanakos | #define VHD_TYPE_VHD_FILE 0x02 |
63 | abdb293f | Chrysostomos Nanakos | #define VHD_TYPE_RAW_VOLUME 0x04 |
64 | abdb293f | Chrysostomos Nanakos | #define VHD_TYPE_VHD_VOLUME 0x08 |
65 | abdb293f | Chrysostomos Nanakos | |
66 | abdb293f | Chrysostomos Nanakos | #define EPRINTF(_f, _a...) \
|
67 | abdb293f | Chrysostomos Nanakos | do { \
|
68 | abdb293f | Chrysostomos Nanakos | syslog(LOG_INFO, "%s: " _f, __func__, ##_a); \ |
69 | abdb293f | Chrysostomos Nanakos | } while (0) |
70 | abdb293f | Chrysostomos Nanakos | |
71 | abdb293f | Chrysostomos Nanakos | static inline int |
72 | abdb293f | Chrysostomos Nanakos | target_volume(uint8_t type) |
73 | abdb293f | Chrysostomos Nanakos | { |
74 | abdb293f | Chrysostomos Nanakos | return (type == VHD_TYPE_RAW_VOLUME || type == VHD_TYPE_VHD_VOLUME);
|
75 | abdb293f | Chrysostomos Nanakos | } |
76 | abdb293f | Chrysostomos Nanakos | |
77 | abdb293f | Chrysostomos Nanakos | static inline int |
78 | abdb293f | Chrysostomos Nanakos | target_vhd(uint8_t type) |
79 | abdb293f | Chrysostomos Nanakos | { |
80 | abdb293f | Chrysostomos Nanakos | return (type == VHD_TYPE_VHD_FILE || type == VHD_TYPE_VHD_VOLUME);
|
81 | abdb293f | Chrysostomos Nanakos | } |
82 | abdb293f | Chrysostomos Nanakos | |
83 | abdb293f | Chrysostomos Nanakos | struct target {
|
84 | abdb293f | Chrysostomos Nanakos | char name[VHD_MAX_NAME_LEN];
|
85 | abdb293f | Chrysostomos Nanakos | char device[VHD_MAX_NAME_LEN];
|
86 | abdb293f | Chrysostomos Nanakos | uint64_t size; |
87 | abdb293f | Chrysostomos Nanakos | uint64_t start; |
88 | abdb293f | Chrysostomos Nanakos | uint64_t end; |
89 | abdb293f | Chrysostomos Nanakos | uint8_t type; |
90 | abdb293f | Chrysostomos Nanakos | }; |
91 | abdb293f | Chrysostomos Nanakos | |
92 | abdb293f | Chrysostomos Nanakos | struct iterator {
|
93 | abdb293f | Chrysostomos Nanakos | int cur;
|
94 | abdb293f | Chrysostomos Nanakos | int cur_size;
|
95 | abdb293f | Chrysostomos Nanakos | int max_size;
|
96 | abdb293f | Chrysostomos Nanakos | struct target *targets;
|
97 | abdb293f | Chrysostomos Nanakos | }; |
98 | abdb293f | Chrysostomos Nanakos | |
99 | abdb293f | Chrysostomos Nanakos | struct vhd_image {
|
100 | abdb293f | Chrysostomos Nanakos | char *name;
|
101 | abdb293f | Chrysostomos Nanakos | char *parent;
|
102 | abdb293f | Chrysostomos Nanakos | uint64_t capacity; |
103 | abdb293f | Chrysostomos Nanakos | off64_t size; |
104 | abdb293f | Chrysostomos Nanakos | uint8_t hidden; |
105 | abdb293f | Chrysostomos Nanakos | char marker;
|
106 | abdb293f | Chrysostomos Nanakos | int error;
|
107 | abdb293f | Chrysostomos Nanakos | char *message;
|
108 | abdb293f | Chrysostomos Nanakos | |
109 | abdb293f | Chrysostomos Nanakos | struct target *target;
|
110 | abdb293f | Chrysostomos Nanakos | |
111 | abdb293f | Chrysostomos Nanakos | struct list_head sibling;
|
112 | abdb293f | Chrysostomos Nanakos | struct list_head children;
|
113 | abdb293f | Chrysostomos Nanakos | struct vhd_image *parent_image;
|
114 | abdb293f | Chrysostomos Nanakos | }; |
115 | abdb293f | Chrysostomos Nanakos | |
116 | abdb293f | Chrysostomos Nanakos | struct vhd_scan {
|
117 | abdb293f | Chrysostomos Nanakos | int cur;
|
118 | abdb293f | Chrysostomos Nanakos | int size;
|
119 | abdb293f | Chrysostomos Nanakos | |
120 | abdb293f | Chrysostomos Nanakos | int lists_cur;
|
121 | abdb293f | Chrysostomos Nanakos | int lists_size;
|
122 | abdb293f | Chrysostomos Nanakos | |
123 | abdb293f | Chrysostomos Nanakos | struct vhd_image **images;
|
124 | abdb293f | Chrysostomos Nanakos | struct vhd_image **lists;
|
125 | abdb293f | Chrysostomos Nanakos | }; |
126 | abdb293f | Chrysostomos Nanakos | |
127 | abdb293f | Chrysostomos Nanakos | static int flags; |
128 | abdb293f | Chrysostomos Nanakos | static struct vg vg; |
129 | abdb293f | Chrysostomos Nanakos | static struct vhd_scan scan; |
130 | abdb293f | Chrysostomos Nanakos | |
131 | abdb293f | Chrysostomos Nanakos | static int |
132 | abdb293f | Chrysostomos Nanakos | vhd_util_scan_pretty_allocate_list(int cnt)
|
133 | abdb293f | Chrysostomos Nanakos | { |
134 | abdb293f | Chrysostomos Nanakos | int i;
|
135 | abdb293f | Chrysostomos Nanakos | |
136 | abdb293f | Chrysostomos Nanakos | memset(&scan, 0, sizeof(scan)); |
137 | abdb293f | Chrysostomos Nanakos | |
138 | abdb293f | Chrysostomos Nanakos | scan.lists_cur = 1;
|
139 | abdb293f | Chrysostomos Nanakos | scan.lists_size = 10;
|
140 | abdb293f | Chrysostomos Nanakos | |
141 | abdb293f | Chrysostomos Nanakos | scan.lists = calloc(scan.lists_size, sizeof(struct vhd_image *)); |
142 | abdb293f | Chrysostomos Nanakos | if (!scan.lists)
|
143 | abdb293f | Chrysostomos Nanakos | goto fail;
|
144 | abdb293f | Chrysostomos Nanakos | |
145 | abdb293f | Chrysostomos Nanakos | scan.lists[0] = calloc(cnt, sizeof(struct vhd_image)); |
146 | abdb293f | Chrysostomos Nanakos | if (!scan.lists[0]) |
147 | abdb293f | Chrysostomos Nanakos | goto fail;
|
148 | abdb293f | Chrysostomos Nanakos | |
149 | abdb293f | Chrysostomos Nanakos | scan.images = calloc(cnt, sizeof(struct vhd_image *)); |
150 | abdb293f | Chrysostomos Nanakos | if (!scan.images)
|
151 | abdb293f | Chrysostomos Nanakos | goto fail;
|
152 | abdb293f | Chrysostomos Nanakos | |
153 | abdb293f | Chrysostomos Nanakos | for (i = 0; i < cnt; i++) |
154 | abdb293f | Chrysostomos Nanakos | scan.images[i] = scan.lists[0] + i;
|
155 | abdb293f | Chrysostomos Nanakos | |
156 | abdb293f | Chrysostomos Nanakos | scan.cur = 0;
|
157 | abdb293f | Chrysostomos Nanakos | scan.size = cnt; |
158 | abdb293f | Chrysostomos Nanakos | |
159 | abdb293f | Chrysostomos Nanakos | return 0; |
160 | abdb293f | Chrysostomos Nanakos | |
161 | abdb293f | Chrysostomos Nanakos | fail:
|
162 | abdb293f | Chrysostomos Nanakos | if (scan.lists) {
|
163 | abdb293f | Chrysostomos Nanakos | free(scan.lists[0]);
|
164 | abdb293f | Chrysostomos Nanakos | free(scan.lists); |
165 | abdb293f | Chrysostomos Nanakos | } |
166 | abdb293f | Chrysostomos Nanakos | |
167 | abdb293f | Chrysostomos Nanakos | free(scan.images); |
168 | abdb293f | Chrysostomos Nanakos | memset(&scan, 0, sizeof(scan)); |
169 | abdb293f | Chrysostomos Nanakos | return -ENOMEM;
|
170 | abdb293f | Chrysostomos Nanakos | } |
171 | abdb293f | Chrysostomos Nanakos | |
172 | abdb293f | Chrysostomos Nanakos | static void |
173 | abdb293f | Chrysostomos Nanakos | vhd_util_scan_pretty_free_list(void)
|
174 | abdb293f | Chrysostomos Nanakos | { |
175 | abdb293f | Chrysostomos Nanakos | int i;
|
176 | abdb293f | Chrysostomos Nanakos | |
177 | abdb293f | Chrysostomos Nanakos | if (scan.lists) {
|
178 | abdb293f | Chrysostomos Nanakos | for (i = 0; i < scan.lists_cur; i++) |
179 | abdb293f | Chrysostomos Nanakos | free(scan.lists[i]); |
180 | abdb293f | Chrysostomos Nanakos | free(scan.lists); |
181 | abdb293f | Chrysostomos Nanakos | } |
182 | abdb293f | Chrysostomos Nanakos | |
183 | abdb293f | Chrysostomos Nanakos | free(scan.images); |
184 | abdb293f | Chrysostomos Nanakos | memset(&scan, 0, sizeof(scan)); |
185 | abdb293f | Chrysostomos Nanakos | } |
186 | abdb293f | Chrysostomos Nanakos | |
187 | abdb293f | Chrysostomos Nanakos | static int |
188 | abdb293f | Chrysostomos Nanakos | vhd_util_scan_pretty_add_image(struct vhd_image *image)
|
189 | abdb293f | Chrysostomos Nanakos | { |
190 | abdb293f | Chrysostomos Nanakos | int i;
|
191 | abdb293f | Chrysostomos Nanakos | struct vhd_image *img;
|
192 | abdb293f | Chrysostomos Nanakos | |
193 | abdb293f | Chrysostomos Nanakos | for (i = 0; i < scan.cur; i++) { |
194 | abdb293f | Chrysostomos Nanakos | img = scan.images[i]; |
195 | abdb293f | Chrysostomos Nanakos | if (!strcmp(img->name, image->name))
|
196 | abdb293f | Chrysostomos Nanakos | return 0; |
197 | abdb293f | Chrysostomos Nanakos | } |
198 | abdb293f | Chrysostomos Nanakos | |
199 | abdb293f | Chrysostomos Nanakos | if (scan.cur >= scan.size) {
|
200 | abdb293f | Chrysostomos Nanakos | struct vhd_image *new, **list;
|
201 | abdb293f | Chrysostomos Nanakos | |
202 | abdb293f | Chrysostomos Nanakos | if (scan.lists_cur >= scan.lists_size) {
|
203 | abdb293f | Chrysostomos Nanakos | list = realloc(scan.lists, scan.lists_size * 2 *
|
204 | abdb293f | Chrysostomos Nanakos | sizeof(struct vhd_image *)); |
205 | abdb293f | Chrysostomos Nanakos | if (!list)
|
206 | abdb293f | Chrysostomos Nanakos | return -ENOMEM;
|
207 | abdb293f | Chrysostomos Nanakos | |
208 | abdb293f | Chrysostomos Nanakos | scan.lists_size *= 2;
|
209 | abdb293f | Chrysostomos Nanakos | scan.lists = list; |
210 | abdb293f | Chrysostomos Nanakos | } |
211 | abdb293f | Chrysostomos Nanakos | |
212 | abdb293f | Chrysostomos Nanakos | new = calloc(scan.size, sizeof(struct vhd_image)); |
213 | abdb293f | Chrysostomos Nanakos | if (!new)
|
214 | abdb293f | Chrysostomos Nanakos | return -ENOMEM;
|
215 | abdb293f | Chrysostomos Nanakos | |
216 | abdb293f | Chrysostomos Nanakos | scan.lists[scan.lists_cur++] = new; |
217 | abdb293f | Chrysostomos Nanakos | scan.size *= 2;
|
218 | abdb293f | Chrysostomos Nanakos | |
219 | abdb293f | Chrysostomos Nanakos | list = realloc(scan.images, scan.size * |
220 | abdb293f | Chrysostomos Nanakos | sizeof(struct vhd_image *)); |
221 | abdb293f | Chrysostomos Nanakos | if (!list)
|
222 | abdb293f | Chrysostomos Nanakos | return -ENOMEM;
|
223 | abdb293f | Chrysostomos Nanakos | |
224 | abdb293f | Chrysostomos Nanakos | scan.images = list; |
225 | abdb293f | Chrysostomos Nanakos | for (i = 0; i + scan.cur < scan.size; i++) |
226 | abdb293f | Chrysostomos Nanakos | scan.images[i + scan.cur] = new + i; |
227 | abdb293f | Chrysostomos Nanakos | } |
228 | abdb293f | Chrysostomos Nanakos | |
229 | abdb293f | Chrysostomos Nanakos | img = scan.images[scan.cur]; |
230 | abdb293f | Chrysostomos Nanakos | INIT_LIST_HEAD(&img->sibling); |
231 | abdb293f | Chrysostomos Nanakos | INIT_LIST_HEAD(&img->children); |
232 | abdb293f | Chrysostomos Nanakos | |
233 | abdb293f | Chrysostomos Nanakos | img->capacity = image->capacity; |
234 | abdb293f | Chrysostomos Nanakos | img->size = image->size; |
235 | abdb293f | Chrysostomos Nanakos | img->hidden = image->hidden; |
236 | abdb293f | Chrysostomos Nanakos | img->marker = image->marker; |
237 | abdb293f | Chrysostomos Nanakos | img->error = image->error; |
238 | abdb293f | Chrysostomos Nanakos | img->message = image->message; |
239 | abdb293f | Chrysostomos Nanakos | |
240 | abdb293f | Chrysostomos Nanakos | img->name = strdup(image->name); |
241 | abdb293f | Chrysostomos Nanakos | if (!img->name)
|
242 | abdb293f | Chrysostomos Nanakos | goto fail;
|
243 | abdb293f | Chrysostomos Nanakos | |
244 | abdb293f | Chrysostomos Nanakos | if (image->parent) {
|
245 | abdb293f | Chrysostomos Nanakos | img->parent = strdup(image->parent); |
246 | abdb293f | Chrysostomos Nanakos | if (!img->parent)
|
247 | abdb293f | Chrysostomos Nanakos | goto fail;
|
248 | abdb293f | Chrysostomos Nanakos | } |
249 | abdb293f | Chrysostomos Nanakos | |
250 | abdb293f | Chrysostomos Nanakos | scan.cur++; |
251 | abdb293f | Chrysostomos Nanakos | return 0; |
252 | abdb293f | Chrysostomos Nanakos | |
253 | abdb293f | Chrysostomos Nanakos | fail:
|
254 | abdb293f | Chrysostomos Nanakos | free(img->name); |
255 | abdb293f | Chrysostomos Nanakos | free(img->parent); |
256 | abdb293f | Chrysostomos Nanakos | memset(img, 0, sizeof(*img)); |
257 | abdb293f | Chrysostomos Nanakos | return -ENOMEM;
|
258 | abdb293f | Chrysostomos Nanakos | } |
259 | abdb293f | Chrysostomos Nanakos | |
260 | abdb293f | Chrysostomos Nanakos | static int |
261 | abdb293f | Chrysostomos Nanakos | vhd_util_scan_pretty_image_compare(const void *lhs, const void *rhs) |
262 | abdb293f | Chrysostomos Nanakos | { |
263 | abdb293f | Chrysostomos Nanakos | struct vhd_image *l, *r;
|
264 | abdb293f | Chrysostomos Nanakos | |
265 | abdb293f | Chrysostomos Nanakos | l = *(struct vhd_image **)lhs;
|
266 | abdb293f | Chrysostomos Nanakos | r = *(struct vhd_image **)rhs;
|
267 | abdb293f | Chrysostomos Nanakos | |
268 | abdb293f | Chrysostomos Nanakos | return strcmp(l->name, r->name);
|
269 | abdb293f | Chrysostomos Nanakos | } |
270 | abdb293f | Chrysostomos Nanakos | |
271 | abdb293f | Chrysostomos Nanakos | static void |
272 | abdb293f | Chrysostomos Nanakos | vhd_util_scan_print_image_indent(struct vhd_image *image, int tab) |
273 | abdb293f | Chrysostomos Nanakos | { |
274 | abdb293f | Chrysostomos Nanakos | char *pad, *name, *pmsg, *parent;
|
275 | abdb293f | Chrysostomos Nanakos | |
276 | abdb293f | Chrysostomos Nanakos | pad = (tab ? " " : ""); |
277 | abdb293f | Chrysostomos Nanakos | name = image->name; |
278 | abdb293f | Chrysostomos Nanakos | parent = (image->parent ? : "none");
|
279 | abdb293f | Chrysostomos Nanakos | |
280 | abdb293f | Chrysostomos Nanakos | if ((flags & VHD_SCAN_PRETTY) && image->parent && !image->parent_image)
|
281 | abdb293f | Chrysostomos Nanakos | pmsg = " (not found in scan)";
|
282 | abdb293f | Chrysostomos Nanakos | else
|
283 | abdb293f | Chrysostomos Nanakos | pmsg = "";
|
284 | abdb293f | Chrysostomos Nanakos | |
285 | abdb293f | Chrysostomos Nanakos | if (!(flags & VHD_SCAN_VERBOSE)) {
|
286 | abdb293f | Chrysostomos Nanakos | name = basename(image->name); |
287 | abdb293f | Chrysostomos Nanakos | if (image->parent)
|
288 | abdb293f | Chrysostomos Nanakos | parent = basename(image->parent); |
289 | abdb293f | Chrysostomos Nanakos | } |
290 | abdb293f | Chrysostomos Nanakos | |
291 | abdb293f | Chrysostomos Nanakos | if (image->error)
|
292 | abdb293f | Chrysostomos Nanakos | printf("%*svhd=%s scan-error=%d error-message='%s'\n",
|
293 | abdb293f | Chrysostomos Nanakos | tab, pad, image->name, image->error, image->message); |
294 | abdb293f | Chrysostomos Nanakos | else if (!(flags & VHD_SCAN_MARKERS)) |
295 | abdb293f | Chrysostomos Nanakos | printf("%*svhd=%s capacity=%"PRIu64" size=%"PRIu64" hidden=%u " |
296 | abdb293f | Chrysostomos Nanakos | "parent=%s%s\n", tab, pad, name, image->capacity,
|
297 | abdb293f | Chrysostomos Nanakos | image->size, image->hidden, parent, pmsg); |
298 | abdb293f | Chrysostomos Nanakos | else
|
299 | abdb293f | Chrysostomos Nanakos | printf("%*svhd=%s capacity=%"PRIu64" size=%"PRIu64" hidden=%u " |
300 | abdb293f | Chrysostomos Nanakos | "marker=%u parent=%s%s\n", tab, pad, name,
|
301 | abdb293f | Chrysostomos Nanakos | image->capacity, image->size, image->hidden, |
302 | abdb293f | Chrysostomos Nanakos | (uint8_t)image->marker, parent, pmsg); |
303 | abdb293f | Chrysostomos Nanakos | } |
304 | abdb293f | Chrysostomos Nanakos | |
305 | abdb293f | Chrysostomos Nanakos | static void |
306 | abdb293f | Chrysostomos Nanakos | vhd_util_scan_pretty_print_tree(struct vhd_image *image, int depth) |
307 | abdb293f | Chrysostomos Nanakos | { |
308 | abdb293f | Chrysostomos Nanakos | struct vhd_image *img, *tmp;
|
309 | abdb293f | Chrysostomos Nanakos | |
310 | abdb293f | Chrysostomos Nanakos | vhd_util_scan_print_image_indent(image, depth * 3);
|
311 | abdb293f | Chrysostomos Nanakos | |
312 | abdb293f | Chrysostomos Nanakos | list_for_each_entry_safe(img, tmp, &image->children, sibling) |
313 | abdb293f | Chrysostomos Nanakos | if (!img->hidden)
|
314 | abdb293f | Chrysostomos Nanakos | vhd_util_scan_pretty_print_tree(img, depth + 1);
|
315 | abdb293f | Chrysostomos Nanakos | |
316 | abdb293f | Chrysostomos Nanakos | list_for_each_entry_safe(img, tmp, &image->children, sibling) |
317 | abdb293f | Chrysostomos Nanakos | if (img->hidden)
|
318 | abdb293f | Chrysostomos Nanakos | vhd_util_scan_pretty_print_tree(img, depth + 1);
|
319 | abdb293f | Chrysostomos Nanakos | |
320 | abdb293f | Chrysostomos Nanakos | free(image->name); |
321 | abdb293f | Chrysostomos Nanakos | free(image->parent); |
322 | abdb293f | Chrysostomos Nanakos | |
323 | abdb293f | Chrysostomos Nanakos | image->name = NULL;
|
324 | abdb293f | Chrysostomos Nanakos | image->parent = NULL;
|
325 | abdb293f | Chrysostomos Nanakos | } |
326 | abdb293f | Chrysostomos Nanakos | |
327 | abdb293f | Chrysostomos Nanakos | static void |
328 | abdb293f | Chrysostomos Nanakos | vhd_util_scan_pretty_print_images(void)
|
329 | abdb293f | Chrysostomos Nanakos | { |
330 | abdb293f | Chrysostomos Nanakos | int i;
|
331 | abdb293f | Chrysostomos Nanakos | struct vhd_image *image, **parentp, *parent, *keyp, key;
|
332 | abdb293f | Chrysostomos Nanakos | |
333 | abdb293f | Chrysostomos Nanakos | qsort(scan.images, scan.cur, sizeof(scan.images[0]), |
334 | abdb293f | Chrysostomos Nanakos | vhd_util_scan_pretty_image_compare); |
335 | abdb293f | Chrysostomos Nanakos | |
336 | abdb293f | Chrysostomos Nanakos | for (i = 0; i < scan.cur; i++) { |
337 | abdb293f | Chrysostomos Nanakos | image = scan.images[i]; |
338 | abdb293f | Chrysostomos Nanakos | |
339 | abdb293f | Chrysostomos Nanakos | if (!image->parent) {
|
340 | abdb293f | Chrysostomos Nanakos | image->parent_image = NULL;
|
341 | abdb293f | Chrysostomos Nanakos | continue;
|
342 | abdb293f | Chrysostomos Nanakos | } |
343 | abdb293f | Chrysostomos Nanakos | |
344 | abdb293f | Chrysostomos Nanakos | memset(&key, 0, sizeof(key)); |
345 | abdb293f | Chrysostomos Nanakos | key.name = image->parent; |
346 | abdb293f | Chrysostomos Nanakos | keyp = &key; |
347 | abdb293f | Chrysostomos Nanakos | |
348 | abdb293f | Chrysostomos Nanakos | parentp = bsearch(&keyp, scan.images, scan.cur, |
349 | abdb293f | Chrysostomos Nanakos | sizeof(scan.images[0]), |
350 | abdb293f | Chrysostomos Nanakos | vhd_util_scan_pretty_image_compare); |
351 | abdb293f | Chrysostomos Nanakos | if (!parentp) {
|
352 | abdb293f | Chrysostomos Nanakos | image->parent_image = NULL;
|
353 | abdb293f | Chrysostomos Nanakos | continue;
|
354 | abdb293f | Chrysostomos Nanakos | } |
355 | abdb293f | Chrysostomos Nanakos | |
356 | abdb293f | Chrysostomos Nanakos | parent = *parentp; |
357 | abdb293f | Chrysostomos Nanakos | image->parent_image = parent; |
358 | abdb293f | Chrysostomos Nanakos | list_add_tail(&image->sibling, &parent->children); |
359 | abdb293f | Chrysostomos Nanakos | } |
360 | abdb293f | Chrysostomos Nanakos | |
361 | abdb293f | Chrysostomos Nanakos | for (i = 0; i < scan.cur; i++) { |
362 | abdb293f | Chrysostomos Nanakos | image = scan.images[i]; |
363 | abdb293f | Chrysostomos Nanakos | |
364 | abdb293f | Chrysostomos Nanakos | if (image->parent_image || !image->hidden)
|
365 | abdb293f | Chrysostomos Nanakos | continue;
|
366 | abdb293f | Chrysostomos Nanakos | |
367 | abdb293f | Chrysostomos Nanakos | vhd_util_scan_pretty_print_tree(image, 0);
|
368 | abdb293f | Chrysostomos Nanakos | } |
369 | abdb293f | Chrysostomos Nanakos | |
370 | abdb293f | Chrysostomos Nanakos | for (i = 0; i < scan.cur; i++) { |
371 | abdb293f | Chrysostomos Nanakos | image = scan.images[i]; |
372 | abdb293f | Chrysostomos Nanakos | |
373 | abdb293f | Chrysostomos Nanakos | if (!image->name || image->parent_image)
|
374 | abdb293f | Chrysostomos Nanakos | continue;
|
375 | abdb293f | Chrysostomos Nanakos | |
376 | abdb293f | Chrysostomos Nanakos | vhd_util_scan_pretty_print_tree(image, 0);
|
377 | abdb293f | Chrysostomos Nanakos | } |
378 | abdb293f | Chrysostomos Nanakos | |
379 | abdb293f | Chrysostomos Nanakos | for (i = 0; i < scan.cur; i++) { |
380 | abdb293f | Chrysostomos Nanakos | image = scan.images[i]; |
381 | abdb293f | Chrysostomos Nanakos | |
382 | abdb293f | Chrysostomos Nanakos | if (!image->name)
|
383 | abdb293f | Chrysostomos Nanakos | continue;
|
384 | abdb293f | Chrysostomos Nanakos | |
385 | abdb293f | Chrysostomos Nanakos | vhd_util_scan_pretty_print_tree(image, 0);
|
386 | abdb293f | Chrysostomos Nanakos | } |
387 | abdb293f | Chrysostomos Nanakos | } |
388 | abdb293f | Chrysostomos Nanakos | |
389 | abdb293f | Chrysostomos Nanakos | static void |
390 | abdb293f | Chrysostomos Nanakos | vhd_util_scan_print_image(struct vhd_image *image)
|
391 | abdb293f | Chrysostomos Nanakos | { |
392 | abdb293f | Chrysostomos Nanakos | int err;
|
393 | abdb293f | Chrysostomos Nanakos | |
394 | abdb293f | Chrysostomos Nanakos | if (!image->error && (flags & VHD_SCAN_PRETTY)) {
|
395 | abdb293f | Chrysostomos Nanakos | err = vhd_util_scan_pretty_add_image(image); |
396 | abdb293f | Chrysostomos Nanakos | if (!err)
|
397 | abdb293f | Chrysostomos Nanakos | return;
|
398 | abdb293f | Chrysostomos Nanakos | |
399 | abdb293f | Chrysostomos Nanakos | if (!image->error) {
|
400 | abdb293f | Chrysostomos Nanakos | image->error = err; |
401 | abdb293f | Chrysostomos Nanakos | image->message = "allocating memory";
|
402 | abdb293f | Chrysostomos Nanakos | } |
403 | abdb293f | Chrysostomos Nanakos | } |
404 | abdb293f | Chrysostomos Nanakos | |
405 | abdb293f | Chrysostomos Nanakos | vhd_util_scan_print_image_indent(image, 0);
|
406 | abdb293f | Chrysostomos Nanakos | } |
407 | abdb293f | Chrysostomos Nanakos | |
408 | abdb293f | Chrysostomos Nanakos | static int |
409 | abdb293f | Chrysostomos Nanakos | vhd_util_scan_error(const char *file, int err) |
410 | abdb293f | Chrysostomos Nanakos | { |
411 | abdb293f | Chrysostomos Nanakos | struct vhd_image image;
|
412 | abdb293f | Chrysostomos Nanakos | |
413 | abdb293f | Chrysostomos Nanakos | memset(&image, 0, sizeof(image)); |
414 | abdb293f | Chrysostomos Nanakos | image.name = (char *)file;
|
415 | abdb293f | Chrysostomos Nanakos | image.error = err; |
416 | abdb293f | Chrysostomos Nanakos | image.message = "failure scanning target";
|
417 | abdb293f | Chrysostomos Nanakos | |
418 | abdb293f | Chrysostomos Nanakos | vhd_util_scan_print_image(&image); |
419 | abdb293f | Chrysostomos Nanakos | |
420 | abdb293f | Chrysostomos Nanakos | /*
|
421 | abdb293f | Chrysostomos Nanakos | if (flags & VHD_SCAN_NOFAIL)
|
422 | abdb293f | Chrysostomos Nanakos | return 0;
|
423 | abdb293f | Chrysostomos Nanakos | */
|
424 | abdb293f | Chrysostomos Nanakos | |
425 | abdb293f | Chrysostomos Nanakos | return err;
|
426 | abdb293f | Chrysostomos Nanakos | } |
427 | abdb293f | Chrysostomos Nanakos | |
428 | abdb293f | Chrysostomos Nanakos | static vhd_parent_locator_t *
|
429 | abdb293f | Chrysostomos Nanakos | vhd_util_scan_get_parent_locator(vhd_context_t *vhd) |
430 | abdb293f | Chrysostomos Nanakos | { |
431 | abdb293f | Chrysostomos Nanakos | int i;
|
432 | abdb293f | Chrysostomos Nanakos | vhd_parent_locator_t *loc; |
433 | abdb293f | Chrysostomos Nanakos | |
434 | abdb293f | Chrysostomos Nanakos | loc = NULL;
|
435 | abdb293f | Chrysostomos Nanakos | |
436 | abdb293f | Chrysostomos Nanakos | for (i = 0; i < 8; i++) { |
437 | abdb293f | Chrysostomos Nanakos | if (vhd->header.loc[i].code == PLAT_CODE_MACX) {
|
438 | abdb293f | Chrysostomos Nanakos | loc = vhd->header.loc + i; |
439 | abdb293f | Chrysostomos Nanakos | break;
|
440 | abdb293f | Chrysostomos Nanakos | } |
441 | abdb293f | Chrysostomos Nanakos | |
442 | abdb293f | Chrysostomos Nanakos | if (vhd->header.loc[i].code == PLAT_CODE_W2RU)
|
443 | abdb293f | Chrysostomos Nanakos | loc = vhd->header.loc + i; |
444 | abdb293f | Chrysostomos Nanakos | |
445 | abdb293f | Chrysostomos Nanakos | if (!loc && vhd->header.loc[i].code != PLAT_CODE_NONE)
|
446 | abdb293f | Chrysostomos Nanakos | loc = vhd->header.loc + i; |
447 | abdb293f | Chrysostomos Nanakos | } |
448 | abdb293f | Chrysostomos Nanakos | |
449 | abdb293f | Chrysostomos Nanakos | return loc;
|
450 | abdb293f | Chrysostomos Nanakos | } |
451 | abdb293f | Chrysostomos Nanakos | |
452 | abdb293f | Chrysostomos Nanakos | static inline int |
453 | abdb293f | Chrysostomos Nanakos | copy_name(char *dst, const char *src) |
454 | abdb293f | Chrysostomos Nanakos | { |
455 | abdb293f | Chrysostomos Nanakos | if (snprintf(dst, VHD_MAX_NAME_LEN, "%s", src) < VHD_MAX_NAME_LEN) |
456 | abdb293f | Chrysostomos Nanakos | return 0; |
457 | abdb293f | Chrysostomos Nanakos | |
458 | abdb293f | Chrysostomos Nanakos | return -ENAMETOOLONG;
|
459 | abdb293f | Chrysostomos Nanakos | } |
460 | abdb293f | Chrysostomos Nanakos | |
461 | abdb293f | Chrysostomos Nanakos | /*
|
462 | abdb293f | Chrysostomos Nanakos | * LVHD stores realpath(parent) in parent locators, so
|
463 | abdb293f | Chrysostomos Nanakos | * /dev/<vol-group>/<lv-name> becomes /dev/mapper/<vol--group>-<lv--name>
|
464 | abdb293f | Chrysostomos Nanakos | */
|
465 | abdb293f | Chrysostomos Nanakos | static int |
466 | abdb293f | Chrysostomos Nanakos | vhd_util_scan_extract_volume_name(char *dst, const char *src) |
467 | abdb293f | Chrysostomos Nanakos | { |
468 | abdb293f | Chrysostomos Nanakos | char copy[VHD_MAX_NAME_LEN], *name, *s, *c;
|
469 | abdb293f | Chrysostomos Nanakos | |
470 | abdb293f | Chrysostomos Nanakos | name = strrchr(src, '/');
|
471 | abdb293f | Chrysostomos Nanakos | if (!name)
|
472 | abdb293f | Chrysostomos Nanakos | name = (char *)src;
|
473 | abdb293f | Chrysostomos Nanakos | |
474 | abdb293f | Chrysostomos Nanakos | /* convert single dashes to slashes, double dashes to single dashes */
|
475 | abdb293f | Chrysostomos Nanakos | for (c = copy, s = name; *s != '\0'; s++, c++) { |
476 | abdb293f | Chrysostomos Nanakos | if (*s == '-') { |
477 | abdb293f | Chrysostomos Nanakos | if (s[1] != '-') |
478 | abdb293f | Chrysostomos Nanakos | *c = '/';
|
479 | abdb293f | Chrysostomos Nanakos | else {
|
480 | abdb293f | Chrysostomos Nanakos | s++; |
481 | abdb293f | Chrysostomos Nanakos | *c = '-';
|
482 | abdb293f | Chrysostomos Nanakos | } |
483 | abdb293f | Chrysostomos Nanakos | } else
|
484 | abdb293f | Chrysostomos Nanakos | *c = *s; |
485 | abdb293f | Chrysostomos Nanakos | } |
486 | abdb293f | Chrysostomos Nanakos | |
487 | abdb293f | Chrysostomos Nanakos | *c = '\0';
|
488 | abdb293f | Chrysostomos Nanakos | c = strrchr(copy, '/');
|
489 | abdb293f | Chrysostomos Nanakos | if (c == name) {
|
490 | abdb293f | Chrysostomos Nanakos | /* unrecognized format */
|
491 | abdb293f | Chrysostomos Nanakos | strcpy(dst, src); |
492 | abdb293f | Chrysostomos Nanakos | return -EINVAL;
|
493 | abdb293f | Chrysostomos Nanakos | } |
494 | abdb293f | Chrysostomos Nanakos | |
495 | abdb293f | Chrysostomos Nanakos | strcpy(dst, ++c); |
496 | abdb293f | Chrysostomos Nanakos | return 0; |
497 | abdb293f | Chrysostomos Nanakos | } |
498 | abdb293f | Chrysostomos Nanakos | |
499 | abdb293f | Chrysostomos Nanakos | static int |
500 | abdb293f | Chrysostomos Nanakos | vhd_util_scan_get_volume_parent(vhd_context_t *vhd, struct vhd_image *image)
|
501 | abdb293f | Chrysostomos Nanakos | { |
502 | abdb293f | Chrysostomos Nanakos | int err;
|
503 | abdb293f | Chrysostomos Nanakos | char name[VHD_MAX_NAME_LEN];
|
504 | abdb293f | Chrysostomos Nanakos | vhd_parent_locator_t *loc, copy; |
505 | abdb293f | Chrysostomos Nanakos | |
506 | abdb293f | Chrysostomos Nanakos | if (flags & VHD_SCAN_FAST) {
|
507 | abdb293f | Chrysostomos Nanakos | err = vhd_header_decode_parent(vhd, |
508 | abdb293f | Chrysostomos Nanakos | &vhd->header, &image->parent); |
509 | abdb293f | Chrysostomos Nanakos | if (!err)
|
510 | abdb293f | Chrysostomos Nanakos | goto found;
|
511 | abdb293f | Chrysostomos Nanakos | } |
512 | abdb293f | Chrysostomos Nanakos | |
513 | abdb293f | Chrysostomos Nanakos | loc = vhd_util_scan_get_parent_locator(vhd); |
514 | abdb293f | Chrysostomos Nanakos | if (!loc)
|
515 | abdb293f | Chrysostomos Nanakos | return -EINVAL;
|
516 | abdb293f | Chrysostomos Nanakos | |
517 | abdb293f | Chrysostomos Nanakos | copy = *loc; |
518 | abdb293f | Chrysostomos Nanakos | copy.data_offset += image->target->start; |
519 | abdb293f | Chrysostomos Nanakos | err = vhd_parent_locator_read(vhd, ©, &image->parent); |
520 | abdb293f | Chrysostomos Nanakos | if (err)
|
521 | abdb293f | Chrysostomos Nanakos | return err;
|
522 | abdb293f | Chrysostomos Nanakos | |
523 | abdb293f | Chrysostomos Nanakos | found:
|
524 | abdb293f | Chrysostomos Nanakos | err = vhd_util_scan_extract_volume_name(name, image->parent); |
525 | abdb293f | Chrysostomos Nanakos | if (!err)
|
526 | abdb293f | Chrysostomos Nanakos | return copy_name(image->parent, name);
|
527 | abdb293f | Chrysostomos Nanakos | |
528 | abdb293f | Chrysostomos Nanakos | return 0; |
529 | abdb293f | Chrysostomos Nanakos | } |
530 | abdb293f | Chrysostomos Nanakos | |
531 | abdb293f | Chrysostomos Nanakos | static int |
532 | abdb293f | Chrysostomos Nanakos | vhd_util_scan_get_parent(vhd_context_t *vhd, struct vhd_image *image)
|
533 | abdb293f | Chrysostomos Nanakos | { |
534 | abdb293f | Chrysostomos Nanakos | int err;
|
535 | abdb293f | Chrysostomos Nanakos | vhd_parent_locator_t *loc; |
536 | abdb293f | Chrysostomos Nanakos | |
537 | abdb293f | Chrysostomos Nanakos | if (!target_vhd(image->target->type)) {
|
538 | abdb293f | Chrysostomos Nanakos | image->parent = NULL;
|
539 | abdb293f | Chrysostomos Nanakos | return 0; |
540 | abdb293f | Chrysostomos Nanakos | } |
541 | abdb293f | Chrysostomos Nanakos | |
542 | abdb293f | Chrysostomos Nanakos | loc = NULL;
|
543 | abdb293f | Chrysostomos Nanakos | |
544 | abdb293f | Chrysostomos Nanakos | if (target_volume(image->target->type))
|
545 | abdb293f | Chrysostomos Nanakos | return vhd_util_scan_get_volume_parent(vhd, image);
|
546 | abdb293f | Chrysostomos Nanakos | |
547 | abdb293f | Chrysostomos Nanakos | if (flags & VHD_SCAN_FAST) {
|
548 | abdb293f | Chrysostomos Nanakos | err = vhd_header_decode_parent(vhd, |
549 | abdb293f | Chrysostomos Nanakos | &vhd->header, &image->parent); |
550 | abdb293f | Chrysostomos Nanakos | if (!err)
|
551 | abdb293f | Chrysostomos Nanakos | return 0; |
552 | abdb293f | Chrysostomos Nanakos | } else {
|
553 | abdb293f | Chrysostomos Nanakos | /*
|
554 | abdb293f | Chrysostomos Nanakos | * vhd_parent_locator_get checks for the existence of the
|
555 | abdb293f | Chrysostomos Nanakos | * parent file. if this call succeeds, all is well; if not,
|
556 | abdb293f | Chrysostomos Nanakos | * we'll try to return whatever string we have before failing
|
557 | abdb293f | Chrysostomos Nanakos | * outright.
|
558 | abdb293f | Chrysostomos Nanakos | */
|
559 | abdb293f | Chrysostomos Nanakos | err = vhd_parent_locator_get(vhd, &image->parent); |
560 | abdb293f | Chrysostomos Nanakos | if (!err)
|
561 | abdb293f | Chrysostomos Nanakos | return 0; |
562 | abdb293f | Chrysostomos Nanakos | } |
563 | abdb293f | Chrysostomos Nanakos | |
564 | abdb293f | Chrysostomos Nanakos | loc = vhd_util_scan_get_parent_locator(vhd); |
565 | abdb293f | Chrysostomos Nanakos | if (!loc)
|
566 | abdb293f | Chrysostomos Nanakos | return -EINVAL;
|
567 | abdb293f | Chrysostomos Nanakos | |
568 | abdb293f | Chrysostomos Nanakos | return vhd_parent_locator_read(vhd, loc, &image->parent);
|
569 | abdb293f | Chrysostomos Nanakos | } |
570 | abdb293f | Chrysostomos Nanakos | |
571 | abdb293f | Chrysostomos Nanakos | static int |
572 | abdb293f | Chrysostomos Nanakos | vhd_util_scan_get_hidden(vhd_context_t *vhd, struct vhd_image *image)
|
573 | abdb293f | Chrysostomos Nanakos | { |
574 | abdb293f | Chrysostomos Nanakos | int err, hidden;
|
575 | abdb293f | Chrysostomos Nanakos | |
576 | abdb293f | Chrysostomos Nanakos | err = 0;
|
577 | abdb293f | Chrysostomos Nanakos | hidden = 0;
|
578 | abdb293f | Chrysostomos Nanakos | |
579 | abdb293f | Chrysostomos Nanakos | if (target_vhd(image->target->type))
|
580 | abdb293f | Chrysostomos Nanakos | err = vhd_hidden(vhd, &hidden); |
581 | abdb293f | Chrysostomos Nanakos | else
|
582 | abdb293f | Chrysostomos Nanakos | hidden = 1;
|
583 | abdb293f | Chrysostomos Nanakos | |
584 | abdb293f | Chrysostomos Nanakos | if (err)
|
585 | abdb293f | Chrysostomos Nanakos | return err;
|
586 | abdb293f | Chrysostomos Nanakos | |
587 | abdb293f | Chrysostomos Nanakos | image->hidden = hidden; |
588 | abdb293f | Chrysostomos Nanakos | return 0; |
589 | abdb293f | Chrysostomos Nanakos | } |
590 | abdb293f | Chrysostomos Nanakos | |
591 | abdb293f | Chrysostomos Nanakos | static int |
592 | abdb293f | Chrysostomos Nanakos | vhd_util_scan_get_marker(vhd_context_t *vhd, struct vhd_image *image)
|
593 | abdb293f | Chrysostomos Nanakos | { |
594 | abdb293f | Chrysostomos Nanakos | int err;
|
595 | abdb293f | Chrysostomos Nanakos | char marker;
|
596 | abdb293f | Chrysostomos Nanakos | |
597 | abdb293f | Chrysostomos Nanakos | err = 0;
|
598 | abdb293f | Chrysostomos Nanakos | marker = 0;
|
599 | abdb293f | Chrysostomos Nanakos | |
600 | abdb293f | Chrysostomos Nanakos | if (target_vhd(image->target->type) && vhd_has_batmap(vhd))
|
601 | abdb293f | Chrysostomos Nanakos | err = vhd_marker(vhd, &marker); |
602 | abdb293f | Chrysostomos Nanakos | |
603 | abdb293f | Chrysostomos Nanakos | image->marker = marker; |
604 | abdb293f | Chrysostomos Nanakos | return err;
|
605 | abdb293f | Chrysostomos Nanakos | } |
606 | abdb293f | Chrysostomos Nanakos | |
607 | abdb293f | Chrysostomos Nanakos | static int |
608 | abdb293f | Chrysostomos Nanakos | vhd_util_scan_get_size(vhd_context_t *vhd, struct vhd_image *image)
|
609 | abdb293f | Chrysostomos Nanakos | { |
610 | abdb293f | Chrysostomos Nanakos | image->size = image->target->size; |
611 | abdb293f | Chrysostomos Nanakos | |
612 | abdb293f | Chrysostomos Nanakos | if (target_vhd(image->target->type))
|
613 | abdb293f | Chrysostomos Nanakos | image->capacity = vhd->footer.curr_size; |
614 | abdb293f | Chrysostomos Nanakos | else
|
615 | abdb293f | Chrysostomos Nanakos | image->capacity = image->size; |
616 | abdb293f | Chrysostomos Nanakos | |
617 | abdb293f | Chrysostomos Nanakos | return 0; |
618 | abdb293f | Chrysostomos Nanakos | } |
619 | abdb293f | Chrysostomos Nanakos | |
620 | abdb293f | Chrysostomos Nanakos | static int |
621 | abdb293f | Chrysostomos Nanakos | vhd_util_scan_open_file(vhd_context_t *vhd, struct vhd_image *image)
|
622 | abdb293f | Chrysostomos Nanakos | { |
623 | abdb293f | Chrysostomos Nanakos | int err, vhd_flags;
|
624 | abdb293f | Chrysostomos Nanakos | |
625 | abdb293f | Chrysostomos Nanakos | if (!target_vhd(image->target->type))
|
626 | abdb293f | Chrysostomos Nanakos | return 0; |
627 | abdb293f | Chrysostomos Nanakos | |
628 | abdb293f | Chrysostomos Nanakos | vhd_flags = VHD_OPEN_RDONLY | VHD_OPEN_IGNORE_DISABLED; |
629 | abdb293f | Chrysostomos Nanakos | if (flags & VHD_SCAN_FAST)
|
630 | abdb293f | Chrysostomos Nanakos | vhd_flags |= VHD_OPEN_FAST; |
631 | abdb293f | Chrysostomos Nanakos | |
632 | abdb293f | Chrysostomos Nanakos | err = vhd_open(vhd, image->name, vhd_flags); |
633 | abdb293f | Chrysostomos Nanakos | if (err) {
|
634 | abdb293f | Chrysostomos Nanakos | vhd->file = NULL;
|
635 | abdb293f | Chrysostomos Nanakos | image->message = "opening file";
|
636 | abdb293f | Chrysostomos Nanakos | image->error = err; |
637 | abdb293f | Chrysostomos Nanakos | return image->error;
|
638 | abdb293f | Chrysostomos Nanakos | } |
639 | abdb293f | Chrysostomos Nanakos | |
640 | abdb293f | Chrysostomos Nanakos | return 0; |
641 | abdb293f | Chrysostomos Nanakos | } |
642 | abdb293f | Chrysostomos Nanakos | |
643 | abdb293f | Chrysostomos Nanakos | static int |
644 | abdb293f | Chrysostomos Nanakos | vhd_util_scan_read_volume_headers(vhd_context_t *vhd, struct vhd_image *image)
|
645 | abdb293f | Chrysostomos Nanakos | { |
646 | abdb293f | Chrysostomos Nanakos | int err;
|
647 | abdb293f | Chrysostomos Nanakos | void *buf;
|
648 | abdb293f | Chrysostomos Nanakos | size_t size; |
649 | abdb293f | Chrysostomos Nanakos | struct target *target;
|
650 | abdb293f | Chrysostomos Nanakos | |
651 | abdb293f | Chrysostomos Nanakos | buf = NULL;
|
652 | abdb293f | Chrysostomos Nanakos | target = image->target; |
653 | abdb293f | Chrysostomos Nanakos | size = sizeof(vhd_footer_t) + sizeof(vhd_header_t); |
654 | abdb293f | Chrysostomos Nanakos | |
655 | abdb293f | Chrysostomos Nanakos | err = posix_memalign(&buf, VHD_SECTOR_SIZE, size); |
656 | abdb293f | Chrysostomos Nanakos | if (err) {
|
657 | abdb293f | Chrysostomos Nanakos | buf = NULL;
|
658 | abdb293f | Chrysostomos Nanakos | image->message = "allocating image";
|
659 | abdb293f | Chrysostomos Nanakos | image->error = -err; |
660 | abdb293f | Chrysostomos Nanakos | goto out;
|
661 | abdb293f | Chrysostomos Nanakos | } |
662 | abdb293f | Chrysostomos Nanakos | |
663 | abdb293f | Chrysostomos Nanakos | err = vhd_seek(vhd, target->start, SEEK_SET); |
664 | abdb293f | Chrysostomos Nanakos | if (err) {
|
665 | abdb293f | Chrysostomos Nanakos | image->message = "seeking to headers";
|
666 | abdb293f | Chrysostomos Nanakos | image->error = err; |
667 | abdb293f | Chrysostomos Nanakos | goto out;
|
668 | abdb293f | Chrysostomos Nanakos | } |
669 | abdb293f | Chrysostomos Nanakos | |
670 | abdb293f | Chrysostomos Nanakos | err = vhd_read(vhd, buf, size); |
671 | abdb293f | Chrysostomos Nanakos | if (err) {
|
672 | abdb293f | Chrysostomos Nanakos | image->message = "reading headers";
|
673 | abdb293f | Chrysostomos Nanakos | image->error = err; |
674 | abdb293f | Chrysostomos Nanakos | goto out;
|
675 | abdb293f | Chrysostomos Nanakos | } |
676 | abdb293f | Chrysostomos Nanakos | |
677 | abdb293f | Chrysostomos Nanakos | memcpy(&vhd->footer, buf, sizeof(vhd_footer_t));
|
678 | abdb293f | Chrysostomos Nanakos | vhd_footer_in(&vhd->footer); |
679 | abdb293f | Chrysostomos Nanakos | err = vhd_validate_footer(&vhd->footer); |
680 | abdb293f | Chrysostomos Nanakos | if (err) {
|
681 | abdb293f | Chrysostomos Nanakos | image->message = "invalid footer";
|
682 | abdb293f | Chrysostomos Nanakos | image->error = err; |
683 | abdb293f | Chrysostomos Nanakos | goto out;
|
684 | abdb293f | Chrysostomos Nanakos | } |
685 | abdb293f | Chrysostomos Nanakos | |
686 | abdb293f | Chrysostomos Nanakos | /* lvhd vhds should always be dynamic */
|
687 | abdb293f | Chrysostomos Nanakos | if (vhd_type_dynamic(vhd)) {
|
688 | abdb293f | Chrysostomos Nanakos | if (vhd->footer.data_offset != sizeof(vhd_footer_t)) |
689 | abdb293f | Chrysostomos Nanakos | err = vhd_read_header_at(vhd, &vhd->header, |
690 | abdb293f | Chrysostomos Nanakos | vhd->footer.data_offset + |
691 | abdb293f | Chrysostomos Nanakos | target->start); |
692 | abdb293f | Chrysostomos Nanakos | else {
|
693 | abdb293f | Chrysostomos Nanakos | memcpy(&vhd->header, |
694 | abdb293f | Chrysostomos Nanakos | buf + sizeof(vhd_footer_t),
|
695 | abdb293f | Chrysostomos Nanakos | sizeof(vhd_header_t));
|
696 | abdb293f | Chrysostomos Nanakos | vhd_header_in(&vhd->header); |
697 | abdb293f | Chrysostomos Nanakos | err = vhd_validate_header(&vhd->header); |
698 | abdb293f | Chrysostomos Nanakos | } |
699 | abdb293f | Chrysostomos Nanakos | |
700 | abdb293f | Chrysostomos Nanakos | if (err) {
|
701 | abdb293f | Chrysostomos Nanakos | image->message = "reading header";
|
702 | abdb293f | Chrysostomos Nanakos | image->error = err; |
703 | abdb293f | Chrysostomos Nanakos | goto out;
|
704 | abdb293f | Chrysostomos Nanakos | } |
705 | abdb293f | Chrysostomos Nanakos | |
706 | abdb293f | Chrysostomos Nanakos | vhd->spb = vhd->header.block_size >> VHD_SECTOR_SHIFT; |
707 | abdb293f | Chrysostomos Nanakos | vhd->bm_secs = secs_round_up_no_zero(vhd->spb >> 3);
|
708 | abdb293f | Chrysostomos Nanakos | } |
709 | abdb293f | Chrysostomos Nanakos | |
710 | abdb293f | Chrysostomos Nanakos | out:
|
711 | abdb293f | Chrysostomos Nanakos | free(buf); |
712 | abdb293f | Chrysostomos Nanakos | return image->error;
|
713 | abdb293f | Chrysostomos Nanakos | } |
714 | abdb293f | Chrysostomos Nanakos | |
715 | abdb293f | Chrysostomos Nanakos | static int |
716 | abdb293f | Chrysostomos Nanakos | vhd_util_scan_open_volume(vhd_context_t *vhd, struct vhd_image *image)
|
717 | abdb293f | Chrysostomos Nanakos | { |
718 | abdb293f | Chrysostomos Nanakos | struct target *target;
|
719 | abdb293f | Chrysostomos Nanakos | |
720 | abdb293f | Chrysostomos Nanakos | target = image->target; |
721 | abdb293f | Chrysostomos Nanakos | memset(vhd, 0, sizeof(*vhd)); |
722 | abdb293f | Chrysostomos Nanakos | vhd->oflags = VHD_OPEN_RDONLY | VHD_OPEN_FAST; |
723 | abdb293f | Chrysostomos Nanakos | |
724 | abdb293f | Chrysostomos Nanakos | if (target->end - target->start < 4096) { |
725 | abdb293f | Chrysostomos Nanakos | image->message = "device too small";
|
726 | abdb293f | Chrysostomos Nanakos | image->error = -EINVAL; |
727 | abdb293f | Chrysostomos Nanakos | return image->error;
|
728 | abdb293f | Chrysostomos Nanakos | } |
729 | abdb293f | Chrysostomos Nanakos | |
730 | abdb293f | Chrysostomos Nanakos | vhd->file = strdup(image->name); |
731 | abdb293f | Chrysostomos Nanakos | if (!vhd->file) {
|
732 | abdb293f | Chrysostomos Nanakos | image->message = "allocating device";
|
733 | abdb293f | Chrysostomos Nanakos | image->error = -ENOMEM; |
734 | abdb293f | Chrysostomos Nanakos | return image->error;
|
735 | abdb293f | Chrysostomos Nanakos | } |
736 | abdb293f | Chrysostomos Nanakos | |
737 | abdb293f | Chrysostomos Nanakos | vhd->fd = open(target->device, O_RDONLY | O_DIRECT | O_LARGEFILE); |
738 | abdb293f | Chrysostomos Nanakos | if (vhd->fd == -1) { |
739 | abdb293f | Chrysostomos Nanakos | free(vhd->file); |
740 | abdb293f | Chrysostomos Nanakos | vhd->file = NULL;
|
741 | abdb293f | Chrysostomos Nanakos | |
742 | abdb293f | Chrysostomos Nanakos | image->message = "opening device";
|
743 | abdb293f | Chrysostomos Nanakos | image->error = -errno; |
744 | abdb293f | Chrysostomos Nanakos | return image->error;
|
745 | abdb293f | Chrysostomos Nanakos | } |
746 | abdb293f | Chrysostomos Nanakos | |
747 | abdb293f | Chrysostomos Nanakos | if (target_vhd(target->type))
|
748 | abdb293f | Chrysostomos Nanakos | return vhd_util_scan_read_volume_headers(vhd, image);
|
749 | abdb293f | Chrysostomos Nanakos | |
750 | abdb293f | Chrysostomos Nanakos | return 0; |
751 | abdb293f | Chrysostomos Nanakos | } |
752 | abdb293f | Chrysostomos Nanakos | |
753 | abdb293f | Chrysostomos Nanakos | static int |
754 | abdb293f | Chrysostomos Nanakos | vhd_util_scan_open(vhd_context_t *vhd, struct vhd_image *image)
|
755 | abdb293f | Chrysostomos Nanakos | { |
756 | abdb293f | Chrysostomos Nanakos | struct target *target;
|
757 | abdb293f | Chrysostomos Nanakos | |
758 | abdb293f | Chrysostomos Nanakos | target = image->target; |
759 | abdb293f | Chrysostomos Nanakos | |
760 | abdb293f | Chrysostomos Nanakos | if (target_volume(image->target->type) || !(flags & VHD_SCAN_PRETTY))
|
761 | abdb293f | Chrysostomos Nanakos | image->name = target->name; |
762 | abdb293f | Chrysostomos Nanakos | else {
|
763 | abdb293f | Chrysostomos Nanakos | char __image_name[PATH_MAX];
|
764 | abdb293f | Chrysostomos Nanakos | |
765 | abdb293f | Chrysostomos Nanakos | image->name = realpath(target->name, __image_name); |
766 | abdb293f | Chrysostomos Nanakos | if (image->name)
|
767 | abdb293f | Chrysostomos Nanakos | image->name = strdup(__image_name); |
768 | abdb293f | Chrysostomos Nanakos | if (!image->name) {
|
769 | abdb293f | Chrysostomos Nanakos | image->name = target->name; |
770 | abdb293f | Chrysostomos Nanakos | image->message = "resolving name";
|
771 | abdb293f | Chrysostomos Nanakos | image->error = -errno; |
772 | abdb293f | Chrysostomos Nanakos | return image->error;
|
773 | abdb293f | Chrysostomos Nanakos | } |
774 | abdb293f | Chrysostomos Nanakos | } |
775 | abdb293f | Chrysostomos Nanakos | |
776 | abdb293f | Chrysostomos Nanakos | if (target_volume(target->type))
|
777 | abdb293f | Chrysostomos Nanakos | return vhd_util_scan_open_volume(vhd, image);
|
778 | abdb293f | Chrysostomos Nanakos | else
|
779 | abdb293f | Chrysostomos Nanakos | return vhd_util_scan_open_file(vhd, image);
|
780 | abdb293f | Chrysostomos Nanakos | } |
781 | abdb293f | Chrysostomos Nanakos | |
782 | abdb293f | Chrysostomos Nanakos | static int |
783 | abdb293f | Chrysostomos Nanakos | vhd_util_scan_init_file_target(struct target *target,
|
784 | abdb293f | Chrysostomos Nanakos | const char *file, uint8_t type) |
785 | abdb293f | Chrysostomos Nanakos | { |
786 | abdb293f | Chrysostomos Nanakos | int err;
|
787 | abdb293f | Chrysostomos Nanakos | struct stat stats;
|
788 | abdb293f | Chrysostomos Nanakos | |
789 | abdb293f | Chrysostomos Nanakos | err = stat(file, &stats); |
790 | abdb293f | Chrysostomos Nanakos | if (err == -1) |
791 | abdb293f | Chrysostomos Nanakos | return -errno;
|
792 | abdb293f | Chrysostomos Nanakos | |
793 | abdb293f | Chrysostomos Nanakos | err = copy_name(target->name, file); |
794 | abdb293f | Chrysostomos Nanakos | if (err)
|
795 | abdb293f | Chrysostomos Nanakos | return err;
|
796 | abdb293f | Chrysostomos Nanakos | |
797 | abdb293f | Chrysostomos Nanakos | err = copy_name(target->device, file); |
798 | abdb293f | Chrysostomos Nanakos | if (err)
|
799 | abdb293f | Chrysostomos Nanakos | return err;
|
800 | abdb293f | Chrysostomos Nanakos | |
801 | abdb293f | Chrysostomos Nanakos | target->type = type; |
802 | abdb293f | Chrysostomos Nanakos | target->start = 0;
|
803 | abdb293f | Chrysostomos Nanakos | target->size = stats.st_size; |
804 | abdb293f | Chrysostomos Nanakos | target->end = stats.st_size; |
805 | abdb293f | Chrysostomos Nanakos | |
806 | abdb293f | Chrysostomos Nanakos | return 0; |
807 | abdb293f | Chrysostomos Nanakos | } |
808 | abdb293f | Chrysostomos Nanakos | |
809 | abdb293f | Chrysostomos Nanakos | static int |
810 | abdb293f | Chrysostomos Nanakos | vhd_util_scan_init_volume_target(struct target *target,
|
811 | abdb293f | Chrysostomos Nanakos | struct lv *lv, uint8_t type)
|
812 | abdb293f | Chrysostomos Nanakos | { |
813 | abdb293f | Chrysostomos Nanakos | int err;
|
814 | abdb293f | Chrysostomos Nanakos | |
815 | abdb293f | Chrysostomos Nanakos | if (lv->first_segment.type != LVM_SEG_TYPE_LINEAR)
|
816 | abdb293f | Chrysostomos Nanakos | return -ENOSYS;
|
817 | abdb293f | Chrysostomos Nanakos | |
818 | abdb293f | Chrysostomos Nanakos | err = copy_name(target->name, lv->name); |
819 | abdb293f | Chrysostomos Nanakos | if (err) {
|
820 | abdb293f | Chrysostomos Nanakos | EPRINTF("copy target name failed: '%s'\n", lv->name);
|
821 | abdb293f | Chrysostomos Nanakos | return err;
|
822 | abdb293f | Chrysostomos Nanakos | } |
823 | abdb293f | Chrysostomos Nanakos | |
824 | abdb293f | Chrysostomos Nanakos | err = copy_name(target->device, lv->first_segment.device); |
825 | abdb293f | Chrysostomos Nanakos | if (err) {
|
826 | abdb293f | Chrysostomos Nanakos | EPRINTF("copy target device failed: '%s'\n",
|
827 | abdb293f | Chrysostomos Nanakos | lv->first_segment.device); |
828 | abdb293f | Chrysostomos Nanakos | return err;
|
829 | abdb293f | Chrysostomos Nanakos | } |
830 | abdb293f | Chrysostomos Nanakos | |
831 | abdb293f | Chrysostomos Nanakos | target->type = type; |
832 | abdb293f | Chrysostomos Nanakos | target->size = lv->size; |
833 | abdb293f | Chrysostomos Nanakos | target->start = lv->first_segment.pe_start; |
834 | abdb293f | Chrysostomos Nanakos | target->end = target->start + lv->first_segment.pe_size; |
835 | abdb293f | Chrysostomos Nanakos | |
836 | abdb293f | Chrysostomos Nanakos | return 0; |
837 | abdb293f | Chrysostomos Nanakos | } |
838 | abdb293f | Chrysostomos Nanakos | |
839 | abdb293f | Chrysostomos Nanakos | static int |
840 | abdb293f | Chrysostomos Nanakos | iterator_init(struct iterator *itr, int cnt, struct target *targets) |
841 | abdb293f | Chrysostomos Nanakos | { |
842 | abdb293f | Chrysostomos Nanakos | memset(itr, 0, sizeof(*itr)); |
843 | abdb293f | Chrysostomos Nanakos | |
844 | abdb293f | Chrysostomos Nanakos | itr->targets = malloc(sizeof(struct target) * cnt); |
845 | abdb293f | Chrysostomos Nanakos | if (!itr->targets)
|
846 | abdb293f | Chrysostomos Nanakos | return -ENOMEM;
|
847 | abdb293f | Chrysostomos Nanakos | |
848 | abdb293f | Chrysostomos Nanakos | memcpy(itr->targets, targets, sizeof(struct target) * cnt); |
849 | abdb293f | Chrysostomos Nanakos | |
850 | abdb293f | Chrysostomos Nanakos | itr->cur = 0;
|
851 | abdb293f | Chrysostomos Nanakos | itr->cur_size = cnt; |
852 | abdb293f | Chrysostomos Nanakos | itr->max_size = cnt; |
853 | abdb293f | Chrysostomos Nanakos | |
854 | abdb293f | Chrysostomos Nanakos | return 0; |
855 | abdb293f | Chrysostomos Nanakos | } |
856 | abdb293f | Chrysostomos Nanakos | |
857 | abdb293f | Chrysostomos Nanakos | static struct target * |
858 | abdb293f | Chrysostomos Nanakos | iterator_next(struct iterator *itr)
|
859 | abdb293f | Chrysostomos Nanakos | { |
860 | abdb293f | Chrysostomos Nanakos | if (itr->cur == itr->cur_size)
|
861 | abdb293f | Chrysostomos Nanakos | return NULL; |
862 | abdb293f | Chrysostomos Nanakos | |
863 | abdb293f | Chrysostomos Nanakos | return itr->targets + itr->cur++;
|
864 | abdb293f | Chrysostomos Nanakos | } |
865 | abdb293f | Chrysostomos Nanakos | |
866 | abdb293f | Chrysostomos Nanakos | static int |
867 | abdb293f | Chrysostomos Nanakos | iterator_add_file(struct iterator *itr,
|
868 | abdb293f | Chrysostomos Nanakos | struct target *target, const char *parent, uint8_t type) |
869 | abdb293f | Chrysostomos Nanakos | { |
870 | abdb293f | Chrysostomos Nanakos | int i;
|
871 | abdb293f | Chrysostomos Nanakos | struct target *t;
|
872 | abdb293f | Chrysostomos Nanakos | char *lname, *rname;
|
873 | abdb293f | Chrysostomos Nanakos | |
874 | abdb293f | Chrysostomos Nanakos | for (i = 0; i < itr->cur_size; i++) { |
875 | abdb293f | Chrysostomos Nanakos | t = itr->targets + i; |
876 | abdb293f | Chrysostomos Nanakos | lname = basename((char *)t->name);
|
877 | abdb293f | Chrysostomos Nanakos | rname = basename((char *)parent);
|
878 | abdb293f | Chrysostomos Nanakos | |
879 | abdb293f | Chrysostomos Nanakos | if (!strcmp(lname, rname))
|
880 | abdb293f | Chrysostomos Nanakos | return -EEXIST;
|
881 | abdb293f | Chrysostomos Nanakos | } |
882 | abdb293f | Chrysostomos Nanakos | |
883 | abdb293f | Chrysostomos Nanakos | return vhd_util_scan_init_file_target(target, parent, type);
|
884 | abdb293f | Chrysostomos Nanakos | } |
885 | abdb293f | Chrysostomos Nanakos | |
886 | abdb293f | Chrysostomos Nanakos | static int |
887 | abdb293f | Chrysostomos Nanakos | iterator_add_volume(struct iterator *itr,
|
888 | abdb293f | Chrysostomos Nanakos | struct target *target, const char *parent, uint8_t type) |
889 | abdb293f | Chrysostomos Nanakos | { |
890 | abdb293f | Chrysostomos Nanakos | int i, err;
|
891 | abdb293f | Chrysostomos Nanakos | struct lv *lv;
|
892 | abdb293f | Chrysostomos Nanakos | |
893 | abdb293f | Chrysostomos Nanakos | lv = NULL;
|
894 | abdb293f | Chrysostomos Nanakos | err = -ENOENT; |
895 | abdb293f | Chrysostomos Nanakos | |
896 | abdb293f | Chrysostomos Nanakos | for (i = 0; i < itr->cur_size; i++) |
897 | abdb293f | Chrysostomos Nanakos | if (!strcmp(parent, itr->targets[i].name))
|
898 | abdb293f | Chrysostomos Nanakos | return -EEXIST;
|
899 | abdb293f | Chrysostomos Nanakos | |
900 | abdb293f | Chrysostomos Nanakos | for (i = 0; i < vg.lv_cnt; i++) { |
901 | abdb293f | Chrysostomos Nanakos | err = fnmatch(parent, vg.lvs[i].name, FNM_PATHNAME); |
902 | abdb293f | Chrysostomos Nanakos | if (err != FNM_NOMATCH) {
|
903 | abdb293f | Chrysostomos Nanakos | lv = vg.lvs + i; |
904 | abdb293f | Chrysostomos Nanakos | break;
|
905 | abdb293f | Chrysostomos Nanakos | } |
906 | abdb293f | Chrysostomos Nanakos | } |
907 | abdb293f | Chrysostomos Nanakos | |
908 | abdb293f | Chrysostomos Nanakos | if (err && err != FNM_PATHNAME)
|
909 | abdb293f | Chrysostomos Nanakos | return err;
|
910 | abdb293f | Chrysostomos Nanakos | |
911 | abdb293f | Chrysostomos Nanakos | if (!lv)
|
912 | abdb293f | Chrysostomos Nanakos | return -ENOENT;
|
913 | abdb293f | Chrysostomos Nanakos | |
914 | abdb293f | Chrysostomos Nanakos | return vhd_util_scan_init_volume_target(target, lv, type);
|
915 | abdb293f | Chrysostomos Nanakos | } |
916 | abdb293f | Chrysostomos Nanakos | |
917 | abdb293f | Chrysostomos Nanakos | static int |
918 | abdb293f | Chrysostomos Nanakos | iterator_add(struct iterator *itr, const char *parent, uint8_t type) |
919 | abdb293f | Chrysostomos Nanakos | { |
920 | abdb293f | Chrysostomos Nanakos | int err;
|
921 | abdb293f | Chrysostomos Nanakos | struct target *target;
|
922 | abdb293f | Chrysostomos Nanakos | |
923 | abdb293f | Chrysostomos Nanakos | if (itr->cur_size == itr->max_size) {
|
924 | abdb293f | Chrysostomos Nanakos | struct target *new;
|
925 | abdb293f | Chrysostomos Nanakos | |
926 | abdb293f | Chrysostomos Nanakos | new = realloc(itr->targets, |
927 | abdb293f | Chrysostomos Nanakos | sizeof(struct target) * |
928 | abdb293f | Chrysostomos Nanakos | itr->max_size * 2);
|
929 | abdb293f | Chrysostomos Nanakos | if (!new)
|
930 | abdb293f | Chrysostomos Nanakos | return -ENOMEM;
|
931 | abdb293f | Chrysostomos Nanakos | |
932 | abdb293f | Chrysostomos Nanakos | itr->max_size *= 2;
|
933 | abdb293f | Chrysostomos Nanakos | itr->targets = new; |
934 | abdb293f | Chrysostomos Nanakos | } |
935 | abdb293f | Chrysostomos Nanakos | |
936 | abdb293f | Chrysostomos Nanakos | target = itr->targets + itr->cur_size; |
937 | abdb293f | Chrysostomos Nanakos | |
938 | abdb293f | Chrysostomos Nanakos | if (target_volume(type))
|
939 | abdb293f | Chrysostomos Nanakos | err = iterator_add_volume(itr, target, parent, type); |
940 | abdb293f | Chrysostomos Nanakos | else
|
941 | abdb293f | Chrysostomos Nanakos | err = iterator_add_file(itr, target, parent, type); |
942 | abdb293f | Chrysostomos Nanakos | |
943 | abdb293f | Chrysostomos Nanakos | if (err)
|
944 | abdb293f | Chrysostomos Nanakos | memset(target, 0, sizeof(*target)); |
945 | abdb293f | Chrysostomos Nanakos | else
|
946 | abdb293f | Chrysostomos Nanakos | itr->cur_size++; |
947 | abdb293f | Chrysostomos Nanakos | |
948 | abdb293f | Chrysostomos Nanakos | return (err == -EEXIST ? 0 : err); |
949 | abdb293f | Chrysostomos Nanakos | } |
950 | abdb293f | Chrysostomos Nanakos | |
951 | abdb293f | Chrysostomos Nanakos | static void |
952 | abdb293f | Chrysostomos Nanakos | iterator_free(struct iterator *itr)
|
953 | abdb293f | Chrysostomos Nanakos | { |
954 | abdb293f | Chrysostomos Nanakos | free(itr->targets); |
955 | abdb293f | Chrysostomos Nanakos | memset(itr, 0, sizeof(*itr)); |
956 | abdb293f | Chrysostomos Nanakos | } |
957 | abdb293f | Chrysostomos Nanakos | |
958 | abdb293f | Chrysostomos Nanakos | static void |
959 | abdb293f | Chrysostomos Nanakos | vhd_util_scan_add_parent(struct iterator *itr,
|
960 | abdb293f | Chrysostomos Nanakos | vhd_context_t *vhd, struct vhd_image *image)
|
961 | abdb293f | Chrysostomos Nanakos | { |
962 | abdb293f | Chrysostomos Nanakos | int err;
|
963 | abdb293f | Chrysostomos Nanakos | uint8_t type; |
964 | abdb293f | Chrysostomos Nanakos | |
965 | abdb293f | Chrysostomos Nanakos | if (vhd_parent_raw(vhd))
|
966 | abdb293f | Chrysostomos Nanakos | type = target_volume(image->target->type) ? |
967 | abdb293f | Chrysostomos Nanakos | VHD_TYPE_RAW_VOLUME : VHD_TYPE_RAW_FILE; |
968 | abdb293f | Chrysostomos Nanakos | else
|
969 | abdb293f | Chrysostomos Nanakos | type = target_volume(image->target->type) ? |
970 | abdb293f | Chrysostomos Nanakos | VHD_TYPE_VHD_VOLUME : VHD_TYPE_VHD_FILE; |
971 | abdb293f | Chrysostomos Nanakos | |
972 | abdb293f | Chrysostomos Nanakos | err = iterator_add(itr, image->parent, type); |
973 | abdb293f | Chrysostomos Nanakos | if (err)
|
974 | abdb293f | Chrysostomos Nanakos | vhd_util_scan_error(image->parent, err); |
975 | abdb293f | Chrysostomos Nanakos | } |
976 | abdb293f | Chrysostomos Nanakos | |
977 | abdb293f | Chrysostomos Nanakos | static int |
978 | abdb293f | Chrysostomos Nanakos | vhd_util_scan_targets(int cnt, struct target *targets) |
979 | abdb293f | Chrysostomos Nanakos | { |
980 | abdb293f | Chrysostomos Nanakos | int ret, err;
|
981 | abdb293f | Chrysostomos Nanakos | vhd_context_t vhd; |
982 | abdb293f | Chrysostomos Nanakos | struct iterator itr;
|
983 | abdb293f | Chrysostomos Nanakos | struct target *target;
|
984 | abdb293f | Chrysostomos Nanakos | struct vhd_image image;
|
985 | abdb293f | Chrysostomos Nanakos | |
986 | abdb293f | Chrysostomos Nanakos | ret = 0;
|
987 | abdb293f | Chrysostomos Nanakos | err = 0;
|
988 | abdb293f | Chrysostomos Nanakos | |
989 | abdb293f | Chrysostomos Nanakos | err = iterator_init(&itr, cnt, targets); |
990 | abdb293f | Chrysostomos Nanakos | if (err)
|
991 | abdb293f | Chrysostomos Nanakos | return err;
|
992 | abdb293f | Chrysostomos Nanakos | |
993 | abdb293f | Chrysostomos Nanakos | while ((target = iterator_next(&itr))) {
|
994 | abdb293f | Chrysostomos Nanakos | memset(&vhd, 0, sizeof(vhd)); |
995 | abdb293f | Chrysostomos Nanakos | memset(&image, 0, sizeof(image)); |
996 | abdb293f | Chrysostomos Nanakos | |
997 | abdb293f | Chrysostomos Nanakos | image.target = target; |
998 | abdb293f | Chrysostomos Nanakos | |
999 | abdb293f | Chrysostomos Nanakos | err = vhd_util_scan_open(&vhd, &image); |
1000 | abdb293f | Chrysostomos Nanakos | if (err) {
|
1001 | abdb293f | Chrysostomos Nanakos | ret = -EAGAIN; |
1002 | abdb293f | Chrysostomos Nanakos | goto end;
|
1003 | abdb293f | Chrysostomos Nanakos | } |
1004 | abdb293f | Chrysostomos Nanakos | |
1005 | abdb293f | Chrysostomos Nanakos | err = vhd_util_scan_get_size(&vhd, &image); |
1006 | abdb293f | Chrysostomos Nanakos | if (err) {
|
1007 | abdb293f | Chrysostomos Nanakos | ret = -EAGAIN; |
1008 | abdb293f | Chrysostomos Nanakos | image.message = "getting physical size";
|
1009 | abdb293f | Chrysostomos Nanakos | image.error = err; |
1010 | abdb293f | Chrysostomos Nanakos | goto end;
|
1011 | abdb293f | Chrysostomos Nanakos | } |
1012 | abdb293f | Chrysostomos Nanakos | |
1013 | abdb293f | Chrysostomos Nanakos | err = vhd_util_scan_get_hidden(&vhd, &image); |
1014 | abdb293f | Chrysostomos Nanakos | if (err) {
|
1015 | abdb293f | Chrysostomos Nanakos | ret = -EAGAIN; |
1016 | abdb293f | Chrysostomos Nanakos | image.message = "checking 'hidden' field";
|
1017 | abdb293f | Chrysostomos Nanakos | image.error = err; |
1018 | abdb293f | Chrysostomos Nanakos | goto end;
|
1019 | abdb293f | Chrysostomos Nanakos | } |
1020 | abdb293f | Chrysostomos Nanakos | |
1021 | abdb293f | Chrysostomos Nanakos | if (flags & VHD_SCAN_MARKERS) {
|
1022 | abdb293f | Chrysostomos Nanakos | err = vhd_util_scan_get_marker(&vhd, &image); |
1023 | abdb293f | Chrysostomos Nanakos | if (err) {
|
1024 | abdb293f | Chrysostomos Nanakos | ret = -EAGAIN; |
1025 | abdb293f | Chrysostomos Nanakos | image.message = "checking marker";
|
1026 | abdb293f | Chrysostomos Nanakos | image.error = err; |
1027 | abdb293f | Chrysostomos Nanakos | goto end;
|
1028 | abdb293f | Chrysostomos Nanakos | } |
1029 | abdb293f | Chrysostomos Nanakos | } |
1030 | abdb293f | Chrysostomos Nanakos | |
1031 | abdb293f | Chrysostomos Nanakos | if (vhd.footer.type == HD_TYPE_DIFF) {
|
1032 | abdb293f | Chrysostomos Nanakos | err = vhd_util_scan_get_parent(&vhd, &image); |
1033 | abdb293f | Chrysostomos Nanakos | if (err) {
|
1034 | abdb293f | Chrysostomos Nanakos | ret = -EAGAIN; |
1035 | abdb293f | Chrysostomos Nanakos | image.message = "getting parent";
|
1036 | abdb293f | Chrysostomos Nanakos | image.error = err; |
1037 | abdb293f | Chrysostomos Nanakos | goto end;
|
1038 | abdb293f | Chrysostomos Nanakos | } |
1039 | abdb293f | Chrysostomos Nanakos | } |
1040 | abdb293f | Chrysostomos Nanakos | |
1041 | abdb293f | Chrysostomos Nanakos | end:
|
1042 | abdb293f | Chrysostomos Nanakos | vhd_util_scan_print_image(&image); |
1043 | abdb293f | Chrysostomos Nanakos | |
1044 | abdb293f | Chrysostomos Nanakos | if (flags & VHD_SCAN_PARENTS && image.parent)
|
1045 | abdb293f | Chrysostomos Nanakos | vhd_util_scan_add_parent(&itr, &vhd, &image); |
1046 | abdb293f | Chrysostomos Nanakos | |
1047 | abdb293f | Chrysostomos Nanakos | if (vhd.file)
|
1048 | abdb293f | Chrysostomos Nanakos | vhd_close(&vhd); |
1049 | abdb293f | Chrysostomos Nanakos | if (image.name != target->name)
|
1050 | abdb293f | Chrysostomos Nanakos | free(image.name); |
1051 | abdb293f | Chrysostomos Nanakos | free(image.parent); |
1052 | abdb293f | Chrysostomos Nanakos | |
1053 | abdb293f | Chrysostomos Nanakos | if (err && !(flags & VHD_SCAN_NOFAIL))
|
1054 | abdb293f | Chrysostomos Nanakos | break;
|
1055 | abdb293f | Chrysostomos Nanakos | } |
1056 | abdb293f | Chrysostomos Nanakos | |
1057 | abdb293f | Chrysostomos Nanakos | iterator_free(&itr); |
1058 | abdb293f | Chrysostomos Nanakos | |
1059 | abdb293f | Chrysostomos Nanakos | if (flags & VHD_SCAN_NOFAIL)
|
1060 | abdb293f | Chrysostomos Nanakos | return ret;
|
1061 | abdb293f | Chrysostomos Nanakos | |
1062 | abdb293f | Chrysostomos Nanakos | return err;
|
1063 | abdb293f | Chrysostomos Nanakos | } |
1064 | abdb293f | Chrysostomos Nanakos | |
1065 | abdb293f | Chrysostomos Nanakos | static int |
1066 | abdb293f | Chrysostomos Nanakos | vhd_util_scan_targets_pretty(int cnt, struct target *targets) |
1067 | abdb293f | Chrysostomos Nanakos | { |
1068 | abdb293f | Chrysostomos Nanakos | int err;
|
1069 | abdb293f | Chrysostomos Nanakos | |
1070 | abdb293f | Chrysostomos Nanakos | err = vhd_util_scan_pretty_allocate_list(cnt); |
1071 | abdb293f | Chrysostomos Nanakos | if (err) {
|
1072 | abdb293f | Chrysostomos Nanakos | printf("scan failed: no memory\n");
|
1073 | abdb293f | Chrysostomos Nanakos | return -ENOMEM;
|
1074 | abdb293f | Chrysostomos Nanakos | } |
1075 | abdb293f | Chrysostomos Nanakos | |
1076 | abdb293f | Chrysostomos Nanakos | err = vhd_util_scan_targets(cnt, targets); |
1077 | abdb293f | Chrysostomos Nanakos | |
1078 | abdb293f | Chrysostomos Nanakos | vhd_util_scan_pretty_print_images(); |
1079 | abdb293f | Chrysostomos Nanakos | vhd_util_scan_pretty_free_list(); |
1080 | abdb293f | Chrysostomos Nanakos | |
1081 | abdb293f | Chrysostomos Nanakos | return ((flags & VHD_SCAN_NOFAIL) ? 0 : err); |
1082 | abdb293f | Chrysostomos Nanakos | } |
1083 | abdb293f | Chrysostomos Nanakos | |
1084 | abdb293f | Chrysostomos Nanakos | static int |
1085 | abdb293f | Chrysostomos Nanakos | vhd_util_scan_find_file_targets(int cnt, char **names, |
1086 | abdb293f | Chrysostomos Nanakos | const char *filter, |
1087 | abdb293f | Chrysostomos Nanakos | struct target **_targets, int *_total) |
1088 | abdb293f | Chrysostomos Nanakos | { |
1089 | abdb293f | Chrysostomos Nanakos | glob_t g; |
1090 | abdb293f | Chrysostomos Nanakos | struct target *targets;
|
1091 | abdb293f | Chrysostomos Nanakos | int i, globs, err, total;
|
1092 | abdb293f | Chrysostomos Nanakos | |
1093 | abdb293f | Chrysostomos Nanakos | total = cnt; |
1094 | abdb293f | Chrysostomos Nanakos | globs = 0;
|
1095 | abdb293f | Chrysostomos Nanakos | *_total = 0;
|
1096 | abdb293f | Chrysostomos Nanakos | *_targets = NULL;
|
1097 | abdb293f | Chrysostomos Nanakos | |
1098 | abdb293f | Chrysostomos Nanakos | memset(&g, 0, sizeof(g)); |
1099 | abdb293f | Chrysostomos Nanakos | |
1100 | abdb293f | Chrysostomos Nanakos | if (filter) {
|
1101 | abdb293f | Chrysostomos Nanakos | int gflags = ((flags & VHD_SCAN_FAST) ? GLOB_NOSORT : 0); |
1102 | abdb293f | Chrysostomos Nanakos | |
1103 | abdb293f | Chrysostomos Nanakos | errno = 0;
|
1104 | abdb293f | Chrysostomos Nanakos | err = glob(filter, gflags, vhd_util_scan_error, &g); |
1105 | abdb293f | Chrysostomos Nanakos | |
1106 | abdb293f | Chrysostomos Nanakos | switch (err) {
|
1107 | abdb293f | Chrysostomos Nanakos | case GLOB_NOSPACE:
|
1108 | abdb293f | Chrysostomos Nanakos | err = -ENOMEM; |
1109 | abdb293f | Chrysostomos Nanakos | break;
|
1110 | abdb293f | Chrysostomos Nanakos | case GLOB_ABORTED:
|
1111 | abdb293f | Chrysostomos Nanakos | err = -EIO; |
1112 | abdb293f | Chrysostomos Nanakos | break;
|
1113 | abdb293f | Chrysostomos Nanakos | case GLOB_NOMATCH:
|
1114 | abdb293f | Chrysostomos Nanakos | err = -errno; |
1115 | abdb293f | Chrysostomos Nanakos | break;
|
1116 | abdb293f | Chrysostomos Nanakos | } |
1117 | abdb293f | Chrysostomos Nanakos | |
1118 | abdb293f | Chrysostomos Nanakos | if (err) {
|
1119 | abdb293f | Chrysostomos Nanakos | vhd_util_scan_error(filter, err); |
1120 | abdb293f | Chrysostomos Nanakos | return err;
|
1121 | abdb293f | Chrysostomos Nanakos | } |
1122 | abdb293f | Chrysostomos Nanakos | |
1123 | abdb293f | Chrysostomos Nanakos | globs = g.gl_pathc; |
1124 | abdb293f | Chrysostomos Nanakos | total += globs; |
1125 | abdb293f | Chrysostomos Nanakos | } |
1126 | abdb293f | Chrysostomos Nanakos | |
1127 | abdb293f | Chrysostomos Nanakos | targets = calloc(total, sizeof(struct target)); |
1128 | abdb293f | Chrysostomos Nanakos | if (!targets) {
|
1129 | abdb293f | Chrysostomos Nanakos | err = -ENOMEM; |
1130 | abdb293f | Chrysostomos Nanakos | goto out;
|
1131 | abdb293f | Chrysostomos Nanakos | } |
1132 | abdb293f | Chrysostomos Nanakos | |
1133 | abdb293f | Chrysostomos Nanakos | for (i = 0; i < g.gl_pathc; i++) { |
1134 | abdb293f | Chrysostomos Nanakos | err = vhd_util_scan_init_file_target(targets + i, |
1135 | abdb293f | Chrysostomos Nanakos | g.gl_pathv[i], |
1136 | abdb293f | Chrysostomos Nanakos | VHD_TYPE_VHD_FILE); |
1137 | abdb293f | Chrysostomos Nanakos | if (err) {
|
1138 | abdb293f | Chrysostomos Nanakos | vhd_util_scan_error(g.gl_pathv[i], err); |
1139 | abdb293f | Chrysostomos Nanakos | if (!(flags & VHD_SCAN_NOFAIL))
|
1140 | abdb293f | Chrysostomos Nanakos | goto out;
|
1141 | abdb293f | Chrysostomos Nanakos | } |
1142 | abdb293f | Chrysostomos Nanakos | } |
1143 | abdb293f | Chrysostomos Nanakos | |
1144 | abdb293f | Chrysostomos Nanakos | for (i = 0; i + globs < total; i++) { |
1145 | abdb293f | Chrysostomos Nanakos | err = vhd_util_scan_init_file_target(targets + i + globs, |
1146 | abdb293f | Chrysostomos Nanakos | names[i], |
1147 | abdb293f | Chrysostomos Nanakos | VHD_TYPE_VHD_FILE); |
1148 | abdb293f | Chrysostomos Nanakos | if (err) {
|
1149 | abdb293f | Chrysostomos Nanakos | vhd_util_scan_error(names[i], err); |
1150 | abdb293f | Chrysostomos Nanakos | if (!(flags & VHD_SCAN_NOFAIL))
|
1151 | abdb293f | Chrysostomos Nanakos | goto out;
|
1152 | abdb293f | Chrysostomos Nanakos | } |
1153 | abdb293f | Chrysostomos Nanakos | } |
1154 | abdb293f | Chrysostomos Nanakos | |
1155 | abdb293f | Chrysostomos Nanakos | err = 0;
|
1156 | abdb293f | Chrysostomos Nanakos | *_total = total; |
1157 | abdb293f | Chrysostomos Nanakos | *_targets = targets; |
1158 | abdb293f | Chrysostomos Nanakos | |
1159 | abdb293f | Chrysostomos Nanakos | out:
|
1160 | abdb293f | Chrysostomos Nanakos | if (err)
|
1161 | abdb293f | Chrysostomos Nanakos | free(targets); |
1162 | abdb293f | Chrysostomos Nanakos | if (filter)
|
1163 | abdb293f | Chrysostomos Nanakos | globfree(&g); |
1164 | abdb293f | Chrysostomos Nanakos | |
1165 | abdb293f | Chrysostomos Nanakos | return err;
|
1166 | abdb293f | Chrysostomos Nanakos | } |
1167 | abdb293f | Chrysostomos Nanakos | |
1168 | abdb293f | Chrysostomos Nanakos | static inline void |
1169 | abdb293f | Chrysostomos Nanakos | swap_volume(struct lv *lvs, int dst, int src) |
1170 | abdb293f | Chrysostomos Nanakos | { |
1171 | abdb293f | Chrysostomos Nanakos | struct lv copy, *ldst, *lsrc;
|
1172 | abdb293f | Chrysostomos Nanakos | |
1173 | abdb293f | Chrysostomos Nanakos | if (dst == src)
|
1174 | abdb293f | Chrysostomos Nanakos | return;
|
1175 | abdb293f | Chrysostomos Nanakos | |
1176 | abdb293f | Chrysostomos Nanakos | lsrc = lvs + src; |
1177 | abdb293f | Chrysostomos Nanakos | ldst = lvs + dst; |
1178 | abdb293f | Chrysostomos Nanakos | |
1179 | abdb293f | Chrysostomos Nanakos | memcpy(©, ldst, sizeof(copy));
|
1180 | abdb293f | Chrysostomos Nanakos | memcpy(ldst, lsrc, sizeof(*ldst));
|
1181 | abdb293f | Chrysostomos Nanakos | memcpy(lsrc, ©, sizeof(copy));
|
1182 | abdb293f | Chrysostomos Nanakos | } |
1183 | abdb293f | Chrysostomos Nanakos | |
1184 | abdb293f | Chrysostomos Nanakos | static int |
1185 | abdb293f | Chrysostomos Nanakos | vhd_util_scan_sort_volumes(struct lv *lvs, int cnt, |
1186 | abdb293f | Chrysostomos Nanakos | const char *filter, int *_matches) |
1187 | abdb293f | Chrysostomos Nanakos | { |
1188 | abdb293f | Chrysostomos Nanakos | struct lv *lv;
|
1189 | abdb293f | Chrysostomos Nanakos | int i, err, matches;
|
1190 | abdb293f | Chrysostomos Nanakos | |
1191 | abdb293f | Chrysostomos Nanakos | matches = 0;
|
1192 | abdb293f | Chrysostomos Nanakos | *_matches = 0;
|
1193 | abdb293f | Chrysostomos Nanakos | |
1194 | abdb293f | Chrysostomos Nanakos | if (!filter)
|
1195 | abdb293f | Chrysostomos Nanakos | return 0; |
1196 | abdb293f | Chrysostomos Nanakos | |
1197 | abdb293f | Chrysostomos Nanakos | for (i = 0; i < cnt; i++) { |
1198 | abdb293f | Chrysostomos Nanakos | lv = lvs + i; |
1199 | abdb293f | Chrysostomos Nanakos | |
1200 | abdb293f | Chrysostomos Nanakos | err = fnmatch(filter, lv->name, FNM_PATHNAME); |
1201 | abdb293f | Chrysostomos Nanakos | if (err) {
|
1202 | abdb293f | Chrysostomos Nanakos | if (err != FNM_NOMATCH) {
|
1203 | abdb293f | Chrysostomos Nanakos | EPRINTF("fnmatch failed: '%s', '%s'\n",
|
1204 | abdb293f | Chrysostomos Nanakos | filter, lv->name); |
1205 | abdb293f | Chrysostomos Nanakos | vhd_util_scan_error(lv->name, err); |
1206 | abdb293f | Chrysostomos Nanakos | if (!(flags & VHD_SCAN_NOFAIL))
|
1207 | abdb293f | Chrysostomos Nanakos | return err;
|
1208 | abdb293f | Chrysostomos Nanakos | } |
1209 | abdb293f | Chrysostomos Nanakos | |
1210 | abdb293f | Chrysostomos Nanakos | continue;
|
1211 | abdb293f | Chrysostomos Nanakos | } |
1212 | abdb293f | Chrysostomos Nanakos | |
1213 | abdb293f | Chrysostomos Nanakos | swap_volume(lvs, matches++, i); |
1214 | abdb293f | Chrysostomos Nanakos | } |
1215 | abdb293f | Chrysostomos Nanakos | |
1216 | abdb293f | Chrysostomos Nanakos | *_matches = matches; |
1217 | abdb293f | Chrysostomos Nanakos | return 0; |
1218 | abdb293f | Chrysostomos Nanakos | } |
1219 | abdb293f | Chrysostomos Nanakos | |
1220 | abdb293f | Chrysostomos Nanakos | static int |
1221 | abdb293f | Chrysostomos Nanakos | vhd_util_scan_find_volume_targets(int cnt, char **names, |
1222 | abdb293f | Chrysostomos Nanakos | const char *volume, const char *filter, |
1223 | abdb293f | Chrysostomos Nanakos | struct target **_targets, int *_total) |
1224 | abdb293f | Chrysostomos Nanakos | { |
1225 | abdb293f | Chrysostomos Nanakos | struct target *targets;
|
1226 | abdb293f | Chrysostomos Nanakos | int i, err, total, matches;
|
1227 | abdb293f | Chrysostomos Nanakos | |
1228 | abdb293f | Chrysostomos Nanakos | *_total = 0;
|
1229 | abdb293f | Chrysostomos Nanakos | *_targets = NULL;
|
1230 | abdb293f | Chrysostomos Nanakos | targets = NULL;
|
1231 | abdb293f | Chrysostomos Nanakos | |
1232 | abdb293f | Chrysostomos Nanakos | err = lvm_scan_vg(volume, &vg); |
1233 | abdb293f | Chrysostomos Nanakos | if (err)
|
1234 | abdb293f | Chrysostomos Nanakos | return err;
|
1235 | abdb293f | Chrysostomos Nanakos | |
1236 | abdb293f | Chrysostomos Nanakos | err = vhd_util_scan_sort_volumes(vg.lvs, vg.lv_cnt, |
1237 | abdb293f | Chrysostomos Nanakos | filter, &matches); |
1238 | abdb293f | Chrysostomos Nanakos | if (err)
|
1239 | abdb293f | Chrysostomos Nanakos | goto out;
|
1240 | abdb293f | Chrysostomos Nanakos | |
1241 | abdb293f | Chrysostomos Nanakos | total = matches; |
1242 | abdb293f | Chrysostomos Nanakos | for (i = 0; i < cnt; i++) { |
1243 | abdb293f | Chrysostomos Nanakos | err = vhd_util_scan_sort_volumes(vg.lvs + total, |
1244 | abdb293f | Chrysostomos Nanakos | vg.lv_cnt - total, |
1245 | abdb293f | Chrysostomos Nanakos | names[i], &matches); |
1246 | abdb293f | Chrysostomos Nanakos | if (err)
|
1247 | abdb293f | Chrysostomos Nanakos | goto out;
|
1248 | abdb293f | Chrysostomos Nanakos | |
1249 | abdb293f | Chrysostomos Nanakos | total += matches; |
1250 | abdb293f | Chrysostomos Nanakos | } |
1251 | abdb293f | Chrysostomos Nanakos | |
1252 | abdb293f | Chrysostomos Nanakos | targets = calloc(total, sizeof(struct target)); |
1253 | abdb293f | Chrysostomos Nanakos | if (!targets) {
|
1254 | abdb293f | Chrysostomos Nanakos | err = -ENOMEM; |
1255 | abdb293f | Chrysostomos Nanakos | goto out;
|
1256 | abdb293f | Chrysostomos Nanakos | } |
1257 | abdb293f | Chrysostomos Nanakos | |
1258 | abdb293f | Chrysostomos Nanakos | for (i = 0; i < total; i++) { |
1259 | abdb293f | Chrysostomos Nanakos | err = vhd_util_scan_init_volume_target(targets + i, |
1260 | abdb293f | Chrysostomos Nanakos | vg.lvs + i, |
1261 | abdb293f | Chrysostomos Nanakos | VHD_TYPE_VHD_VOLUME); |
1262 | abdb293f | Chrysostomos Nanakos | if (err) {
|
1263 | abdb293f | Chrysostomos Nanakos | vhd_util_scan_error(vg.lvs[i].name, err); |
1264 | abdb293f | Chrysostomos Nanakos | if (!(flags & VHD_SCAN_NOFAIL))
|
1265 | abdb293f | Chrysostomos Nanakos | goto out;
|
1266 | abdb293f | Chrysostomos Nanakos | } |
1267 | abdb293f | Chrysostomos Nanakos | } |
1268 | abdb293f | Chrysostomos Nanakos | |
1269 | abdb293f | Chrysostomos Nanakos | err = 0;
|
1270 | abdb293f | Chrysostomos Nanakos | *_total = total; |
1271 | abdb293f | Chrysostomos Nanakos | *_targets = targets; |
1272 | abdb293f | Chrysostomos Nanakos | |
1273 | abdb293f | Chrysostomos Nanakos | out:
|
1274 | abdb293f | Chrysostomos Nanakos | if (err)
|
1275 | abdb293f | Chrysostomos Nanakos | free(targets); |
1276 | abdb293f | Chrysostomos Nanakos | return err;
|
1277 | abdb293f | Chrysostomos Nanakos | } |
1278 | abdb293f | Chrysostomos Nanakos | |
1279 | abdb293f | Chrysostomos Nanakos | static int |
1280 | abdb293f | Chrysostomos Nanakos | vhd_util_scan_find_targets(int cnt, char **names, |
1281 | abdb293f | Chrysostomos Nanakos | const char *volume, const char *filter, |
1282 | abdb293f | Chrysostomos Nanakos | struct target **targets, int *total) |
1283 | abdb293f | Chrysostomos Nanakos | { |
1284 | abdb293f | Chrysostomos Nanakos | if (flags & VHD_SCAN_VOLUME)
|
1285 | abdb293f | Chrysostomos Nanakos | return vhd_util_scan_find_volume_targets(cnt, names,
|
1286 | abdb293f | Chrysostomos Nanakos | volume, filter, |
1287 | abdb293f | Chrysostomos Nanakos | targets, total); |
1288 | abdb293f | Chrysostomos Nanakos | return vhd_util_scan_find_file_targets(cnt, names,
|
1289 | abdb293f | Chrysostomos Nanakos | filter, targets, total); |
1290 | abdb293f | Chrysostomos Nanakos | } |
1291 | abdb293f | Chrysostomos Nanakos | |
1292 | abdb293f | Chrysostomos Nanakos | int
|
1293 | abdb293f | Chrysostomos Nanakos | vhd_util_scan(int argc, char **argv) |
1294 | abdb293f | Chrysostomos Nanakos | { |
1295 | abdb293f | Chrysostomos Nanakos | int c, err, cnt;
|
1296 | abdb293f | Chrysostomos Nanakos | char *filter, *volume;
|
1297 | abdb293f | Chrysostomos Nanakos | struct target *targets;
|
1298 | abdb293f | Chrysostomos Nanakos | |
1299 | abdb293f | Chrysostomos Nanakos | cnt = 0;
|
1300 | abdb293f | Chrysostomos Nanakos | err = 0;
|
1301 | abdb293f | Chrysostomos Nanakos | flags = 0;
|
1302 | abdb293f | Chrysostomos Nanakos | filter = NULL;
|
1303 | abdb293f | Chrysostomos Nanakos | volume = NULL;
|
1304 | abdb293f | Chrysostomos Nanakos | targets = NULL;
|
1305 | abdb293f | Chrysostomos Nanakos | |
1306 | abdb293f | Chrysostomos Nanakos | optind = 0;
|
1307 | abdb293f | Chrysostomos Nanakos | while ((c = getopt(argc, argv, "m:fcl:pavMh")) != -1) { |
1308 | abdb293f | Chrysostomos Nanakos | switch (c) {
|
1309 | abdb293f | Chrysostomos Nanakos | case 'm': |
1310 | abdb293f | Chrysostomos Nanakos | filter = optarg; |
1311 | abdb293f | Chrysostomos Nanakos | break;
|
1312 | abdb293f | Chrysostomos Nanakos | case 'f': |
1313 | abdb293f | Chrysostomos Nanakos | flags |= VHD_SCAN_FAST; |
1314 | abdb293f | Chrysostomos Nanakos | break;
|
1315 | abdb293f | Chrysostomos Nanakos | case 'c': |
1316 | abdb293f | Chrysostomos Nanakos | flags |= VHD_SCAN_NOFAIL; |
1317 | abdb293f | Chrysostomos Nanakos | break;
|
1318 | abdb293f | Chrysostomos Nanakos | case 'l': |
1319 | abdb293f | Chrysostomos Nanakos | volume = optarg; |
1320 | abdb293f | Chrysostomos Nanakos | flags |= VHD_SCAN_VOLUME; |
1321 | abdb293f | Chrysostomos Nanakos | break;
|
1322 | abdb293f | Chrysostomos Nanakos | case 'p': |
1323 | abdb293f | Chrysostomos Nanakos | flags |= VHD_SCAN_PRETTY; |
1324 | abdb293f | Chrysostomos Nanakos | break;
|
1325 | abdb293f | Chrysostomos Nanakos | case 'a': |
1326 | abdb293f | Chrysostomos Nanakos | flags |= VHD_SCAN_PARENTS; |
1327 | abdb293f | Chrysostomos Nanakos | break;
|
1328 | abdb293f | Chrysostomos Nanakos | case 'v': |
1329 | abdb293f | Chrysostomos Nanakos | flags |= VHD_SCAN_VERBOSE; |
1330 | abdb293f | Chrysostomos Nanakos | break;
|
1331 | abdb293f | Chrysostomos Nanakos | case 'M': |
1332 | abdb293f | Chrysostomos Nanakos | flags |= VHD_SCAN_MARKERS; |
1333 | abdb293f | Chrysostomos Nanakos | break;
|
1334 | abdb293f | Chrysostomos Nanakos | case 'h': |
1335 | abdb293f | Chrysostomos Nanakos | goto usage;
|
1336 | abdb293f | Chrysostomos Nanakos | default:
|
1337 | abdb293f | Chrysostomos Nanakos | err = -EINVAL; |
1338 | abdb293f | Chrysostomos Nanakos | goto usage;
|
1339 | abdb293f | Chrysostomos Nanakos | } |
1340 | abdb293f | Chrysostomos Nanakos | } |
1341 | abdb293f | Chrysostomos Nanakos | |
1342 | abdb293f | Chrysostomos Nanakos | if (!filter && argc - optind == 0) { |
1343 | abdb293f | Chrysostomos Nanakos | err = -EINVAL; |
1344 | abdb293f | Chrysostomos Nanakos | goto usage;
|
1345 | abdb293f | Chrysostomos Nanakos | } |
1346 | abdb293f | Chrysostomos Nanakos | |
1347 | abdb293f | Chrysostomos Nanakos | if (flags & VHD_SCAN_PRETTY)
|
1348 | abdb293f | Chrysostomos Nanakos | flags &= ~VHD_SCAN_FAST; |
1349 | abdb293f | Chrysostomos Nanakos | |
1350 | abdb293f | Chrysostomos Nanakos | err = vhd_util_scan_find_targets(argc - optind, argv + optind, |
1351 | abdb293f | Chrysostomos Nanakos | volume, filter, &targets, &cnt); |
1352 | abdb293f | Chrysostomos Nanakos | if (err) {
|
1353 | abdb293f | Chrysostomos Nanakos | printf("scan failed: %d\n", err);
|
1354 | abdb293f | Chrysostomos Nanakos | return err;
|
1355 | abdb293f | Chrysostomos Nanakos | } |
1356 | abdb293f | Chrysostomos Nanakos | |
1357 | abdb293f | Chrysostomos Nanakos | if (!cnt)
|
1358 | abdb293f | Chrysostomos Nanakos | return 0; |
1359 | abdb293f | Chrysostomos Nanakos | |
1360 | abdb293f | Chrysostomos Nanakos | if (flags & VHD_SCAN_PRETTY)
|
1361 | abdb293f | Chrysostomos Nanakos | err = vhd_util_scan_targets_pretty(cnt, targets); |
1362 | abdb293f | Chrysostomos Nanakos | else
|
1363 | abdb293f | Chrysostomos Nanakos | err = vhd_util_scan_targets(cnt, targets); |
1364 | abdb293f | Chrysostomos Nanakos | |
1365 | abdb293f | Chrysostomos Nanakos | free(targets); |
1366 | abdb293f | Chrysostomos Nanakos | lvm_free_vg(&vg); |
1367 | abdb293f | Chrysostomos Nanakos | |
1368 | abdb293f | Chrysostomos Nanakos | return ((flags & VHD_SCAN_NOFAIL) ? 0 : err); |
1369 | abdb293f | Chrysostomos Nanakos | |
1370 | abdb293f | Chrysostomos Nanakos | usage:
|
1371 | abdb293f | Chrysostomos Nanakos | printf("usage: [OPTIONS] FILES\n"
|
1372 | abdb293f | Chrysostomos Nanakos | "options: [-m match filter] [-f fast] [-c continue on failure] "
|
1373 | abdb293f | Chrysostomos Nanakos | "[-l LVM volume] [-p pretty print] [-a scan parents] "
|
1374 | abdb293f | Chrysostomos Nanakos | "[-v verbose] [-h help] [-M show markers]\n");
|
1375 | abdb293f | Chrysostomos Nanakos | return err;
|
1376 | abdb293f | Chrysostomos Nanakos | } |