Annotation of qemu/block.c, revision 1.1.1.10
1.1 root 1: /*
2: * QEMU System Emulator block driver
1.1.1.6 root 3: *
1.1 root 4: * Copyright (c) 2003 Fabrice Bellard
1.1.1.6 root 5: *
1.1 root 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: */
1.1.1.7 root 24: #include "config-host.h"
25: #ifdef _BSD
26: /* include native header before sys-queue.h */
27: #include <sys/queue.h>
28: #endif
29:
1.1.1.6 root 30: #include "qemu-common.h"
31: #include "console.h"
1.1 root 32: #include "block_int.h"
33:
34: #ifdef _BSD
35: #include <sys/types.h>
36: #include <sys/stat.h>
37: #include <sys/ioctl.h>
38: #include <sys/disk.h>
39: #endif
40:
1.1.1.5 root 41: #define SECTOR_BITS 9
42: #define SECTOR_SIZE (1 << SECTOR_BITS)
1.1.1.2 root 43:
1.1.1.10! root 44: static AIOPool vectored_aio_pool;
! 45:
1.1.1.5 root 46: typedef struct BlockDriverAIOCBSync {
47: BlockDriverAIOCB common;
48: QEMUBH *bh;
49: int ret;
50: } BlockDriverAIOCBSync;
51:
52: static BlockDriverAIOCB *bdrv_aio_read_em(BlockDriverState *bs,
53: int64_t sector_num, uint8_t *buf, int nb_sectors,
54: BlockDriverCompletionFunc *cb, void *opaque);
55: static BlockDriverAIOCB *bdrv_aio_write_em(BlockDriverState *bs,
56: int64_t sector_num, const uint8_t *buf, int nb_sectors,
57: BlockDriverCompletionFunc *cb, void *opaque);
58: static void bdrv_aio_cancel_em(BlockDriverAIOCB *acb);
1.1.1.6 root 59: static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
1.1.1.5 root 60: uint8_t *buf, int nb_sectors);
61: static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num,
62: const uint8_t *buf, int nb_sectors);
1.1.1.3 root 63:
1.1.1.6 root 64: BlockDriverState *bdrv_first;
1.1.1.7 root 65:
1.1 root 66: static BlockDriver *first_drv;
67:
1.1.1.5 root 68: int path_is_absolute(const char *path)
69: {
70: const char *p;
71: #ifdef _WIN32
72: /* specific case for names like: "\\.\d:" */
73: if (*path == '/' || *path == '\\')
74: return 1;
75: #endif
76: p = strchr(path, ':');
77: if (p)
78: p++;
79: else
80: p = path;
81: #ifdef _WIN32
82: return (*p == '/' || *p == '\\');
83: #else
84: return (*p == '/');
85: #endif
1.1.1.2 root 86: }
87:
1.1.1.5 root 88: /* if filename is absolute, just copy it to dest. Otherwise, build a
89: path to it by considering it is relative to base_path. URL are
90: supported. */
91: void path_combine(char *dest, int dest_size,
92: const char *base_path,
93: const char *filename)
94: {
95: const char *p, *p1;
96: int len;
97:
98: if (dest_size <= 0)
99: return;
100: if (path_is_absolute(filename)) {
101: pstrcpy(dest, dest_size, filename);
102: } else {
103: p = strchr(base_path, ':');
104: if (p)
105: p++;
106: else
107: p = base_path;
108: p1 = strrchr(base_path, '/');
109: #ifdef _WIN32
110: {
111: const char *p2;
112: p2 = strrchr(base_path, '\\');
113: if (!p1 || p2 > p1)
114: p1 = p2;
1.1.1.2 root 115: }
1.1.1.5 root 116: #endif
117: if (p1)
118: p1++;
119: else
120: p1 = base_path;
121: if (p1 > p)
122: p = p1;
123: len = p - base_path;
124: if (len > dest_size - 1)
125: len = dest_size - 1;
126: memcpy(dest, base_path, len);
127: dest[len] = '\0';
128: pstrcat(dest, dest_size, filename);
1.1.1.2 root 129: }
130: }
131:
132:
1.1.1.6 root 133: static void bdrv_register(BlockDriver *bdrv)
1.1 root 134: {
1.1.1.5 root 135: if (!bdrv->bdrv_aio_read) {
136: /* add AIO emulation layer */
137: bdrv->bdrv_aio_read = bdrv_aio_read_em;
138: bdrv->bdrv_aio_write = bdrv_aio_write_em;
139: bdrv->bdrv_aio_cancel = bdrv_aio_cancel_em;
140: bdrv->aiocb_size = sizeof(BlockDriverAIOCBSync);
141: } else if (!bdrv->bdrv_read && !bdrv->bdrv_pread) {
142: /* add synchronous IO emulation layer */
143: bdrv->bdrv_read = bdrv_read_em;
144: bdrv->bdrv_write = bdrv_write_em;
145: }
1.1.1.10! root 146: aio_pool_init(&bdrv->aio_pool, bdrv->aiocb_size, bdrv->bdrv_aio_cancel);
1.1 root 147: bdrv->next = first_drv;
148: first_drv = bdrv;
149: }
150:
151: /* create a new block device (by default it is empty) */
152: BlockDriverState *bdrv_new(const char *device_name)
153: {
154: BlockDriverState **pbs, *bs;
155:
156: bs = qemu_mallocz(sizeof(BlockDriverState));
157: pstrcpy(bs->device_name, sizeof(bs->device_name), device_name);
158: if (device_name[0] != '\0') {
159: /* insert at the end */
160: pbs = &bdrv_first;
161: while (*pbs != NULL)
162: pbs = &(*pbs)->next;
163: *pbs = bs;
164: }
165: return bs;
166: }
167:
168: BlockDriver *bdrv_find_format(const char *format_name)
169: {
170: BlockDriver *drv1;
171: for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
172: if (!strcmp(drv1->format_name, format_name))
173: return drv1;
174: }
175: return NULL;
176: }
177:
1.1.1.6 root 178: int bdrv_create(BlockDriver *drv,
1.1 root 179: const char *filename, int64_t size_in_sectors,
180: const char *backing_file, int flags)
181: {
182: if (!drv->bdrv_create)
183: return -ENOTSUP;
184: return drv->bdrv_create(filename, size_in_sectors, backing_file, flags);
185: }
186:
187: #ifdef _WIN32
1.1.1.2 root 188: void get_tmp_filename(char *filename, int size)
1.1 root 189: {
1.1.1.5 root 190: char temp_dir[MAX_PATH];
1.1.1.6 root 191:
1.1.1.5 root 192: GetTempPath(MAX_PATH, temp_dir);
193: GetTempFileName(temp_dir, "qem", 0, filename);
1.1 root 194: }
195: #else
1.1.1.2 root 196: void get_tmp_filename(char *filename, int size)
1.1 root 197: {
198: int fd;
1.1.1.7 root 199: const char *tmpdir;
1.1 root 200: /* XXX: race condition possible */
1.1.1.7 root 201: tmpdir = getenv("TMPDIR");
202: if (!tmpdir)
203: tmpdir = "/tmp";
204: snprintf(filename, size, "%s/vl.XXXXXX", tmpdir);
1.1 root 205: fd = mkstemp(filename);
206: close(fd);
207: }
208: #endif
209:
1.1.1.5 root 210: #ifdef _WIN32
211: static int is_windows_drive_prefix(const char *filename)
212: {
213: return (((filename[0] >= 'a' && filename[0] <= 'z') ||
214: (filename[0] >= 'A' && filename[0] <= 'Z')) &&
215: filename[1] == ':');
216: }
1.1.1.6 root 217:
1.1.1.5 root 218: static int is_windows_drive(const char *filename)
219: {
1.1.1.6 root 220: if (is_windows_drive_prefix(filename) &&
1.1.1.5 root 221: filename[2] == '\0')
222: return 1;
223: if (strstart(filename, "\\\\.\\", NULL) ||
224: strstart(filename, "//./", NULL))
225: return 1;
226: return 0;
227: }
228: #endif
229:
230: static BlockDriver *find_protocol(const char *filename)
231: {
232: BlockDriver *drv1;
233: char protocol[128];
234: int len;
235: const char *p;
236:
237: #ifdef _WIN32
238: if (is_windows_drive(filename) ||
239: is_windows_drive_prefix(filename))
240: return &bdrv_raw;
241: #endif
242: p = strchr(filename, ':');
243: if (!p)
244: return &bdrv_raw;
245: len = p - filename;
246: if (len > sizeof(protocol) - 1)
247: len = sizeof(protocol) - 1;
248: memcpy(protocol, filename, len);
249: protocol[len] = '\0';
250: for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
1.1.1.6 root 251: if (drv1->protocol_name &&
1.1.1.5 root 252: !strcmp(drv1->protocol_name, protocol))
253: return drv1;
254: }
255: return NULL;
256: }
257:
1.1 root 258: /* XXX: force raw format if block or character device ? It would
259: simplify the BSD case */
260: static BlockDriver *find_image_format(const char *filename)
261: {
1.1.1.5 root 262: int ret, score, score_max;
1.1 root 263: BlockDriver *drv1, *drv;
1.1.1.5 root 264: uint8_t buf[2048];
265: BlockDriverState *bs;
1.1.1.6 root 266:
1.1.1.5 root 267: /* detect host devices. By convention, /dev/cdrom[N] is always
268: recognized as a host CDROM */
269: if (strstart(filename, "/dev/cdrom", NULL))
270: return &bdrv_host_device;
271: #ifdef _WIN32
272: if (is_windows_drive(filename))
273: return &bdrv_host_device;
274: #else
275: {
276: struct stat st;
1.1.1.6 root 277: if (stat(filename, &st) >= 0 &&
1.1.1.5 root 278: (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode))) {
279: return &bdrv_host_device;
1.1 root 280: }
281: }
1.1.1.5 root 282: #endif
1.1.1.6 root 283:
1.1.1.5 root 284: drv = find_protocol(filename);
285: /* no need to test disk image formats for vvfat */
286: if (drv == &bdrv_vvfat)
287: return drv;
288:
289: ret = bdrv_file_open(&bs, filename, BDRV_O_RDONLY);
290: if (ret < 0)
291: return NULL;
292: ret = bdrv_pread(bs, 0, buf, sizeof(buf));
293: bdrv_delete(bs);
294: if (ret < 0) {
295: return NULL;
296: }
297:
1.1 root 298: score_max = 0;
299: for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
1.1.1.5 root 300: if (drv1->bdrv_probe) {
301: score = drv1->bdrv_probe(buf, ret, filename);
302: if (score > score_max) {
303: score_max = score;
304: drv = drv1;
305: }
1.1 root 306: }
307: }
308: return drv;
309: }
310:
1.1.1.5 root 311: int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags)
1.1 root 312: {
1.1.1.5 root 313: BlockDriverState *bs;
314: int ret;
315:
316: bs = bdrv_new("");
317: ret = bdrv_open2(bs, filename, flags | BDRV_O_FILE, NULL);
318: if (ret < 0) {
319: bdrv_delete(bs);
320: return ret;
1.1.1.2 root 321: }
1.1.1.7 root 322: bs->growable = 1;
1.1.1.5 root 323: *pbs = bs;
324: return 0;
325: }
326:
327: int bdrv_open(BlockDriverState *bs, const char *filename, int flags)
328: {
329: return bdrv_open2(bs, filename, flags, NULL);
1.1 root 330: }
331:
1.1.1.5 root 332: int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
1.1 root 333: BlockDriver *drv)
334: {
1.1.1.5 root 335: int ret, open_flags;
1.1.1.6 root 336: char tmp_filename[PATH_MAX];
337: char backing_filename[PATH_MAX];
338:
1.1 root 339: bs->read_only = 0;
340: bs->is_temporary = 0;
341: bs->encrypted = 0;
1.1.1.8 root 342: bs->valid_key = 0;
1.1 root 343:
1.1.1.5 root 344: if (flags & BDRV_O_SNAPSHOT) {
1.1 root 345: BlockDriverState *bs1;
346: int64_t total_size;
1.1.1.7 root 347: int is_protocol = 0;
1.1.1.6 root 348:
1.1 root 349: /* if snapshot, we create a temporary backing file and open it
350: instead of opening 'filename' directly */
351:
352: /* if there is a backing file, use it */
353: bs1 = bdrv_new("");
1.1.1.8 root 354: ret = bdrv_open(bs1, filename, 0);
355: if (ret < 0) {
1.1 root 356: bdrv_delete(bs1);
1.1.1.8 root 357: return ret;
1.1 root 358: }
1.1.1.5 root 359: total_size = bdrv_getlength(bs1) >> SECTOR_BITS;
1.1.1.7 root 360:
361: if (bs1->drv && bs1->drv->protocol_name)
362: is_protocol = 1;
363:
1.1 root 364: bdrv_delete(bs1);
1.1.1.6 root 365:
1.1 root 366: get_tmp_filename(tmp_filename, sizeof(tmp_filename));
1.1.1.7 root 367:
368: /* Real path is meaningless for protocols */
369: if (is_protocol)
370: snprintf(backing_filename, sizeof(backing_filename),
371: "%s", filename);
372: else
373: realpath(filename, backing_filename);
374:
1.1.1.8 root 375: ret = bdrv_create(&bdrv_qcow2, tmp_filename,
376: total_size, backing_filename, 0);
377: if (ret < 0) {
378: return ret;
1.1 root 379: }
380: filename = tmp_filename;
381: bs->is_temporary = 1;
382: }
383:
384: pstrcpy(bs->filename, sizeof(bs->filename), filename);
1.1.1.5 root 385: if (flags & BDRV_O_FILE) {
386: drv = find_protocol(filename);
1.1.1.8 root 387: } else if (!drv) {
388: drv = find_image_format(filename);
389: }
390: if (!drv) {
391: ret = -ENOENT;
392: goto unlink_and_fail;
1.1 root 393: }
394: bs->drv = drv;
395: bs->opaque = qemu_mallocz(drv->instance_size);
1.1.1.5 root 396: /* Note: for compatibility, we open disk image files as RDWR, and
397: RDONLY as fallback */
398: if (!(flags & BDRV_O_FILE))
1.1.1.7 root 399: open_flags = BDRV_O_RDWR | (flags & BDRV_O_CACHE_MASK);
1.1.1.5 root 400: else
401: open_flags = flags & ~(BDRV_O_FILE | BDRV_O_SNAPSHOT);
402: ret = drv->bdrv_open(bs, filename, open_flags);
1.1.1.7 root 403: if ((ret == -EACCES || ret == -EPERM) && !(flags & BDRV_O_FILE)) {
404: ret = drv->bdrv_open(bs, filename, open_flags & ~BDRV_O_RDWR);
1.1.1.5 root 405: bs->read_only = 1;
406: }
1.1 root 407: if (ret < 0) {
408: qemu_free(bs->opaque);
1.1.1.5 root 409: bs->opaque = NULL;
410: bs->drv = NULL;
1.1.1.8 root 411: unlink_and_fail:
412: if (bs->is_temporary)
413: unlink(filename);
1.1.1.5 root 414: return ret;
415: }
416: if (drv->bdrv_getlength) {
417: bs->total_sectors = bdrv_getlength(bs) >> SECTOR_BITS;
1.1 root 418: }
419: #ifndef _WIN32
420: if (bs->is_temporary) {
421: unlink(filename);
422: }
423: #endif
1.1.1.5 root 424: if (bs->backing_file[0] != '\0') {
1.1 root 425: /* if there is a backing file, use it */
426: bs->backing_hd = bdrv_new("");
1.1.1.5 root 427: path_combine(backing_filename, sizeof(backing_filename),
428: filename, bs->backing_file);
1.1.1.8 root 429: ret = bdrv_open(bs->backing_hd, backing_filename, open_flags);
430: if (ret < 0) {
431: bdrv_close(bs);
432: return ret;
433: }
1.1 root 434: }
435:
436: /* call the change callback */
1.1.1.5 root 437: bs->media_changed = 1;
1.1 root 438: if (bs->change_cb)
439: bs->change_cb(bs->change_opaque);
440:
441: return 0;
442: }
443:
444: void bdrv_close(BlockDriverState *bs)
445: {
1.1.1.5 root 446: if (bs->drv) {
1.1 root 447: if (bs->backing_hd)
448: bdrv_delete(bs->backing_hd);
449: bs->drv->bdrv_close(bs);
450: qemu_free(bs->opaque);
451: #ifdef _WIN32
452: if (bs->is_temporary) {
453: unlink(bs->filename);
454: }
455: #endif
456: bs->opaque = NULL;
457: bs->drv = NULL;
458:
459: /* call the change callback */
1.1.1.5 root 460: bs->media_changed = 1;
1.1 root 461: if (bs->change_cb)
462: bs->change_cb(bs->change_opaque);
463: }
464: }
465:
466: void bdrv_delete(BlockDriverState *bs)
467: {
1.1.1.7 root 468: BlockDriverState **pbs;
469:
470: pbs = &bdrv_first;
471: while (*pbs != bs && *pbs != NULL)
472: pbs = &(*pbs)->next;
473: if (*pbs == bs)
474: *pbs = bs->next;
475:
1.1 root 476: bdrv_close(bs);
477: qemu_free(bs);
478: }
479:
480: /* commit COW file into the raw image */
481: int bdrv_commit(BlockDriverState *bs)
482: {
1.1.1.5 root 483: BlockDriver *drv = bs->drv;
484: int64_t i, total_sectors;
1.1 root 485: int n, j;
486: unsigned char sector[512];
487:
1.1.1.5 root 488: if (!drv)
489: return -ENOMEDIUM;
1.1 root 490:
491: if (bs->read_only) {
492: return -EACCES;
493: }
494:
495: if (!bs->backing_hd) {
496: return -ENOTSUP;
497: }
498:
1.1.1.5 root 499: total_sectors = bdrv_getlength(bs) >> SECTOR_BITS;
500: for (i = 0; i < total_sectors;) {
501: if (drv->bdrv_is_allocated(bs, i, 65536, &n)) {
1.1 root 502: for(j = 0; j < n; j++) {
503: if (bdrv_read(bs, i, sector, 1) != 0) {
504: return -EIO;
505: }
506:
507: if (bdrv_write(bs->backing_hd, i, sector, 1) != 0) {
508: return -EIO;
509: }
510: i++;
511: }
512: } else {
513: i += n;
514: }
515: }
1.1.1.2 root 516:
1.1.1.5 root 517: if (drv->bdrv_make_empty)
518: return drv->bdrv_make_empty(bs);
1.1.1.2 root 519:
1.1 root 520: return 0;
521: }
522:
1.1.1.7 root 523: static int bdrv_check_byte_request(BlockDriverState *bs, int64_t offset,
524: size_t size)
525: {
526: int64_t len;
527:
528: if (!bdrv_is_inserted(bs))
529: return -ENOMEDIUM;
530:
531: if (bs->growable)
532: return 0;
533:
534: len = bdrv_getlength(bs);
535:
536: if ((offset + size) > len)
537: return -EIO;
538:
539: return 0;
540: }
541:
542: static int bdrv_check_request(BlockDriverState *bs, int64_t sector_num,
543: int nb_sectors)
544: {
545: int64_t offset;
546:
547: /* Deal with byte accesses */
548: if (sector_num < 0)
549: offset = -sector_num;
550: else
551: offset = sector_num * 512;
552:
553: return bdrv_check_byte_request(bs, offset, nb_sectors * 512);
554: }
555:
1.1.1.5 root 556: /* return < 0 if error. See bdrv_write() for the return codes */
1.1.1.6 root 557: int bdrv_read(BlockDriverState *bs, int64_t sector_num,
1.1 root 558: uint8_t *buf, int nb_sectors)
559: {
560: BlockDriver *drv = bs->drv;
561:
1.1.1.5 root 562: if (!drv)
563: return -ENOMEDIUM;
1.1.1.7 root 564: if (bdrv_check_request(bs, sector_num, nb_sectors))
565: return -EIO;
1.1 root 566:
1.1.1.5 root 567: if (drv->bdrv_pread) {
568: int ret, len;
569: len = nb_sectors * 512;
570: ret = drv->bdrv_pread(bs, sector_num * 512, buf, len);
571: if (ret < 0)
572: return ret;
573: else if (ret != len)
574: return -EINVAL;
1.1.1.6 root 575: else {
576: bs->rd_bytes += (unsigned) len;
577: bs->rd_ops ++;
1.1.1.5 root 578: return 0;
1.1.1.6 root 579: }
1.1.1.5 root 580: } else {
581: return drv->bdrv_read(bs, sector_num, buf, nb_sectors);
1.1 root 582: }
583: }
584:
1.1.1.6 root 585: /* Return < 0 if error. Important errors are:
1.1.1.5 root 586: -EIO generic I/O error (may happen for all errors)
587: -ENOMEDIUM No media inserted.
588: -EINVAL Invalid sector number or nb_sectors
589: -EACCES Trying to write a read-only device
590: */
1.1.1.6 root 591: int bdrv_write(BlockDriverState *bs, int64_t sector_num,
1.1 root 592: const uint8_t *buf, int nb_sectors)
593: {
1.1.1.5 root 594: BlockDriver *drv = bs->drv;
595: if (!bs->drv)
596: return -ENOMEDIUM;
1.1 root 597: if (bs->read_only)
1.1.1.5 root 598: return -EACCES;
1.1.1.7 root 599: if (bdrv_check_request(bs, sector_num, nb_sectors))
600: return -EIO;
601:
1.1.1.5 root 602: if (drv->bdrv_pwrite) {
1.1.1.7 root 603: int ret, len, count = 0;
1.1.1.5 root 604: len = nb_sectors * 512;
1.1.1.7 root 605: do {
606: ret = drv->bdrv_pwrite(bs, sector_num * 512, buf, len - count);
607: if (ret < 0) {
608: printf("bdrv_write ret=%d\n", ret);
609: return ret;
610: }
611: count += ret;
612: buf += ret;
613: } while (count != len);
614: bs->wr_bytes += (unsigned) len;
615: bs->wr_ops ++;
616: return 0;
1.1.1.5 root 617: }
1.1.1.7 root 618: return drv->bdrv_write(bs, sector_num, buf, nb_sectors);
1.1 root 619: }
620:
1.1.1.6 root 621: static int bdrv_pread_em(BlockDriverState *bs, int64_t offset,
1.1.1.5 root 622: uint8_t *buf, int count1)
623: {
624: uint8_t tmp_buf[SECTOR_SIZE];
625: int len, nb_sectors, count;
626: int64_t sector_num;
627:
628: count = count1;
629: /* first read to align to sector start */
630: len = (SECTOR_SIZE - offset) & (SECTOR_SIZE - 1);
631: if (len > count)
632: len = count;
633: sector_num = offset >> SECTOR_BITS;
634: if (len > 0) {
635: if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
636: return -EIO;
637: memcpy(buf, tmp_buf + (offset & (SECTOR_SIZE - 1)), len);
638: count -= len;
639: if (count == 0)
640: return count1;
641: sector_num++;
642: buf += len;
643: }
644:
645: /* read the sectors "in place" */
646: nb_sectors = count >> SECTOR_BITS;
647: if (nb_sectors > 0) {
648: if (bdrv_read(bs, sector_num, buf, nb_sectors) < 0)
649: return -EIO;
650: sector_num += nb_sectors;
651: len = nb_sectors << SECTOR_BITS;
652: buf += len;
653: count -= len;
654: }
655:
656: /* add data from the last sector */
657: if (count > 0) {
658: if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
659: return -EIO;
660: memcpy(buf, tmp_buf, count);
661: }
662: return count1;
663: }
664:
1.1.1.6 root 665: static int bdrv_pwrite_em(BlockDriverState *bs, int64_t offset,
1.1.1.5 root 666: const uint8_t *buf, int count1)
667: {
668: uint8_t tmp_buf[SECTOR_SIZE];
669: int len, nb_sectors, count;
670: int64_t sector_num;
671:
672: count = count1;
673: /* first write to align to sector start */
674: len = (SECTOR_SIZE - offset) & (SECTOR_SIZE - 1);
675: if (len > count)
676: len = count;
677: sector_num = offset >> SECTOR_BITS;
678: if (len > 0) {
679: if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
680: return -EIO;
681: memcpy(tmp_buf + (offset & (SECTOR_SIZE - 1)), buf, len);
682: if (bdrv_write(bs, sector_num, tmp_buf, 1) < 0)
683: return -EIO;
684: count -= len;
685: if (count == 0)
686: return count1;
687: sector_num++;
688: buf += len;
689: }
690:
691: /* write the sectors "in place" */
692: nb_sectors = count >> SECTOR_BITS;
693: if (nb_sectors > 0) {
694: if (bdrv_write(bs, sector_num, buf, nb_sectors) < 0)
695: return -EIO;
696: sector_num += nb_sectors;
697: len = nb_sectors << SECTOR_BITS;
698: buf += len;
699: count -= len;
700: }
701:
702: /* add data from the last sector */
703: if (count > 0) {
704: if (bdrv_read(bs, sector_num, tmp_buf, 1) < 0)
705: return -EIO;
706: memcpy(tmp_buf, buf, count);
707: if (bdrv_write(bs, sector_num, tmp_buf, 1) < 0)
708: return -EIO;
709: }
710: return count1;
711: }
712:
713: /**
1.1.1.6 root 714: * Read with byte offsets (needed only for file protocols)
1.1.1.5 root 715: */
1.1.1.6 root 716: int bdrv_pread(BlockDriverState *bs, int64_t offset,
1.1.1.5 root 717: void *buf1, int count1)
718: {
719: BlockDriver *drv = bs->drv;
720:
721: if (!drv)
722: return -ENOMEDIUM;
1.1.1.7 root 723: if (bdrv_check_byte_request(bs, offset, count1))
724: return -EIO;
725:
1.1.1.5 root 726: if (!drv->bdrv_pread)
727: return bdrv_pread_em(bs, offset, buf1, count1);
728: return drv->bdrv_pread(bs, offset, buf1, count1);
729: }
730:
1.1.1.6 root 731: /**
732: * Write with byte offsets (needed only for file protocols)
1.1.1.5 root 733: */
1.1.1.6 root 734: int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
1.1.1.5 root 735: const void *buf1, int count1)
736: {
737: BlockDriver *drv = bs->drv;
738:
739: if (!drv)
740: return -ENOMEDIUM;
1.1.1.7 root 741: if (bdrv_check_byte_request(bs, offset, count1))
742: return -EIO;
743:
1.1.1.5 root 744: if (!drv->bdrv_pwrite)
745: return bdrv_pwrite_em(bs, offset, buf1, count1);
746: return drv->bdrv_pwrite(bs, offset, buf1, count1);
747: }
748:
749: /**
750: * Truncate file to 'offset' bytes (needed only for file protocols)
751: */
752: int bdrv_truncate(BlockDriverState *bs, int64_t offset)
753: {
754: BlockDriver *drv = bs->drv;
755: if (!drv)
756: return -ENOMEDIUM;
757: if (!drv->bdrv_truncate)
758: return -ENOTSUP;
759: return drv->bdrv_truncate(bs, offset);
760: }
761:
762: /**
763: * Length of a file in bytes. Return < 0 if error or unknown.
764: */
765: int64_t bdrv_getlength(BlockDriverState *bs)
766: {
767: BlockDriver *drv = bs->drv;
768: if (!drv)
769: return -ENOMEDIUM;
770: if (!drv->bdrv_getlength) {
771: /* legacy mode */
772: return bs->total_sectors * SECTOR_SIZE;
773: }
774: return drv->bdrv_getlength(bs);
775: }
776:
777: /* return 0 as number of sectors if no device present or error */
1.1.1.6 root 778: void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr)
1.1 root 779: {
1.1.1.5 root 780: int64_t length;
781: length = bdrv_getlength(bs);
782: if (length < 0)
783: length = 0;
784: else
785: length = length >> SECTOR_BITS;
786: *nb_sectors_ptr = length;
1.1 root 787: }
788:
1.1.1.7 root 789: struct partition {
790: uint8_t boot_ind; /* 0x80 - active */
791: uint8_t head; /* starting head */
792: uint8_t sector; /* starting sector */
793: uint8_t cyl; /* starting cylinder */
794: uint8_t sys_ind; /* What partition type */
795: uint8_t end_head; /* end head */
796: uint8_t end_sector; /* end sector */
797: uint8_t end_cyl; /* end cylinder */
798: uint32_t start_sect; /* starting sector counting from 0 */
799: uint32_t nr_sects; /* nr of sectors in partition */
800: } __attribute__((packed));
801:
802: /* try to guess the disk logical geometry from the MSDOS partition table. Return 0 if OK, -1 if could not guess */
803: static int guess_disk_lchs(BlockDriverState *bs,
804: int *pcylinders, int *pheads, int *psectors)
805: {
806: uint8_t buf[512];
807: int ret, i, heads, sectors, cylinders;
808: struct partition *p;
809: uint32_t nr_sects;
810: uint64_t nb_sectors;
811:
812: bdrv_get_geometry(bs, &nb_sectors);
813:
814: ret = bdrv_read(bs, 0, buf, 1);
815: if (ret < 0)
816: return -1;
817: /* test msdos magic */
818: if (buf[510] != 0x55 || buf[511] != 0xaa)
819: return -1;
820: for(i = 0; i < 4; i++) {
821: p = ((struct partition *)(buf + 0x1be)) + i;
822: nr_sects = le32_to_cpu(p->nr_sects);
823: if (nr_sects && p->end_head) {
824: /* We make the assumption that the partition terminates on
825: a cylinder boundary */
826: heads = p->end_head + 1;
827: sectors = p->end_sector & 63;
828: if (sectors == 0)
829: continue;
830: cylinders = nb_sectors / (heads * sectors);
831: if (cylinders < 1 || cylinders > 16383)
832: continue;
833: *pheads = heads;
834: *psectors = sectors;
835: *pcylinders = cylinders;
836: #if 0
837: printf("guessed geometry: LCHS=%d %d %d\n",
838: cylinders, heads, sectors);
839: #endif
840: return 0;
841: }
842: }
843: return -1;
844: }
845:
846: void bdrv_guess_geometry(BlockDriverState *bs, int *pcyls, int *pheads, int *psecs)
1.1 root 847: {
1.1.1.7 root 848: int translation, lba_detected = 0;
849: int cylinders, heads, secs;
850: uint64_t nb_sectors;
851:
852: /* if a geometry hint is available, use it */
853: bdrv_get_geometry(bs, &nb_sectors);
854: bdrv_get_geometry_hint(bs, &cylinders, &heads, &secs);
855: translation = bdrv_get_translation_hint(bs);
856: if (cylinders != 0) {
857: *pcyls = cylinders;
858: *pheads = heads;
859: *psecs = secs;
860: } else {
861: if (guess_disk_lchs(bs, &cylinders, &heads, &secs) == 0) {
862: if (heads > 16) {
863: /* if heads > 16, it means that a BIOS LBA
864: translation was active, so the default
865: hardware geometry is OK */
866: lba_detected = 1;
867: goto default_geometry;
868: } else {
869: *pcyls = cylinders;
870: *pheads = heads;
871: *psecs = secs;
872: /* disable any translation to be in sync with
873: the logical geometry */
874: if (translation == BIOS_ATA_TRANSLATION_AUTO) {
875: bdrv_set_translation_hint(bs,
876: BIOS_ATA_TRANSLATION_NONE);
877: }
878: }
879: } else {
880: default_geometry:
881: /* if no geometry, use a standard physical disk geometry */
882: cylinders = nb_sectors / (16 * 63);
883:
884: if (cylinders > 16383)
885: cylinders = 16383;
886: else if (cylinders < 2)
887: cylinders = 2;
888: *pcyls = cylinders;
889: *pheads = 16;
890: *psecs = 63;
891: if ((lba_detected == 1) && (translation == BIOS_ATA_TRANSLATION_AUTO)) {
892: if ((*pcyls * *pheads) <= 131072) {
893: bdrv_set_translation_hint(bs,
894: BIOS_ATA_TRANSLATION_LARGE);
895: } else {
896: bdrv_set_translation_hint(bs,
897: BIOS_ATA_TRANSLATION_LBA);
898: }
899: }
900: }
901: bdrv_set_geometry_hint(bs, *pcyls, *pheads, *psecs);
902: }
1.1 root 903: }
904:
1.1.1.6 root 905: void bdrv_set_geometry_hint(BlockDriverState *bs,
1.1 root 906: int cyls, int heads, int secs)
907: {
908: bs->cyls = cyls;
909: bs->heads = heads;
910: bs->secs = secs;
911: }
912:
913: void bdrv_set_type_hint(BlockDriverState *bs, int type)
914: {
915: bs->type = type;
916: bs->removable = ((type == BDRV_TYPE_CDROM ||
917: type == BDRV_TYPE_FLOPPY));
918: }
919:
920: void bdrv_set_translation_hint(BlockDriverState *bs, int translation)
921: {
922: bs->translation = translation;
923: }
924:
1.1.1.6 root 925: void bdrv_get_geometry_hint(BlockDriverState *bs,
1.1 root 926: int *pcyls, int *pheads, int *psecs)
927: {
928: *pcyls = bs->cyls;
929: *pheads = bs->heads;
930: *psecs = bs->secs;
931: }
932:
933: int bdrv_get_type_hint(BlockDriverState *bs)
934: {
935: return bs->type;
936: }
937:
938: int bdrv_get_translation_hint(BlockDriverState *bs)
939: {
940: return bs->translation;
941: }
942:
943: int bdrv_is_removable(BlockDriverState *bs)
944: {
945: return bs->removable;
946: }
947:
948: int bdrv_is_read_only(BlockDriverState *bs)
949: {
950: return bs->read_only;
951: }
952:
1.1.1.6 root 953: int bdrv_is_sg(BlockDriverState *bs)
954: {
955: return bs->sg;
956: }
957:
1.1.1.5 root 958: /* XXX: no longer used */
1.1.1.6 root 959: void bdrv_set_change_cb(BlockDriverState *bs,
1.1 root 960: void (*change_cb)(void *opaque), void *opaque)
961: {
962: bs->change_cb = change_cb;
963: bs->change_opaque = opaque;
964: }
965:
966: int bdrv_is_encrypted(BlockDriverState *bs)
967: {
968: if (bs->backing_hd && bs->backing_hd->encrypted)
969: return 1;
970: return bs->encrypted;
971: }
972:
1.1.1.8 root 973: int bdrv_key_required(BlockDriverState *bs)
974: {
975: BlockDriverState *backing_hd = bs->backing_hd;
976:
977: if (backing_hd && backing_hd->encrypted && !backing_hd->valid_key)
978: return 1;
979: return (bs->encrypted && !bs->valid_key);
980: }
981:
1.1 root 982: int bdrv_set_key(BlockDriverState *bs, const char *key)
983: {
984: int ret;
985: if (bs->backing_hd && bs->backing_hd->encrypted) {
986: ret = bdrv_set_key(bs->backing_hd, key);
987: if (ret < 0)
988: return ret;
989: if (!bs->encrypted)
990: return 0;
991: }
992: if (!bs->encrypted || !bs->drv || !bs->drv->bdrv_set_key)
993: return -1;
1.1.1.8 root 994: ret = bs->drv->bdrv_set_key(bs, key);
995: bs->valid_key = (ret == 0);
996: return ret;
1.1 root 997: }
998:
999: void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size)
1000: {
1.1.1.5 root 1001: if (!bs->drv) {
1.1 root 1002: buf[0] = '\0';
1003: } else {
1004: pstrcpy(buf, buf_size, bs->drv->format_name);
1005: }
1006: }
1007:
1.1.1.6 root 1008: void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
1.1 root 1009: void *opaque)
1010: {
1011: BlockDriver *drv;
1012:
1013: for (drv = first_drv; drv != NULL; drv = drv->next) {
1014: it(opaque, drv->format_name);
1015: }
1016: }
1017:
1018: BlockDriverState *bdrv_find(const char *name)
1019: {
1020: BlockDriverState *bs;
1021:
1022: for (bs = bdrv_first; bs != NULL; bs = bs->next) {
1023: if (!strcmp(name, bs->device_name))
1024: return bs;
1025: }
1026: return NULL;
1027: }
1028:
1.1.1.8 root 1029: void bdrv_iterate(void (*it)(void *opaque, BlockDriverState *bs), void *opaque)
1.1 root 1030: {
1031: BlockDriverState *bs;
1032:
1033: for (bs = bdrv_first; bs != NULL; bs = bs->next) {
1.1.1.8 root 1034: it(opaque, bs);
1.1 root 1035: }
1036: }
1037:
1038: const char *bdrv_get_device_name(BlockDriverState *bs)
1039: {
1040: return bs->device_name;
1041: }
1042:
1.1.1.4 root 1043: void bdrv_flush(BlockDriverState *bs)
1044: {
1045: if (bs->drv->bdrv_flush)
1046: bs->drv->bdrv_flush(bs);
1047: if (bs->backing_hd)
1048: bdrv_flush(bs->backing_hd);
1049: }
1050:
1.1.1.7 root 1051: void bdrv_flush_all(void)
1052: {
1053: BlockDriverState *bs;
1054:
1055: for (bs = bdrv_first; bs != NULL; bs = bs->next)
1056: if (bs->drv && !bdrv_is_read_only(bs) &&
1057: (!bdrv_is_removable(bs) || bdrv_is_inserted(bs)))
1058: bdrv_flush(bs);
1059: }
1060:
1061: /*
1062: * Returns true iff the specified sector is present in the disk image. Drivers
1063: * not implementing the functionality are assumed to not support backing files,
1064: * hence all their sectors are reported as allocated.
1065: *
1066: * 'pnum' is set to the number of sectors (including and immediately following
1067: * the specified sector) that are known to be in the same
1068: * allocated/unallocated state.
1069: *
1070: * 'nb_sectors' is the max value 'pnum' should be set to.
1071: */
1072: int bdrv_is_allocated(BlockDriverState *bs, int64_t sector_num, int nb_sectors,
1073: int *pnum)
1074: {
1075: int64_t n;
1076: if (!bs->drv->bdrv_is_allocated) {
1077: if (sector_num >= bs->total_sectors) {
1078: *pnum = 0;
1079: return 0;
1080: }
1081: n = bs->total_sectors - sector_num;
1082: *pnum = (n < nb_sectors) ? (n) : (nb_sectors);
1083: return 1;
1084: }
1085: return bs->drv->bdrv_is_allocated(bs, sector_num, nb_sectors, pnum);
1086: }
1087:
1.1 root 1088: void bdrv_info(void)
1089: {
1090: BlockDriverState *bs;
1091:
1092: for (bs = bdrv_first; bs != NULL; bs = bs->next) {
1093: term_printf("%s:", bs->device_name);
1094: term_printf(" type=");
1095: switch(bs->type) {
1096: case BDRV_TYPE_HD:
1097: term_printf("hd");
1098: break;
1099: case BDRV_TYPE_CDROM:
1100: term_printf("cdrom");
1101: break;
1102: case BDRV_TYPE_FLOPPY:
1103: term_printf("floppy");
1104: break;
1105: }
1106: term_printf(" removable=%d", bs->removable);
1107: if (bs->removable) {
1108: term_printf(" locked=%d", bs->locked);
1109: }
1.1.1.5 root 1110: if (bs->drv) {
1111: term_printf(" file=");
1112: term_print_filename(bs->filename);
1113: if (bs->backing_file[0] != '\0') {
1114: term_printf(" backing_file=");
1115: term_print_filename(bs->backing_file);
1116: }
1.1 root 1117: term_printf(" ro=%d", bs->read_only);
1118: term_printf(" drv=%s", bs->drv->format_name);
1.1.1.8 root 1119: term_printf(" encrypted=%d", bdrv_is_encrypted(bs));
1.1 root 1120: } else {
1121: term_printf(" [not inserted]");
1122: }
1123: term_printf("\n");
1124: }
1125: }
1126:
1.1.1.6 root 1127: /* The "info blockstats" command. */
1128: void bdrv_info_stats (void)
1129: {
1130: BlockDriverState *bs;
1131:
1132: for (bs = bdrv_first; bs != NULL; bs = bs->next) {
1133: term_printf ("%s:"
1134: " rd_bytes=%" PRIu64
1135: " wr_bytes=%" PRIu64
1136: " rd_operations=%" PRIu64
1137: " wr_operations=%" PRIu64
1.1.1.8 root 1138: "\n",
1.1.1.6 root 1139: bs->device_name,
1140: bs->rd_bytes, bs->wr_bytes,
1141: bs->rd_ops, bs->wr_ops);
1142: }
1143: }
1144:
1.1.1.8 root 1145: const char *bdrv_get_encrypted_filename(BlockDriverState *bs)
1146: {
1147: if (bs->backing_hd && bs->backing_hd->encrypted)
1148: return bs->backing_file;
1149: else if (bs->encrypted)
1150: return bs->filename;
1151: else
1152: return NULL;
1153: }
1154:
1.1.1.6 root 1155: void bdrv_get_backing_filename(BlockDriverState *bs,
1.1.1.5 root 1156: char *filename, int filename_size)
1157: {
1158: if (!bs->backing_hd) {
1159: pstrcpy(filename, filename_size, "");
1160: } else {
1161: pstrcpy(filename, filename_size, bs->backing_file);
1162: }
1163: }
1164:
1.1.1.6 root 1165: int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,
1.1.1.5 root 1166: const uint8_t *buf, int nb_sectors)
1167: {
1168: BlockDriver *drv = bs->drv;
1169: if (!drv)
1170: return -ENOMEDIUM;
1171: if (!drv->bdrv_write_compressed)
1172: return -ENOTSUP;
1173: return drv->bdrv_write_compressed(bs, sector_num, buf, nb_sectors);
1174: }
1.1.1.6 root 1175:
1.1.1.5 root 1176: int bdrv_get_info(BlockDriverState *bs, BlockDriverInfo *bdi)
1177: {
1178: BlockDriver *drv = bs->drv;
1179: if (!drv)
1180: return -ENOMEDIUM;
1181: if (!drv->bdrv_get_info)
1182: return -ENOTSUP;
1183: memset(bdi, 0, sizeof(*bdi));
1184: return drv->bdrv_get_info(bs, bdi);
1185: }
1186:
1.1.1.9 root 1187: int bdrv_put_buffer(BlockDriverState *bs, const uint8_t *buf, int64_t pos, int size)
1188: {
1189: BlockDriver *drv = bs->drv;
1190: if (!drv)
1191: return -ENOMEDIUM;
1192: if (!drv->bdrv_put_buffer)
1193: return -ENOTSUP;
1194: return drv->bdrv_put_buffer(bs, buf, pos, size);
1195: }
1196:
1197: int bdrv_get_buffer(BlockDriverState *bs, uint8_t *buf, int64_t pos, int size)
1198: {
1199: BlockDriver *drv = bs->drv;
1200: if (!drv)
1201: return -ENOMEDIUM;
1202: if (!drv->bdrv_get_buffer)
1203: return -ENOTSUP;
1204: return drv->bdrv_get_buffer(bs, buf, pos, size);
1205: }
1206:
1.1 root 1207: /**************************************************************/
1.1.1.5 root 1208: /* handling of snapshots */
1.1 root 1209:
1.1.1.6 root 1210: int bdrv_snapshot_create(BlockDriverState *bs,
1.1.1.5 root 1211: QEMUSnapshotInfo *sn_info)
1212: {
1213: BlockDriver *drv = bs->drv;
1214: if (!drv)
1215: return -ENOMEDIUM;
1216: if (!drv->bdrv_snapshot_create)
1217: return -ENOTSUP;
1218: return drv->bdrv_snapshot_create(bs, sn_info);
1219: }
1.1 root 1220:
1.1.1.6 root 1221: int bdrv_snapshot_goto(BlockDriverState *bs,
1.1.1.5 root 1222: const char *snapshot_id)
1.1 root 1223: {
1.1.1.5 root 1224: BlockDriver *drv = bs->drv;
1225: if (!drv)
1226: return -ENOMEDIUM;
1227: if (!drv->bdrv_snapshot_goto)
1228: return -ENOTSUP;
1229: return drv->bdrv_snapshot_goto(bs, snapshot_id);
1.1 root 1230: }
1231:
1.1.1.5 root 1232: int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id)
1.1 root 1233: {
1.1.1.5 root 1234: BlockDriver *drv = bs->drv;
1235: if (!drv)
1236: return -ENOMEDIUM;
1237: if (!drv->bdrv_snapshot_delete)
1238: return -ENOTSUP;
1239: return drv->bdrv_snapshot_delete(bs, snapshot_id);
1240: }
1.1 root 1241:
1.1.1.6 root 1242: int bdrv_snapshot_list(BlockDriverState *bs,
1.1.1.5 root 1243: QEMUSnapshotInfo **psn_info)
1244: {
1245: BlockDriver *drv = bs->drv;
1246: if (!drv)
1247: return -ENOMEDIUM;
1248: if (!drv->bdrv_snapshot_list)
1249: return -ENOTSUP;
1250: return drv->bdrv_snapshot_list(bs, psn_info);
1251: }
1252:
1253: #define NB_SUFFIXES 4
1254:
1255: char *get_human_readable_size(char *buf, int buf_size, int64_t size)
1256: {
1257: static const char suffixes[NB_SUFFIXES] = "KMGT";
1258: int64_t base;
1259: int i;
1260:
1261: if (size <= 999) {
1262: snprintf(buf, buf_size, "%" PRId64, size);
1263: } else {
1264: base = 1024;
1265: for(i = 0; i < NB_SUFFIXES; i++) {
1266: if (size < (10 * base)) {
1.1.1.6 root 1267: snprintf(buf, buf_size, "%0.1f%c",
1.1.1.5 root 1268: (double)size / base,
1269: suffixes[i]);
1270: break;
1271: } else if (size < (1000 * base) || i == (NB_SUFFIXES - 1)) {
1.1.1.6 root 1272: snprintf(buf, buf_size, "%" PRId64 "%c",
1.1.1.5 root 1273: ((size + (base >> 1)) / base),
1274: suffixes[i]);
1275: break;
1276: }
1277: base = base * 1024;
1278: }
1.1 root 1279: }
1.1.1.5 root 1280: return buf;
1281: }
1282:
1283: char *bdrv_snapshot_dump(char *buf, int buf_size, QEMUSnapshotInfo *sn)
1284: {
1285: char buf1[128], date_buf[128], clock_buf[128];
1286: #ifdef _WIN32
1287: struct tm *ptm;
1.1.1.2 root 1288: #else
1.1.1.5 root 1289: struct tm tm;
1.1.1.2 root 1290: #endif
1.1.1.5 root 1291: time_t ti;
1292: int64_t secs;
1293:
1294: if (!sn) {
1.1.1.6 root 1295: snprintf(buf, buf_size,
1296: "%-10s%-20s%7s%20s%15s",
1.1.1.5 root 1297: "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK");
1298: } else {
1299: ti = sn->date_sec;
1.1 root 1300: #ifdef _WIN32
1.1.1.5 root 1301: ptm = localtime(&ti);
1302: strftime(date_buf, sizeof(date_buf),
1303: "%Y-%m-%d %H:%M:%S", ptm);
1304: #else
1305: localtime_r(&ti, &tm);
1306: strftime(date_buf, sizeof(date_buf),
1307: "%Y-%m-%d %H:%M:%S", &tm);
1.1 root 1308: #endif
1.1.1.5 root 1309: secs = sn->vm_clock_nsec / 1000000000;
1310: snprintf(clock_buf, sizeof(clock_buf),
1311: "%02d:%02d:%02d.%03d",
1312: (int)(secs / 3600),
1313: (int)((secs / 60) % 60),
1.1.1.6 root 1314: (int)(secs % 60),
1.1.1.5 root 1315: (int)((sn->vm_clock_nsec / 1000000) % 1000));
1316: snprintf(buf, buf_size,
1.1.1.6 root 1317: "%-10s%-20s%7s%20s%15s",
1.1.1.5 root 1318: sn->id_str, sn->name,
1319: get_human_readable_size(buf1, sizeof(buf1), sn->vm_state_size),
1320: date_buf,
1321: clock_buf);
1322: }
1323: return buf;
1.1 root 1324: }
1325:
1326:
1.1.1.5 root 1327: /**************************************************************/
1328: /* async I/Os */
1329:
1.1.1.7 root 1330: typedef struct VectorTranslationState {
1331: QEMUIOVector *iov;
1332: uint8_t *bounce;
1333: int is_write;
1334: BlockDriverAIOCB *aiocb;
1335: BlockDriverAIOCB *this_aiocb;
1336: } VectorTranslationState;
1337:
1.1.1.10! root 1338: static void bdrv_aio_cancel_vector(BlockDriverAIOCB *acb)
! 1339: {
! 1340: VectorTranslationState *s = acb->opaque;
! 1341:
! 1342: bdrv_aio_cancel(s->aiocb);
! 1343: }
! 1344:
1.1.1.7 root 1345: static void bdrv_aio_rw_vector_cb(void *opaque, int ret)
1346: {
1347: VectorTranslationState *s = opaque;
1348:
1349: if (!s->is_write) {
1350: qemu_iovec_from_buffer(s->iov, s->bounce, s->iov->size);
1351: }
1352: qemu_vfree(s->bounce);
1353: s->this_aiocb->cb(s->this_aiocb->opaque, ret);
1354: qemu_aio_release(s->this_aiocb);
1355: }
1356:
1357: static BlockDriverAIOCB *bdrv_aio_rw_vector(BlockDriverState *bs,
1358: int64_t sector_num,
1359: QEMUIOVector *iov,
1360: int nb_sectors,
1361: BlockDriverCompletionFunc *cb,
1362: void *opaque,
1363: int is_write)
1364:
1365: {
1366: VectorTranslationState *s = qemu_mallocz(sizeof(*s));
1.1.1.10! root 1367: BlockDriverAIOCB *aiocb = qemu_aio_get_pool(&vectored_aio_pool, bs,
! 1368: cb, opaque);
1.1.1.7 root 1369:
1370: s->this_aiocb = aiocb;
1371: s->iov = iov;
1372: s->bounce = qemu_memalign(512, nb_sectors * 512);
1373: s->is_write = is_write;
1374: if (is_write) {
1375: qemu_iovec_to_buffer(s->iov, s->bounce);
1376: s->aiocb = bdrv_aio_write(bs, sector_num, s->bounce, nb_sectors,
1377: bdrv_aio_rw_vector_cb, s);
1378: } else {
1379: s->aiocb = bdrv_aio_read(bs, sector_num, s->bounce, nb_sectors,
1380: bdrv_aio_rw_vector_cb, s);
1381: }
1382: return aiocb;
1383: }
1384:
1385: BlockDriverAIOCB *bdrv_aio_readv(BlockDriverState *bs, int64_t sector_num,
1386: QEMUIOVector *iov, int nb_sectors,
1387: BlockDriverCompletionFunc *cb, void *opaque)
1388: {
1389: if (bdrv_check_request(bs, sector_num, nb_sectors))
1390: return NULL;
1391:
1392: return bdrv_aio_rw_vector(bs, sector_num, iov, nb_sectors,
1393: cb, opaque, 0);
1394: }
1395:
1396: BlockDriverAIOCB *bdrv_aio_writev(BlockDriverState *bs, int64_t sector_num,
1397: QEMUIOVector *iov, int nb_sectors,
1398: BlockDriverCompletionFunc *cb, void *opaque)
1399: {
1400: if (bdrv_check_request(bs, sector_num, nb_sectors))
1401: return NULL;
1402:
1403: return bdrv_aio_rw_vector(bs, sector_num, iov, nb_sectors,
1404: cb, opaque, 1);
1405: }
1406:
1.1.1.5 root 1407: BlockDriverAIOCB *bdrv_aio_read(BlockDriverState *bs, int64_t sector_num,
1408: uint8_t *buf, int nb_sectors,
1409: BlockDriverCompletionFunc *cb, void *opaque)
1.1 root 1410: {
1.1.1.5 root 1411: BlockDriver *drv = bs->drv;
1.1.1.6 root 1412: BlockDriverAIOCB *ret;
1.1.1.5 root 1413:
1414: if (!drv)
1415: return NULL;
1.1.1.7 root 1416: if (bdrv_check_request(bs, sector_num, nb_sectors))
1417: return NULL;
1.1.1.5 root 1418:
1.1.1.6 root 1419: ret = drv->bdrv_aio_read(bs, sector_num, buf, nb_sectors, cb, opaque);
1420:
1421: if (ret) {
1422: /* Update stats even though technically transfer has not happened. */
1423: bs->rd_bytes += (unsigned) nb_sectors * SECTOR_SIZE;
1424: bs->rd_ops ++;
1425: }
1426:
1427: return ret;
1.1 root 1428: }
1429:
1.1.1.5 root 1430: BlockDriverAIOCB *bdrv_aio_write(BlockDriverState *bs, int64_t sector_num,
1431: const uint8_t *buf, int nb_sectors,
1432: BlockDriverCompletionFunc *cb, void *opaque)
1.1 root 1433: {
1.1.1.5 root 1434: BlockDriver *drv = bs->drv;
1.1.1.6 root 1435: BlockDriverAIOCB *ret;
1.1 root 1436:
1.1.1.5 root 1437: if (!drv)
1438: return NULL;
1439: if (bs->read_only)
1440: return NULL;
1.1.1.7 root 1441: if (bdrv_check_request(bs, sector_num, nb_sectors))
1442: return NULL;
1.1.1.4 root 1443:
1.1.1.6 root 1444: ret = drv->bdrv_aio_write(bs, sector_num, buf, nb_sectors, cb, opaque);
1445:
1446: if (ret) {
1447: /* Update stats even though technically transfer has not happened. */
1448: bs->wr_bytes += (unsigned) nb_sectors * SECTOR_SIZE;
1449: bs->wr_ops ++;
1450: }
1451:
1452: return ret;
1.1.1.5 root 1453: }
1454:
1455: void bdrv_aio_cancel(BlockDriverAIOCB *acb)
1.1.1.4 root 1456: {
1.1.1.10! root 1457: acb->pool->cancel(acb);
1.1.1.5 root 1458: }
1.1.1.4 root 1459:
1460:
1.1.1.5 root 1461: /**************************************************************/
1462: /* async block device emulation */
1.1.1.4 root 1463:
1.1.1.5 root 1464: static void bdrv_aio_bh_cb(void *opaque)
1.1.1.4 root 1465: {
1.1.1.5 root 1466: BlockDriverAIOCBSync *acb = opaque;
1467: acb->common.cb(acb->common.opaque, acb->ret);
1468: qemu_aio_release(acb);
1.1.1.4 root 1469: }
1470:
1.1.1.5 root 1471: static BlockDriverAIOCB *bdrv_aio_read_em(BlockDriverState *bs,
1472: int64_t sector_num, uint8_t *buf, int nb_sectors,
1473: BlockDriverCompletionFunc *cb, void *opaque)
1.1 root 1474: {
1.1.1.5 root 1475: BlockDriverAIOCBSync *acb;
1476: int ret;
1.1 root 1477:
1.1.1.5 root 1478: acb = qemu_aio_get(bs, cb, opaque);
1479: if (!acb->bh)
1480: acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
1481: ret = bdrv_read(bs, sector_num, buf, nb_sectors);
1482: acb->ret = ret;
1483: qemu_bh_schedule(acb->bh);
1484: return &acb->common;
1485: }
1.1 root 1486:
1.1.1.5 root 1487: static BlockDriverAIOCB *bdrv_aio_write_em(BlockDriverState *bs,
1488: int64_t sector_num, const uint8_t *buf, int nb_sectors,
1489: BlockDriverCompletionFunc *cb, void *opaque)
1490: {
1491: BlockDriverAIOCBSync *acb;
1492: int ret;
1493:
1494: acb = qemu_aio_get(bs, cb, opaque);
1495: if (!acb->bh)
1496: acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb);
1497: ret = bdrv_write(bs, sector_num, buf, nb_sectors);
1498: acb->ret = ret;
1499: qemu_bh_schedule(acb->bh);
1500: return &acb->common;
1501: }
1502:
1503: static void bdrv_aio_cancel_em(BlockDriverAIOCB *blockacb)
1504: {
1505: BlockDriverAIOCBSync *acb = (BlockDriverAIOCBSync *)blockacb;
1506: qemu_bh_cancel(acb->bh);
1507: qemu_aio_release(acb);
1.1 root 1508: }
1509:
1.1.1.5 root 1510: /**************************************************************/
1511: /* sync block device emulation */
1512:
1513: static void bdrv_rw_em_cb(void *opaque, int ret)
1.1.1.4 root 1514: {
1.1.1.5 root 1515: *(int *)opaque = ret;
1.1.1.4 root 1516: }
1517:
1.1.1.5 root 1518: #define NOT_DONE 0x7fffffff
1519:
1.1.1.6 root 1520: static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
1.1.1.5 root 1521: uint8_t *buf, int nb_sectors)
1522: {
1523: int async_ret;
1524: BlockDriverAIOCB *acb;
1525:
1526: async_ret = NOT_DONE;
1.1.1.6 root 1527: acb = bdrv_aio_read(bs, sector_num, buf, nb_sectors,
1.1.1.5 root 1528: bdrv_rw_em_cb, &async_ret);
1.1.1.7 root 1529: if (acb == NULL)
1.1.1.5 root 1530: return -1;
1.1.1.7 root 1531:
1.1.1.5 root 1532: while (async_ret == NOT_DONE) {
1533: qemu_aio_wait();
1534: }
1.1.1.7 root 1535:
1.1.1.5 root 1536: return async_ret;
1537: }
1538:
1539: static int bdrv_write_em(BlockDriverState *bs, int64_t sector_num,
1540: const uint8_t *buf, int nb_sectors)
1541: {
1542: int async_ret;
1543: BlockDriverAIOCB *acb;
1544:
1545: async_ret = NOT_DONE;
1.1.1.6 root 1546: acb = bdrv_aio_write(bs, sector_num, buf, nb_sectors,
1.1.1.5 root 1547: bdrv_rw_em_cb, &async_ret);
1.1.1.7 root 1548: if (acb == NULL)
1.1.1.5 root 1549: return -1;
1550: while (async_ret == NOT_DONE) {
1551: qemu_aio_wait();
1552: }
1553: return async_ret;
1554: }
1.1 root 1555:
1556: void bdrv_init(void)
1557: {
1.1.1.10! root 1558: aio_pool_init(&vectored_aio_pool, sizeof(BlockDriverAIOCB),
! 1559: bdrv_aio_cancel_vector);
! 1560:
1.1 root 1561: bdrv_register(&bdrv_raw);
1.1.1.5 root 1562: bdrv_register(&bdrv_host_device);
1.1 root 1563: #ifndef _WIN32
1564: bdrv_register(&bdrv_cow);
1565: #endif
1566: bdrv_register(&bdrv_qcow);
1567: bdrv_register(&bdrv_vmdk);
1568: bdrv_register(&bdrv_cloop);
1569: bdrv_register(&bdrv_dmg);
1570: bdrv_register(&bdrv_bochs);
1571: bdrv_register(&bdrv_vpc);
1572: bdrv_register(&bdrv_vvfat);
1.1.1.5 root 1573: bdrv_register(&bdrv_qcow2);
1.1.1.6 root 1574: bdrv_register(&bdrv_parallels);
1.1.1.7 root 1575: bdrv_register(&bdrv_nbd);
1.1.1.5 root 1576: }
1577:
1.1.1.10! root 1578: void aio_pool_init(AIOPool *pool, int aiocb_size,
! 1579: void (*cancel)(BlockDriverAIOCB *acb))
! 1580: {
! 1581: pool->aiocb_size = aiocb_size;
! 1582: pool->cancel = cancel;
! 1583: pool->free_aiocb = NULL;
! 1584: }
! 1585:
! 1586: void *qemu_aio_get_pool(AIOPool *pool, BlockDriverState *bs,
! 1587: BlockDriverCompletionFunc *cb, void *opaque)
1.1.1.5 root 1588: {
1589: BlockDriverAIOCB *acb;
1590:
1.1.1.10! root 1591: if (pool->free_aiocb) {
! 1592: acb = pool->free_aiocb;
! 1593: pool->free_aiocb = acb->next;
1.1.1.5 root 1594: } else {
1.1.1.10! root 1595: acb = qemu_mallocz(pool->aiocb_size);
! 1596: acb->pool = pool;
1.1.1.5 root 1597: }
1598: acb->bs = bs;
1599: acb->cb = cb;
1600: acb->opaque = opaque;
1601: return acb;
1602: }
1603:
1.1.1.10! root 1604: void *qemu_aio_get(BlockDriverState *bs, BlockDriverCompletionFunc *cb,
! 1605: void *opaque)
! 1606: {
! 1607: return qemu_aio_get_pool(&bs->drv->aio_pool, bs, cb, opaque);
! 1608: }
! 1609:
1.1.1.5 root 1610: void qemu_aio_release(void *p)
1611: {
1.1.1.10! root 1612: BlockDriverAIOCB *acb = (BlockDriverAIOCB *)p;
! 1613: AIOPool *pool = acb->pool;
! 1614: acb->next = pool->free_aiocb;
! 1615: pool->free_aiocb = acb;
1.1.1.5 root 1616: }
1617:
1618: /**************************************************************/
1619: /* removable device support */
1620:
1621: /**
1622: * Return TRUE if the media is present
1623: */
1624: int bdrv_is_inserted(BlockDriverState *bs)
1625: {
1626: BlockDriver *drv = bs->drv;
1627: int ret;
1628: if (!drv)
1629: return 0;
1630: if (!drv->bdrv_is_inserted)
1631: return 1;
1632: ret = drv->bdrv_is_inserted(bs);
1633: return ret;
1634: }
1635:
1636: /**
1637: * Return TRUE if the media changed since the last call to this
1.1.1.6 root 1638: * function. It is currently only used for floppy disks
1.1.1.5 root 1639: */
1640: int bdrv_media_changed(BlockDriverState *bs)
1641: {
1642: BlockDriver *drv = bs->drv;
1643: int ret;
1644:
1645: if (!drv || !drv->bdrv_media_changed)
1646: ret = -ENOTSUP;
1647: else
1648: ret = drv->bdrv_media_changed(bs);
1649: if (ret == -ENOTSUP)
1650: ret = bs->media_changed;
1651: bs->media_changed = 0;
1652: return ret;
1653: }
1654:
1655: /**
1656: * If eject_flag is TRUE, eject the media. Otherwise, close the tray
1657: */
1658: void bdrv_eject(BlockDriverState *bs, int eject_flag)
1659: {
1660: BlockDriver *drv = bs->drv;
1661: int ret;
1662:
1663: if (!drv || !drv->bdrv_eject) {
1664: ret = -ENOTSUP;
1665: } else {
1666: ret = drv->bdrv_eject(bs, eject_flag);
1667: }
1668: if (ret == -ENOTSUP) {
1669: if (eject_flag)
1670: bdrv_close(bs);
1671: }
1672: }
1673:
1674: int bdrv_is_locked(BlockDriverState *bs)
1675: {
1676: return bs->locked;
1677: }
1678:
1679: /**
1680: * Lock or unlock the media (if it is locked, the user won't be able
1681: * to eject it manually).
1682: */
1683: void bdrv_set_locked(BlockDriverState *bs, int locked)
1684: {
1685: BlockDriver *drv = bs->drv;
1686:
1687: bs->locked = locked;
1688: if (drv && drv->bdrv_set_locked) {
1689: drv->bdrv_set_locked(bs, locked);
1690: }
1.1 root 1691: }
1.1.1.6 root 1692:
1693: /* needed for generic scsi interface */
1694:
1695: int bdrv_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
1696: {
1697: BlockDriver *drv = bs->drv;
1698:
1699: if (drv && drv->bdrv_ioctl)
1700: return drv->bdrv_ioctl(bs, req, buf);
1701: return -ENOTSUP;
1702: }
unix.superglobalmegacorp.com