Statistics
| Branch: | Revision:

root / block / raw-posix.c @ 343f8568

History | View | Annotate | Download (39.1 kB)

1
/*
2
 * Block driver for RAW files (posix)
3
 *
4
 * Copyright (c) 2006 Fabrice Bellard
5
 *
6
 * Permission is hereby granted, free of charge, to any person obtaining a copy
7
 * of this software and associated documentation files (the "Software"), to deal
8
 * in the Software without restriction, including without limitation the rights
9
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
 * copies of the Software, and to permit persons to whom the Software is
11
 * furnished to do so, subject to the following conditions:
12
 *
13
 * The above copyright notice and this permission notice shall be included in
14
 * all copies or substantial portions of the Software.
15
 *
16
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
19
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22
 * THE SOFTWARE.
23
 */
24
#include "qemu-common.h"
25
#include "qemu-timer.h"
26
#include "qemu-char.h"
27
#include "qemu-log.h"
28
#include "block_int.h"
29
#include "module.h"
30
#include "block/raw-posix-aio.h"
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 <sys/dkio.h>
47
#endif
48
#ifdef __linux__
49
#include <sys/types.h>
50
#include <sys/stat.h>
51
#include <sys/ioctl.h>
52
#include <sys/param.h>
53
#include <linux/cdrom.h>
54
#include <linux/fd.h>
55
#endif
56
#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
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 __NetBSD__
68
#include <sys/ioctl.h>
69
#include <sys/disklabel.h>
70
#include <sys/dkio.h>
71
#include <sys/disk.h>
72
#endif
73

    
74
#ifdef __DragonFly__
75
#include <sys/ioctl.h>
76
#include <sys/diskslice.h>
77
#endif
78

    
79
#ifdef CONFIG_XFS
80
#include <xfs/xfs.h>
81
#endif
82

    
83
//#define DEBUG_FLOPPY
84

    
85
//#define DEBUG_BLOCK
86
#if defined(DEBUG_BLOCK)
87
#define DEBUG_BLOCK_PRINT(formatCstr, ...) do { if (qemu_log_enabled()) \
88
    { qemu_log(formatCstr, ## __VA_ARGS__); qemu_log_flush(); } } while (0)
89
#else
90
#define DEBUG_BLOCK_PRINT(formatCstr, ...)
91
#endif
92

    
93
/* OS X does not have O_DSYNC */
94
#ifndef O_DSYNC
95
#ifdef O_SYNC
96
#define O_DSYNC O_SYNC
97
#elif defined(O_FSYNC)
98
#define O_DSYNC O_FSYNC
99
#endif
100
#endif
101

    
102
/* Approximate O_DIRECT with O_DSYNC if O_DIRECT isn't available */
103
#ifndef O_DIRECT
104
#define O_DIRECT O_DSYNC
105
#endif
106

    
107
#define FTYPE_FILE   0
108
#define FTYPE_CD     1
109
#define FTYPE_FD     2
110

    
111
/* if the FD is not accessed during that time (in ns), we try to
112
   reopen it to see if the disk has been changed */
113
#define FD_OPEN_TIMEOUT (1000000000)
114

    
115
#define MAX_BLOCKSIZE        4096
116

    
117
typedef struct BDRVRawState {
118
    int fd;
119
    int type;
120
    int open_flags;
121
#if defined(__linux__)
122
    /* linux floppy specific */
123
    int64_t fd_open_time;
124
    int64_t fd_error_time;
125
    int fd_got_error;
126
    int fd_media_changed;
127
#endif
128
#ifdef CONFIG_LINUX_AIO
129
    int use_aio;
130
    void *aio_ctx;
131
#endif
132
    uint8_t *aligned_buf;
133
    unsigned aligned_buf_size;
134
#ifdef CONFIG_XFS
135
    bool is_xfs : 1;
136
#endif
137
} BDRVRawState;
138

    
139
static int fd_open(BlockDriverState *bs);
140
static int64_t raw_getlength(BlockDriverState *bs);
141

    
142
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
143
static int cdrom_reopen(BlockDriverState *bs);
144
#endif
145

    
146
#if defined(__NetBSD__)
147
static int raw_normalize_devicepath(const char **filename)
148
{
149
    static char namebuf[PATH_MAX];
150
    const char *dp, *fname;
151
    struct stat sb;
152

    
153
    fname = *filename;
154
    dp = strrchr(fname, '/');
155
    if (lstat(fname, &sb) < 0) {
156
        fprintf(stderr, "%s: stat failed: %s\n",
157
            fname, strerror(errno));
158
        return -errno;
159
    }
160

    
161
    if (!S_ISBLK(sb.st_mode)) {
162
        return 0;
163
    }
164

    
165
    if (dp == NULL) {
166
        snprintf(namebuf, PATH_MAX, "r%s", fname);
167
    } else {
168
        snprintf(namebuf, PATH_MAX, "%.*s/r%s",
169
            (int)(dp - fname), fname, dp + 1);
170
    }
171
    fprintf(stderr, "%s is a block device", fname);
172
    *filename = namebuf;
173
    fprintf(stderr, ", using %s\n", *filename);
174

    
175
    return 0;
176
}
177
#else
178
static int raw_normalize_devicepath(const char **filename)
179
{
180
    return 0;
181
}
182
#endif
183

    
184
static int raw_open_common(BlockDriverState *bs, const char *filename,
185
                           int bdrv_flags, int open_flags)
186
{
187
    BDRVRawState *s = bs->opaque;
188
    int fd, ret;
189

    
190
    ret = raw_normalize_devicepath(&filename);
191
    if (ret != 0) {
192
        return ret;
193
    }
194

    
195
    s->open_flags = open_flags | O_BINARY;
196
    s->open_flags &= ~O_ACCMODE;
197
    if (bdrv_flags & BDRV_O_RDWR) {
198
        s->open_flags |= O_RDWR;
199
    } else {
200
        s->open_flags |= O_RDONLY;
201
    }
202

    
203
    /* Use O_DSYNC for write-through caching, no flags for write-back caching,
204
     * and O_DIRECT for no caching. */
205
    if ((bdrv_flags & BDRV_O_NOCACHE))
206
        s->open_flags |= O_DIRECT;
207
    if (!(bdrv_flags & BDRV_O_CACHE_WB))
208
        s->open_flags |= O_DSYNC;
209

    
210
    s->fd = -1;
211
    fd = qemu_open(filename, s->open_flags, 0644);
212
    if (fd < 0) {
213
        ret = -errno;
214
        if (ret == -EROFS)
215
            ret = -EACCES;
216
        return ret;
217
    }
218
    s->fd = fd;
219
    s->aligned_buf = NULL;
220

    
221
    if ((bdrv_flags & BDRV_O_NOCACHE)) {
222
        /*
223
         * Allocate a buffer for read/modify/write cycles.  Chose the size
224
         * pessimistically as we don't know the block size yet.
225
         */
226
        s->aligned_buf_size = 32 * MAX_BLOCKSIZE;
227
        s->aligned_buf = qemu_memalign(MAX_BLOCKSIZE, s->aligned_buf_size);
228
        if (s->aligned_buf == NULL) {
229
            goto out_close;
230
        }
231
    }
232

    
233
#ifdef CONFIG_LINUX_AIO
234
    if ((bdrv_flags & (BDRV_O_NOCACHE|BDRV_O_NATIVE_AIO)) ==
235
                      (BDRV_O_NOCACHE|BDRV_O_NATIVE_AIO)) {
236

    
237
        /* We're falling back to POSIX AIO in some cases */
238
        paio_init();
239

    
240
        s->aio_ctx = laio_init();
241
        if (!s->aio_ctx) {
242
            goto out_free_buf;
243
        }
244
        s->use_aio = 1;
245
    } else
246
#endif
247
    {
248
        if (paio_init() < 0) {
249
            goto out_free_buf;
250
        }
251
#ifdef CONFIG_LINUX_AIO
252
        s->use_aio = 0;
253
#endif
254
    }
255

    
256
#ifdef CONFIG_XFS
257
    if (platform_test_xfs_fd(s->fd)) {
258
        s->is_xfs = 1;
259
    }
260
#endif
261

    
262
    return 0;
263

    
264
out_free_buf:
265
    qemu_vfree(s->aligned_buf);
266
out_close:
267
    close(fd);
268
    return -errno;
269
}
270

    
271
static int raw_open(BlockDriverState *bs, const char *filename, int flags)
272
{
273
    BDRVRawState *s = bs->opaque;
274

    
275
    s->type = FTYPE_FILE;
276
    return raw_open_common(bs, filename, flags, 0);
277
}
278

    
279
/* XXX: use host sector size if necessary with:
280
#ifdef DIOCGSECTORSIZE
281
        {
282
            unsigned int sectorsize = 512;
283
            if (!ioctl(fd, DIOCGSECTORSIZE, &sectorsize) &&
284
                sectorsize > bufsize)
285
                bufsize = sectorsize;
286
        }
287
#endif
288
#ifdef CONFIG_COCOA
289
        uint32_t blockSize = 512;
290
        if ( !ioctl( fd, DKIOCGETBLOCKSIZE, &blockSize ) && blockSize > bufsize) {
291
            bufsize = blockSize;
292
        }
293
#endif
294
*/
295

    
296
/*
297
 * offset and count are in bytes, but must be multiples of 512 for files
298
 * opened with O_DIRECT. buf must be aligned to 512 bytes then.
299
 *
300
 * This function may be called without alignment if the caller ensures
301
 * that O_DIRECT is not in effect.
302
 */
303
static int raw_pread_aligned(BlockDriverState *bs, int64_t offset,
304
                     uint8_t *buf, int count)
305
{
306
    BDRVRawState *s = bs->opaque;
307
    int ret;
308

    
309
    ret = fd_open(bs);
310
    if (ret < 0)
311
        return ret;
312

    
313
    ret = pread(s->fd, buf, count, offset);
314
    if (ret == count)
315
        return ret;
316

    
317
    /* Allow reads beyond the end (needed for pwrite) */
318
    if ((ret == 0) && bs->growable) {
319
        int64_t size = raw_getlength(bs);
320
        if (offset >= size) {
321
            memset(buf, 0, count);
322
            return count;
323
        }
324
    }
325

    
326
    DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
327
                      "] read failed %d : %d = %s\n",
328
                      s->fd, bs->filename, offset, buf, count,
329
                      bs->total_sectors, ret, errno, strerror(errno));
330

    
331
    /* Try harder for CDrom. */
332
    if (s->type != FTYPE_FILE) {
333
        ret = pread(s->fd, buf, count, offset);
334
        if (ret == count)
335
            return ret;
336
        ret = pread(s->fd, buf, count, offset);
337
        if (ret == count)
338
            return ret;
339

    
340
        DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
341
                          "] retry read failed %d : %d = %s\n",
342
                          s->fd, bs->filename, offset, buf, count,
343
                          bs->total_sectors, ret, errno, strerror(errno));
344
    }
345

    
346
    return  (ret < 0) ? -errno : ret;
347
}
348

    
349
/*
350
 * offset and count are in bytes, but must be multiples of the sector size
351
 * for files opened with O_DIRECT. buf must be aligned to sector size bytes
352
 * then.
353
 *
354
 * This function may be called without alignment if the caller ensures
355
 * that O_DIRECT is not in effect.
356
 */
