soft mmu support
[qemu] / vlmkcow.c
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 <netinet/in.h>
42
43 #include "vl.h"
44
45 #define NO_THUNK_TYPE_SIZE
46 #include "thunk.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 }