root / qemu-mkcow.c @ 6c9bf893
History | View | Annotate | Download (4.3 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 <sys/mman.h> |
32 |
#include <fcntl.h> |
33 |
#include <signal.h> |
34 |
#include <time.h> |
35 |
#include <sys/time.h> |
36 |
#include <malloc.h> |
37 |
#include <termios.h> |
38 |
#include <sys/poll.h> |
39 |
#include <errno.h> |
40 |
#include <sys/wait.h> |
41 |
#include <sys/stat.h> |
42 |
#include <netinet/in.h> |
43 |
|
44 |
#include "vl.h" |
45 |
|
46 |
#include "bswap.h" |
47 |
|
48 |
int cow_create(int cow_fd, const char *image_filename, |
49 |
int64_t image_sectors) |
50 |
{ |
51 |
struct cow_header_v2 cow_header;
|
52 |
int fd;
|
53 |
struct stat st;
|
54 |
|
55 |
memset(&cow_header, 0, sizeof(cow_header)); |
56 |
cow_header.magic = htonl(COW_MAGIC); |
57 |
cow_header.version = htonl(COW_VERSION); |
58 |
if (image_filename) {
|
59 |
fd = open(image_filename, O_RDONLY); |
60 |
if (fd < 0) { |
61 |
perror(image_filename); |
62 |
exit(1);
|
63 |
} |
64 |
image_sectors = lseek64(fd, 0, SEEK_END);
|
65 |
if (fstat(fd, &st) != 0) { |
66 |
close(fd); |
67 |
return -1; |
68 |
} |
69 |
close(fd); |
70 |
image_sectors /= 512;
|
71 |
cow_header.mtime = htonl(st.st_mtime); |
72 |
realpath(image_filename, cow_header.backing_file); |
73 |
} |
74 |
cow_header.sectorsize = htonl(512);
|
75 |
cow_header.size = image_sectors * 512;
|
76 |
#ifndef WORDS_BIGENDIAN
|
77 |
cow_header.size = bswap64(cow_header.size); |
78 |
#endif
|
79 |
write(cow_fd, &cow_header, sizeof(cow_header));
|
80 |
/* resize to include at least all the bitmap */
|
81 |
ftruncate(cow_fd, sizeof(cow_header) + ((image_sectors + 7) >> 3)); |
82 |
lseek(cow_fd, 0, SEEK_SET);
|
83 |
return 0; |
84 |
} |
85 |
|
86 |
void help(void) |
87 |
{ |
88 |
printf("vlmkcow version " QEMU_VERSION ", Copyright (c) 2003 Fabrice Bellard\n" |
89 |
"usage: vlmkcow [-h] [-f disk_image] cow_image [cow_size]\n"
|
90 |
"Create a Copy On Write disk image from an optional raw disk image\n"
|
91 |
"\n"
|
92 |
"-f disk_image set the raw disk image name\n"
|
93 |
"cow_image the created cow_image\n"
|
94 |
"cow_size the create cow_image size in MB if no raw disk image is used\n"
|
95 |
"\n"
|
96 |
"Once the cow_image is created from a raw disk image, you must not modify the original raw disk image\n"
|
97 |
); |
98 |
exit(1);
|
99 |
} |
100 |
|
101 |
int main(int argc, char **argv) |
102 |
{ |
103 |
const char *image_filename, *cow_filename; |
104 |
int cow_fd, c, nb_args;
|
105 |
int64_t image_size; |
106 |
|
107 |
image_filename = NULL;
|
108 |
image_size = 0;
|
109 |
for(;;) {
|
110 |
c = getopt(argc, argv, "hf:");
|
111 |
if (c == -1) |
112 |
break;
|
113 |
switch(c) {
|
114 |
case 'h': |
115 |
help(); |
116 |
break;
|
117 |
case 'f': |
118 |
image_filename = optarg; |
119 |
break;
|
120 |
} |
121 |
} |
122 |
if (!image_filename)
|
123 |
nb_args = 2;
|
124 |
else
|
125 |
nb_args = 1;
|
126 |
if (optind + nb_args != argc)
|
127 |
help(); |
128 |
|
129 |
cow_filename = argv[optind]; |
130 |
if (nb_args == 2) { |
131 |
image_size = (int64_t)atoi(argv[optind + 1]) * 2 * 1024; |
132 |
} |
133 |
|
134 |
cow_fd = open(cow_filename, O_RDWR | O_CREAT | O_TRUNC, 0644);
|
135 |
if (!cow_fd < 0) |
136 |
return -1; |
137 |
if (cow_create(cow_fd, image_filename, image_size) < 0) { |
138 |
fprintf(stderr, "%s: error while formating\n", cow_filename);
|
139 |
exit(1);
|
140 |
} |
141 |
close(cow_fd); |
142 |
return 0; |
143 |
} |