357
static int raw_pwrite_aligned(BlockDriverState *bs, int64_t offset,
358
                      const uint8_t *buf, int count)
359
{
360
    BDRVRawState *s = bs->opaque;
361
    int ret;
362

    
363
    ret = fd_open(bs);
364
    if (ret < 0)
365
        return -errno;
366

    
367
    ret = pwrite(s->fd, buf, count, offset);
368
    if (ret == count)
369
        return ret;
370

    
371
    DEBUG_BLOCK_PRINT("raw_pwrite(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
372
                      "] write failed %d : %d = %s\n",
373
                      s->fd, bs->filename, offset, buf, count,
374
                      bs->total_sectors, ret, errno, strerror(errno));
375

    
376
    return  (ret < 0) ? -errno : ret;
377
}
378

    
379

    
380
/*
381
 * offset and count are in bytes and possibly not aligned. For files opened
382
 * with O_DIRECT, necessary alignments are ensured before calling
383
 * raw_pread_aligned to do the actual read.
384
 */
385
static int raw_pread(BlockDriverState *bs, int64_t offset,
386
                     uint8_t *buf, int count)
387
{
388
    BDRVRawState *s = bs->opaque;
389
    unsigned sector_mask = bs->buffer_alignment - 1;
390
    int size, ret, shift, sum;
391

    
392
    sum = 0;
393

    
394
    if (s->aligned_buf != NULL)  {
395

    
396
        if (offset & sector_mask) {
397
            /* align offset on a sector size bytes boundary */
398

    
399
            shift = offset & sector_mask;
400
            size = (shift + count + sector_mask) & ~sector_mask;
401
            if (size > s->aligned_buf_size)
402
                size = s->aligned_buf_size;
403
            ret = raw_pread_aligned(bs, offset - shift, s->aligned_buf, size);
404
            if (ret < 0)
405
                return ret;
406

    
407
            size = bs->buffer_alignment - shift;
408
            if (size > count)
409
                size = count;
410
            memcpy(buf, s->aligned_buf + shift, size);
411

    
412
            buf += size;
413
            offset += size;
414
            count -= size;
415
            sum += size;
416

    
417
            if (count == 0)
418
                return sum;
419
        }
420
        if (count & sector_mask || (uintptr_t) buf & sector_mask) {
421

    
422
            /* read on aligned buffer */
423

    
424
            while (count) {
425

    
426
                size = (count + sector_mask) & ~sector_mask;
427
                if (size > s->aligned_buf_size)
428
                    size = s->aligned_buf_size;
429

    
430
                ret = raw_pread_aligned(bs, offset, s->aligned_buf, size);
431
                if (ret < 0) {
432
                    return ret;
433
                } else if (ret == 0) {
434
                    fprintf(stderr, "raw_pread: read beyond end of file\n");
435
                    abort();
436
                }
437

    
438
                size = ret;
439
                if (size > count)
440
                    size = count;
441

    
442
                memcpy(buf, s->aligned_buf, size);
443

    
444
                buf += size;
445
                offset += size;
446
                count -= size;
447
                sum += size;
448
            }
449

    
450
            return sum;
451
        }
452
    }
453

    
454
    return raw_pread_aligned(bs, offset, buf, count) + sum;
455
}
456

    
457
static int raw_read(BlockDriverState *bs, int64_t sector_num,
458
                    uint8_t *buf, int nb_sectors)
