Statistics
| Branch: | Revision:

root / block / raw-posix.c @ 7267c094

History | View | Annotate | Download (39.6 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
    /* We're falling back to POSIX AIO in some cases so init always */
234
    if (paio_init() < 0) {
235
        goto out_free_buf;
236
    }
237

    
238
#ifdef CONFIG_LINUX_AIO
239
    if ((bdrv_flags & (BDRV_O_NOCACHE|BDRV_O_NATIVE_AIO)) ==
240
                      (BDRV_O_NOCACHE|BDRV_O_NATIVE_AIO)) {
241

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

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

    
261
    return 0;
262

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
378

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

    
391
    sum = 0;
392

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

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

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

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

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

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

    
421
            /* read on aligned buffer */
422

    
423
            while (count) {
424

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

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

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

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

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

    
449
            return sum;
450
        }
451
    }
452

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

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

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

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

    
480
    sum = 0;
481

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
575
    return 1;
576
}
577

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
795
static int64_t raw_get_allocated_file_size(BlockDriverState *bs)
796
{
797
    struct stat st;
798
    BDRVRawState *s = bs->opaque;
799

    
800
    if (fstat(s->fd, &st) < 0) {
801
        return -errno;
802
    }
803
    return (int64_t)st.st_blocks * 512;
804
}
805

    
806
static int raw_create(const char *filename, QEMUOptionParameter *options)
807
{
808
    int fd;
809
    int result = 0;
810
    int64_t total_size = 0;
811

    
812
    /* Read out options */
813
    while (options && options->name) {
814
        if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
815
            total_size = options->value.n / BDRV_SECTOR_SIZE;
816
        }
817
        options++;
818
    }
819

    
820
    fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
821
              0644);
822
    if (fd < 0) {
823
        result = -errno;
824
    } else {
825
        if (ftruncate(fd, total_size * BDRV_SECTOR_SIZE) != 0) {
826
            result = -errno;
827
        }
828
        if (close(fd) != 0) {
829
            result = -errno;
830
        }
831
    }
832
    return result;
