File:  [Qemu by Fabrice Bellard] / qemu / block.c
Revision 1.1.1.10 (vendor branch): download - view: text, annotated - select for diffs
Tue Apr 24 17:06:50 2018 UTC (19 months, 2 weeks ago) by root
Branches: qemu, MAIN
CVS tags: qemu0103, HEAD
qemu 0.10.3

    1: /*
    2:  * QEMU System Emulator block driver
    3:  *
    4:  * Copyright (c) 2003 Fabrice Bellard
    5:  *
    6:  * Permission is hereby granted, free of charge, to any person obtaining a copy
    7:  * of this software and associated documentation files (the "Software"), to deal
    8:  * in the Software without restriction, including without limitation the rights
    9:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   10:  * copies of the Software, and to permit persons to whom the Software is
   11:  * furnished to do so, subject to the following conditions:
   12:  *
   13:  * The above copyright notice and this permission notice shall be included in
   14:  * all copies or substantial portions of the Software.
   15:  *
   16:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   17:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   18:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   19:  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   20:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   21:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   22:  * THE SOFTWARE.
   23:  */
   24: #include "config-host.h"
   25: #ifdef _BSD
   26: /* include native header before sys-queue.h */
   27: #include <sys/queue.h>
   28: #endif
   29: 
   30: #include "qemu-common.h"
   31: #include "console.h"
   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: 
   41: #define SECTOR_BITS 9
   42: #define SECTOR_SIZE (1 << SECTOR_BITS)
   43: 
   44: static AIOPool vectored_aio_pool;
   45: 
   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);
   59: static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
   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);
   63: 
   64: BlockDriverState *bdrv_first;
   65: 
   66: static BlockDriver *first_drv;
   67: 
   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
   86: }
   87: 
   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;
  115:         }
  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);
  129:     }
  130: }
  131: 
  132: 
  133: static void bdrv_register(BlockDriver *bdrv)
  134: {
  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:     }
  146:     aio_pool_init(&bdrv->aio_pool, bdrv->aiocb_size, bdrv->bdrv_aio_cancel);
  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: 
  178: int bdrv_create(BlockDriver *drv,
  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
  188: void get_tmp_filename(char *filename, int size)
  189: {
  190:     char temp_dir[MAX_PATH];
  191: 
  192:     GetTempPath(MAX_PATH, temp_dir);
  193:     GetTempFileName(temp_dir, "qem", 0, filename);
  194: }
  195: #else
  196: void get_tmp_filename(char *filename, int size)
  197: {
  198:     int fd;
  199:     const char *tmpdir;
  200:     /* XXX: race condition possible */
  201:     tmpdir = getenv("TMPDIR");
  202:     if (!tmpdir)
  203:         tmpdir = "/tmp";
  204:     snprintf(filename, size, "%s/vl.XXXXXX", tmpdir);
  205:     fd = mkstemp(filename);
  206:     close(fd);
  207: }
  208: #endif
  209: 
  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: }
  217: 
  218: static int is_windows_drive(const char *filename)
  219: {
  220:     if (is_windows_drive_prefix(filename) &&
  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) {
  251:         if (drv1->protocol_name &&
  252:             !strcmp(drv1->protocol_name, protocol))
  253:             return drv1;
  254:     }
  255:     return NULL;
  256: }
  257: 
  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: {
  262:     int ret, score, score_max;
  263:     BlockDriver *drv1, *drv;
  264:     uint8_t buf[2048];
  265:     BlockDriverState *bs;
  266: 
  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;
  277:         if (stat(filename, &st) >= 0 &&
  278:             (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode))) {
  279:             return &bdrv_host_device;
  280:         }
  281:     }
  282: #endif
  283: 
  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: 
  298:     score_max = 0;
  299:     for(drv1 = first_drv; drv1 != NULL; drv1 = drv1->next) {
  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:             }
  306:         }
  307:     }
  308:     return drv;
  309: }
  310: 
  311: int bdrv_file_open(BlockDriverState **pbs, const char *filename, int flags)
  312: {
  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;
  321:     }
  322:     bs->growable = 1;
  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);
  330: }
  331: 
  332: int bdrv_open2(BlockDriverState *bs, const char *filename, int flags,
  333:                BlockDriver *drv)
  334: {
  335:     int ret, open_flags;
  336:     char tmp_filename[PATH_MAX];
  337:     char backing_filename[PATH_MAX];
  338: 
  339:     bs->read_only = 0;
  340:     bs->is_temporary = 0;
  341:     bs->encrypted = 0;
  342:     bs->valid_key = 0;
  343: 
  344:     if (flags & BDRV_O_SNAPSHOT) {
  345:         BlockDriverState *bs1;
  346:         int64_t total_size;
  347:         int is_protocol = 0;
  348: 
  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("");
  354:         ret = bdrv_open(bs1, filename, 0);
  355:         if (ret < 0) {
  356:             bdrv_delete(bs1);
  357:             return ret;
  358:         }
  359:         total_size = bdrv_getlength(bs1) >> SECTOR_BITS;
  360: 
  361:         if (bs1->drv && bs1->drv->protocol_name)
  362:             is_protocol = 1;
  363: 
  364:         bdrv_delete(bs1);
  365: 
  366:         get_tmp_filename(tmp_filename, sizeof(tmp_filename));
  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: 
  375:         ret = bdrv_create(&bdrv_qcow2, tmp_filename,
  376:                           total_size, backing_filename, 0);
  377:         if (ret < 0) {
  378:             return ret;
  379:         }
  380:         filename = tmp_filename;
  381:         bs->is_temporary = 1;
  382:     }
  383: 
  384:     pstrcpy(bs->filename, sizeof(bs->filename), filename);
  385:     if (flags & BDRV_O_FILE) {
  386:         drv = find_protocol(filename);
  387:     } else if (!drv) {
  388:         drv = find_image_format(filename);
  389:     }
  390:     if (!drv) {
  391:         ret = -ENOENT;
  392:         goto unlink_and_fail;
  393:     }
  394:     bs->drv = drv;
  395:     bs->opaque = qemu_mallocz(drv->instance_size);
  396:     /* Note: for compatibility, we open disk image files as RDWR, and
  397:        RDONLY as fallback */
  398:     if (!(flags & BDRV_O_FILE))
  399:         open_flags = BDRV_O_RDWR | (flags & BDRV_O_CACHE_MASK);
  400:     else
  401:         open_flags = flags & ~(BDRV_O_FILE | BDRV_O_SNAPSHOT);
  402:     ret = drv->bdrv_open(bs, filename, open_flags);
  403:     if ((ret == -EACCES || ret == -EPERM) && !(flags & BDRV_O_FILE)) {
  404:         ret = drv->bdrv_open(bs, filename, open_flags & ~BDRV_O_RDWR);
  405:         bs->read_only = 1;
  406:     }
  407:     if (ret < 0) {
  408:         qemu_free(bs->opaque);
  409:         bs->opaque = NULL;
  410:         bs->drv = NULL;
  411:     unlink_and_fail:
  412:         if (bs->is_temporary)
  413:             unlink(filename);
  414:         return ret;
  415:     }
  416:     if (drv->bdrv_getlength) {
  417:         bs->total_sectors = bdrv_getlength(bs) >> SECTOR_BITS;
  418:     }
  419: #ifndef _WIN32
  420:     if (bs->is_temporary) {
  421:         unlink(filename);
  422:     }
  423: #endif
  424:     if (bs->backing_file[0] != '\0') {
  425:         /* if there is a backing file, use it */
  426:         bs->backing_hd = bdrv_new("");
  427:         path_combine(backing_filename, sizeof(backing_filename),
  428:                      filename, bs->backing_file);
  429:         ret = bdrv_open(bs->backing_hd, backing_filename, open_flags);
  430:         if (ret < 0) {
  431:             bdrv_close(bs);
  432:             return ret;
  433:         }
  434:     }
  435: 
  436:     /* call the change callback */
  437:     bs->media_changed = 1;
  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: {
  446:     if (bs->drv) {
  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 */
  460:         bs->media_changed = 1;
  461:         if (bs->change_cb)
  462:             bs->change_cb(bs->change_opaque);
  463:     }
  464: }
  465: 
  466: void bdrv_delete(BlockDriverState *bs)
  467: {
  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: 
  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: {
  483:     BlockDriver *drv = bs->drv;
  484:     int64_t i, total_sectors;
  485:     int n, j;
  486:     unsigned char sector[512];
  487: 
  488:     if (!drv)
  489:         return -ENOMEDIUM;
  490: 
  491:     if (bs->read_only) {
  492: 	return -EACCES;
  493:     }
  494: 
  495:     if (!bs->backing_hd) {
  496: 	return -ENOTSUP;
  497:     }
  498: 
  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)) {
  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:     }
  516: 
  517:     if (drv->bdrv_make_empty)
  518: 	return drv->bdrv_make_empty(bs);
  519: 
  520:     return 0;
  521: }
  522: 
  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: 
  556: /* return < 0 if error. See bdrv_write() for the return codes */
  557: int bdrv_read(BlockDriverState *bs, int64_t sector_num,
  558:               uint8_t *buf, int nb_sectors)
  559: {
  560:     BlockDriver *drv = bs->drv;
  561: 
  562:     if (!drv)
  563:         return -ENOMEDIUM;
  564:     if (bdrv_check_request(bs, sector_num, nb_sectors))
  565:         return -EIO;
  566: 
  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;
  575:         else {
  576: 	    bs->rd_bytes += (unsigned) len;
  577: 	    bs->rd_ops ++;
  578:             return 0;
  579: 	}
  580:     } else {
  581:         return drv->bdrv_read(bs, sector_num, buf, nb_sectors);
  582:     }
  583: }
  584: 
  585: /* Return < 0 if error. Important errors are:
  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: */
  591: int bdrv_write(BlockDriverState *bs, int64_t sector_num,
  592:                const uint8_t *buf, int nb_sectors)
  593: {
  594:     BlockDriver *drv = bs->drv;
  595:     if (!bs->drv)
  596:         return -ENOMEDIUM;
  597:     if (bs->read_only)
  598:         return -EACCES;
  599:     if (bdrv_check_request(bs, sector_num, nb_sectors))
  600:         return -EIO;
  601: 
  602:     if (drv->bdrv_pwrite) {
  603:         int ret, len, count = 0;
  604:         len = nb_sectors * 512;
  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;
  617:     }
  618:     return drv->bdrv_write(bs, sector_num, buf, nb_sectors);
  619: }
  620: 
  621: static int bdrv_pread_em(BlockDriverState *bs, int64_t offset,
  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: 
  665: static int bdrv_pwrite_em(BlockDriverState *bs, int64_t offset,
  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: /**
  714:  * Read with byte offsets (needed only for file protocols)
  715:  */
  716: int bdrv_pread(BlockDriverState *bs, int64_t offset,
  717:                void *buf1, int count1)
  718: {
  719:     BlockDriver *drv = bs->drv;
  720: 
  721:     if (!drv)
  722:         return -ENOMEDIUM;
  723:     if (bdrv_check_byte_request(bs, offset, count1))
  724:         return -EIO;
  725: 
  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: 
  731: /**
  732:  * Write with byte offsets (needed only for file protocols)
  733:  */
  734: int bdrv_pwrite(BlockDriverState *bs, int64_t offset,
  735:                 const void *buf1, int count1)
  736: {
  737:     BlockDriver *drv = bs->drv;
  738: 
  739:     if (!drv)
  740:         return -ENOMEDIUM;
  741:     if (bdrv_check_byte_request(bs, offset, count1))
  742:         return -EIO;
  743: 
  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 */
  778: void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr)
  779: {
  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;
  787: }
  788: 
  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)
  847: {
  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:     }
  903: }
  904: 
  905: void bdrv_set_geometry_hint(BlockDriverState *bs,
  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: 
  925: void bdrv_get_geometry_hint(BlockDriverState *bs,
  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: 
  953: int bdrv_is_sg(BlockDriverState *bs)
  954: {
  955:     return bs->sg;
  956: }
  957: 
  958: /* XXX: no longer used */
  959: void bdrv_set_change_cb(BlockDriverState *bs,
  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: 
  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: 
  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;
  994:     ret = bs->drv->bdrv_set_key(bs, key);
  995:     bs->valid_key = (ret == 0);
  996:     return ret;
  997: }
  998: 
  999: void bdrv_get_format(BlockDriverState *bs, char *buf, int buf_size)
 1000: {
 1001:     if (!bs->drv) {
 1002:         buf[0] = '\0';
 1003:     } else {
 1004:         pstrcpy(buf, buf_size, bs->drv->format_name);
 1005:     }
 1006: }
 1007: 
 1008: void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
 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: 
 1029: void bdrv_iterate(void (*it)(void *opaque, BlockDriverState *bs), void *opaque)
 1030: {
 1031:     BlockDriverState *bs;
 1032: 
 1033:     for (bs = bdrv_first; bs != NULL; bs = bs->next) {
 1034:         it(opaque, bs);
 1035:     }
 1036: }
 1037: 
 1038: const char *bdrv_get_device_name(BlockDriverState *bs)
 1039: {
 1040:     return bs->device_name;
 1041: }
 1042: 
 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: 
 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: 
 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:         }
 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: 	    }
 1117:             term_printf(" ro=%d", bs->read_only);
 1118:             term_printf(" drv=%s", bs->drv->format_name);
 1119:             term_printf(" encrypted=%d", bdrv_is_encrypted(bs));
 1120:         } else {
 1121:             term_printf(" [not inserted]");
 1122:         }
 1123:         term_printf("\n");
 1124:     }
 1125: }
 1126: 
 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
 1138:                      "\n",
 1139: 		     bs->device_name,
 1140: 		     bs->rd_bytes, bs->wr_bytes,
 1141: 		     bs->rd_ops, bs->wr_ops);
 1142:     }
 1143: }
 1144: 
 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: 
 1155: void bdrv_get_backing_filename(BlockDriverState *bs,
 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: 
 1165: int bdrv_write_compressed(BlockDriverState *bs, int64_t sector_num,
 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: }
 1175: 
 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: 
 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: 
 1207: /**************************************************************/
 1208: /* handling of snapshots */
 1209: 
 1210: int bdrv_snapshot_create(BlockDriverState *bs,
 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: }
 1220: 
 1221: int bdrv_snapshot_goto(BlockDriverState *bs,
 1222:                        const char *snapshot_id)
 1223: {
 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);
 1230: }
 1231: 
 1232: int bdrv_snapshot_delete(BlockDriverState *bs, const char *snapshot_id)
 1233: {
 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: }
 1241: 
 1242: int bdrv_snapshot_list(BlockDriverState *bs,
 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)) {
 1267:                 snprintf(buf, buf_size, "%0.1f%c",
 1268:                          (double)size / base,
 1269:                          suffixes[i]);
 1270:                 break;
 1271:             } else if (size < (1000 * base) || i == (NB_SUFFIXES - 1)) {
 1272:                 snprintf(buf, buf_size, "%" PRId64 "%c",
 1273:                          ((size + (base >> 1)) / base),
 1274:                          suffixes[i]);
 1275:                 break;
 1276:             }
 1277:             base = base * 1024;
 1278:         }
 1279:     }
 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;
 1288: #else
 1289:     struct tm tm;
 1290: #endif
 1291:     time_t ti;
 1292:     int64_t secs;
 1293: 
 1294:     if (!sn) {
 1295:         snprintf(buf, buf_size,
 1296:                  "%-10s%-20s%7s%20s%15s",
 1297:                  "ID", "TAG", "VM SIZE", "DATE", "VM CLOCK");
 1298:     } else {
 1299:         ti = sn->date_sec;
 1300: #ifdef _WIN32
 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);
 1308: #endif
 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),
 1314:                  (int)(secs % 60),
 1315:                  (int)((sn->vm_clock_nsec / 1000000) % 1000));
 1316:         snprintf(buf, buf_size,
 1317:                  "%-10s%-20s%7s%20s%15s",
 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;
 1324: }
 1325: 
 1326: 
 1327: /**************************************************************/
 1328: /* async I/Os */
 1329: 
 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: 
 1338: static void bdrv_aio_cancel_vector(BlockDriverAIOCB *acb)
 1339: {
 1340:     VectorTranslationState *s = acb->opaque;
 1341: 
 1342:     bdrv_aio_cancel(s->aiocb);
 1343: }
 1344: 
 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));
 1367:     BlockDriverAIOCB *aiocb = qemu_aio_get_pool(&vectored_aio_pool, bs,
 1368:                                                 cb, opaque);
 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: 
 1407: BlockDriverAIOCB *bdrv_aio_read(BlockDriverState *bs, int64_t sector_num,
 1408:                                 uint8_t *buf, int nb_sectors,
 1409:                                 BlockDriverCompletionFunc *cb, void *opaque)
 1410: {
 1411:     BlockDriver *drv = bs->drv;
 1412:     BlockDriverAIOCB *ret;
 1413: 
 1414:     if (!drv)
 1415:         return NULL;
 1416:     if (bdrv_check_request(bs, sector_num, nb_sectors))
 1417:         return NULL;
 1418: 
 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;
 1428: }
 1429: 
 1430: BlockDriverAIOCB *bdrv_aio_write(BlockDriverState *bs, int64_t sector_num,
 1431:                                  const uint8_t *buf, int nb_sectors,
 1432:                                  BlockDriverCompletionFunc *cb, void *opaque)
 1433: {
 1434:     BlockDriver *drv = bs->drv;
 1435:     BlockDriverAIOCB *ret;
 1436: 
 1437:     if (!drv)
 1438:         return NULL;
 1439:     if (bs->read_only)
 1440:         return NULL;
 1441:     if (bdrv_check_request(bs, sector_num, nb_sectors))
 1442:         return NULL;
 1443: 
 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;
 1453: }
 1454: 
 1455: void bdrv_aio_cancel(BlockDriverAIOCB *acb)
 1456: {
 1457:     acb->pool->cancel(acb);
 1458: }
 1459: 
 1460: 
 1461: /**************************************************************/
 1462: /* async block device emulation */
 1463: 
 1464: static void bdrv_aio_bh_cb(void *opaque)
 1465: {
 1466:     BlockDriverAIOCBSync *acb = opaque;
 1467:     acb->common.cb(acb->common.opaque, acb->ret);
 1468:     qemu_aio_release(acb);
 1469: }
 1470: 
 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)
 1474: {
 1475:     BlockDriverAIOCBSync *acb;
 1476:     int ret;
 1477: 
 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: }
 1486: 
 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);
 1508: }
 1509: 
 1510: /**************************************************************/
 1511: /* sync block device emulation */
 1512: 
 1513: static void bdrv_rw_em_cb(void *opaque, int ret)
 1514: {
 1515:     *(int *)opaque = ret;
 1516: }
 1517: 
 1518: #define NOT_DONE 0x7fffffff
 1519: 
 1520: static int bdrv_read_em(BlockDriverState *bs, int64_t sector_num,
 1521:                         uint8_t *buf, int nb_sectors)
 1522: {
 1523:     int async_ret;
 1524:     BlockDriverAIOCB *acb;
 1525: 
 1526:     async_ret = NOT_DONE;
 1527:     acb = bdrv_aio_read(bs, sector_num, buf, nb_sectors,
 1528:                         bdrv_rw_em_cb, &async_ret);
 1529:     if (acb == NULL)
 1530:         return -1;
 1531: 
 1532:     while (async_ret == NOT_DONE) {
 1533:         qemu_aio_wait();
 1534:     }
 1535: 
 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;
 1546:     acb = bdrv_aio_write(bs, sector_num, buf, nb_sectors,
 1547:                          bdrv_rw_em_cb, &async_ret);
 1548:     if (acb == NULL)
 1549:         return -1;
 1550:     while (async_ret == NOT_DONE) {
 1551:         qemu_aio_wait();
 1552:     }
 1553:     return async_ret;
 1554: }
 1555: 
 1556: void bdrv_init(void)
 1557: {
 1558:     aio_pool_init(&vectored_aio_pool, sizeof(BlockDriverAIOCB),
 1559:                   bdrv_aio_cancel_vector);
 1560: 
 1561:     bdrv_register(&bdrv_raw);
 1562:     bdrv_register(&bdrv_host_device);
 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);
 1573:     bdrv_register(&bdrv_qcow2);
 1574:     bdrv_register(&bdrv_parallels);
 1575:     bdrv_register(&bdrv_nbd);
 1576: }
 1577: 
 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)
 1588: {
 1589:     BlockDriverAIOCB *acb;
 1590: 
 1591:     if (pool->free_aiocb) {
 1592:         acb = pool->free_aiocb;
 1593:         pool->free_aiocb = acb->next;
 1594:     } else {
 1595:         acb = qemu_mallocz(pool->aiocb_size);
 1596:         acb->pool = pool;
 1597:     }
 1598:     acb->bs = bs;
 1599:     acb->cb = cb;
 1600:     acb->opaque = opaque;
 1601:     return acb;
 1602: }
 1603: 
 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: 
 1610: void qemu_aio_release(void *p)
 1611: {
 1612:     BlockDriverAIOCB *acb = (BlockDriverAIOCB *)p;
 1613:     AIOPool *pool = acb->pool;
 1614:     acb->next = pool->free_aiocb;
 1615:     pool->free_aiocb = acb;
 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
 1638:  * function. It is currently only used for floppy disks
 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:     }
 1691: }
 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