Statistics
| Branch: | Revision:

root / vhd / lib / vhd-util-modify.c @ abdb293f

History | View | Annotate | Download (4.2 kB)

1
/*
2
 * Copyright (c) 2008, XenSource Inc.
3
 * Copyright (c) 2010, Citrix Systems, Inc.
4
 *
5
 * All rights reserved.
6
 *
7
 * Redistribution and use in source and binary forms, with or without
8
 * modification, are permitted provided that the following conditions are met:
9
 *     * Redistributions of source code must retain the above copyright
10
 *       notice, this list of conditions and the following disclaimer.
11
 *     * 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
 *     * Neither the name of XenSource Inc. nor the names of its contributors
15
 *       may be used to endorse or promote products derived from this software
16
 *       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

    
41
#include "libvhd.h"
42

    
43
TEST_FAIL_EXTERN_VARS;
44

    
45
static int
46
vhd_util_zero_bat(vhd_context_t *vhd)
47
{
48
        int err, map_bytes;
49
        uint64_t i;
50

    
51
        err = vhd_get_bat(vhd);
52
        if (err)
53
                return err;
54

    
55
        if (vhd_has_batmap(vhd)) {
56
                err = vhd_get_batmap(vhd);
57
                if (err)
58
                        return err;
59
        }
60

    
61
        for (i = 0; i < vhd->bat.entries; i++)
62
                vhd->bat.bat[i] = DD_BLK_UNUSED;
63
        err = vhd_write_bat(vhd, &vhd->bat);
64
        if (err)
65
                return err;
66

    
67
        map_bytes = ((vhd->footer.curr_size >> VHD_SECTOR_SHIFT) /
68
                        vhd->spb) >> 3;
69
        map_bytes = vhd_sectors_to_bytes(secs_round_up_no_zero(map_bytes));
70
        memset(vhd->batmap.map, 0, map_bytes);
71
        return vhd_write_batmap(vhd, &vhd->batmap);
72
}
73

    
74
int
75
vhd_util_modify(int argc, char **argv)
76
{
77
        char *name;
78
        vhd_context_t vhd;
79
        int err, c, size, parent, parent_raw, kill_data;
80
        off64_t newsize = 0;
81
        char *newparent = NULL;
82

    
83
        name       = NULL;
84
        size       = 0;
85
        parent     = 0;
86
        parent_raw = 0;
87
        kill_data  = 0;
88

    
89
        optind = 0;
90
        while ((c = getopt(argc, argv, "n:s:p:mzh")) != -1) {
91
                switch (c) {
92
                case 'n':
93
                        name = optarg;
94
                        break;
95
                case 's':
96
                        size = 1;
97
                        errno = 0;
98
                        newsize = strtoll(optarg, NULL, 10);
99
                        if (errno) {
100
                                fprintf(stderr, "Invalid size '%s'\n", optarg);
101
                                goto usage;
102
                        }
103
                        break;
104
                case 'p':
105
                        parent = 1;
106
                        newparent = optarg;
107
                        break;
108
                case 'm':
109
                        parent_raw = 1;
110
                        break;
111
                case 'z':
112
                        kill_data = 1;
113
                        break;
114
                case 'h':
115
                default:
116
                        goto usage;
117
                }
118
        }
119

    
120
        if (!name || optind != argc)
121
                goto usage;
122

    
123
        err = vhd_open(&vhd, name, VHD_OPEN_RDWR);
124
        if (err) {
125
                printf("error opening %s: %d\n", name, err);
126
                return err;
127
        }
128

    
129
        if (kill_data) {
130
                if (vhd_type_dynamic(&vhd))
131
                        err = vhd_util_zero_bat(&vhd);
132
                else
133
                        err = -ENOSYS;
134

    
135
                if (!err && !vhd.is_block) // truncate file-based VHDs
136
                        err = vhd_write_footer(&vhd, &vhd.footer);
137

    
138
                if (err)
139
                        printf("failed to zero VHD: %d\n", err);
140
        }
141

    
142
        if (size) {
143
                err = vhd_set_phys_size(&vhd, newsize);
144
                if (err)
145
                        printf("failed to set physical size to %"PRIu64":"
146
                               " %d\n", newsize, err);
147
        }
148

    
149
        if (parent) {
150
                TEST_FAIL_AT(FAIL_REPARENT_BEGIN);
151
                err = vhd_change_parent(&vhd, newparent, parent_raw);
152
                if (err) {
153
                        printf("failed to set parent to '%s': %d\n",
154
                                        newparent, err);
155
                        goto done;
156
                }
157
                TEST_FAIL_AT(FAIL_REPARENT_END);
158
        }
159

    
160
done:
161
        vhd_close(&vhd);
162
        return err;
163

    
164
usage:
165
        printf("*** Dangerous operations, use with care ***\n");
166
        printf("options: <-n name> [-p NEW_PARENT set parent [-m raw]] "
167
                        "[-s NEW_SIZE set size] [-z zero (kill data)] "
168
                        "[-h help]\n");
169
        return -EINVAL;
170
}