459
{
460
    int ret;
461

    
462
    ret = raw_pread(bs, sector_num * BDRV_SECTOR_SIZE, buf,
463
                    nb_sectors * BDRV_SECTOR_SIZE);
464
    if (ret == (nb_sectors * BDRV_SECTOR_SIZE))
465
        ret = 0;
466
    return ret;
467
}
468

    
469
/*
470
 * offset and count are in bytes and possibly not aligned. For files opened
471
 * with O_DIRECT, necessary alignments are ensured before calling
472
 * raw_pwrite_aligned to do the actual write.
473
 */
474
static int raw_pwrite(BlockDriverState *bs, int64_t offset,
475
                      const uint8_t *buf, int count)
476
{
477
    BDRVRawState *s = bs->opaque;
478
    unsigned sector_mask = bs->buffer_alignment - 1;
479
    int size, ret, shift, sum;
480

    
481
    sum = 0;
482

    
483
    if (s->aligned_buf != NULL) {
484

    
485
        if (offset & sector_mask) {
486
            /* align offset on a sector size bytes boundary */
487
            shift = offset & sector_mask;
488
            ret = raw_pread_aligned(bs, offset - shift, s->aligned_buf,
489
                                    bs->buffer_alignment);
490
            if (ret < 0)
491
                return ret;
492

    
493
            size = bs->buffer_alignment - shift;
494
            if (size > count)
495
                size = count;
496
            memcpy(s->aligned_buf + shift, buf, size);
497

    
498
            ret = raw_pwrite_aligned(bs, offset - shift, s->aligned_buf,
499
                                     bs->buffer_alignment);
500
            if (ret < 0)
501
                return ret;
502

    
503
            buf += size;
504
            offset += size;
505
            count -= size;
506
            sum += size;
507

    
508
            if (count == 0)
509
                return sum;
510
        }
511
        if (count & sector_mask || (uintptr_t) buf & sector_mask) {
512

    
513
            while ((size = (count & ~sector_mask)) != 0) {
514

    
515
                if (size > s->aligned_buf_size)
516
                    size = s->aligned_buf_size;
517

    
518
                memcpy(s->aligned_buf, buf, size);
519

    
520
                ret = raw_pwrite_aligned(bs, offset, s->aligned_buf, size);
521
                if (ret < 0)
522
                    return ret;
523

    
524
                buf += ret;
525
                offset += ret;
526
                count -= ret;
527
                sum += ret;
528
            }
529
            /* here, count < sector_size because (count & ~sector_mask) == 0 */
530
            if (count) {
531
                ret = raw_pread_aligned(bs, offset, s->aligned_buf,
532
                                     bs->buffer_alignment);
533
                if (ret < 0)
534
                    return ret;
535
                 memcpy(s->aligned_buf, buf, count);
536

    
537
                 ret = raw_pwrite_aligned(bs, offset, s->aligned_buf,
538
                                     bs->buffer_alignment);
539
                 if (ret < 0)
540
                     return ret;
541
                 if (count < ret)
542
                     ret = count;
543

    
544
                 sum += ret;
545
            }
546
            return sum;
547
        }
548
    }
549
    return raw_pwrite_aligned(bs, offset, buf, count) + sum;
550
}
551

    
552
static int raw_write(BlockDriverState *bs, int64_t sector_num,
553
                     const uint8_t *buf, int nb_sectors)
554
{
555
    int ret;
556
    ret = raw_pwrite(bs, sector_num * BDRV_SECTOR_SIZE, buf,
557
                     nb_sectors * BDRV_SECTOR_SIZE);
558
    if (ret == (nb_sectors * BDRV_SECTOR_SIZE))
559
        ret = 0;
560
    return ret;
561
}
562

    
563
/*
564
 * Check if all memory in this vector is sector aligned.
565
 */
566
static int qiov_is_aligned(BlockDriverState *bs, QEMUIOVector *qiov)
567
{
568
    int i;
569

    
570
    for (i = 0; i < qiov->niov; i++) {
571
        if ((uintptr_t) qiov->iov[i].iov_base % bs->buffer_alignment) {
572
            return 0;
573
        }
574
    }
575

    
576
    return 1;
577
}
578

    
579
static BlockDriverAIOCB *raw_aio_submit(BlockDriverState *bs,
580
        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
581
        BlockDriverCompletionFunc *cb, void *opaque, int type)
582
{
583
    BDRVRawState *s = bs->opaque;
584

    
585
    if (fd_open(bs) < 0)
586
        return NULL;
587

    
588
    /*
589
     * If O_DIRECT is used the buffer needs to be aligned on a sector
590
     * boundary.  Check if this is the case or telll the low-level
591
     * driver that it needs to copy the buffer.
592
     */
593
    if (s->aligned_buf) {
594
        if (!qiov_is_aligned(bs, qiov)) {
595
            type |= QEMU_AIO_MISALIGNED;
596
#ifdef CONFIG_LINUX_AIO
597
        } else if (s->use_aio) {
598
            return laio_submit(bs, s->aio_ctx, s->fd, sector_num, qiov,
599
                               nb_sectors, cb, opaque, type);
600
#endif
601
        }
602
    }
603

    
604
    return paio_submit(bs, s->fd, sector_num, qiov, nb_sectors,
605
                       cb, opaque, type);
606
}
607

    
608
static BlockDriverAIOCB *raw_aio_readv(BlockDriverState *bs,
609
        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
610
        BlockDriverCompletionFunc *cb, void *opaque)
611
{
612
    return raw_aio_submit(bs, sector_num, qiov, nb_sectors,
613
                          cb, opaque, QEMU_AIO_READ);
614
}
615

    
616
static BlockDriverAIOCB *raw_aio_writev(BlockDriverState *bs,
617
        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
618
        BlockDriverCompletionFunc *cb, void *opaque)
619
{
620
    return raw_aio_submit(bs, sector_num, qiov, nb_sectors,
621
                          cb, opaque, QEMU_AIO_WRITE);
622
}
623

    
624
static BlockDriverAIOCB *raw_aio_flush(BlockDriverState *bs,
625
        BlockDriverCompletionFunc *cb, void *opaque)
626
{
627
    BDRVRawState *s = bs->opaque;
628

    
629
    if (fd_open(bs) < 0)
630
        return NULL;
631

    
632
    return paio_submit(bs, s->fd, 0, NULL, 0, cb, opaque, QEMU_AIO_FLUSH);
633
}
634

    
635
static void raw_close(BlockDriverState *bs)
636
{
637
    BDRVRawState *s = bs->opaque;
638
    if (s->fd >= 0) {
639
        close(s->fd);
640
        s->fd = -1;
641
        if (s->aligned_buf != NULL)
642
            qemu_vfree(s->aligned_buf);
643
    }
644
}
645

    
646
static int raw_truncate(BlockDriverState *bs, int64_t offset)
647
{
648
    BDRVRawState *s = bs->opaque;
649
    if (s->type != FTYPE_FILE)
650
        return -ENOTSUP;
651
    if (ftruncate(s->fd, offset) < 0)
652
        return -errno;
653
    return 0;
654
}
655

    
656
#ifdef __OpenBSD__
657
static int64_t raw_getlength(BlockDriverState *bs)
658
{
659
    BDRVRawState *s = bs->opaque;
660
    int fd = s->fd;
661
    struct stat st;
662

    
663
    if (fstat(fd, &st))
664
        return -1;
665
    if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) {
666
        struct disklabel dl;
667

    
668
        if (ioctl(fd, DIOCGDINFO, &dl))
669
            return -1;
670
        return (uint64_t)dl.d_secsize *
671
            dl.d_partitions[DISKPART(st.st_rdev)].p_size;
672
    } else
673
        return st.st_size;
674
}
675
#elif defined(__NetBSD__)
676
static int64_t raw_getlength(BlockDriverState *bs)
677
{
678
    BDRVRawState *s = bs->opaque;
679
    int fd = s->fd;
680
    struct stat st;
681

    
682
    if (fstat(fd, &st))
683
        return -1;
684
    if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) {
685
        struct dkwedge_info dkw;
686

    
687
        if (ioctl(fd, DIOCGWEDGEINFO, &dkw) != -1) {
688
            return dkw.dkw_size * 512;
689
        } else {
690
            struct disklabel dl;
691

    
692
            if (ioctl(fd, DIOCGDINFO, &dl))
693
                return -1;
694
            return (uint64_t)dl.d_secsize *
695
                dl.d_partitions[DISKPART(st.st_rdev)].p_size;
696
        }
697
    } else
698
        return st.st_size;
699
}
700
#elif defined(__sun__)
701
static int64_t raw_getlength(BlockDriverState *bs)
702
{
703
    BDRVRawState *s = bs->opaque;
704
    struct dk_minfo minfo;
705
    int ret;
706

    
707
    ret = fd_open(bs);
708
    if (ret < 0) {
709
        return ret;
710
    }
711

    
712
    /*
713
     * Use the DKIOCGMEDIAINFO ioctl to read the size.
714
     */
715
    ret = ioctl(s->fd, DKIOCGMEDIAINFO, &minfo);
716
    if (ret != -1) {
717
        return minfo.dki_lbsize * minfo.dki_capacity;
718
    }
719

    
720
    /*
721
     * There are reports that lseek on some devices fails, but
722
     * irc discussion said that contingency on contingency was overkill.
723
     */
724
    return lseek(s->fd, 0, SEEK_END);
725
}
726
#elif defined(CONFIG_BSD)
727
static int64_t raw_getlength(BlockDriverState *bs)
728
{
729
    BDRVRawState *s = bs->opaque;
730
    int fd = s->fd;
731
    int64_t size;
732
    struct stat sb;
733
#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
734
    int reopened = 0;
735
#endif
736
    int ret;
737

    
738
    ret = fd_open(bs);
739
    if (ret < 0)
740
        return ret;
741

    
742
#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
743
again:
744
#endif
745
    if (!fstat(fd, &sb) && (S_IFCHR & sb.st_mode)) {
746
#ifdef DIOCGMEDIASIZE
747
        if (ioctl(fd, DIOCGMEDIASIZE, (off_t *)&size))
748
#elif defined(DIOCGPART)
749
        {
750
                struct partinfo pi;
751
                if (ioctl(fd, DIOCGPART, &pi) == 0)
752
                        size = pi.media_size;
753
                else
754
                        size = 0;
755
        }
756
        if (size == 0)
757
#endif
758
#ifdef CONFIG_COCOA
759
        size = LONG_LONG_MAX;
760
#else
761
        size = lseek(fd, 0LL, SEEK_END);
762
#endif
763
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
764
        switch(s->type) {
765
        case FTYPE_CD:
766
            /* XXX FreeBSD acd returns UINT_MAX sectors for an empty drive */
767
            if (size == 2048LL * (unsigned)-1)
768
                size = 0;
769
            /* XXX no disc?  maybe we need to reopen... */
770
            if (size <= 0 && !reopened && cdrom_reopen(bs) >= 0) {
771
                reopened = 1;
772
                goto again;
773
            }
774
        }
775
#endif
776
    } else {
777
        size = lseek(fd, 0, SEEK_END);
778
    }
779
    return size;
780
}
781
#else
782
static int64_t raw_getlength(BlockDriverState *bs)
783
{
784
    BDRVRawState *s = bs->opaque;
785
    int ret;
786

    
787
    ret = fd_open(bs);
788
    if (ret < 0) {
789
        return ret;
790
    }
791

    
792
    return lseek(s->fd, 0, SEEK_END);
793
}
794
#endif
795

    
796
static int raw_create(const char *filename, QEMUOptionParameter *options)
797
{
798
    int fd;
799
    int result = 0;
800
    int64_t total_size = 0;
801

    
802
    /* Read out options */
803
    while (options && options->name) {
804
        if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
805
            total_size = options->value.n / BDRV_SECTOR_SIZE;
806
        }
807
        options++;
808
    }