833
}
834

    
835
static int raw_flush(BlockDriverState *bs)
836
{
837
    BDRVRawState *s = bs->opaque;
838
    return qemu_fdatasync(s->fd);
839
}
840

    
841
#ifdef CONFIG_XFS
842
static int xfs_discard(BDRVRawState *s, int64_t sector_num, int nb_sectors)
843
{
844
    struct xfs_flock64 fl;
845

    
846
    memset(&fl, 0, sizeof(fl));
847
    fl.l_whence = SEEK_SET;
848
    fl.l_start = sector_num << 9;
849
    fl.l_len = (int64_t)nb_sectors << 9;
850

    
851
    if (xfsctl(NULL, s->fd, XFS_IOC_UNRESVSP64, &fl) < 0) {
852
        DEBUG_BLOCK_PRINT("cannot punch hole (%s)\n", strerror(errno));
853
        return -errno;
854
    }
855

    
856
    return 0;
857
}
858
#endif
859

    
860
static int raw_discard(BlockDriverState *bs, int64_t sector_num, int nb_sectors)
861
{
862
#ifdef CONFIG_XFS
863
    BDRVRawState *s = bs->opaque;
864

    
865
    if (s->is_xfs) {
866
        return xfs_discard(s, sector_num, nb_sectors);
867
    }
868
#endif
869

    
870
    return 0;
871
}
872

    
873
static QEMUOptionParameter raw_create_options[] = {
874
    {
875
        .name = BLOCK_OPT_SIZE,
876
        .type = OPT_SIZE,
877
        .help = "Virtual disk size"
878
    },
879
    { NULL }
880
};
881

    
882
static BlockDriver bdrv_file = {
883
    .format_name = "file",
884
    .protocol_name = "file",
885
    .instance_size = sizeof(BDRVRawState),
886
    .bdrv_probe = NULL, /* no probe for protocols */
887
    .bdrv_file_open = raw_open,
888
    .bdrv_read = raw_read,
889
    .bdrv_write = raw_write,
890
    .bdrv_close = raw_close,
891
    .bdrv_create = raw_create,
892
    .bdrv_flush = raw_flush,
893
    .bdrv_discard = raw_discard,
894

    
895
    .bdrv_aio_readv = raw_aio_readv,
896
    .bdrv_aio_writev = raw_aio_writev,
897
    .bdrv_aio_flush = raw_aio_flush,
898

    
899
    .bdrv_truncate = raw_truncate,
900
    .bdrv_getlength = raw_getlength,
901
    .bdrv_get_allocated_file_size
902
                        = raw_get_allocated_file_size,
903

    
904
    .create_options = raw_create_options,
905
};
906

    
907
/***********************************************/
908
/* host device */
909

    
910
#ifdef CONFIG_COCOA
911
static kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator );
912
static kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize );
913

    
914
kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator )
915
{
916
    kern_return_t       kernResult;
917
    mach_port_t     masterPort;
918
    CFMutableDictionaryRef  classesToMatch;
919

    
920
    kernResult = IOMasterPort( MACH_PORT_NULL, &masterPort );
921
    if ( KERN_SUCCESS != kernResult ) {
922
        printf( "IOMasterPort returned %d\n", kernResult );
923
    }
924

    
925
    classesToMatch = IOServiceMatching( kIOCDMediaClass );
926
    if ( classesToMatch == NULL ) {
927
        printf( "IOServiceMatching returned a NULL dictionary.\n" );
928
    } else {
929
    CFDictionarySetValue( classesToMatch, CFSTR( kIOMediaEjectableKey ), kCFBooleanTrue );
930
    }
931
    kernResult = IOServiceGetMatchingServices( masterPort, classesToMatch, mediaIterator );
932
    if ( KERN_SUCCESS != kernResult )
933
    {
934
        printf( "IOServiceGetMatchingServices returned %d\n", kernResult );
935
    }
936

    
937
    return kernResult;
938
}
939

    
940
kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize )
941
{
942
    io_object_t     nextMedia;
943
    kern_return_t   kernResult = KERN_FAILURE;
944
    *bsdPath = '\0';
945
    nextMedia = IOIteratorNext( mediaIterator );
946
    if ( nextMedia )
947
    {
948
        CFTypeRef   bsdPathAsCFString;
949
    bsdPathAsCFString = IORegistryEntryCreateCFProperty( nextMedia, CFSTR( kIOBSDNameKey ), kCFAllocatorDefault, 0 );
950
        if ( bsdPathAsCFString ) {
951
            size_t devPathLength;
952
            strcpy( bsdPath, _PATH_DEV );
953
            strcat( bsdPath, "r" );
954
            devPathLength = strlen( bsdPath );
955
            if ( CFStringGetCString( bsdPathAsCFString, bsdPath + devPathLength, maxPathSize - devPathLength, kCFStringEncodingASCII ) ) {
956
                kernResult = KERN_SUCCESS;
957
            }
958
            CFRelease( bsdPathAsCFString );
959
        }
960
        IOObjectRelease( nextMedia );
961
    }
962

    
963
    return kernResult;
964
}
965

    
966
#endif
967

    
968
static int hdev_probe_device(const char *filename)
969
{
970
    struct stat st;
971

    
972
    /* allow a dedicated CD-ROM driver to match with a higher priority */
973
    if (strstart(filename, "/dev/cdrom", NULL))
974
        return 50;
975

    
976
    if (stat(filename, &st) >= 0 &&
977
            (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode))) {
978
        return 100;
979
    }
980

    
981
    return 0;
