Annotation of qemu/block/raw-posix.c, revision 1.1.1.1

1.1       root        1: /*
                      2:  * Block driver for RAW files (posix)
                      3:  *
                      4:  * Copyright (c) 2006 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 "qemu-common.h"
                     25: #include "qemu-timer.h"
                     26: #include "qemu-char.h"
                     27: #include "qemu-log.h"
                     28: #include "block_int.h"
                     29: #include "module.h"
                     30: #ifdef CONFIG_AIO
                     31: #include "posix-aio-compat.h"
                     32: #endif
                     33: 
                     34: #ifdef CONFIG_COCOA
                     35: #include <paths.h>
                     36: #include <sys/param.h>
                     37: #include <IOKit/IOKitLib.h>
                     38: #include <IOKit/IOBSD.h>
                     39: #include <IOKit/storage/IOMediaBSDClient.h>
                     40: #include <IOKit/storage/IOMedia.h>
                     41: #include <IOKit/storage/IOCDMedia.h>
                     42: //#include <IOKit/storage/IOCDTypes.h>
                     43: #include <CoreFoundation/CoreFoundation.h>
                     44: #endif
                     45: 
                     46: #ifdef __sun__
                     47: #define _POSIX_PTHREAD_SEMANTICS 1
                     48: #include <signal.h>
                     49: #include <sys/dkio.h>
                     50: #endif
                     51: #ifdef __linux__
                     52: #include <sys/ioctl.h>
                     53: #include <linux/cdrom.h>
                     54: #include <linux/fd.h>
                     55: #endif
                     56: #ifdef __FreeBSD__
                     57: #include <signal.h>
                     58: #include <sys/disk.h>
                     59: #include <sys/cdio.h>
                     60: #endif
                     61: 
                     62: #ifdef __OpenBSD__
                     63: #include <sys/ioctl.h>
                     64: #include <sys/disklabel.h>
                     65: #include <sys/dkio.h>
                     66: #endif
                     67: 
                     68: #ifdef __DragonFly__
                     69: #include <sys/ioctl.h>
                     70: #include <sys/diskslice.h>
                     71: #endif
                     72: 
                     73: //#define DEBUG_FLOPPY
                     74: 
                     75: //#define DEBUG_BLOCK
                     76: #if defined(DEBUG_BLOCK)
                     77: #define DEBUG_BLOCK_PRINT(formatCstr, ...) do { if (qemu_log_enabled()) \
                     78:     { qemu_log(formatCstr, ## __VA_ARGS__); qemu_log_flush(); } } while (0)
                     79: #else
                     80: #define DEBUG_BLOCK_PRINT(formatCstr, ...)
                     81: #endif
                     82: 
                     83: /* OS X does not have O_DSYNC */
                     84: #ifndef O_DSYNC
                     85: #ifdef O_SYNC
                     86: #define O_DSYNC O_SYNC
                     87: #elif defined(O_FSYNC)
                     88: #define O_DSYNC O_FSYNC
                     89: #endif
                     90: #endif
                     91: 
                     92: /* Approximate O_DIRECT with O_DSYNC if O_DIRECT isn't available */
                     93: #ifndef O_DIRECT
                     94: #define O_DIRECT O_DSYNC
                     95: #endif
                     96: 
                     97: #define FTYPE_FILE   0
                     98: #define FTYPE_CD     1
                     99: #define FTYPE_FD     2
                    100: 
                    101: #define ALIGNED_BUFFER_SIZE (32 * 512)
                    102: 
                    103: /* if the FD is not accessed during that time (in ms), we try to
                    104:    reopen it to see if the disk has been changed */
                    105: #define FD_OPEN_TIMEOUT 1000
                    106: 
                    107: typedef struct BDRVRawState {
                    108:     int fd;
                    109:     int type;
                    110:     unsigned int lseek_err_cnt;
                    111:     int open_flags;
                    112: #if defined(__linux__)
                    113:     /* linux floppy specific */
                    114:     int64_t fd_open_time;
                    115:     int64_t fd_error_time;
                    116:     int fd_got_error;
                    117:     int fd_media_changed;
                    118: #endif
                    119:     uint8_t* aligned_buf;
                    120: } BDRVRawState;
                    121: 
                    122: static int posix_aio_init(void);
                    123: 
                    124: static int fd_open(BlockDriverState *bs);
                    125: static int64_t raw_getlength(BlockDriverState *bs);
                    126: 
                    127: #if defined(__FreeBSD__)
                    128: static int cdrom_reopen(BlockDriverState *bs);
                    129: #endif
                    130: 
                    131: static int raw_open_common(BlockDriverState *bs, const char *filename,
                    132:                            int bdrv_flags, int open_flags)
                    133: {
                    134:     BDRVRawState *s = bs->opaque;
                    135:     int fd, ret;
                    136: 
                    137:     posix_aio_init();
                    138: 
                    139:     s->lseek_err_cnt = 0;
                    140: 
                    141:     s->open_flags = open_flags | O_BINARY;
                    142:     s->open_flags &= ~O_ACCMODE;
                    143:     if ((bdrv_flags & BDRV_O_ACCESS) == BDRV_O_RDWR) {
                    144:         s->open_flags |= O_RDWR;
                    145:     } else {
                    146:         s->open_flags |= O_RDONLY;
                    147:         bs->read_only = 1;
                    148:     }
                    149: 
                    150:     /* Use O_DSYNC for write-through caching, no flags for write-back caching,
                    151:      * and O_DIRECT for no caching. */
                    152:     if ((bdrv_flags & BDRV_O_NOCACHE))
                    153:         s->open_flags |= O_DIRECT;
                    154:     else if (!(bdrv_flags & BDRV_O_CACHE_WB))
                    155:         s->open_flags |= O_DSYNC;
                    156: 
                    157:     s->fd = -1;
                    158:     fd = open(filename, s->open_flags, 0644);
                    159:     if (fd < 0) {
                    160:         ret = -errno;
                    161:         if (ret == -EROFS)
                    162:             ret = -EACCES;
                    163:         return ret;
                    164:     }
                    165:     s->fd = fd;
                    166:     s->aligned_buf = NULL;
                    167:     if ((bdrv_flags & BDRV_O_NOCACHE)) {
                    168:         s->aligned_buf = qemu_blockalign(bs, ALIGNED_BUFFER_SIZE);
                    169:         if (s->aligned_buf == NULL) {
                    170:             ret = -errno;
                    171:             close(fd);
                    172:             return ret;
                    173:         }
                    174:     }
                    175:     return 0;
                    176: }
                    177: 
                    178: static int raw_open(BlockDriverState *bs, const char *filename, int flags)
                    179: {
                    180:     BDRVRawState *s = bs->opaque;
                    181:     int open_flags = 0;
                    182: 
                    183:     s->type = FTYPE_FILE;
                    184:     if (flags & BDRV_O_CREAT)
                    185:         open_flags = O_CREAT | O_TRUNC;
                    186: 
                    187:     return raw_open_common(bs, filename, flags, open_flags);
                    188: }
                    189: 
                    190: /* XXX: use host sector size if necessary with:
                    191: #ifdef DIOCGSECTORSIZE
                    192:         {
                    193:             unsigned int sectorsize = 512;
                    194:             if (!ioctl(fd, DIOCGSECTORSIZE, &sectorsize) &&
                    195:                 sectorsize > bufsize)
                    196:                 bufsize = sectorsize;
                    197:         }
                    198: #endif
                    199: #ifdef CONFIG_COCOA
                    200:         u_int32_t   blockSize = 512;
                    201:         if ( !ioctl( fd, DKIOCGETBLOCKSIZE, &blockSize ) && blockSize > bufsize) {
                    202:             bufsize = blockSize;
                    203:         }
                    204: #endif
                    205: */
                    206: 
                    207: /*
                    208:  * offset and count are in bytes, but must be multiples of 512 for files
                    209:  * opened with O_DIRECT. buf must be aligned to 512 bytes then.
                    210:  *
                    211:  * This function may be called without alignment if the caller ensures
                    212:  * that O_DIRECT is not in effect.
                    213:  */
                    214: static int raw_pread_aligned(BlockDriverState *bs, int64_t offset,
                    215:                      uint8_t *buf, int count)
                    216: {
                    217:     BDRVRawState *s = bs->opaque;
                    218:     int ret;
                    219: 
                    220:     ret = fd_open(bs);
                    221:     if (ret < 0)
                    222:         return ret;
                    223: 
                    224:     if (offset >= 0 && lseek(s->fd, offset, SEEK_SET) == (off_t)-1) {
                    225:         ++(s->lseek_err_cnt);
                    226:         if(s->lseek_err_cnt <= 10) {
                    227:             DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
                    228:                               "] lseek failed : %d = %s\n",
                    229:                               s->fd, bs->filename, offset, buf, count,
                    230:                               bs->total_sectors, errno, strerror(errno));
                    231:         }
                    232:         return -1;
                    233:     }
                    234:     s->lseek_err_cnt=0;
                    235: 
                    236:     ret = read(s->fd, buf, count);
                    237:     if (ret == count)
                    238:         goto label__raw_read__success;
                    239: 
                    240:     /* Allow reads beyond the end (needed for pwrite) */
                    241:     if ((ret == 0) && bs->growable) {
                    242:         int64_t size = raw_getlength(bs);
                    243:         if (offset >= size) {
                    244:             memset(buf, 0, count);
                    245:             ret = count;
                    246:             goto label__raw_read__success;
                    247:         }
                    248:     }
                    249: 
                    250:     DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
                    251:                       "] read failed %d : %d = %s\n",
                    252:                       s->fd, bs->filename, offset, buf, count,
                    253:                       bs->total_sectors, ret, errno, strerror(errno));
                    254: 
                    255:     /* Try harder for CDrom. */
                    256:     if (bs->type == BDRV_TYPE_CDROM) {
                    257:         lseek(s->fd, offset, SEEK_SET);
                    258:         ret = read(s->fd, buf, count);
                    259:         if (ret == count)
                    260:             goto label__raw_read__success;
                    261:         lseek(s->fd, offset, SEEK_SET);
                    262:         ret = read(s->fd, buf, count);
                    263:         if (ret == count)
                    264:             goto label__raw_read__success;
                    265: 
                    266:         DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
                    267:                           "] retry read failed %d : %d = %s\n",
                    268:                           s->fd, bs->filename, offset, buf, count,
                    269:                           bs->total_sectors, ret, errno, strerror(errno));
                    270:     }
                    271: 
                    272: label__raw_read__success:
                    273: 
                    274:     return  (ret < 0) ? -errno : ret;
                    275: }
                    276: 
                    277: /*
                    278:  * offset and count are in bytes, but must be multiples of 512 for files
                    279:  * opened with O_DIRECT. buf must be aligned to 512 bytes then.
                    280:  *
                    281:  * This function may be called without alignment if the caller ensures
                    282:  * that O_DIRECT is not in effect.
                    283:  */
                    284: static int raw_pwrite_aligned(BlockDriverState *bs, int64_t offset,
                    285:                       const uint8_t *buf, int count)
                    286: {
                    287:     BDRVRawState *s = bs->opaque;
                    288:     int ret;
                    289: 
                    290:     ret = fd_open(bs);
                    291:     if (ret < 0)
                    292:         return -errno;
                    293: 
                    294:     if (offset >= 0 && lseek(s->fd, offset, SEEK_SET) == (off_t)-1) {
                    295:         ++(s->lseek_err_cnt);
                    296:         if(s->lseek_err_cnt) {
                    297:             DEBUG_BLOCK_PRINT("raw_pwrite(%d:%s, %" PRId64 ", %p, %d) [%"
                    298:                               PRId64 "] lseek failed : %d = %s\n",
                    299:                               s->fd, bs->filename, offset, buf, count,
                    300:                               bs->total_sectors, errno, strerror(errno));
                    301:         }
                    302:         return -EIO;
                    303:     }
                    304:     s->lseek_err_cnt = 0;
                    305: 
                    306:     ret = write(s->fd, buf, count);
                    307:     if (ret == count)
                    308:         goto label__raw_write__success;
                    309: 
                    310:     DEBUG_BLOCK_PRINT("raw_pwrite(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
                    311:                       "] write failed %d : %d = %s\n",
                    312:                       s->fd, bs->filename, offset, buf, count,
                    313:                       bs->total_sectors, ret, errno, strerror(errno));
                    314: 
                    315: label__raw_write__success:
                    316: 
                    317:     return  (ret < 0) ? -errno : ret;
                    318: }
                    319: 
                    320: 
                    321: /*
                    322:  * offset and count are in bytes and possibly not aligned. For files opened
                    323:  * with O_DIRECT, necessary alignments are ensured before calling
                    324:  * raw_pread_aligned to do the actual read.
                    325:  */
                    326: static int raw_pread(BlockDriverState *bs, int64_t offset,
                    327:                      uint8_t *buf, int count)
                    328: {
                    329:     BDRVRawState *s = bs->opaque;
                    330:     int size, ret, shift, sum;
                    331: 
                    332:     sum = 0;
                    333: 
                    334:     if (s->aligned_buf != NULL)  {
                    335: 
                    336:         if (offset & 0x1ff) {
                    337:             /* align offset on a 512 bytes boundary */
                    338: 
                    339:             shift = offset & 0x1ff;
                    340:             size = (shift + count + 0x1ff) & ~0x1ff;
                    341:             if (size > ALIGNED_BUFFER_SIZE)
                    342:                 size = ALIGNED_BUFFER_SIZE;
                    343:             ret = raw_pread_aligned(bs, offset - shift, s->aligned_buf, size);
                    344:             if (ret < 0)
                    345:                 return ret;
                    346: 
                    347:             size = 512 - shift;
                    348:             if (size > count)
                    349:                 size = count;
                    350:             memcpy(buf, s->aligned_buf + shift, size);
                    351: 
                    352:             buf += size;
                    353:             offset += size;
                    354:             count -= size;
                    355:             sum += size;
                    356: 
                    357:             if (count == 0)
                    358:                 return sum;
                    359:         }
                    360:         if (count & 0x1ff || (uintptr_t) buf & 0x1ff) {
                    361: 
                    362:             /* read on aligned buffer */
                    363: 
                    364:             while (count) {
                    365: 
                    366:                 size = (count + 0x1ff) & ~0x1ff;
                    367:                 if (size > ALIGNED_BUFFER_SIZE)
                    368:                     size = ALIGNED_BUFFER_SIZE;
                    369: 
                    370:                 ret = raw_pread_aligned(bs, offset, s->aligned_buf, size);
                    371:                 if (ret < 0)
                    372:                     return ret;
                    373: 
                    374:                 size = ret;
                    375:                 if (size > count)
                    376:                     size = count;
                    377: 
                    378:                 memcpy(buf, s->aligned_buf, size);
                    379: 
                    380:                 buf += size;
                    381:                 offset += size;
                    382:                 count -= size;
                    383:                 sum += size;
                    384:             }
                    385: 
                    386:             return sum;
                    387:         }
                    388:     }
                    389: 
                    390:     return raw_pread_aligned(bs, offset, buf, count) + sum;
                    391: }
                    392: 
                    393: static int raw_read(BlockDriverState *bs, int64_t sector_num,
                    394:                     uint8_t *buf, int nb_sectors)
                    395: {
                    396:     int ret;
                    397: 
                    398:     ret = raw_pread(bs, sector_num * 512, buf, nb_sectors * 512);
                    399:     if (ret == (nb_sectors * 512))
                    400:         ret = 0;
                    401:     return ret;
                    402: }
                    403: 
                    404: /*
                    405:  * offset and count are in bytes and possibly not aligned. For files opened
                    406:  * with O_DIRECT, necessary alignments are ensured before calling
                    407:  * raw_pwrite_aligned to do the actual write.
                    408:  */
                    409: static int raw_pwrite(BlockDriverState *bs, int64_t offset,
                    410:                       const uint8_t *buf, int count)
                    411: {
                    412:     BDRVRawState *s = bs->opaque;
                    413:     int size, ret, shift, sum;
                    414: 
                    415:     sum = 0;
                    416: 
                    417:     if (s->aligned_buf != NULL) {
                    418: 
                    419:         if (offset & 0x1ff) {
                    420:             /* align offset on a 512 bytes boundary */
                    421:             shift = offset & 0x1ff;
                    422:             ret = raw_pread_aligned(bs, offset - shift, s->aligned_buf, 512);
                    423:             if (ret < 0)
                    424:                 return ret;
                    425: 
                    426:             size = 512 - shift;
                    427:             if (size > count)
                    428:                 size = count;
                    429:             memcpy(s->aligned_buf + shift, buf, size);
                    430: 
                    431:             ret = raw_pwrite_aligned(bs, offset - shift, s->aligned_buf, 512);
                    432:             if (ret < 0)
                    433:                 return ret;
                    434: 
                    435:             buf += size;
                    436:             offset += size;
                    437:             count -= size;
                    438:             sum += size;
                    439: 
                    440:             if (count == 0)
                    441:                 return sum;
                    442:         }
                    443:         if (count & 0x1ff || (uintptr_t) buf & 0x1ff) {
                    444: 
                    445:             while ((size = (count & ~0x1ff)) != 0) {
                    446: 
                    447:                 if (size > ALIGNED_BUFFER_SIZE)
                    448:                     size = ALIGNED_BUFFER_SIZE;
                    449: 
                    450:                 memcpy(s->aligned_buf, buf, size);
                    451: 
                    452:                 ret = raw_pwrite_aligned(bs, offset, s->aligned_buf, size);
                    453:                 if (ret < 0)
                    454:                     return ret;
                    455: 
                    456:                 buf += ret;
                    457:                 offset += ret;
                    458:                 count -= ret;
                    459:                 sum += ret;
                    460:             }
                    461:             /* here, count < 512 because (count & ~0x1ff) == 0 */
                    462:             if (count) {
                    463:                 ret = raw_pread_aligned(bs, offset, s->aligned_buf, 512);
                    464:                 if (ret < 0)
                    465:                     return ret;
                    466:                  memcpy(s->aligned_buf, buf, count);
                    467: 
                    468:                  ret = raw_pwrite_aligned(bs, offset, s->aligned_buf, 512);
                    469:                  if (ret < 0)
                    470:                      return ret;
                    471:                  if (count < ret)
                    472:                      ret = count;
                    473: 
                    474:                  sum += ret;
                    475:             }
                    476:             return sum;
                    477:         }
                    478:     }
                    479:     return raw_pwrite_aligned(bs, offset, buf, count) + sum;
                    480: }
                    481: 
                    482: static int raw_write(BlockDriverState *bs, int64_t sector_num,
                    483:                      const uint8_t *buf, int nb_sectors)
                    484: {
                    485:     int ret;
                    486:     ret = raw_pwrite(bs, sector_num * 512, buf, nb_sectors * 512);
                    487:     if (ret == (nb_sectors * 512))
                    488:         ret = 0;
                    489:     return ret;
                    490: }
                    491: 
                    492: #ifdef CONFIG_AIO
                    493: /***********************************************************/
                    494: /* Unix AIO using POSIX AIO */
                    495: 
                    496: typedef struct RawAIOCB {
                    497:     BlockDriverAIOCB common;
                    498:     struct qemu_paiocb aiocb;
                    499:     struct RawAIOCB *next;
                    500:     int ret;
                    501: } RawAIOCB;
                    502: 
                    503: typedef struct PosixAioState
                    504: {
                    505:     int rfd, wfd;
                    506:     RawAIOCB *first_aio;
                    507: } PosixAioState;
                    508: 
                    509: static void posix_aio_read(void *opaque)
                    510: {
                    511:     PosixAioState *s = opaque;
                    512:     RawAIOCB *acb, **pacb;
                    513:     int ret;
                    514:     ssize_t len;
                    515: 
                    516:     /* read all bytes from signal pipe */
                    517:     for (;;) {
                    518:         char bytes[16];
                    519: 
                    520:         len = read(s->rfd, bytes, sizeof(bytes));
                    521:         if (len == -1 && errno == EINTR)
                    522:             continue; /* try again */
                    523:         if (len == sizeof(bytes))
                    524:             continue; /* more to read */
                    525:         break;
                    526:     }
                    527: 
                    528:     for(;;) {
                    529:         pacb = &s->first_aio;
                    530:         for(;;) {
                    531:             acb = *pacb;
                    532:             if (!acb)
                    533:                 goto the_end;
                    534:             ret = qemu_paio_error(&acb->aiocb);
                    535:             if (ret == ECANCELED) {
                    536:                 /* remove the request */
                    537:                 *pacb = acb->next;
                    538:                 qemu_aio_release(acb);
                    539:             } else if (ret != EINPROGRESS) {
                    540:                 /* end of aio */
                    541:                 if (ret == 0) {
                    542:                     ret = qemu_paio_return(&acb->aiocb);
                    543:                     if (ret == acb->aiocb.aio_nbytes)
                    544:                         ret = 0;
                    545:                     else
                    546:                         ret = -EINVAL;
                    547:                 } else {
                    548:                     ret = -ret;
                    549:                 }
                    550:                 /* remove the request */
                    551:                 *pacb = acb->next;
                    552:                 /* call the callback */
                    553:                 acb->common.cb(acb->common.opaque, ret);
                    554:                 qemu_aio_release(acb);
                    555:                 break;
                    556:             } else {
                    557:                 pacb = &acb->next;
                    558:             }
                    559:         }
                    560:     }
                    561:  the_end: ;
                    562: }
                    563: 
                    564: static int posix_aio_flush(void *opaque)
                    565: {
                    566:     PosixAioState *s = opaque;
                    567:     return !!s->first_aio;
                    568: }
                    569: 
                    570: static PosixAioState *posix_aio_state;
                    571: 
                    572: static void aio_signal_handler(int signum)
                    573: {
                    574:     if (posix_aio_state) {
                    575:         char byte = 0;
                    576: 
                    577:         write(posix_aio_state->wfd, &byte, sizeof(byte));
                    578:     }
                    579: 
                    580:     qemu_service_io();
                    581: }
                    582: 
                    583: static int posix_aio_init(void)
                    584: {
                    585:     struct sigaction act;
                    586:     PosixAioState *s;
                    587:     int fds[2];
                    588:     struct qemu_paioinit ai;
                    589:   
                    590:     if (posix_aio_state)
                    591:         return 0;
                    592: 
                    593:     s = qemu_malloc(sizeof(PosixAioState));
                    594: 
                    595:     sigfillset(&act.sa_mask);
                    596:     act.sa_flags = 0; /* do not restart syscalls to interrupt select() */
                    597:     act.sa_handler = aio_signal_handler;
                    598:     sigaction(SIGUSR2, &act, NULL);
                    599: 
                    600:     s->first_aio = NULL;
                    601:     if (pipe(fds) == -1) {
                    602:         fprintf(stderr, "failed to create pipe\n");
                    603:         return -errno;
                    604:     }
                    605: 
                    606:     s->rfd = fds[0];
                    607:     s->wfd = fds[1];
                    608: 
                    609:     fcntl(s->rfd, F_SETFL, O_NONBLOCK);
                    610:     fcntl(s->wfd, F_SETFL, O_NONBLOCK);
                    611: 
                    612:     qemu_aio_set_fd_handler(s->rfd, posix_aio_read, NULL, posix_aio_flush, s);
                    613: 
                    614:     memset(&ai, 0, sizeof(ai));
                    615:     ai.aio_threads = 64;
                    616:     ai.aio_num = 64;
                    617:     qemu_paio_init(&ai);
                    618: 
                    619:     posix_aio_state = s;
                    620: 
                    621:     return 0;
                    622: }
                    623: 
                    624: static void raw_aio_remove(RawAIOCB *acb)
                    625: {
                    626:     RawAIOCB **pacb;
                    627: 
                    628:     /* remove the callback from the queue */
                    629:     pacb = &posix_aio_state->first_aio;
                    630:     for(;;) {
                    631:         if (*pacb == NULL) {
                    632:             fprintf(stderr, "raw_aio_remove: aio request not found!\n");
                    633:             break;
                    634:         } else if (*pacb == acb) {
                    635:             *pacb = acb->next;
                    636:             qemu_aio_release(acb);
                    637:             break;
                    638:         }
                    639:         pacb = &(*pacb)->next;
                    640:     }
                    641: }
                    642: 
                    643: static void raw_aio_cancel(BlockDriverAIOCB *blockacb)
                    644: {
                    645:     int ret;
                    646:     RawAIOCB *acb = (RawAIOCB *)blockacb;
                    647: 
                    648:     ret = qemu_paio_cancel(acb->aiocb.aio_fildes, &acb->aiocb);
                    649:     if (ret == QEMU_PAIO_NOTCANCELED) {
                    650:         /* fail safe: if the aio could not be canceled, we wait for
                    651:            it */
                    652:         while (qemu_paio_error(&acb->aiocb) == EINPROGRESS);
                    653:     }
                    654: 
                    655:     raw_aio_remove(acb);
                    656: }
                    657: 
                    658: static AIOPool raw_aio_pool = {
                    659:     .aiocb_size         = sizeof(RawAIOCB),
                    660:     .cancel             = raw_aio_cancel,
                    661: };
                    662: 
                    663: static RawAIOCB *raw_aio_setup(BlockDriverState *bs, int64_t sector_num,
                    664:         QEMUIOVector *qiov, int nb_sectors,
                    665:         BlockDriverCompletionFunc *cb, void *opaque)
                    666: {
                    667:     BDRVRawState *s = bs->opaque;
                    668:     RawAIOCB *acb;
                    669: 
                    670:     if (fd_open(bs) < 0)
                    671:         return NULL;
                    672: 
                    673:     acb = qemu_aio_get(&raw_aio_pool, bs, cb, opaque);
                    674:     if (!acb)
                    675:         return NULL;
                    676:     acb->aiocb.aio_fildes = s->fd;
                    677:     acb->aiocb.ev_signo = SIGUSR2;
                    678:     acb->aiocb.aio_iov = qiov->iov;
                    679:     acb->aiocb.aio_niov = qiov->niov;
                    680:     acb->aiocb.aio_nbytes = nb_sectors * 512;
                    681:     acb->aiocb.aio_offset = sector_num * 512;
                    682:     acb->aiocb.aio_flags = 0;
                    683: 
                    684:     /*
                    685:      * If O_DIRECT is used the buffer needs to be aligned on a sector
                    686:      * boundary. Tell the low level code to ensure that in case it's
                    687:      * not done yet.
                    688:      */
                    689:     if (s->aligned_buf)
                    690:         acb->aiocb.aio_flags |= QEMU_AIO_SECTOR_ALIGNED;
                    691: 
                    692:     acb->next = posix_aio_state->first_aio;
                    693:     posix_aio_state->first_aio = acb;
                    694:     return acb;
                    695: }
                    696: 
                    697: static BlockDriverAIOCB *raw_aio_readv(BlockDriverState *bs,
                    698:         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
                    699:         BlockDriverCompletionFunc *cb, void *opaque)
                    700: {
                    701:     RawAIOCB *acb;
                    702: 
                    703:     acb = raw_aio_setup(bs, sector_num, qiov, nb_sectors, cb, opaque);
                    704:     if (!acb)
                    705:         return NULL;
                    706:     if (qemu_paio_read(&acb->aiocb) < 0) {
                    707:         raw_aio_remove(acb);
                    708:         return NULL;
                    709:     }
                    710:     return &acb->common;
                    711: }
                    712: 
                    713: static BlockDriverAIOCB *raw_aio_writev(BlockDriverState *bs,
                    714:         int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
                    715:         BlockDriverCompletionFunc *cb, void *opaque)
                    716: {
                    717:     RawAIOCB *acb;
                    718: 
                    719:     acb = raw_aio_setup(bs, sector_num, qiov, nb_sectors, cb, opaque);
                    720:     if (!acb)
                    721:         return NULL;
                    722:     if (qemu_paio_write(&acb->aiocb) < 0) {
                    723:         raw_aio_remove(acb);
                    724:         return NULL;
                    725:     }
                    726:     return &acb->common;
                    727: }
                    728: #else /* CONFIG_AIO */
                    729: static int posix_aio_init(void)
                    730: {
                    731:     return 0;
                    732: }
                    733: #endif /* CONFIG_AIO */
                    734: 
                    735: 
                    736: static void raw_close(BlockDriverState *bs)
                    737: {
                    738:     BDRVRawState *s = bs->opaque;
                    739:     if (s->fd >= 0) {
                    740:         close(s->fd);
                    741:         s->fd = -1;
                    742:         if (s->aligned_buf != NULL)
                    743:             qemu_free(s->aligned_buf);
                    744:     }
                    745: }
                    746: 
                    747: static int raw_truncate(BlockDriverState *bs, int64_t offset)
                    748: {
                    749:     BDRVRawState *s = bs->opaque;
                    750:     if (s->type != FTYPE_FILE)
                    751:         return -ENOTSUP;
                    752:     if (ftruncate(s->fd, offset) < 0)
                    753:         return -errno;
                    754:     return 0;
                    755: }
                    756: 
                    757: #ifdef __OpenBSD__
                    758: static int64_t raw_getlength(BlockDriverState *bs)
                    759: {
                    760:     BDRVRawState *s = bs->opaque;
                    761:     int fd = s->fd;
                    762:     struct stat st;
                    763: 
                    764:     if (fstat(fd, &st))
                    765:         return -1;
                    766:     if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) {
                    767:         struct disklabel dl;
                    768: 
                    769:         if (ioctl(fd, DIOCGDINFO, &dl))
                    770:             return -1;
                    771:         return (uint64_t)dl.d_secsize *
                    772:             dl.d_partitions[DISKPART(st.st_rdev)].p_size;
                    773:     } else
                    774:         return st.st_size;
                    775: }
                    776: #else /* !__OpenBSD__ */
                    777: static int64_t  raw_getlength(BlockDriverState *bs)
                    778: {
                    779:     BDRVRawState *s = bs->opaque;
                    780:     int fd = s->fd;
                    781:     int64_t size;
                    782: #ifdef HOST_BSD
                    783:     struct stat sb;
                    784: #ifdef __FreeBSD__
                    785:     int reopened = 0;
                    786: #endif
                    787: #endif
                    788: #ifdef __sun__
                    789:     struct dk_minfo minfo;
                    790:     int rv;
                    791: #endif
                    792:     int ret;
                    793: 
                    794:     ret = fd_open(bs);
                    795:     if (ret < 0)
                    796:         return ret;
                    797: 
                    798: #ifdef HOST_BSD
                    799: #ifdef __FreeBSD__
                    800: again:
                    801: #endif
                    802:     if (!fstat(fd, &sb) && (S_IFCHR & sb.st_mode)) {
                    803: #ifdef DIOCGMEDIASIZE
                    804:        if (ioctl(fd, DIOCGMEDIASIZE, (off_t *)&size))
                    805: #elif defined(DIOCGPART)
                    806:         {
                    807:                 struct partinfo pi;
                    808:                 if (ioctl(fd, DIOCGPART, &pi) == 0)
                    809:                         size = pi.media_size;
                    810:                 else
                    811:                         size = 0;
                    812:         }
                    813:         if (size == 0)
                    814: #endif
                    815: #ifdef CONFIG_COCOA
                    816:         size = LONG_LONG_MAX;
                    817: #else
                    818:         size = lseek(fd, 0LL, SEEK_END);
                    819: #endif
                    820: #ifdef __FreeBSD__
                    821:         switch(s->type) {
                    822:         case FTYPE_CD:
                    823:             /* XXX FreeBSD acd returns UINT_MAX sectors for an empty drive */
                    824:             if (size == 2048LL * (unsigned)-1)
                    825:                 size = 0;
                    826:             /* XXX no disc?  maybe we need to reopen... */
                    827:             if (size <= 0 && !reopened && cdrom_reopen(bs) >= 0) {
                    828:                 reopened = 1;
                    829:                 goto again;
                    830:             }
                    831:         }
                    832: #endif
                    833:     } else
                    834: #endif
                    835: #ifdef __sun__
                    836:     /*
                    837:      * use the DKIOCGMEDIAINFO ioctl to read the size.
                    838:      */
                    839:     rv = ioctl ( fd, DKIOCGMEDIAINFO, &minfo );
                    840:     if ( rv != -1 ) {
                    841:         size = minfo.dki_lbsize * minfo.dki_capacity;
                    842:     } else /* there are reports that lseek on some devices
                    843:               fails, but irc discussion said that contingency
                    844:               on contingency was overkill */
                    845: #endif
                    846:     {
                    847:         size = lseek(fd, 0, SEEK_END);
                    848:     }
                    849:     return size;
                    850: }
                    851: #endif
                    852: 
                    853: static int raw_create(const char *filename, QEMUOptionParameter *options)
                    854: {
                    855:     int fd;
                    856:     int result = 0;
                    857:     int64_t total_size = 0;
                    858: 
                    859:     /* Read out options */
                    860:     while (options && options->name) {
                    861:         if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
                    862:             total_size = options->value.n / 512;
                    863:         }
                    864:         options++;
                    865:     }
                    866: 
                    867:     fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
                    868:               0644);
                    869:     if (fd < 0) {
                    870:         result = -errno;
                    871:     } else {
                    872:         if (ftruncate(fd, total_size * 512) != 0) {
                    873:             result = -errno;
                    874:         }
                    875:         if (close(fd) != 0) {
                    876:             result = -errno;
                    877:         }
                    878:     }
                    879:     return result;
                    880: }
                    881: 
                    882: static void raw_flush(BlockDriverState *bs)
                    883: {
                    884:     BDRVRawState *s = bs->opaque;
                    885:     fsync(s->fd);
                    886: }
                    887: 
                    888: 
                    889: static QEMUOptionParameter raw_create_options[] = {
                    890:     {
                    891:         .name = BLOCK_OPT_SIZE,
                    892:         .type = OPT_SIZE,
                    893:         .help = "Virtual disk size"
                    894:     },
                    895:     { NULL }
                    896: };
                    897: 
                    898: static BlockDriver bdrv_raw = {
                    899:     .format_name = "raw",
                    900:     .instance_size = sizeof(BDRVRawState),
                    901:     .bdrv_probe = NULL, /* no probe for protocols */
                    902:     .bdrv_open = raw_open,
                    903:     .bdrv_read = raw_read,
                    904:     .bdrv_write = raw_write,
                    905:     .bdrv_close = raw_close,
                    906:     .bdrv_create = raw_create,
                    907:     .bdrv_flush = raw_flush,
                    908: 
                    909: #ifdef CONFIG_AIO
                    910:     .bdrv_aio_readv = raw_aio_readv,
                    911:     .bdrv_aio_writev = raw_aio_writev,
                    912: #endif
                    913: 
                    914:     .bdrv_truncate = raw_truncate,
                    915:     .bdrv_getlength = raw_getlength,
                    916: 
                    917:     .create_options = raw_create_options,
                    918: };
                    919: 
                    920: /***********************************************/
                    921: /* host device */
                    922: 
                    923: #ifdef CONFIG_COCOA
                    924: static kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator );
                    925: static kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize );
                    926: 
                    927: kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator )
                    928: {
                    929:     kern_return_t       kernResult;
                    930:     mach_port_t     masterPort;
                    931:     CFMutableDictionaryRef  classesToMatch;
                    932: 
                    933:     kernResult = IOMasterPort( MACH_PORT_NULL, &masterPort );
                    934:     if ( KERN_SUCCESS != kernResult ) {
                    935:         printf( "IOMasterPort returned %d\n", kernResult );
                    936:     }
                    937: 
                    938:     classesToMatch = IOServiceMatching( kIOCDMediaClass );
                    939:     if ( classesToMatch == NULL ) {
                    940:         printf( "IOServiceMatching returned a NULL dictionary.\n" );
                    941:     } else {
                    942:     CFDictionarySetValue( classesToMatch, CFSTR( kIOMediaEjectableKey ), kCFBooleanTrue );
                    943:     }
                    944:     kernResult = IOServiceGetMatchingServices( masterPort, classesToMatch, mediaIterator );
                    945:     if ( KERN_SUCCESS != kernResult )
                    946:     {
                    947:         printf( "IOServiceGetMatchingServices returned %d\n", kernResult );
                    948:     }
                    949: 
                    950:     return kernResult;
                    951: }
                    952: 
                    953: kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize )
                    954: {
                    955:     io_object_t     nextMedia;
                    956:     kern_return_t   kernResult = KERN_FAILURE;
                    957:     *bsdPath = '\0';
                    958:     nextMedia = IOIteratorNext( mediaIterator );
                    959:     if ( nextMedia )
                    960:     {
                    961:         CFTypeRef   bsdPathAsCFString;
                    962:     bsdPathAsCFString = IORegistryEntryCreateCFProperty( nextMedia, CFSTR( kIOBSDNameKey ), kCFAllocatorDefault, 0 );
                    963:         if ( bsdPathAsCFString ) {
                    964:             size_t devPathLength;
                    965:             strcpy( bsdPath, _PATH_DEV );
                    966:             strcat( bsdPath, "r" );
                    967:             devPathLength = strlen( bsdPath );
                    968:             if ( CFStringGetCString( bsdPathAsCFString, bsdPath + devPathLength, maxPathSize - devPathLength, kCFStringEncodingASCII ) ) {
                    969:                 kernResult = KERN_SUCCESS;
                    970:             }
                    971:             CFRelease( bsdPathAsCFString );
                    972:         }
                    973:         IOObjectRelease( nextMedia );
                    974:     }
                    975: 
                    976:     return kernResult;
                    977: }
                    978: 
                    979: #endif
                    980: 
                    981: static int hdev_probe_device(const char *filename)
                    982: {
                    983:     struct stat st;
                    984: 
                    985:     /* allow a dedicated CD-ROM driver to match with a higher priority */
                    986:     if (strstart(filename, "/dev/cdrom", NULL))
                    987:         return 50;
                    988: 
                    989:     if (stat(filename, &st) >= 0 &&
                    990:             (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode))) {
                    991:         return 100;
                    992:     }
                    993: 
                    994:     return 0;
                    995: }
                    996: 
                    997: static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
                    998: {
                    999:     BDRVRawState *s = bs->opaque;
                   1000: 
                   1001: #ifdef CONFIG_COCOA
                   1002:     if (strstart(filename, "/dev/cdrom", NULL)) {
                   1003:         kern_return_t kernResult;
                   1004:         io_iterator_t mediaIterator;
                   1005:         char bsdPath[ MAXPATHLEN ];
                   1006:         int fd;
                   1007: 
                   1008:         kernResult = FindEjectableCDMedia( &mediaIterator );
                   1009:         kernResult = GetBSDPath( mediaIterator, bsdPath, sizeof( bsdPath ) );
                   1010: 
                   1011:         if ( bsdPath[ 0 ] != '\0' ) {
                   1012:             strcat(bsdPath,"s0");
                   1013:             /* some CDs don't have a partition 0 */
                   1014:             fd = open(bsdPath, O_RDONLY | O_BINARY | O_LARGEFILE);
                   1015:             if (fd < 0) {
                   1016:                 bsdPath[strlen(bsdPath)-1] = '1';
                   1017:             } else {
                   1018:                 close(fd);
                   1019:             }
                   1020:             filename = bsdPath;
                   1021:         }
                   1022: 
                   1023:         if ( mediaIterator )
                   1024:             IOObjectRelease( mediaIterator );
                   1025:     }
                   1026: #endif
                   1027: 
                   1028:     s->type = FTYPE_FILE;
                   1029: #if defined(__linux__) && defined(CONFIG_AIO)
                   1030:     if (strstart(filename, "/dev/sg", NULL)) {
                   1031:         bs->sg = 1;
                   1032:     }
                   1033: #endif
                   1034: 
                   1035:     return raw_open_common(bs, filename, flags, 0);
                   1036: }
                   1037: 
                   1038: #if defined(__linux__)
                   1039: /* Note: we do not have a reliable method to detect if the floppy is
                   1040:    present. The current method is to try to open the floppy at every
                   1041:    I/O and to keep it opened during a few hundreds of ms. */
                   1042: static int fd_open(BlockDriverState *bs)
                   1043: {
                   1044:     BDRVRawState *s = bs->opaque;
                   1045:     int last_media_present;
                   1046: 
                   1047:     if (s->type != FTYPE_FD)
                   1048:         return 0;
                   1049:     last_media_present = (s->fd >= 0);
                   1050:     if (s->fd >= 0 &&
                   1051:         (qemu_get_clock(rt_clock) - s->fd_open_time) >= FD_OPEN_TIMEOUT) {
                   1052:         close(s->fd);
                   1053:         s->fd = -1;
                   1054: #ifdef DEBUG_FLOPPY
                   1055:         printf("Floppy closed\n");
                   1056: #endif
                   1057:     }
                   1058:     if (s->fd < 0) {
                   1059:         if (s->fd_got_error &&
                   1060:             (qemu_get_clock(rt_clock) - s->fd_error_time) < FD_OPEN_TIMEOUT) {
                   1061: #ifdef DEBUG_FLOPPY
                   1062:             printf("No floppy (open delayed)\n");
                   1063: #endif
                   1064:             return -EIO;
                   1065:         }
                   1066:         s->fd = open(bs->filename, s->open_flags & ~O_NONBLOCK);
                   1067:         if (s->fd < 0) {
                   1068:             s->fd_error_time = qemu_get_clock(rt_clock);
                   1069:             s->fd_got_error = 1;
                   1070:             if (last_media_present)
                   1071:                 s->fd_media_changed = 1;
                   1072: #ifdef DEBUG_FLOPPY
                   1073:             printf("No floppy\n");
                   1074: #endif
                   1075:             return -EIO;
                   1076:         }
                   1077: #ifdef DEBUG_FLOPPY
                   1078:         printf("Floppy opened\n");
                   1079: #endif
                   1080:     }
                   1081:     if (!last_media_present)
                   1082:         s->fd_media_changed = 1;
                   1083:     s->fd_open_time = qemu_get_clock(rt_clock);
                   1084:     s->fd_got_error = 0;
                   1085:     return 0;
                   1086: }
                   1087: 
                   1088: static int hdev_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
                   1089: {
                   1090:     BDRVRawState *s = bs->opaque;
                   1091: 
                   1092:     return ioctl(s->fd, req, buf);
                   1093: }
                   1094: 
                   1095: #ifdef CONFIG_AIO
                   1096: static BlockDriverAIOCB *hdev_aio_ioctl(BlockDriverState *bs,
                   1097:         unsigned long int req, void *buf,
                   1098:         BlockDriverCompletionFunc *cb, void *opaque)
                   1099: {
                   1100:     BDRVRawState *s = bs->opaque;
                   1101:     RawAIOCB *acb;
                   1102: 
                   1103:     if (fd_open(bs) < 0)
                   1104:         return NULL;
                   1105: 
                   1106:     acb = qemu_aio_get(&raw_aio_pool, bs, cb, opaque);
                   1107:     if (!acb)
                   1108:         return NULL;
                   1109:     acb->aiocb.aio_fildes = s->fd;
                   1110:     acb->aiocb.ev_signo = SIGUSR2;
                   1111:     acb->aiocb.aio_offset = 0;
                   1112:     acb->aiocb.aio_flags = 0;
                   1113: 
                   1114:     acb->next = posix_aio_state->first_aio;
                   1115:     posix_aio_state->first_aio = acb;
                   1116: 
                   1117:     acb->aiocb.aio_ioctl_buf = buf;
                   1118:     acb->aiocb.aio_ioctl_cmd = req;
                   1119:     if (qemu_paio_ioctl(&acb->aiocb) < 0) {
                   1120:         raw_aio_remove(acb);
                   1121:         return NULL;
                   1122:     }
                   1123: 
                   1124:     return &acb->common;
                   1125: }
                   1126: #endif
                   1127: 
                   1128: #elif defined(__FreeBSD__)
                   1129: static int fd_open(BlockDriverState *bs)
                   1130: {
                   1131:     BDRVRawState *s = bs->opaque;
                   1132: 
                   1133:     /* this is just to ensure s->fd is sane (its called by io ops) */
                   1134:     if (s->fd >= 0)
                   1135:         return 0;
                   1136:     return -EIO;
                   1137: }
                   1138: #else /* !linux && !FreeBSD */
                   1139: 
                   1140: static int fd_open(BlockDriverState *bs)
                   1141: {
                   1142:     return 0;
                   1143: }
                   1144: 
                   1145: #endif /* !linux && !FreeBSD */
                   1146: 
                   1147: static int hdev_create(const char *filename, QEMUOptionParameter *options)
                   1148: {
                   1149:     int fd;
                   1150:     int ret = 0;
                   1151:     struct stat stat_buf;
                   1152:     int64_t total_size = 0;
                   1153: 
                   1154:     /* Read out options */
                   1155:     while (options && options->name) {
                   1156:         if (!strcmp(options->name, "size")) {
                   1157:             total_size = options->value.n / 512;
                   1158:         }
                   1159:         options++;
                   1160:     }
                   1161: 
                   1162:     fd = open(filename, O_WRONLY | O_BINARY);
                   1163:     if (fd < 0)
                   1164:         return -EIO;
                   1165: 
                   1166:     if (fstat(fd, &stat_buf) < 0)
                   1167:         ret = -EIO;
                   1168:     else if (!S_ISBLK(stat_buf.st_mode) && !S_ISCHR(stat_buf.st_mode))
                   1169:         ret = -EIO;
                   1170:     else if (lseek(fd, 0, SEEK_END) < total_size * 512)
                   1171:         ret = -ENOSPC;
                   1172: 
                   1173:     close(fd);
                   1174:     return ret;
                   1175: }
                   1176: 
                   1177: static BlockDriver bdrv_host_device = {
                   1178:     .format_name       = "host_device",
                   1179:     .instance_size     = sizeof(BDRVRawState),
                   1180:     .bdrv_probe_device = hdev_probe_device,
                   1181:     .bdrv_open         = hdev_open,
                   1182:     .bdrv_close                = raw_close,
                   1183:     .bdrv_create        = hdev_create,
                   1184:     .bdrv_flush                = raw_flush,
                   1185: 
                   1186: #ifdef CONFIG_AIO
                   1187:     .bdrv_aio_readv    = raw_aio_readv,
                   1188:     .bdrv_aio_writev   = raw_aio_writev,
                   1189: #endif
                   1190: 
                   1191:     .bdrv_read          = raw_read,
                   1192:     .bdrv_write         = raw_write,
                   1193:     .bdrv_getlength    = raw_getlength,
                   1194: 
                   1195:     /* generic scsi device */
                   1196: #ifdef __linux__
                   1197:     .bdrv_ioctl         = hdev_ioctl,
                   1198: #ifdef CONFIG_AIO
                   1199:     .bdrv_aio_ioctl     = hdev_aio_ioctl,
                   1200: #endif
                   1201: #endif
                   1202: };
                   1203: 
                   1204: #ifdef __linux__
                   1205: static int floppy_open(BlockDriverState *bs, const char *filename, int flags)
                   1206: {
                   1207:     BDRVRawState *s = bs->opaque;
                   1208:     int ret;
                   1209: 
                   1210:     posix_aio_init();
                   1211: 
                   1212:     s->type = FTYPE_FD;
                   1213: 
                   1214:     /* open will not fail even if no floppy is inserted, so add O_NONBLOCK */
                   1215:     ret = raw_open_common(bs, filename, flags, O_NONBLOCK);
                   1216:     if (ret)
                   1217:         return ret;
                   1218: 
                   1219:     /* close fd so that we can reopen it as needed */
                   1220:     close(s->fd);
                   1221:     s->fd = -1;
                   1222:     s->fd_media_changed = 1;
                   1223: 
                   1224:     return 0;
                   1225: }
                   1226: 
                   1227: static int floppy_probe_device(const char *filename)
                   1228: {
                   1229:     if (strstart(filename, "/dev/fd", NULL))
                   1230:         return 100;
                   1231:     return 0;
                   1232: }
                   1233: 
                   1234: 
                   1235: static int floppy_is_inserted(BlockDriverState *bs)
                   1236: {
                   1237:     return fd_open(bs) >= 0;
                   1238: }
                   1239: 
                   1240: static int floppy_media_changed(BlockDriverState *bs)
                   1241: {
                   1242:     BDRVRawState *s = bs->opaque;
                   1243:     int ret;
                   1244: 
                   1245:     /*
                   1246:      * XXX: we do not have a true media changed indication.
                   1247:      * It does not work if the floppy is changed without trying to read it.
                   1248:      */
                   1249:     fd_open(bs);
                   1250:     ret = s->fd_media_changed;
                   1251:     s->fd_media_changed = 0;
                   1252: #ifdef DEBUG_FLOPPY
                   1253:     printf("Floppy changed=%d\n", ret);
                   1254: #endif
                   1255:     return ret;
                   1256: }
                   1257: 
                   1258: static int floppy_eject(BlockDriverState *bs, int eject_flag)
                   1259: {
                   1260:     BDRVRawState *s = bs->opaque;
                   1261:     int fd;
                   1262: 
                   1263:     if (s->fd >= 0) {
                   1264:         close(s->fd);
                   1265:         s->fd = -1;
                   1266:     }
                   1267:     fd = open(bs->filename, s->open_flags | O_NONBLOCK);
                   1268:     if (fd >= 0) {
                   1269:         if (ioctl(fd, FDEJECT, 0) < 0)
                   1270:             perror("FDEJECT");
                   1271:         close(fd);
                   1272:     }
                   1273: 
                   1274:     return 0;
                   1275: }
                   1276: 
                   1277: static BlockDriver bdrv_host_floppy = {
                   1278:     .format_name        = "host_floppy",
                   1279:     .instance_size      = sizeof(BDRVRawState),
                   1280:     .bdrv_probe_device = floppy_probe_device,
                   1281:     .bdrv_open          = floppy_open,
                   1282:     .bdrv_close         = raw_close,
                   1283:     .bdrv_create        = hdev_create,
                   1284:     .bdrv_flush         = raw_flush,
                   1285: 
                   1286: #ifdef CONFIG_AIO
                   1287:     .bdrv_aio_readv     = raw_aio_readv,
                   1288:     .bdrv_aio_writev    = raw_aio_writev,
                   1289: #endif
                   1290: 
                   1291:     .bdrv_read          = raw_read,
                   1292:     .bdrv_write         = raw_write,
                   1293:     .bdrv_getlength    = raw_getlength,
                   1294: 
                   1295:     /* removable device support */
                   1296:     .bdrv_is_inserted   = floppy_is_inserted,
                   1297:     .bdrv_media_changed = floppy_media_changed,
                   1298:     .bdrv_eject         = floppy_eject,
                   1299: };
                   1300: 
                   1301: static int cdrom_open(BlockDriverState *bs, const char *filename, int flags)
                   1302: {
                   1303:     BDRVRawState *s = bs->opaque;
                   1304: 
                   1305:     s->type = FTYPE_CD;
                   1306: 
                   1307:     /* open will not fail even if no CD is inserted, so add O_NONBLOCK */
                   1308:     return raw_open_common(bs, filename, flags, O_NONBLOCK);
                   1309: }
                   1310: 
                   1311: static int cdrom_probe_device(const char *filename)
                   1312: {
                   1313:     if (strstart(filename, "/dev/cd", NULL))
                   1314:         return 100;
                   1315:     return 0;
                   1316: }
                   1317: 
                   1318: static int cdrom_is_inserted(BlockDriverState *bs)
                   1319: {
                   1320:     BDRVRawState *s = bs->opaque;
                   1321:     int ret;
                   1322: 
                   1323:     ret = ioctl(s->fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);
                   1324:     if (ret == CDS_DISC_OK)
                   1325:         return 1;
                   1326:     return 0;
                   1327: }
                   1328: 
                   1329: static int cdrom_eject(BlockDriverState *bs, int eject_flag)
                   1330: {
                   1331:     BDRVRawState *s = bs->opaque;
                   1332: 
                   1333:     if (eject_flag) {
                   1334:         if (ioctl(s->fd, CDROMEJECT, NULL) < 0)
                   1335:             perror("CDROMEJECT");
                   1336:     } else {
                   1337:         if (ioctl(s->fd, CDROMCLOSETRAY, NULL) < 0)
                   1338:             perror("CDROMEJECT");
                   1339:     }
                   1340: 
                   1341:     return 0;
                   1342: }
                   1343: 
                   1344: static int cdrom_set_locked(BlockDriverState *bs, int locked)
                   1345: {
                   1346:     BDRVRawState *s = bs->opaque;
                   1347: 
                   1348:     if (ioctl(s->fd, CDROM_LOCKDOOR, locked) < 0) {
                   1349:         /*
                   1350:          * Note: an error can happen if the distribution automatically
                   1351:          * mounts the CD-ROM
                   1352:          */
                   1353:         /* perror("CDROM_LOCKDOOR"); */
                   1354:     }
                   1355: 
                   1356:     return 0;
                   1357: }
                   1358: 
                   1359: static BlockDriver bdrv_host_cdrom = {
                   1360:     .format_name        = "host_cdrom",
                   1361:     .instance_size      = sizeof(BDRVRawState),
                   1362:     .bdrv_probe_device = cdrom_probe_device,
                   1363:     .bdrv_open          = cdrom_open,
                   1364:     .bdrv_close         = raw_close,
                   1365:     .bdrv_create        = hdev_create,
                   1366:     .bdrv_flush         = raw_flush,
                   1367: 
                   1368: #ifdef CONFIG_AIO
                   1369:     .bdrv_aio_readv     = raw_aio_readv,
                   1370:     .bdrv_aio_writev    = raw_aio_writev,
                   1371: #endif
                   1372: 
                   1373:     .bdrv_read          = raw_read,
                   1374:     .bdrv_write         = raw_write,
                   1375:     .bdrv_getlength     = raw_getlength,
                   1376: 
                   1377:     /* removable device support */
                   1378:     .bdrv_is_inserted   = cdrom_is_inserted,
                   1379:     .bdrv_eject         = cdrom_eject,
                   1380:     .bdrv_set_locked    = cdrom_set_locked,
                   1381: 
                   1382:     /* generic scsi device */
                   1383:     .bdrv_ioctl         = hdev_ioctl,
                   1384: #ifdef CONFIG_AIO
                   1385:     .bdrv_aio_ioctl     = hdev_aio_ioctl,
                   1386: #endif
                   1387: };
                   1388: #endif /* __linux__ */
                   1389: 
                   1390: #ifdef __FreeBSD__
                   1391: static int cdrom_open(BlockDriverState *bs, const char *filename, int flags)
                   1392: {
                   1393:     BDRVRawState *s = bs->opaque;
                   1394:     int ret;
                   1395: 
                   1396:     s->type = FTYPE_CD;
                   1397: 
                   1398:     ret = raw_open_common(bs, filename, flags, 0);
                   1399:     if (ret)
                   1400:         return ret;
                   1401: 
                   1402:     /* make sure the door isnt locked at this time */
                   1403:     ioctl(s->fd, CDIOCALLOW);
                   1404:     return 0;
                   1405: }
                   1406: 
                   1407: static int cdrom_probe_device(const char *filename)
                   1408: {
                   1409:     if (strstart(filename, "/dev/cd", NULL) ||
                   1410:             strstart(filename, "/dev/acd", NULL))
                   1411:         return 100;
                   1412:     return 0;
                   1413: }
                   1414: 
                   1415: static int cdrom_reopen(BlockDriverState *bs)
                   1416: {
                   1417:     BDRVRawState *s = bs->opaque;
                   1418:     int fd;
                   1419: 
                   1420:     /*
                   1421:      * Force reread of possibly changed/newly loaded disc,
                   1422:      * FreeBSD seems to not notice sometimes...
                   1423:      */
                   1424:     if (s->fd >= 0)
                   1425:         close(s->fd);
                   1426:     fd = open(bs->filename, s->open_flags, 0644);
                   1427:     if (fd < 0) {
                   1428:         s->fd = -1;
                   1429:         return -EIO;
                   1430:     }
                   1431:     s->fd = fd;
                   1432: 
                   1433:     /* make sure the door isnt locked at this time */
                   1434:     ioctl(s->fd, CDIOCALLOW);
                   1435:     return 0;
                   1436: }
                   1437: 
                   1438: static int cdrom_is_inserted(BlockDriverState *bs)
                   1439: {
                   1440:     return raw_getlength(bs) > 0;
                   1441: }
                   1442: 
                   1443: static int cdrom_eject(BlockDriverState *bs, int eject_flag)
                   1444: {
                   1445:     BDRVRawState *s = bs->opaque;
                   1446: 
                   1447:     if (s->fd < 0)
                   1448:         return -ENOTSUP;
                   1449: 
                   1450:     (void) ioctl(s->fd, CDIOCALLOW);
                   1451: 
                   1452:     if (eject_flag) {
                   1453:         if (ioctl(s->fd, CDIOCEJECT) < 0)
                   1454:             perror("CDIOCEJECT");
                   1455:     } else {
                   1456:         if (ioctl(s->fd, CDIOCCLOSE) < 0)
                   1457:             perror("CDIOCCLOSE");
                   1458:     }
                   1459: 
                   1460:     if (cdrom_reopen(bs) < 0)
                   1461:         return -ENOTSUP;
                   1462:     return 0;
                   1463: }
                   1464: 
                   1465: static int cdrom_set_locked(BlockDriverState *bs, int locked)
                   1466: {
                   1467:     BDRVRawState *s = bs->opaque;
                   1468: 
                   1469:     if (s->fd < 0)
                   1470:         return -ENOTSUP;
                   1471:     if (ioctl(s->fd, (locked ? CDIOCPREVENT : CDIOCALLOW)) < 0) {
                   1472:         /*
                   1473:          * Note: an error can happen if the distribution automatically
                   1474:          * mounts the CD-ROM
                   1475:          */
                   1476:         /* perror("CDROM_LOCKDOOR"); */
                   1477:     }
                   1478: 
                   1479:     return 0;
                   1480: }
                   1481: 
                   1482: static BlockDriver bdrv_host_cdrom = {
                   1483:     .format_name        = "host_cdrom",
                   1484:     .instance_size      = sizeof(BDRVRawState),
                   1485:     .bdrv_probe_device = cdrom_probe_device,
                   1486:     .bdrv_open          = cdrom_open,
                   1487:     .bdrv_close         = raw_close,
                   1488:     .bdrv_create        = hdev_create,
                   1489:     .bdrv_flush         = raw_flush,
                   1490: 
                   1491: #ifdef CONFIG_AIO
                   1492:     .bdrv_aio_readv     = raw_aio_readv,
                   1493:     .bdrv_aio_writev    = raw_aio_writev,
                   1494: #endif
                   1495: 
                   1496:     .bdrv_read          = raw_read,
                   1497:     .bdrv_write         = raw_write,
                   1498:     .bdrv_getlength     = raw_getlength,
                   1499: 
                   1500:     /* removable device support */
                   1501:     .bdrv_is_inserted   = cdrom_is_inserted,
                   1502:     .bdrv_eject         = cdrom_eject,
                   1503:     .bdrv_set_locked    = cdrom_set_locked,
                   1504: };
                   1505: #endif /* __FreeBSD__ */
                   1506: 
                   1507: static void bdrv_raw_init(void)
                   1508: {
                   1509:     /*
                   1510:      * Register all the drivers.  Note that order is important, the driver
                   1511:      * registered last will get probed first.
                   1512:      */
                   1513:     bdrv_register(&bdrv_raw);
                   1514:     bdrv_register(&bdrv_host_device);
                   1515: #ifdef __linux__
                   1516:     bdrv_register(&bdrv_host_floppy);
                   1517:     bdrv_register(&bdrv_host_cdrom);
                   1518: #endif
                   1519: #ifdef __FreeBSD__
                   1520:     bdrv_register(&bdrv_host_cdrom);
                   1521: #endif
                   1522: }
                   1523: 
                   1524: block_init(bdrv_raw_init);

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.