1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24: #include "qemu-common.h"
25: #ifndef QEMU_IMG
26: #include "console.h"
27: #endif
28: #include "block_int.h"
29:
30: #ifdef _BSD
31: #include <sys/types.h>
32: #include <sys/stat.h>
33: #include <sys/ioctl.h>
34: #include <sys/queue.h>
35: #include <sys/disk.h>
36: #endif
37:
38: #define SECTOR_BITS 9
39: #define SECTOR_SIZE (1 << SECTOR_BITS)
40:
41: typedef struct BlockDriverAIOCBSync {
42: BlockDriverAIOCB common;
43: QEMUBH *bh;
44: int ret;
45: } BlockDriverAIOCBSync;
46:
47: static BlockDriverAIOCB *bdrv_aio_read_em(BlockDriverState *bs,
48: int64_t sector_num, uint8_t *buf, int nb_sectors,
49: BlockDriverCompletionFunc *cb, void *opaque);
50: static BlockDriverAIOCB *bdrv_aio_write_em(BlockDriverState *bs,
51: int64_t sector_num, const uint8_t *buf, int nb_sectors,
52: BlockDriverCompletionFunc *cb, void *opaque);
53: static void bdrv_aio_cancel_em(BlockDriverAIOCB *acb);
54: static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
55: uint8_t *buf, int nb_sectors);
56: static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num,
57: const uint8_t *buf, int nb_sectors);
58:
59: BlockDriverState *bdrv_first;
60: static BlockDriver *first_drv;
61:
62: int path_is_absolute(const char *path)
63: {
64: const char *p;
65: #ifdef _WIN32
66:
67: if (*path == '/' || *path == '\\')
68: return 1;
69: #endif
70: p = strchr(path, ':');
71: if (p)
72: p++;
73: else
74: p = path;
75: #ifdef _WIN32
76: return (*p == '/' || *p == '\\');
77: #else
78: return (*p == '/');
79: #endif
80: }
81:
82:
83:
84:
85: void path_combine(char *dest, int dest_size,
86: const char *base_path,
87: const char *filename)
88: {
89: const char *p, *p1;
90: int len;
91:
92: if (dest_size <= 0)
93: return;
94: if (path_is_absolute(filename)) {
95: pstrcpy(dest, dest_size, filename);
96: } else {
97: p = strchr(base_path, ':');
98: if (p)
99: p++;
100: else
101: p = base_path;
102: p1 = strrchr(base_path, '/');
103: #ifdef _WIN32
104: {
105: const char *p2;
106: p2 = strrchr(base_path, '\\');
107: if (!p1 || p2 > p1)
108: p1 = p2;
109: }
110: #endif
111: if (p1)
112: p1++;
113: else
114: p1 = base_path;
115: if (p1 > p)
116: p = p1;
117: len = p - base_path;
118: if (len > dest_size - 1)
119: len = dest_size - 1;
120: memcpy(dest, base_path, len);
121: dest[len] = '\0';
122: pstrcat(dest, dest_size, filename);
123: }
124: }
125:
126:
127: static void bdrv_register(BlockDriver *bdrv)
128: {
129: if (!bdrv->bdrv_aio_read) {
130:
131: bdrv->bdrv_aio_read = bdrv_aio_read_em;
132: bdrv->bdrv_aio_write = bdrv_aio_write_em;
133: bdrv->bdrv_aio_cancel = bdrv_aio_cancel_em;
134: bdrv->aiocb_size = sizeof(BlockDriverAIOCBSync);
135: } else if (!bdrv->bdrv_read && !bdrv->bdrv_pread) {
136:
137: bdrv->bdrv_read = bdrv_read_em;
138: bdrv->bdrv_write = bdrv_write_em;
139: }
140: bdrv->next = first_drv;
141: first_drv = bdrv;
142: }
143:
144:
145: BlockDriverState *bdrv_new(const char *device_name)
146: {
147: BlockDriverState **pbs, *bs;
148:
149: bs = qemu_mallocz(sizeof(BlockDriverState));
150: if(!bs)
151: return NULL;
152: pstrcpy(bs->device_name, sizeof(bs->device_name), device_name);
153: if (device_name[0] != '\0') {
154:
155: pbs = &bdrv_first;
156: while (*pbs != NULL)
157: pbs = &(*pbs)->next;
158: *pbs = bs;
159: }
160: return bs;
161: }
162:
163: BlockDriver *bdrv_find_format(const char *format_name)
164: {
165: BlockDriver *drv1;
166: for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
167: if (!strcmp(drv1->format_name, format_name))
168: return drv1;
169: }
170: return NULL;
171: }
172:
173: int bdrv_create(BlockDriver *drv,
174: const char *filename, int64_t size_in_sectors,
175: const char *backing_file, int flags)
176: {
177: if (!drv->bdrv_create)
178: return -ENOTSUP;
179: return drv->bdrv_create(filename, size_in_sectors, backing_file, flags);
180: }
181:
182: #ifdef _WIN32
183: void get_tmp_filename(char *filename, int size)
184: {
185: char temp_dir[MAX_PATH];
186:
187: GetTempPath(MAX_PATH, temp_dir);
188: GetTempFileName(temp_dir, "qem", 0, filename);
189: }
190: #else
191: void get_tmp_filename(char *filename, int size)
192: {
193: int fd;
194:
195: pstrcpy(filename, size, "/tmp/vl.XXXXXX");
196: fd = mkstemp(filename);
197: close(fd);
198: }
199: #endif
200:
201: #ifdef _WIN32
202: static int is_windows_drive_prefix(const char *filename)
203: {
204: return (((filename[0] >= 'a' && filename[0] <= 'z') ||
205: (filename[0] >= 'A' && filename[0] <= 'Z')) &&
206: filename[1] == ':');
207: }
208:
209: static int is_windows_drive(const char *filename)
210: {
211: if (is_windows_drive_prefix(filename) &&
212: filename[2] == '\0')
213: return 1;
214: if (strstart(filename, "\\\\.\\", NULL) ||
215: strstart(filename, "//./", NULL))
216: return 1;
217: return 0;
218: }
219: #endif
220:
221: static BlockDriver *find_protocol(const char *filename)
222: {
223: BlockDriver *drv1;
224: char protocol[128];
225: int len;
226: const char *p;
227:
228: #ifdef _WIN32
229: if (is_windows_drive(filename) ||
230: is_windows_drive_prefix(filename))
231: return &bdrv_raw;
232: #endif
233: p = strchr(filename, ':');
234: if (!p)
235: return &bdrv_raw;
236: len = p - filename;
237: if (len > sizeof(protocol) - 1)
238: len = sizeof(protocol) - 1;
239: memcpy(protocol, filename, len);
240: protocol[len] = '\0';
241: for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
242: if (drv1->protocol_name &&
243: !strcmp(drv1->protocol_name, protocol))
244: return drv1;
245: }
246: return NULL;
247: }
248:
249:
250:
251: static BlockDriver *find_image_format(const char *filename)
252: {
253: int ret, score, score_max;
254: BlockDriver *drv1, *drv;
255: uint8_t buf[2048];
256: BlockDriverState *bs;
257:
258:
259:
260: if (strstart(filename, "/dev/cdrom", NULL))
261: return &bdrv_host_device;
262: #ifdef _WIN32
263: if (is_windows_drive(filename))
264: return &bdrv_host_device;
265: #else
266: {
267: struct stat st;
268: if (stat(filename, &st) >= 0 &&
269: (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode))) {
270: return &bdrv_host_device;
271: }
272: }
273: #endif
274:
275: drv = find_protocol(filename);
276:
277: if (drv == &bdrv_vvfat)
278: return drv;
279:
280: ret = bdrv_file_open(&bs, filename, BDRV_O_RDONLY);
281: if (ret < 0)
282: return NULL;
283: ret = bdrv_pread(bs, 0, buf, sizeof(buf));
284: bdrv_delete(bs);
285: if (ret < 0) {
286: return NULL;
287: }
288:
289: score_max = 0;
290: for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
291: if (drv1->bdrv_probe) {
292: score = drv1->bdrv_probe(buf, ret, filename);
293: if (score > score_max) {
294: score_max = score;
295: drv = drv1;
296: }
297: }
298: }
299: return drv;
300: }
301:
302: int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags)
303: {
304: BlockDriverState *bs;
305: int ret;
306:
307: bs = bdrv_new("");
308: if (!bs)
309: return -ENOMEM;
310: ret = bdrv_open2(bs, filename, flags | BDRV_O_FILE, NULL);
311: if (ret < 0) {
312: bdrv_delete(bs);
313: return ret;
314: }
315: *pbs = bs;
316: return 0;
317: }
318:
319: int bdrv_open(BlockDriverState *bs, const char *filename, int flags)
320: {
321: return bdrv_open2(bs, filename, flags, NULL);
322: }
323:
324: int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
325: BlockDriver *drv)
326: {
327: int ret, open_flags;
328: char tmp_filename[PATH_MAX];
329: char backing_filename[PATH_MAX];
330:
331: bs->read_only = 0;
332: bs->is_temporary = 0;
333: bs->encrypted = 0;
334:
335: if (flags & BDRV_O_SNAPSHOT) {
336: BlockDriverState *bs1;
337: int64_t total_size;
338:
339:
340:
341:
342:
343: bs1 = bdrv_new("");
344: if (!bs1) {
345: return -ENOMEM;
346: }
347: if (bdrv_open(bs1, filename, 0) < 0) {
348: bdrv_delete(bs1);
349: return -1;
350: }
351: total_size = bdrv_getlength(bs1) >> SECTOR_BITS;
352: bdrv_delete(bs1);
353:
354: get_tmp_filename(tmp_filename, sizeof(tmp_filename));
355: realpath(filename, backing_filename);
356: if (bdrv_create(&bdrv_qcow2, tmp_filename,
357: total_size, backing_filename, 0) < 0) {
358: return -1;
359: }
360: filename = tmp_filename;
361: bs->is_temporary = 1;
362: }
363:
364: pstrcpy(bs->filename, sizeof(bs->filename), filename);
365: if (flags & BDRV_O_FILE) {
366: drv = find_protocol(filename);
367: if (!drv)
368: return -ENOENT;
369: } else {
370: if (!drv) {
371: drv = find_image_format(filename);
372: if (!drv)
373: return -1;
374: }
375: }
376: bs->drv = drv;
377: bs->opaque = qemu_mallocz(drv->instance_size);
378: if (bs->opaque == NULL && drv->instance_size > 0)
379: return -1;
380:
381:
382: if (!(flags & BDRV_O_FILE))
383: open_flags = BDRV_O_RDWR | (flags & BDRV_O_DIRECT);
384: else
385: open_flags = flags & ~(BDRV_O_FILE | BDRV_O_SNAPSHOT);
386: ret = drv->bdrv_open(bs, filename, open_flags);
387: if (ret == -EACCES && !(flags & BDRV_O_FILE)) {
388: ret = drv->bdrv_open(bs, filename, BDRV_O_RDONLY);
389: bs->read_only = 1;
390: }
391: if (ret < 0) {
392: qemu_free(bs->opaque);
393: bs->opaque = NULL;
394: bs->drv = NULL;
395: return ret;
396: }
397: if (drv->bdrv_getlength) {
398: bs->total_sectors = bdrv_getlength(bs) >> SECTOR_BITS;
399: }
400: #ifndef _WIN32
401: if (bs->is_temporary) {
402: unlink(filename);
403: }
404: #endif
405: if (bs->backing_file[0] != '\0') {
406:
407: bs->backing_hd = bdrv_new("");
408: if (!bs->backing_hd) {
409: fail:
410: bdrv_close(bs);
411: return -ENOMEM;
412: }
413: path_combine(backing_filename, sizeof(backing_filename),
414: filename, bs->backing_file);
415: if (bdrv_open(bs->backing_hd, backing_filename, 0) < 0)
416: goto fail;
417: }
418:
419:
420: bs->media_changed = 1;
421: if (bs->change_cb)
422: bs->change_cb(bs->change_opaque);
423:
424: return 0;
425: }
426:
427: void bdrv_close(BlockDriverState *bs)
428: {
429: if (bs->drv) {
430: if (bs->backing_hd)
431: bdrv_delete(bs->backing_hd);
432: bs->drv->bdrv_close(bs);
433: qemu_free(bs->opaque);
434: #ifdef _WIN32
435: if (bs->is_temporary) {
436: unlink(bs->filename);
437: }
438: #endif
439: bs->opaque = NULL;
440: bs->drv = NULL;
441:
442:
443: bs->media_changed = 1;
444: if (bs->change_cb)
445: bs->change_cb(bs->change_opaque);
446: }
447: }
448:
449: void bdrv_delete(BlockDriverState *bs)
450: {
451:
452: bdrv_close(bs);
453: qemu_free(bs);
454: }
455:
456:
457: int bdrv_commit(BlockDriverState *bs)
458: {
459: BlockDriver *drv = bs->drv;
460: int64_t i, total_sectors;
461: int n, j;
462: unsigned char sector[512];
463:
464: if (!drv)
465: return -ENOMEDIUM;
466:
467: if (bs->read_only) {
468: return -EACCES;
469: }
470:
471: if (!bs->backing_hd) {
472: return -ENOTSUP;
473: }
474:
475: total_sectors = bdrv_getlength(bs) >> SECTOR_BITS;
476: for (i = 0; i < total_sectors;) {
477: if (drv->bdrv_is_allocated(bs, i, 65536, &n)) {
478: for(j = 0; j < n; j++) {
479: if (bdrv_read(bs, i, sector, 1) != 0) {
480: return -EIO;
481: }
482:
483: if (bdrv_write(bs->backing_hd, i, sector, 1) != 0) {
484: return -EIO;
485: }
486: i++;
487: }
488: } else {
489: i += n;
490: }
491: }
492:
493: if (drv->bdrv_make_empty)
494: return drv->bdrv_make_empty(bs);
495:
496: return 0;
497: }
498:
499:
500: int bdrv_read(BlockDriverState *bs, int64_t sector_num,
501: uint8_t *buf, int nb_sectors)
502: {
503: BlockDriver *drv = bs->drv;
504:
505: if (!drv)
506: return -ENOMEDIUM;
507:
508: if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
509: memcpy(buf, bs->boot_sector_data, 512);
510: sector_num++;
511: nb_sectors--;
512: buf += 512;
513: if (nb_sectors == 0)
514: return 0;
515: }
516: if (drv->bdrv_pread) {
517: int ret, len;
518: len = nb_sectors * 512;
519: ret = drv->bdrv_pread(bs, sector_num * 512, buf, len);
520: if (ret < 0)
521: return ret;
522: else if (ret != len)
523: return -EINVAL;
524: else {
525: bs->rd_bytes += (unsigned) len;
526: bs->rd_ops ++;
527: return 0;
528: }
529: } else {
530: return drv->bdrv_read(bs, sector_num, buf, nb_sectors);
531: }
532: }
533:
534:
535:
536:
537:
538:
539:
540: int bdrv_write(BlockDriverState *bs, int64_t sector_num,
541: const uint8_t *buf, int nb_sectors)
542: {
543: BlockDriver *drv = bs->drv;
544: if (!bs->drv)
545: return -ENOMEDIUM;
546: if (bs->read_only)
547: return -EACCES;
548: if (sector_num == 0 && bs->boot_sector_enabled && nb_sectors > 0) {
549: memcpy(bs->boot_sector_data, buf, 512);
550: }
551: if (drv->bdrv_pwrite) {
552: int ret, len;
553: len = nb_sectors * 512;
554: ret = drv->bdrv_pwrite(bs, sector_num * 512, buf, len);
555: if (ret < 0)
556: return ret;
557: else if (ret != len)
558: return -EIO;
559: else {
560: bs->wr_bytes += (unsigned) len;
561: bs->wr_ops ++;
562: return 0;
563: }
564: } else {
565: return drv->bdrv_write(bs, sector_num, buf, nb_sectors);
566: }
567: }
568:
569: static int bdrv_pread_em(BlockDriverState *bs, int64_t offset,
570: uint8_t *buf, int count1)
571: {
572: uint8_t tmp_buf[SECTOR_SIZE];
573: int len, nb_sectors, count;
574: int64_t sector_num;
575:
576: count = count1;
577:
578: len = (SECTOR_SIZE - offset) & (SECTOR_SIZE - 1);
579: if (len > count)
580: len = count;
581: sector_num = offset >> SECTOR_BITS;
582: if (len > 0) {
583: if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
584: return -EIO;
585: memcpy(buf, tmp_buf + (offset & (SECTOR_SIZE - 1)), len);
586: count -= len;
587: if (count == 0)
588: return count1;
589: sector_num++;
590: buf += len;
591: }
592:
593:
594: