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