809

    
810
    fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
811
              0644);
812
    if (fd < 0) {
813
        result = -errno;
814
    } else {
815
        if (ftruncate(fd, total_size * BDRV_SECTOR_SIZE) != 0) {
816
            result = -errno;
817
        }
818
        if (close(fd) != 0) {
819
            result = -errno;
820
        }
821
    }
822
    return result;
823
}
824

    
825
static int raw_flush(BlockDriverState *bs)
826
{
827
    BDRVRawState *s = bs->opaque;
828
    return qemu_fdatasync(s->fd);
829
}
830

    
831
#ifdef CONFIG_XFS
832
static int xfs_discard(BDRVRawState *s, int64_t sector_num, int nb_sectors)
833
{
834
    struct xfs_flock64 fl;
835

    
836
    memset(&fl, 0, sizeof(fl));
837
    fl.l_whence = SEEK_SET;
838
    fl.l_start = sector_num << 9;
839
    fl.l_len = (int64_t)nb_sectors << 9;
840

    
841
    if (xfsctl(NULL, s->fd, XFS_IOC_UNRESVSP64, &fl) < 0) {
842
        DEBUG_BLOCK_PRINT("cannot punch hole (%s)\n", strerror(errno));
843
        return -errno;
844
    }
845

    
846
    return 0;
847
}
848
#endif
849

    
850
static int raw_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors)
851
{
852
#ifdef CONFIG_XFS
853
    BDRVRawState *s = bs->opaque;
854

    
855
    if (s->is_xfs) {
856
        return xfs_discard(s, sector_num, nb_sectors);
857
    }
858
#endif
859

    
860
    return 0;
861
}
862

    
863
static QEMUOptionParameter raw_create_options[] = {
864
    {
865
        .name = BLOCK_OPT_SIZE,
866
        .type = OPT_SIZE,
867
        .help = "Virtual disk size"
868
    },
869
    { NULL }
870
};
871

    
872
static BlockDriver bdrv_file = {
873
    .format_name = "file",
874
    .protocol_name = "file",
875
    .instance_size = sizeof(BDRVRawState),
876
    .bdrv_probe = NULL, /* no probe for protocols */
877
    .bdrv_file_open = raw_open,
878
    .bdrv_read = raw_read,
879
    .bdrv_write = raw_write,
880
    .bdrv_close = raw_close,
881
    .bdrv_create = raw_create,
882
    .bdrv_flush = raw_flush,
883
    .bdrv_discard = raw_discard,
884

    
885
    .bdrv_aio_readv = raw_aio_readv,
886
    .bdrv_aio_writev = raw_aio_writev,
887
    .bdrv_aio_flush = raw_aio_flush,
888

    
889
    .bdrv_truncate = raw_truncate,
890
    .bdrv_getlength = raw_getlength,
891

    
892
    .create_options = raw_create_options,
893
};
894

    
895
/***********************************************/
896
/* host device */
897

    
898
#ifdef CONFIG_COCOA
899
static kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator );
900
static kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize );
901

    
902
kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator )
903
{
904
    kern_return_t       kernResult;
905
    mach_port_t     masterPort;
906
    CFMutableDictionaryRef  classesToMatch;
907

    
908
    kernResult = IOMasterPort( MACH_PORT_NULL, &masterPort );
909
    if ( KERN_SUCCESS != kernResult ) {
910
        printf( "IOMasterPort returned %d\n", kernResult );
911
    }
912

    
913
    classesToMatch = IOServiceMatching( kIOCDMediaClass );
914
    if ( classesToMatch == NULL ) {
915
        printf( "IOServiceMatching returned a NULL dictionary.\n" );
916
    } else {
917
    CFDictionarySetValue( classesToMatch, CFSTR( kIOMediaEjectableKey ), kCFBooleanTrue );
918
    }
919
    kernResult = IOServiceGetMatchingServices( masterPort, classesToMatch, mediaIterator );
920
    if ( KERN_SUCCESS != kernResult )
921
    {
922
        printf( "IOServiceGetMatchingServices returned %d\n", kernResult );
923
    }
924

    
925
    return kernResult;
926
}
927

    
928
kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize )
929
{
930
    io_object_t     nextMedia;
931
    kern_return_t   kernResult = KERN_FAILURE;
932
    *bsdPath = '\0';
933
    nextMedia = IOIteratorNext( mediaIterator );
934
    if ( nextMedia )
935
    {
936
        CFTypeRef   bsdPathAsCFString;
937
    bsdPathAsCFString = IORegistryEntryCreateCFProperty( nextMedia, CFSTR( kIOBSDNameKey ), kCFAllocatorDefault, 0 );
938
        if ( bsdPathAsCFString ) {
939
            size_t devPathLength;
940
            strcpy( bsdPath, _PATH_DEV );
941
            strcat( bsdPath, "r" );
942
            devPathLength = strlen( bsdPath );
943
            if ( CFStringGetCString( bsdPathAsCFString, bsdPath + devPathLength, maxPathSize - devPathLength, kCFStringEncodingASCII ) ) {
944
                kernResult = KERN_SUCCESS;
945
            }
946
            CFRelease( bsdPathAsCFString );
947
        }
948
        IOObjectRelease( nextMedia );
949
    }
950

    
951
    return kernResult;
952
}
953

    
954
#endif
955

    
956
static int hdev_probe_device(const char *filename)
957
{
958
    struct stat st;
959

    
960
    /* allow a dedicated CD-ROM driver to match with a higher priority */
961
    if (strstart(filename, "/dev/cdrom", NULL))
962
        return 50;
963

    
964
    if (stat(filename, &st) >= 0 &&
965
            (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode))) {
966
        return 100;
967
    }
968

    
969
    return 0;
