Branch data Line data Source code
1 : : /*
2 : : * Copyright (c) 2016, Citrix Systems, Inc.
3 : : *
4 : : * All rights reserved.
5 : : *
6 : : * Redistribution and use in source and binary forms, with or without
7 : : * modification, are permitted provided that the following conditions are met:
8 : : *
9 : : * 1. Redistributions of source code must retain the above copyright
10 : : * notice, this list of conditions and the following disclaimer.
11 : : * 2. Redistributions in binary form must reproduce the above copyright
12 : : * notice, this list of conditions and the following disclaimer in the
13 : : * documentation and/or other materials provided with the distribution.
14 : : * 3. Neither the name of the copyright holder nor the names of its
15 : : * contributors may be used to endorse or promote products derived from
16 : : * this software without specific prior written permission.
17 : : *
18 : : * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 : : * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 : : * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 : : * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
22 : : * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 : : * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 : : * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
25 : : * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
26 : : * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
27 : : * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
28 : : * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 : : */
30 : :
31 : : #ifdef HAVE_CONFIG_H
32 : : #include "config.h"
33 : : #endif
34 : :
35 : : #include <errno.h>
36 : : #include <fcntl.h>
37 : : #include <stdio.h>
38 : : #include <stdlib.h>
39 : : #include <unistd.h>
40 : : #include <limits.h>
41 : :
42 : : #include "libvhd.h"
43 : : #include "canonpath.h"
44 : :
45 : : TEST_FAIL_EXTERN_VARS;
46 : :
47 : : static int
48 : 0 : vhd_util_zero_bat(vhd_context_t *vhd)
49 : : {
50 : : int err, map_bytes;
51 : : uint64_t i;
52 : :
53 : 0 : err = vhd_get_bat(vhd);
54 [ # # ]: 0 : if (err)
55 : : return err;
56 : :
57 [ # # ]: 0 : if (vhd_has_batmap(vhd)) {
58 : 0 : err = vhd_get_batmap(vhd);
59 [ # # ]: 0 : if (err)
60 : : return err;
61 : : }
62 : :
63 [ # # ]: 0 : for (i = 0; i < vhd->bat.entries; i++)
64 : 0 : vhd->bat.bat[i] = DD_BLK_UNUSED;
65 : 0 : err = vhd_write_bat(vhd, &vhd->bat);
66 [ # # ]: 0 : if (err)
67 : : return err;
68 : :
69 : 0 : map_bytes = ((vhd->footer.curr_size >> VHD_SECTOR_SHIFT) /
70 : 0 : vhd->spb) >> 3;
71 : 0 : map_bytes = vhd_sectors_to_bytes(secs_round_up_no_zero(map_bytes));
72 : 0 : memset(vhd->batmap.map, 0, map_bytes);
73 : 0 : return vhd_write_batmap(vhd, &vhd->batmap);
74 : : }
75 : :
76 : : int
77 : 0 : vhd_util_modify(int argc, char **argv)
78 : : {
79 : : char *name;
80 : : vhd_context_t vhd;
81 : : int err, c, size, parent, parent_raw, kill_data;
82 : 0 : off64_t newsize = 0;
83 : 0 : char *newparent = NULL;
84 : :
85 : 0 : name = NULL;
86 : 0 : size = 0;
87 : 0 : parent = 0;
88 : 0 : parent_raw = 0;
89 : 0 : kill_data = 0;
90 : :
91 : 0 : optind = 0;
92 [ # # ]: 0 : while ((c = getopt(argc, argv, "n:s:p:mzh")) != -1) {
93 [ # # # # : 0 : switch (c) {
# # ]
94 : : case 'n':
95 : 0 : name = optarg;
96 : 0 : break;
97 : : case 's':
98 : 0 : size = 1;
99 : 0 : errno = 0;
100 : 0 : newsize = strtoll(optarg, NULL, 10);
101 [ # # ]: 0 : if (errno) {
102 : 0 : fprintf(stderr, "Invalid size '%s'\n", optarg);
103 : : goto usage;
104 : : }
105 : : break;
106 : : case 'p':
107 : 0 : parent = 1;
108 : 0 : newparent = optarg;
109 : 0 : break;
110 : : case 'm':
111 : : parent_raw = 1;
112 : : break;
113 : : case 'z':
114 : 0 : kill_data = 1;
115 : 0 : break;
116 : : case 'h':
117 : : default:
118 : : goto usage;
119 : : }
120 : : }
121 : :
122 [ # # ][ # # ]: 0 : if (!name || optind != argc)
123 : : goto usage;
124 : :
125 : 0 : err = vhd_open(&vhd, name, VHD_OPEN_RDWR);
126 [ # # ]: 0 : if (err) {
127 : : printf("error opening %s: %d\n", name, err);
128 : 0 : return err;
129 : : }
130 : :
131 [ # # ]: 0 : if (kill_data) {
132 [ # # ]: 0 : if (vhd_type_dynamic(&vhd))
133 : 0 : err = vhd_util_zero_bat(&vhd);
134 : : else
135 : : err = -ENOSYS;
136 : :
137 [ # # ][ # # ]: 0 : if (!err && !vhd.is_block) // truncate file-based VHDs
138 : 0 : err = vhd_write_footer(&vhd, &vhd.footer);
139 : :
140 [ # # ]: 0 : if (err)
141 : : printf("failed to zero VHD: %d\n", err);
142 : : }
143 : :
144 [ # # ]: 0 : if (size) {
145 : 0 : err = vhd_set_phys_size(&vhd, newsize);
146 [ # # ]: 0 : if (err)
147 : : printf("failed to set physical size to %"PRIu64":"
148 : : " %d\n", newsize, err);
149 : : }
150 : :
151 [ # # ]: 0 : if (parent) {
152 [ # # ]: 0 : TEST_FAIL_AT(FAIL_REPARENT_BEGIN);
153 : 0 : err = vhd_change_parent(&vhd, newparent, parent_raw);
154 [ # # ]: 0 : if (err) {
155 : : printf("failed to set parent to '%s': %d\n",
156 : : newparent, err);
157 : : goto done;
158 : : }
159 [ # # ]: 0 : TEST_FAIL_AT(FAIL_REPARENT_END);
160 : : }
161 : :
162 : : done:
163 : 0 : vhd_close(&vhd);
164 : : return err;
165 : :
166 : : usage:
167 : : printf("*** Dangerous operations, use with care ***\n");
168 : : printf("options: <-n name> [-p NEW_PARENT set parent [-m raw]] "
169 : : "[-s NEW_SIZE set size] [-z zero (kill data)] "
170 : : "[-h help]\n");
171 : : return -EINVAL;
172 : : }
|