SDL static config fix (Roman Zippel)
[qemu] / qemu-mkcow.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 <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("vlmkcow version " QEMU_VERSION ", Copyright (c) 2003 Fabrice Bellard\n"
84            "usage: vlmkcow [-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 }