970
}
971

    
972
static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
973
{
974
    BDRVRawState *s = bs->opaque;
975

    
976
#ifdef CONFIG_COCOA
977
    if (strstart(filename, "/dev/cdrom", NULL)) {
978
        kern_return_t kernResult;
979
        io_iterator_t mediaIterator;
980
        char bsdPath[ MAXPATHLEN ];
981
        int fd;
982

    
983
        kernResult = FindEjectableCDMedia( &mediaIterator );
984
        kernResult = GetBSDPath( mediaIterator, bsdPath, sizeof( bsdPath ) );
985

    
986
        if ( bsdPath[ 0 ] != '\0' ) {
987
            strcat(bsdPath,"s0");
988
            /* some CDs don't have a partition 0 */
989
            fd = open(bsdPath, O_RDONLY | O_BINARY | O_LARGEFILE);
990
            if (fd < 0) {
991
                bsdPath[strlen(bsdPath)-1] = '1';
992
            } else {
993
                close(fd);
994
            }
995
            filename = bsdPath;
996
        }
997

    
998
        if ( mediaIterator )
999
            IOObjectRelease( mediaIterator );
1000
    }
1001
#endif
1002

    
1003
    s->type = FTYPE_FILE;
1004
#if defined(__linux__)
1005
    {
1006
        char resolved_path[ MAXPATHLEN ], *temp;
1007

    
1008
        temp = realpath(filename, resolved_path);
1009
        if (temp && strstart(temp, "/dev/sg", NULL)) {
1010
            bs->sg = 1;
1011
        }
1012
    }
1013
#endif
1014

    
1015
    return raw_open_common(bs, filename, flags, 0);
1016
}
1017

    
1018
#if defined(__linux__)
1019
/* Note: we do not have a reliable method to detect if the floppy is
1020
   present. The current method is to try to open the floppy at every
1021
   I/O and to keep it opened during a few hundreds of ms. */
1022
static int fd_open(BlockDriverState *bs)
1023
{
1024
    BDRVRawState *s = bs->opaque;
1025
    int last_media_present;
1026

    
1027
    if (s->type != FTYPE_FD)
1028
        return 0;
1029
    last_media_present = (s->fd >= 0);
1030
    if (s->fd >= 0 &&
1031
        (get_clock() - s->fd_open_time) >= FD_OPEN_TIMEOUT) {
1032
        close(s->fd);
1033
        s->fd = -1;
1034
#ifdef DEBUG_FLOPPY
1035
        printf("Floppy closed\n");
1036
#endif
1037
    }
1038
    if (s->fd < 0) {
1039
        if (s->fd_got_error &&
1040
            (get_clock() - s->fd_error_time) < FD_OPEN_TIMEOUT) {
1041
#ifdef DEBUG_FLOPPY
1042
            printf("No floppy (open delayed)\n");
1043
#endif
1044
            return -EIO;
1045
        }
1046
        s->fd = open(bs->filename, s->open_flags & ~O_NONBLOCK);
1047
        if (s->fd < 0) {
1048
            s->fd_error_time = get_clock();
1049
            s->fd_got_error = 1;
1050
            if (last_media_present)
1051
                s->fd_media_changed = 1;
1052
#ifdef DEBUG_FLOPPY
1053
            printf("No floppy\n");
1054
#endif
1055
            return -EIO;
1056
        }
1057
#ifdef DEBUG_FLOPPY
1058
        printf("Floppy opened\n");
1059
#endif
1060
    }
1061
    if (!last_media_present)
1062
        s->fd_media_changed = 1;
1063
    s->fd_open_time = get_clock();
1064
    s->fd_got_error = 0;
1065
    return 0;
1066
}
1067

    
1068
static int hdev_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
1069
{
1070
    BDRVRawState *s = bs->opaque;
1071

    
1072
    return ioctl(s->fd, req, buf);
1073
}
1074

    
1075
static BlockDriverAIOCB *hdev_aio_ioctl(BlockDriverState *bs,
1076
        unsigned long int req, void *buf,
1077
        BlockDriverCompletionFunc *cb, void *opaque)
