root / qemu-mkcow.c @ fcc941fe
History | View | Annotate | Download (4.4 kB)
1 |
/*
|
---|---|
2 |
* create a COW disk image
|
3 |
*
|
4 |
* Copyright (c) 2003 Fabrice Bellard
|
5 |
*
|
6 |
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
7 |
* of this software and associated documentation files (the "Software"), to deal
|
8 |
* in the Software without restriction, including without limitation the rights
|
9 |
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
10 |
* copies of the Software, and to permit persons to whom the Software is
|
11 |
* furnished to do so, subject to the following conditions:
|
12 |
*
|
13 |
* The above copyright notice and this permission notice shall be included in
|
14 |
* all copies or substantial portions of the Software.
|
15 |
*
|
16 |
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
17 |
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
18 |
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
19 |
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
20 |
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
21 |
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
22 |
* THE SOFTWARE.
|
23 |
*/
|
24 |
#include <stdlib.h> |
25 |
#include <stdio.h> |
26 |
#include <stdarg.h> |
27 |
#include <string.h> |
28 |
#include <getopt.h> |
29 |
#include <inttypes.h> |
30 |
#include <unistd.h> |
31 |
#include <fcntl.h> |
32 |
#include <signal.h> |
33 |
#include <time.h> |
34 |
#include <sys/time.h> |
35 |
#include <errno.h> |
36 |
#include <sys/stat.h> |
37 |
#include <netinet/in.h> |
38 |
|
39 |
#include "cow.h" |
40 |
|
41 |
#include "bswap.h" |
42 |
|
43 |
int cow_create(int cow_fd, const char *image_filename, |
44 |
int64_t image_sectors) |
45 |
{ |
46 |
struct cow_header_v2 cow_header;
|
47 |
int fd;
|
48 |
struct stat st;
|
49 |
|
50 |
memset(&cow_header, 0, sizeof(cow_header)); |
51 |
cow_header.magic = htonl(COW_MAGIC); |
52 |
cow_header.version = htonl(COW_VERSION); |
53 |
if (image_filename) {
|
54 |
fd = open(image_filename, O_RDONLY); |
55 |
if (fd < 0) { |
56 |
perror(image_filename); |
57 |
exit(1);
|
58 |
} |
59 |
image_sectors = lseek64(fd, 0, SEEK_END);
|
60 |
if (fstat(fd, &st) != 0) { |
61 |
close(fd); |
62 |
return -1; |
63 |
} |
64 |
close(fd); |
65 |
image_sectors /= 512;
|
66 |
cow_header.mtime = htonl(st.st_mtime); |
67 |
realpath(image_filename, cow_header.backing_file); |
68 |
} |
69 |
cow_header.sectorsize = htonl(512);
|
70 |
cow_header.size = image_sectors * 512;
|
71 |
#ifndef WORDS_BIGENDIAN
|
72 |
cow_header.size = bswap64(cow_header.size); |
73 |
#endif
|
74 |
write(cow_fd, &cow_header, sizeof(cow_header));
|
75 |
/* resize to include at least all the bitmap */
|
76 |
ftruncate(cow_fd, sizeof(cow_header) + ((image_sectors + 7) >> 3)); |
77 |
lseek(cow_fd, 0, SEEK_SET);
|
78 |
return 0; |
79 |
} |
80 |
|
81 |
void help(void) |
82 |
{ |
83 |
printf("qemu-mkcow version " QEMU_VERSION ", Copyright (c) 2003 Fabrice Bellard\n" |
84 |
"usage: qemu-mkcow [-h] [-f disk_image] cow_image [cow_size]\n"
|
85 |
"Create a Copy On Write disk image from an optional raw disk image\n"
|
86 |
"\n"
|
87 |
"-f disk_image set the raw disk image name\n"
|
88 |
"cow_image the created cow_image\n"
|
89 |
"cow_size the create cow_image size in MB if no raw disk image is used\n"
|
90 |
"\n"
|
91 |
"Once the cow_image is created from a raw disk image, you must not modify the original raw disk image\n"
|
92 |
); |
93 |
exit(1);
|
94 |
} |
95 |
|
96 |
int main(int argc, char **argv) |
97 |
{ |
98 |
const char *image_filename, *cow_filename; |
99 |
int cow_fd, c, nb_args, simple_image;
|
100 |
int64_t image_size; |
101 |
|
102 |
image_filename = NULL;
|
103 |
image_size = 0;
|
104 |
simple_image = 0;
|
105 |
for(;;) {
|
106 |
c = getopt(argc, argv, "hf:s");
|
107 |
if (c == -1) |
108 |
break;
|
109 |
switch(c) {
|
110 |
case 'h': |
111 |
help(); |
112 |
break;
|
113 |
case 'f': |
114 |
image_filename = optarg; |
115 |
break;
|
116 |
case 's': |
117 |
simple_image = 1;
|
118 |
break;
|
119 |
} |
120 |
} |
121 |
if (!image_filename)
|
122 |
nb_args = 2;
|
123 |
else
|
124 |
nb_args = 1;
|
125 |
if (optind + nb_args != argc)
|
126 |
help(); |
127 |
|
128 |
cow_filename = argv[optind]; |
129 |
if (nb_args == 2) { |
130 |
image_size = (int64_t)atoi(argv[optind + 1]) * 2 * 1024; |
131 |
} |
132 |
|
133 |
cow_fd = open(cow_filename, O_RDWR | O_CREAT | O_TRUNC | O_LARGEFILE, 0644);
|
134 |
if (!cow_fd < 0) |
135 |
return -1; |
136 |
if (simple_image) {
|
137 |
ftruncate64(cow_fd, image_size * 512);
|
138 |
} else {
|
139 |
if (cow_create(cow_fd, image_filename, image_size) < 0) { |
140 |
fprintf(stderr, "%s: error while formating\n", cow_filename);
|
141 |
exit(1);
|
142 |
} |
143 |
} |
144 |
close(cow_fd); |
145 |
return 0; |
146 |
} |