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