1078
{
1079
    BDRVRawState *s = bs->opaque;
1080

    
1081
    if (fd_open(bs) < 0)
1082
        return NULL;
1083
    return paio_ioctl(bs, s->fd, req, buf, cb, opaque);
1084
}
1085

    
1086
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1087
static int fd_open(BlockDriverState *bs)
1088
{
1089
    BDRVRawState *s = bs->opaque;
1090

    
1091
    /* this is just to ensure s->fd is sane (its called by io ops) */
1092
    if (s->fd >= 0)
1093
        return 0;
1094
    return -EIO;
1095
}
1096
#else /* !linux && !FreeBSD */
1097

    
1098
static int fd_open(BlockDriverState *bs)
1099
{
1100
    return 0;
1101
}
1102

    
1103
#endif /* !linux && !FreeBSD */
1104

    
1105
static int hdev_create(const char *filename, QEMUOptionParameter *options)
1106
{
1107
    int fd;
1108
    int ret = 0;
1109
    struct stat stat_buf;
1110
    int64_t total_size = 0;
1111

    
1112
    /* Read out options */
1113
    while (options && options->name) {
1114
        if (!strcmp(options->name, "size")) {
1115
            total_size = options->value.n / BDRV_SECTOR_SIZE;
1116
        }
1117
        options++;
1118
    }
1119

    
1120
    fd = open(filename, O_WRONLY | O_BINARY);
1121
    if (fd < 0)
1122
        return -errno;
1123

    
1124
    if (fstat(fd, &stat_buf) < 0)
1125
        ret = -errno;
1126
    else if (!S_ISBLK(stat_buf.st_mode) && !S_ISCHR(stat_buf.st_mode))
1127
        ret = -ENODEV;
1128
    else if (lseek(fd, 0, SEEK_END) < total_size * BDRV_SECTOR_SIZE)
1129
        ret = -ENOSPC;
1130

    
1131
    close(fd);
1132
    return ret;
1133
}
1134

    
1135
static int hdev_has_zero_init(BlockDriverState *bs)
1136
{
1137
    return 0;
1138
}
1139

    
1140
static BlockDriver bdrv_host_device = {
1141
    .format_name        = "host_device",
1142
    .protocol_name        = "host_device",
1143
    .instance_size      = sizeof(BDRVRawState),
1144
    .bdrv_probe_device  = hdev_probe_device,
1145
    .bdrv_file_open     = hdev_open,
1146
    .bdrv_close         = raw_close,
1147
    .bdrv_create        = hdev_create,
1148
    .create_options     = raw_create_options,
1149
    .bdrv_has_zero_init = hdev_has_zero_init,
1150
    .bdrv_flush         = raw_flush,
1151

    
1152
    .bdrv_aio_readv        = raw_aio_readv,
1153
    .bdrv_aio_writev        = raw_aio_writev,
1154
    .bdrv_aio_flush        = raw_aio_flush,
1155

    
1156
    .bdrv_read          = raw_read,
1157
    .bdrv_write         = raw_write,
1158
    .bdrv_getlength        = raw_getlength,
1159

    
1160
    /* generic scsi device */
1161
#ifdef __linux__
1162
    .bdrv_ioctl         = hdev_ioctl,
1163
    .bdrv_aio_ioctl     = hdev_aio_ioctl,
1164
#endif
1165
};
1166

    
1167
#ifdef __linux__
1168
static int floppy_open(BlockDriverState *bs, const char *filename, int flags)
1169
{
1170
    BDRVRawState *s = bs->opaque;
1171
    int ret;
1172

    
1173
    s->type = FTYPE_FD;
1174

    
1175
    /* open will not fail even if no floppy is inserted, so add O_NONBLOCK */
1176
    ret = raw_open_common(bs, filename, flags, O_NONBLOCK);
1177
    if (ret)
1178
        return ret;
1179

    
1180
    /* close fd so that we can reopen it as needed */
1181
    close(s->fd);
1182
    s->fd = -1;
1183
    s->fd_media_changed = 1;
1184

    
1185
    return 0;
1186
}
1187

    
1188
static int floppy_probe_device(const char *filename)
1189
{
1190
    int fd, ret;
1191
    int prio = 0;
1192
    struct floppy_struct fdparam;
1193
    struct stat st;
1194

    
1195
    if (strstart(filename, "/dev/fd", NULL))
1196
        prio = 50;
1197

    
1198
    fd = open(filename, O_RDONLY | O_NONBLOCK);
1199
    if (fd < 0) {
1200
        goto out;
1201
    }
1202
    ret = fstat(fd, &st);
1203
    if (ret == -1 || !S_ISBLK(st.st_mode)) {
1204
        goto outc;
1205
    }
1206

    
1207
    /* Attempt to detect via a floppy specific ioctl */
1208
    ret = ioctl(fd, FDGETPRM, &fdparam);
1209
    if (ret >= 0)
1210
        prio = 100;
1211

    
1212
outc:
1213
    close(fd);
1214
out:
1215
    return prio;
1216
}
1217

    
1218

    
1219
static int floppy_is_inserted(BlockDriverState *bs)
1220
{
1221
    return fd_open(bs) >= 0;
1222
}
1223

    
1224
static int floppy_media_changed(BlockDriverState *bs)
1225
{
1226
    BDRVRawState *s = bs->opaque;
1227
    int ret;
1228

    
1229
    /*
1230
     * XXX: we do not have a true media changed indication.
1231
     * It does not work if the floppy is changed without trying to read it.
1232
     */
1233
    fd_open(bs);
1234
    ret = s->fd_media_changed;
1235
    s->fd_media_changed = 0;
1236
#ifdef DEBUG_FLOPPY
1237
    printf("Floppy changed=%d\n", ret);
1238
#endif
1239
    return ret;
1240
}
1241

    
1242
static int floppy_eject(BlockDriverState *bs, int eject_flag)
1243
{
1244
    BDRVRawState *s = bs->opaque;
1245
    int fd;
1246

    
1247
    if (s->fd >= 0) {
1248
        close(s->fd);
1249
        s->fd = -1;
1250
    }
1251
    fd = open(bs->filename, s->open_flags | O_NONBLOCK);
1252
    if (fd >= 0) {
1253
        if (ioctl(fd, FDEJECT, 0) < 0)
1254
            perror("FDEJECT");
1255
        close(fd);
1256
    }
1257

    
1258
    return 0;
1259
}
1260

    
1261
static BlockDriver bdrv_host_floppy = {
1262
    .format_name        = "host_floppy",
1263
    .protocol_name      = "host_floppy",
1264
    .instance_size      = sizeof(BDRVRawState),
1265
    .bdrv_probe_device        = floppy_probe_device,
1266
    .bdrv_file_open     = floppy_open,
1267
    .bdrv_close         = raw_close,
1268
    .bdrv_create        = hdev_create,
1269
    .create_options     = raw_create_options,
1270
    .bdrv_has_zero_init = hdev_has_zero_init,
1271
    .bdrv_flush         = raw_flush,
1272

    
1273
    .bdrv_aio_readv     = raw_aio_readv,
1274
    .bdrv_aio_writev    = raw_aio_writev,
1275
    .bdrv_aio_flush        = raw_aio_flush,
1276

    
1277
    .bdrv_read          = raw_read,
1278
    .bdrv_write         = raw_write,
1279
    .bdrv_getlength        = raw_getlength,
1280

    
1281
    /* removable device support */
1282
    .bdrv_is_inserted   = floppy_is_inserted,
1283
    .bdrv_media_changed = floppy_media_changed,
1284
    .bdrv_eject         = floppy_eject,
1285
};
1286

    
1287
static int cdrom_open(BlockDriverState *bs, const char *filename, int flags)
1288
{
1289
    BDRVRawState *s = bs->opaque;
1290

    
1291
    s->type = FTYPE_CD;
1292

    
1293
    /* open will not fail even if no CD is inserted, so add O_NONBLOCK */
1294
    return raw_open_common(bs, filename, flags, O_NONBLOCK);
1295
}
1296

    
1297
static int cdrom_probe_device(const char *filename)
1298
{
1299
    int fd, ret;
1300
    int prio = 0;
1301
    struct stat st;
1302

    
1303
    fd = open(filename, O_RDONLY | O_NONBLOCK);
1304
    if (fd < 0) {
1305
        goto out;
1306
    }
1307
    ret = fstat(fd, &st);
1308
    if (ret == -1 || !S_ISBLK(st.st_mode)) {
1309
        goto outc;
1310
    }
1311

    
1312
    /* Attempt to detect via a CDROM specific ioctl */
1313
    ret = ioctl(fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);
1314
    if (ret >= 0)
1315
        prio = 100;
1316

    
1317
outc:
1318
    close(fd);
1319
out:
1320
    return prio;
1321
}
1322

    
1323
static int cdrom_is_inserted(BlockDriverState *bs)
1324
{
1325
    BDRVRawState *s = bs->opaque;
1326
    int ret;
1327

    
1328
    ret = ioctl(s->fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);
1329
    if (ret == CDS_DISC_OK)
1330
        return 1;
1331
    return 0;
1332
}
1333

    
1334
static int cdrom_eject(BlockDriverState *bs, int eject_flag)
1335
{
1336
    BDRVRawState *s = bs->opaque;
1337

    
1338
    if (eject_flag) {
1339
        if (ioctl(s->fd, CDROMEJECT, NULL) < 0)
1340
            perror("CDROMEJECT");
1341
    } else {
1342
        if (ioctl(s->fd, CDROMCLOSETRAY, NULL) < 0)
1343
            perror("CDROMEJECT");
1344
    }
1345

    
1346
    return 0;
1347
}
1348

    
1349
static int cdrom_set_locked(BlockDriverState *bs, int locked)
1350
{
1351
    BDRVRawState *s = bs->opaque;
1352

    
1353
    if (ioctl(s->fd, CDROM_LOCKDOOR, locked) < 0) {
1354
        /*
1355
         * Note: an error can happen if the distribution automatically
1356
         * mounts the CD-ROM
1357
         */
1358
        /* perror("CDROM_LOCKDOOR"); */
1359
    }
1360

    
1361
    return 0;
1362
}
1363

    
1364
static BlockDriver bdrv_host_cdrom = {
1365
    .format_name        = "host_cdrom",
1366
    .protocol_name      = "host_cdrom",
1367
    .instance_size      = sizeof(BDRVRawState),
1368
    .bdrv_probe_device        = cdrom_probe_device,
1369
    .bdrv_file_open     = cdrom_open,
1370
    .bdrv_close         = raw_close,
1371
    .bdrv_create        = hdev_create,
1372
    .create_options     = raw_create_options,
1373
    .bdrv_has_zero_init = hdev_has_zero_init,
1374
    .bdrv_flush         = raw_flush,
1375

    
1376
    .bdrv_aio_readv     = raw_aio_readv,
1377
    .bdrv_aio_writev    = raw_aio_writev,
1378
    .bdrv_aio_flush        = raw_aio_flush,
1379

    
1380
    .bdrv_read          = raw_read,
1381
    .bdrv_write         = raw_write,
1382
    .bdrv_getlength     = raw_getlength,
1383

    
1384
    /* removable device support */
1385
    .bdrv_is_inserted   = cdrom_is_inserted,
1386
    .bdrv_eject         = cdrom_eject,
1387
    .bdrv_set_locked    = cdrom_set_locked,
1388

    
1389
    /* generic scsi device */
1390
    .bdrv_ioctl         = hdev_ioctl,
1391
    .bdrv_aio_ioctl     = hdev_aio_ioctl,
1392
};
1393
#endif /* __linux__ */
1394

    
1395
#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
1396
static int cdrom_open(BlockDriverState *bs, const char *filename, int flags)
1397
{
1398
    BDRVRawState *s = bs->opaque;
1399
    int ret;
1400

    
1401
    s->type = FTYPE_CD;
1402

    
1403
    ret = raw_open_common(bs, filename, flags, 0);
1404
    if (ret)
1405
        return ret;
1406

    
1407
    /* make sure the door isnt locked at this time */
1408
    ioctl(s->fd, CDIOCALLOW);
1409
    return 0;
1410
}
1411

    
1412
static int cdrom_probe_device(const char *filename)
1413
{
1414
    if (strstart(filename, "/dev/cd", NULL) ||
1415
            strstart(filename, "/dev/acd", NULL))
1416
        return 100;
1417
    return 0;
1418
}
1419

    
1420
static int cdrom_reopen(BlockDriverState *bs)
1421
{
1422
    BDRVRawState *s = bs->opaque;
1423
    int fd;
1424

    
1425
    /*
1426
     * Force reread of possibly changed/newly loaded disc,
1427
     * FreeBSD seems to not notice sometimes...
1428
     */
1429
    if (s->fd >= 0)
1430
        close(s->fd);
1431
    fd = open(bs->filename, s->open_flags, 0644);
1432
    if (fd < 0) {
1433
        s->fd = -1;
1434
        return -EIO;
1435
    }
1436
    s->fd = fd;
1437

    
1438
    /* make sure the door isnt locked at this time */
1439
    ioctl(s->fd, CDIOCALLOW);
1440
    return 0;
1441
}
1442

    
1443
static int cdrom_is_inserted(BlockDriverState *bs)
1444
{
1445
    return raw_getlength(bs) > 0;
1446
}
1447

    
1448
static int cdrom_eject(BlockDriverState *bs, int eject_flag)
1449
{
1450
    BDRVRawState *s = bs->opaque;
1451

    
1452
    if (s->fd < 0)
1453
        return -ENOTSUP;
1454

    
1455
    (void) ioctl(s->fd, CDIOCALLOW);
1456

    
1457
    if (eject_flag) {
1458
        if (ioctl(s->fd, CDIOCEJECT) < 0)
1459
            perror("CDIOCEJECT");
1460
    } else {
1461
        if (ioctl(s->fd, CDIOCCLOSE) < 0)
1462
            perror("CDIOCCLOSE");
1463
    }
1464

    
1465
    if (cdrom_reopen(bs) < 0)
1466
        return -ENOTSUP;
1467
    return 0;
1468
}
1469

    
1470
static int cdrom_set_locked(BlockDriverState *bs, int locked)
1471
{
1472
    BDRVRawState *s = bs->opaque;
1473

    
1474
    if (s->fd < 0)
1475
        return -ENOTSUP;
1476
    if (ioctl(s->fd, (locked ? CDIOCPREVENT : CDIOCALLOW)) < 0) {
1477
        /*
1478
         * Note: an error can happen if the distribution automatically
1479
         * mounts the CD-ROM
1480
         */
1481
        /* perror("CDROM_LOCKDOOR"); */
1482
    }
1483

    
1484
    return 0;
1485
}
1486

    
1487
static BlockDriver bdrv_host_cdrom = {
1488
    .format_name        = "host_cdrom",
1489
    .protocol_name      = "host_cdrom",
1490
    .instance_size      = sizeof(BDRVRawState),
1491
    .bdrv_probe_device        = cdrom_probe_device,
1492
    .bdrv_file_open     = cdrom_open,
1493
    .bdrv_close         = raw_close,
1494
    .bdrv_create        = hdev_create,
1495
    .create_options     = raw_create_options,
1496
    .bdrv_has_zero_init = hdev_has_zero_init,
1497
    .bdrv_flush         = raw_flush,
1498

    
1499
    .bdrv_aio_readv     = raw_aio_readv,
1500
    .bdrv_aio_writev    = raw_aio_writev,
1501
    .bdrv_aio_flush        = raw_aio_flush,
1502

    
1503
    .bdrv_read          = raw_read,
1504
    .bdrv_write         = raw_write,
1505
    .bdrv_getlength     = raw_getlength,
1506

    
1507
    /* removable device support */
1508
    .bdrv_is_inserted   = cdrom_is_inserted,
1509
    .bdrv_eject         = cdrom_eject,
1510
    .bdrv_set_locked    = cdrom_set_locked,
1511
};
1512
#endif /* __FreeBSD__ */
1513

    
1514
static void bdrv_file_init(void)
1515
{
1516
    /*
1517
     * Register all the drivers.  Note that order is important, the driver
1518
     * registered last will get probed first.
1519
     */
1520
    bdrv_register(&bdrv_file);
1521
    bdrv_register(&bdrv_host_device);
1522
#ifdef __linux__
1523
    bdrv_register(&bdrv_host_floppy);
1524
    bdrv_register(&bdrv_host_cdrom);
1525
#endif
1526
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1527
    bdrv_register(&bdrv_host_cdrom);
1528
#endif
1529
}
1530

    
1531
block_init(bdrv_file_init);