982
}
983

    
984
static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
985
{
986
    BDRVRawState *s = bs->opaque;
987

    
988
#ifdef CONFIG_COCOA
989
    if (strstart(filename, "/dev/cdrom", NULL)) {
990
        kern_return_t kernResult;
991
        io_iterator_t mediaIterator;
992
        char bsdPath[ MAXPATHLEN ];
993
        int fd;
994

    
995
        kernResult = FindEjectableCDMedia( &mediaIterator );
996
        kernResult = GetBSDPath( mediaIterator, bsdPath, sizeof( bsdPath ) );
997

    
998
        if ( bsdPath[ 0 ] != '\0' ) {
999
            strcat(bsdPath,"s0");
1000
            /* some CDs don't have a partition 0 */
1001
            fd = open(bsdPath, O_RDONLY | O_BINARY | O_LARGEFILE);
1002
            if (fd < 0) {
1003
                bsdPath[strlen(bsdPath)-1] = '1';
1004
            } else {
1005
                close(fd);
1006
            }
1007
            filename = bsdPath;
1008
        }
1009

    
1010
        if ( mediaIterator )
1011
            IOObjectRelease( mediaIterator );
1012
    }
1013
#endif
1014

    
1015
    s->type = FTYPE_FILE;
1016
#if defined(__linux__)
1017
    {
1018
        char resolved_path[ MAXPATHLEN ], *temp;
1019

    
1020
        temp = realpath(filename, resolved_path);
1021
        if (temp && strstart(temp, "/dev/sg", NULL)) {
1022
            bs->sg = 1;
1023
        }
1024
    }
1025
#endif
1026

    
1027
    return raw_open_common(bs, filename, flags, 0);
1028
}
1029

    
1030
#if defined(__linux__)
1031
/* Note: we do not have a reliable method to detect if the floppy is
1032
   present. The current method is to try to open the floppy at every
1033
   I/O and to keep it opened during a few hundreds of ms. */
1034
static int fd_open(BlockDriverState *bs)
1035
{
1036
    BDRVRawState *s = bs->opaque;
1037
    int last_media_present;
1038

    
1039
    if (s->type != FTYPE_FD)
1040
        return 0;
1041
    last_media_present = (s->fd >= 0);
1042
    if (s->fd >= 0 &&
1043
        (get_clock() - s->fd_open_time) >= FD_OPEN_TIMEOUT) {
1044
        close(s->fd);
1045
        s->fd = -1;
1046
#ifdef DEBUG_FLOPPY
1047
        printf("Floppy closed\n");
1048
#endif
1049
    }
1050
    if (s->fd < 0) {
1051
        if (s->fd_got_error &&
1052
            (get_clock() - s->fd_error_time) < FD_OPEN_TIMEOUT) {
1053
#ifdef DEBUG_FLOPPY
1054
            printf("No floppy (open delayed)\n");
1055
#endif
1056
            return -EIO;
1057
        }
1058
        s->fd = open(bs->filename, s->open_flags & ~O_NONBLOCK);
1059
        if (s->fd < 0) {
1060
            s->fd_error_time = get_clock();
1061
            s->fd_got_error = 1;
1062
            if (last_media_present)
1063
                s->fd_media_changed = 1;
1064
#ifdef DEBUG_FLOPPY
1065
            printf("No floppy\n");
1066
#endif
1067
            return -EIO;
1068
        }
1069
#ifdef DEBUG_FLOPPY
1070
        printf("Floppy opened\n");
1071
#endif
1072
    }
1073
    if (!last_media_present)
1074
        s->fd_media_changed = 1;
1075
    s->fd_open_time = get_clock();
1076
    s->fd_got_error = 0;
1077
    return 0;
1078
}
1079

    
1080
static int hdev_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
1081
{
1082
    BDRVRawState *s = bs->opaque;
1083

    
1084
    return ioctl(s->fd, req, buf);
1085
}
1086

    
1087
static BlockDriverAIOCB *hdev_aio_ioctl(BlockDriverState *bs,
1088
        unsigned long int req, void *buf,
1089
        BlockDriverCompletionFunc *cb, void *opaque)
