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

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

unix.superglobalmegacorp.com

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