1090
{
1091
    BDRVRawState *s = bs->opaque;
1092

    
1093
    if (fd_open(bs) < 0)
1094
        return NULL;
1095
    return paio_ioctl(bs, s->fd, req, buf, cb, opaque);
1096
}
1097

    
1098
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1099
static int fd_open(BlockDriverState *bs)
1100
{
1101
    BDRVRawState *s = bs->opaque;
1102

    
1103
    /* this is just to ensure s->fd is sane (its called by io ops) */
1104
    if (s->fd >= 0)
1105
        return 0;
1106
    return -EIO;
1107
}
1108
#else /* !linux && !FreeBSD */
1109

    
1110
static int fd_open(BlockDriverState *bs)
1111
{
1112
    return 0;
1113
}
1114

    
1115
#endif /* !linux && !FreeBSD */
1116

    
1117
static int hdev_create(const char *filename, QEMUOptionParameter *options)
1118
{
1119
    int fd;
1120
    int ret = 0;
1121
    struct stat stat_buf;
1122
    int64_t total_size = 0;
1123

    
1124
    /* Read out options */
1125
    while (options && options->name) {
1126
        if (!strcmp(options->name, "size")) {
1127
            total_size = options->value.n / BDRV_SECTOR_SIZE;
1128
        }
1129
        options++;
1130
    }
1131

    
1132
    fd = open(filename, O_WRONLY | O_BINARY);
1133
    if (fd < 0)
1134
        return -errno;
1135

    
1136
    if (fstat(fd, &stat_buf) < 0)
1137
        ret = -errno;
1138
    else if (!S_ISBLK(stat_buf.st_mode) && !S_ISCHR(stat_buf.st_mode))
1139
        ret = -ENODEV;
1140
    else if (lseek(fd, 0, SEEK_END) < total_size * BDRV_SECTOR_SIZE)
1141
        ret = -ENOSPC;
1142

    
1143
    close(fd);
1144
    return ret;
1145
}
1146

    
1147
static int hdev_has_zero_init(BlockDriverState *bs)
1148
{
1149
    return 0;
1150
}
1151

    
1152
static BlockDriver bdrv_host_device = {
1153
    .format_name        = "host_device",
1154
    .protocol_name        = "host_device",
1155
    .instance_size      = sizeof(BDRVRawState),
1156
    .bdrv_probe_device  = hdev_probe_device,
1157
    .bdrv_file_open     = hdev_open,
1158
    .bdrv_close         = raw_close,
1159
    .bdrv_create        = hdev_create,
1160
    .create_options     = raw_create_options,
1161
    .bdrv_has_zero_init = hdev_has_zero_init,
1162
    .bdrv_flush         = raw_flush,
1163

    
1164
    .bdrv_aio_readv        = raw_aio_readv,
1165
    .bdrv_aio_writev        = raw_aio_writev,
1166
    .bdrv_aio_flush        = raw_aio_flush,
1167

    
1168
    .bdrv_read          = raw_read,
1169
    .bdrv_write         = raw_write,
1170
    .bdrv_getlength        = raw_getlength,
1171
    .bdrv_get_allocated_file_size
1172
                        = raw_get_allocated_file_size,
1173

    
1174
    /* generic scsi device */
1175
#ifdef __linux__
1176
    .bdrv_ioctl         = hdev_ioctl,
1177
    .bdrv_aio_ioctl     = hdev_aio_ioctl,
1178
#endif
1179
};
1180

    
1181
#ifdef __linux__
1182
static int floppy_open(BlockDriverState *bs, const char *filename, int flags)
1183
{
1184
    BDRVRawState *s = bs->opaque;
1185
    int ret;
1186

    
1187
    s->type = FTYPE_FD;
1188

    
1189
    /* open will not fail even if no floppy is inserted, so add O_NONBLOCK */
1190
    ret = raw_open_common(bs, filename, flags, O_NONBLOCK);
1191
    if (ret)
1192
        return ret;
1193

    
1194
    /* close fd so that we can reopen it as needed */
1195
    close(s->fd);
1196
    s->fd = -1;
1197
    s->fd_media_changed = 1;
1198

    
1199
    return 0;
1200
}
1201

    
1202
static int floppy_probe_device(const char *filename)
1203
{
1204
    int fd, ret;
1205
    int prio = 0;
1206
    struct floppy_struct fdparam;
1207
    struct stat st;
1208

    
1209
    if (strstart(filename, "/dev/fd", NULL))
1210
        prio = 50;
1211

    
1212
    fd = open(filename, O_RDONLY | O_NONBLOCK);
1213
    if (fd < 0) {
1214
        goto out;
1215
    }
1216
    ret = fstat(fd, &st);
1217
    if (ret == -1 || !S_ISBLK(st.st_mode)) {
1218
        goto outc;
1219
    }
1220

    
1221
    /* Attempt to detect via a floppy specific ioctl */
1222
    ret = ioctl(fd, FDGETPRM, &fdparam);
1223
    if (ret >= 0)
1224
        prio = 100;
1225

    
1226
outc:
1227
    close(fd);
1228
out:
1229
    return prio;
1230
}
1231

    
1232

    
1233
static int floppy_is_inserted(BlockDriverState *bs)
1234
{
1235
    return fd_open(bs) >= 0;
1236
}
1237

    
1238
static int floppy_media_changed(BlockDriverState *bs)
1239
{
1240
    BDRVRawState *s = bs->opaque;
1241
    int ret;
1242

    
1243
    /*
1244
     * XXX: we do not have a true media changed indication.
1245
     * It does not work if the floppy is changed without trying to read it.
1246
     */
1247
    fd_open(bs);
1248
    ret = s->fd_media_changed;
1249
    s->fd_media_changed = 0;
1250
#ifdef DEBUG_FLOPPY
1251
    printf("Floppy changed=%d\n", ret);
1252
#endif
1253
    return ret;
1254
}
1255

    
1256
static void floppy_eject(BlockDriverState *bs, int eject_flag)
1257
{
1258
    BDRVRawState *s = bs->opaque;
1259
    int fd;
1260

    
1261
    if (s->fd >= 0) {
1262
        close(s->fd);
1263
        s->fd = -1;
1264
    }
1265
    fd = open(bs->filename, s->open_flags | O_NONBLOCK);
1266
    if (fd >= 0) {
1267
        if (ioctl(fd, FDEJECT, 0) < 0)
1268
            perror("FDEJECT");
1269
        close(fd);
1270
    }
1271
}
1272

    
1273
static BlockDriver bdrv_host_floppy = {
1274
    .format_name        = "host_floppy",
1275
    .protocol_name      = "host_floppy",
1276
    .instance_size      = sizeof(BDRVRawState),
1277
    .bdrv_probe_device        = floppy_probe_device,
1278
    .bdrv_file_open     = floppy_open,
1279
    .bdrv_close         = raw_close,
1280
    .bdrv_create        = hdev_create,
1281
    .create_options     = raw_create_options,
1282
    .bdrv_has_zero_init = hdev_has_zero_init,
1283
    .bdrv_flush         = raw_flush,
1284

    
1285
    .bdrv_aio_readv     = raw_aio_readv,
1286
    .bdrv_aio_writev    = raw_aio_writev,
1287
    .bdrv_aio_flush        = raw_aio_flush,
1288

    
1289
    .bdrv_read          = raw_read,
1290
    .bdrv_write         = raw_write,
1291
    .bdrv_getlength        = raw_getlength,
1292
    .bdrv_get_allocated_file_size
1293
                        = raw_get_allocated_file_size,
1294

    
1295
    /* removable device support */
1296
    .bdrv_is_inserted   = floppy_is_inserted,
1297
    .bdrv_media_changed = floppy_media_changed,
1298
    .bdrv_eject         = floppy_eject,
1299
};
1300

    
1301
static int cdrom_open(BlockDriverState *bs, const char *filename, int flags)
1302
{
1303
    BDRVRawState *s = bs->opaque;
1304

    
1305
    s->type = FTYPE_CD;
1306

    
1307
    /* open will not fail even if no CD is inserted, so add O_NONBLOCK */
1308
    return raw_open_common(bs, filename, flags, O_NONBLOCK);
1309
}
1310

    
1311
static int cdrom_probe_device(const char *filename)
1312
{
1313
    int fd, ret;
1314
    int prio = 0;
1315
    struct stat st;
1316

    
1317
    fd = open(filename, O_RDONLY | O_NONBLOCK);
1318
    if (fd < 0) {
1319
        goto out;
1320
    }
1321
    ret = fstat(fd, &st);
1322
    if (ret == -1 || !S_ISBLK(st.st_mode)) {
1323
        goto outc;
1324
    }
1325

    
1326
    /* Attempt to detect via a CDROM specific ioctl */
1327
    ret = ioctl(fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);
1328
    if (ret >= 0)
1329
        prio = 100;
1330

    
1331
outc:
1332
    close(fd);
1333
out:
1334
    return prio;
1335
}
1336

    
1337
static int cdrom_is_inserted(BlockDriverState *bs)
1338
{
1339
    BDRVRawState *s = bs->opaque;
1340
    int ret;
1341

    
1342
    ret = ioctl(s->fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);
1343
    if (ret == CDS_DISC_OK)
1344
        return 1;
1345
    return 0;
1346
}
1347

    
1348
static void cdrom_eject(BlockDriverState *bs, int eject_flag)
1349
{
1350
    BDRVRawState *s = bs->opaque;
1351

    
1352
    if (eject_flag) {
1353
        if (ioctl(s->fd, CDROMEJECT, NULL) < 0)
1354
            perror("CDROMEJECT");
1355
    } else {
1356
        if (ioctl(s->fd, CDROMCLOSETRAY, NULL) < 0)
1357
            perror("CDROMEJECT");
1358
    }
1359
}
1360

    
1361
static void cdrom_set_locked(BlockDriverState *bs, int locked)
1362
{
1363
    BDRVRawState *s = bs->opaque;
1364

    
1365
    if (ioctl(s->fd, CDROM_LOCKDOOR, locked) < 0) {
1366
        /*
1367
         * Note: an error can happen if the distribution automatically
1368
         * mounts the CD-ROM
1369
         */
1370
        /* perror("CDROM_LOCKDOOR"); */
1371
    }
1372
}
1373

    
1374
static BlockDriver bdrv_host_cdrom = {
1375
    .format_name        = "host_cdrom",
1376
    .protocol_name      = "host_cdrom",
1377
    .instance_size      = sizeof(BDRVRawState),
1378
    .bdrv_probe_device        = cdrom_probe_device,
1379
    .bdrv_file_open     = cdrom_open,
1380
    .bdrv_close         = raw_close,
1381
    .bdrv_create        = hdev_create,
1382
    .create_options     = raw_create_options,
1383
    .bdrv_has_zero_init = hdev_has_zero_init,
1384
    .bdrv_flush         = raw_flush,
1385

    
1386
    .bdrv_aio_readv     = raw_aio_readv,
1387
    .bdrv_aio_writev    = raw_aio_writev,
1388
    .bdrv_aio_flush        = raw_aio_flush,
1389

    
1390
    .bdrv_read          = raw_read,
1391
    .bdrv_write         = raw_write,
1392
    .bdrv_getlength     = raw_getlength,
1393
    .bdrv_get_allocated_file_size
1394
                        = raw_get_allocated_file_size,
1395

    
1396
    /* removable device support */
1397
    .bdrv_is_inserted   = cdrom_is_inserted,
1398
    .bdrv_eject         = cdrom_eject,
1399
    .bdrv_set_locked    = cdrom_set_locked,
1400

    
1401
    /* generic scsi device */
1402
    .bdrv_ioctl         = hdev_ioctl,
1403
    .bdrv_aio_ioctl     = hdev_aio_ioctl,
1404
};
1405
#endif /* __linux__ */
1406

    
1407
#if defined (__FreeBSD__) || defined(__FreeBSD_kernel__)
1408
static int cdrom_open(BlockDriverState *bs, const char *filename, int flags)
1409
{
1410
    BDRVRawState *s = bs->opaque;
1411
    int ret;
1412

    
1413
    s->type = FTYPE_CD;
1414

    
1415
    ret = raw_open_common(bs, filename, flags, 0);
1416
    if (ret)
1417
        return ret;
1418

    
1419
    /* make sure the door isnt locked at this time */
1420
    ioctl(s->fd, CDIOCALLOW);
1421
    return 0;
1422
}
1423

    
1424
static int cdrom_probe_device(const char *filename)
1425
{
1426
    if (strstart(filename, "/dev/cd", NULL) ||
1427
            strstart(filename, "/dev/acd", NULL))
1428
        return 100;
1429
    return 0;
1430
}
1431

    
1432
static int cdrom_reopen(BlockDriverState *bs)
1433
{
1434
    BDRVRawState *s = bs->opaque;
1435
    int fd;
1436

    
1437
    /*
1438
     * Force reread of possibly changed/newly loaded disc,
1439
     * FreeBSD seems to not notice sometimes...
1440
     */
1441
    if (s->fd >= 0)
1442
        close(s->fd);
1443
    fd = open(bs->filename, s->open_flags, 0644);
1444
    if (fd < 0) {
1445
        s->fd = -1;
1446
        return -EIO;
1447
    }
1448
    s->fd = fd;
1449

    
1450
    /* make sure the door isnt locked at this time */
1451
    ioctl(s->fd, CDIOCALLOW);
1452
    return 0;
1453
}
1454

    
1455
static int cdrom_is_inserted(BlockDriverState *bs)
1456
{
1457
    return raw_getlength(bs) > 0;
1458
}
1459

    
1460
static void cdrom_eject(BlockDriverState *bs, int eject_flag)
1461
{
1462
    BDRVRawState *s = bs->opaque;
1463

    
1464
    if (s->fd < 0)
1465
        return;
1466

    
1467
    (void) ioctl(s->fd, CDIOCALLOW);
1468

    
1469
    if (eject_flag) {
1470
        if (ioctl(s->fd, CDIOCEJECT) < 0)
1471
            perror("CDIOCEJECT");
1472
    } else {
1473
        if (ioctl(s->fd, CDIOCCLOSE) < 0)
1474
            perror("CDIOCCLOSE");
1475
    }
1476

    
1477
    cdrom_reopen(bs);
1478
}
1479

    
1480
static void cdrom_set_locked(BlockDriverState *bs, int locked)
1481
{
1482
    BDRVRawState *s = bs->opaque;
1483

    
1484
    if (s->fd < 0)
1485
        return;
1486
    if (ioctl(s->fd, (locked ? CDIOCPREVENT : CDIOCALLOW)) < 0) {
1487
        /*
1488
         * Note: an error can happen if the distribution automatically
1489
         * mounts the CD-ROM
1490
         */
1491
        /* perror("CDROM_LOCKDOOR"); */
1492
    }
1493
}
1494

    
1495
static BlockDriver bdrv_host_cdrom = {
1496
    .format_name        = "host_cdrom",
1497
    .protocol_name      = "host_cdrom",
1498
    .instance_size      = sizeof(BDRVRawState),
1499
    .bdrv_probe_device        = cdrom_probe_device,
1500
    .bdrv_file_open     = cdrom_open,
1501
    .bdrv_close         = raw_close,
1502
    .bdrv_create        = hdev_create,
1503
    .create_options     = raw_create_options,
1504
    .bdrv_has_zero_init = hdev_has_zero_init,
1505
    .bdrv_flush         = raw_flush,
1506

    
1507
    .bdrv_aio_readv     = raw_aio_readv,
1508
    .bdrv_aio_writev    = raw_aio_writev,
1509
    .bdrv_aio_flush        = raw_aio_flush,
1510

    
1511
    .bdrv_read          = raw_read,
1512
    .bdrv_write         = raw_write,
1513
    .bdrv_getlength     = raw_getlength,
1514
    .bdrv_get_allocated_file_size
1515
                        = raw_get_allocated_file_size,
1516

    
1517
    /* removable device support */
1518
    .bdrv_is_inserted   = cdrom_is_inserted,
1519
    .bdrv_eject         = cdrom_eject,
1520
    .bdrv_set_locked    = cdrom_set_locked,
1521
};
1522
#endif /* __FreeBSD__ */
1523

    
1524
static void bdrv_file_init(void)
1525
{
1526
    /*
1527
     * Register all the drivers.  Note that order is important, the driver
1528
     * registered last will get probed first.
1529
     */
1530
    bdrv_register(&bdrv_file);
1531
    bdrv_register(&bdrv_host_device);
1532
#ifdef __linux__
1533
    bdrv_register(&bdrv_host_floppy);
1534
    bdrv_register(&bdrv_host_cdrom);
1535
#endif
1536
#if defined(__FreeBSD__) || defined(__FreeBSD_kernel__)
1537
    bdrv_register(&bdrv_host_cdrom);
1538
#endif
1539
}
1540

    
1541
block_init(bdrv_file_init);