Statistics
| Branch: | Revision:

root / block / raw-posix.c @ d2e46345

History | View | Annotate | Download (35 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 <signal.h>
47
#include <sys/dkio.h>
48
#endif
49
#ifdef __linux__
50
#include <sys/ioctl.h>
51
#include <linux/cdrom.h>
52
#include <linux/fd.h>
53
#endif
54
#ifdef __FreeBSD__
55
#include <signal.h>
56
#include <sys/disk.h>
57
#include <sys/cdio.h>
58
#endif
59

    
60
#ifdef __OpenBSD__
61
#include <sys/ioctl.h>
62
#include <sys/disklabel.h>
63
#include <sys/dkio.h>
64
#endif
65

    
66
#ifdef __DragonFly__
67
#include <sys/ioctl.h>
68
#include <sys/diskslice.h>
69
#endif
70

    
71
//#define DEBUG_FLOPPY
72

    
73
//#define DEBUG_BLOCK
74
#if defined(DEBUG_BLOCK)
75
#define DEBUG_BLOCK_PRINT(formatCstr, ...) do { if (qemu_log_enabled()) \
76
    { qemu_log(formatCstr, ## __VA_ARGS__); qemu_log_flush(); } } while (0)
77
#else
78
#define DEBUG_BLOCK_PRINT(formatCstr, ...)
79
#endif
80

    
81
/* OS X does not have O_DSYNC */
82
#ifndef O_DSYNC
83
#ifdef O_SYNC
84
#define O_DSYNC O_SYNC
85
#elif defined(O_FSYNC)
86
#define O_DSYNC O_FSYNC
87
#endif
88
#endif
89

    
90
/* Approximate O_DIRECT with O_DSYNC if O_DIRECT isn't available */
91
#ifndef O_DIRECT
92
#define O_DIRECT O_DSYNC
93
#endif
94

    
95
#define FTYPE_FILE   0
96
#define FTYPE_CD     1
97
#define FTYPE_FD     2
98

    
99
#define ALIGNED_BUFFER_SIZE (32 * 512)
100

    
101
/* if the FD is not accessed during that time (in ms), we try to
102
   reopen it to see if the disk has been changed */
103
#define FD_OPEN_TIMEOUT 1000
104

    
105
typedef struct BDRVRawState {
106
    int fd;
107
    int type;
108
    unsigned int lseek_err_cnt;
109
    int open_flags;
110
    void *aio_ctx;
111
#if defined(__linux__)
112
    /* linux floppy specific */
113
    int64_t fd_open_time;
114
    int64_t fd_error_time;
115
    int fd_got_error;
116
    int fd_media_changed;
117
#endif
118
#ifdef CONFIG_LINUX_AIO
119
    int use_aio;
120
#endif
121
    uint8_t* aligned_buf;
122
} BDRVRawState;
123

    
124
static int fd_open(BlockDriverState *bs);
125
static int64_t raw_getlength(BlockDriverState *bs);
126

    
127
#if defined(__FreeBSD__)
128
static int cdrom_reopen(BlockDriverState *bs);
129
#endif
130

    
131
static int raw_open_common(BlockDriverState *bs, const char *filename,
132
                           int bdrv_flags, int open_flags)
133
{
134
    BDRVRawState *s = bs->opaque;
135
    int fd, ret;
136

    
137
    s->lseek_err_cnt = 0;
138

    
139
    s->open_flags = open_flags | O_BINARY;
140
    s->open_flags &= ~O_ACCMODE;
141
    if ((bdrv_flags & BDRV_O_ACCESS) == BDRV_O_RDWR) {
142
        s->open_flags |= O_RDWR;
143
    } else {
144
        s->open_flags |= O_RDONLY;
145
        bs->read_only = 1;
146
    }
147

    
148
    /* Use O_DSYNC for write-through caching, no flags for write-back caching,
149
     * and O_DIRECT for no caching. */
150
    if ((bdrv_flags & BDRV_O_NOCACHE))
151
        s->open_flags |= O_DIRECT;
152
    else if (!(bdrv_flags & BDRV_O_CACHE_WB))
153
        s->open_flags |= O_DSYNC;
154

    
155
    s->fd = -1;
156
    fd = open(filename, s->open_flags, 0644);
157
    if (fd < 0) {
158
        ret = -errno;
159
        if (ret == -EROFS)
160
            ret = -EACCES;
161
        return ret;
162
    }
163
    s->fd = fd;
164
    s->aligned_buf = NULL;
165

    
166
    if ((bdrv_flags & BDRV_O_NOCACHE)) {
167
        s->aligned_buf = qemu_blockalign(bs, ALIGNED_BUFFER_SIZE);
168
        if (s->aligned_buf == NULL) {
169
            goto out_close;
170
        }
171
    }
172

    
173
#ifdef CONFIG_LINUX_AIO
174
    if ((bdrv_flags & (BDRV_O_NOCACHE|BDRV_O_NATIVE_AIO)) ==
175
                      (BDRV_O_NOCACHE|BDRV_O_NATIVE_AIO)) {
176

    
177
        /* We're falling back to POSIX AIO in some cases */
178
        paio_init();
179

    
180
        s->aio_ctx = laio_init();
181
        if (!s->aio_ctx) {
182
            goto out_free_buf;
183
        }
184
        s->use_aio = 1;
185
    } else
186
#endif
187
    {
188
        s->aio_ctx = paio_init();
189
        if (!s->aio_ctx) {
190
            goto out_free_buf;
191
        }
192
#ifdef CONFIG_LINUX_AIO
193
        s->use_aio = 0;
194
#endif
195
    }
196

    
197
    return 0;
198

    
199
out_free_buf:
200
    qemu_vfree(s->aligned_buf);
201
out_close:
202
    close(fd);
203
    return -errno;
204
}
205

    
206
static int raw_open(BlockDriverState *bs, const char *filename, int flags)
207
{
208
    BDRVRawState *s = bs->opaque;
209
    int open_flags = 0;
210

    
211
    s->type = FTYPE_FILE;
212
    if (flags & BDRV_O_CREAT)
213
        open_flags = O_CREAT | O_TRUNC;
214

    
215
    return raw_open_common(bs, filename, flags, open_flags);
216
}
217

    
218
/* XXX: use host sector size if necessary with:
219
#ifdef DIOCGSECTORSIZE
220
        {
221
            unsigned int sectorsize = 512;
222
            if (!ioctl(fd, DIOCGSECTORSIZE, &sectorsize) &&
223
                sectorsize > bufsize)
224
                bufsize = sectorsize;
225
        }
226
#endif
227
#ifdef CONFIG_COCOA
228
        u_int32_t   blockSize = 512;
229
        if ( !ioctl( fd, DKIOCGETBLOCKSIZE, &blockSize ) && blockSize > bufsize) {
230
            bufsize = blockSize;
231
        }
232
#endif
233
*/
234

    
235
/*
236
 * offset and count are in bytes, but must be multiples of 512 for files
237
 * opened with O_DIRECT. buf must be aligned to 512 bytes then.
238
 *
239
 * This function may be called without alignment if the caller ensures
240
 * that O_DIRECT is not in effect.
241
 */
242
static int raw_pread_aligned(BlockDriverState *bs, int64_t offset,
243
                     uint8_t *buf, int count)
244
{
245
    BDRVRawState *s = bs->opaque;
246
    int ret;
247

    
248
    ret = fd_open(bs);
249
    if (ret < 0)
250
        return ret;
251

    
252
    if (offset >= 0 && lseek(s->fd, offset, SEEK_SET) == (off_t)-1) {
253
        ++(s->lseek_err_cnt);
254
        if(s->lseek_err_cnt <= 10) {
255
            DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
256
                              "] lseek failed : %d = %s\n",
257
                              s->fd, bs->filename, offset, buf, count,
258
                              bs->total_sectors, errno, strerror(errno));
259
        }
260
        return -1;
261
    }
262
    s->lseek_err_cnt=0;
263

    
264
    ret = read(s->fd, buf, count);
265
    if (ret == count)
266
        goto label__raw_read__success;
267

    
268
    /* Allow reads beyond the end (needed for pwrite) */
269
    if ((ret == 0) && bs->growable) {
270
        int64_t size = raw_getlength(bs);
271
        if (offset >= size) {
272
            memset(buf, 0, count);
273
            ret = count;
274
            goto label__raw_read__success;
275
        }
276
    }
277

    
278
    DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
279
                      "] read failed %d : %d = %s\n",
280
                      s->fd, bs->filename, offset, buf, count,
281
                      bs->total_sectors, ret, errno, strerror(errno));
282

    
283
    /* Try harder for CDrom. */
284
    if (bs->type == BDRV_TYPE_CDROM) {
285
        lseek(s->fd, offset, SEEK_SET);
286
        ret = read(s->fd, buf, count);
287
        if (ret == count)
288
            goto label__raw_read__success;
289
        lseek(s->fd, offset, SEEK_SET);
290
        ret = read(s->fd, buf, count);
291
        if (ret == count)
292
            goto label__raw_read__success;
293

    
294
        DEBUG_BLOCK_PRINT("raw_pread(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
295
                          "] retry read failed %d : %d = %s\n",
296
                          s->fd, bs->filename, offset, buf, count,
297
                          bs->total_sectors, ret, errno, strerror(errno));
298
    }
299

    
300
label__raw_read__success:
301

    
302
    return  (ret < 0) ? -errno : ret;
303
}
304

    
305
/*
306
 * offset and count are in bytes, but must be multiples of 512 for files
307
 * opened with O_DIRECT. buf must be aligned to 512 bytes then.
308
 *
309
 * This function may be called without alignment if the caller ensures
310
 * that O_DIRECT is not in effect.
311
 */
312
static int raw_pwrite_aligned(BlockDriverState *bs, int64_t offset,
313
                      const uint8_t *buf, int count)
314
{
315
    BDRVRawState *s = bs->opaque;
316
    int ret;
317

    
318
    ret = fd_open(bs);
319
    if (ret < 0)
320
        return -errno;
321

    
322
    if (offset >= 0 && lseek(s->fd, offset, SEEK_SET) == (off_t)-1) {
323
        ++(s->lseek_err_cnt);
324
        if(s->lseek_err_cnt) {
325
            DEBUG_BLOCK_PRINT("raw_pwrite(%d:%s, %" PRId64 ", %p, %d) [%"
326
                              PRId64 "] lseek failed : %d = %s\n",
327
                              s->fd, bs->filename, offset, buf, count,
328
                              bs->total_sectors, errno, strerror(errno));
329
        }
330
        return -EIO;
331
    }
332
    s->lseek_err_cnt = 0;
333

    
334
    ret = write(s->fd, buf, count);
335
    if (ret == count)
336
        goto label__raw_write__success;
337

    
338
    DEBUG_BLOCK_PRINT("raw_pwrite(%d:%s, %" PRId64 ", %p, %d) [%" PRId64
339
                      "] write failed %d : %d = %s\n",
340
                      s->fd, bs->filename, offset, buf, count,
341
                      bs->total_sectors, ret, errno, strerror(errno));
342

    
343
label__raw_write__success:
344

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

    
348

    
349
/*
350
 * offset and count are in bytes and possibly not aligned. For files opened
351
 * with O_DIRECT, necessary alignments are ensured before calling
352
 * raw_pread_aligned to do the actual read.
353
 */
354
static int raw_pread(BlockDriverState *bs, int64_t offset,
355
                     uint8_t *buf, int count)
356
{
357
    BDRVRawState *s = bs->opaque;
358
    int size, ret, shift, sum;
359

    
360
    sum = 0;
361

    
362
    if (s->aligned_buf != NULL)  {
363

    
364
        if (offset & 0x1ff) {
365
            /* align offset on a 512 bytes boundary */
366

    
367
            shift = offset & 0x1ff;
368
            size = (shift + count + 0x1ff) & ~0x1ff;
369
            if (size > ALIGNED_BUFFER_SIZE)
370
                size = ALIGNED_BUFFER_SIZE;
371
            ret = raw_pread_aligned(bs, offset - shift, s->aligned_buf, size);
372
            if (ret < 0)
373
                return ret;
374

    
375
            size = 512 - shift;
376
            if (size > count)
377
                size = count;
378
            memcpy(buf, s->aligned_buf + shift, size);
379

    
380
            buf += size;
381
            offset += size;
382
            count -= size;
383
            sum += size;
384

    
385
            if (count == 0)
386
                return sum;
387
        }
388
        if (count & 0x1ff || (uintptr_t) buf & 0x1ff) {
389

    
390
            /* read on aligned buffer */
391

    
392
            while (count) {
393

    
394
                size = (count + 0x1ff) & ~0x1ff;
395
                if (size > ALIGNED_BUFFER_SIZE)
396
                    size = ALIGNED_BUFFER_SIZE;
397

    
398
                ret = raw_pread_aligned(bs, offset, s->aligned_buf, size);
399
                if (ret < 0)
400
                    return ret;
401

    
402
                size = ret;
403
                if (size > count)
404
                    size = count;
405

    
406
                memcpy(buf, s->aligned_buf, size);
407

    
408
                buf += size;
409
                offset += size;
410
                count -= size;
411
                sum += size;
412
            }
413

    
414
            return sum;
415
        }
416
    }
417

    
418
    return raw_pread_aligned(bs, offset, buf, count) + sum;
419
}
420

    
421
static int raw_read(BlockDriverState *bs, int64_t sector_num,
422
                    uint8_t *buf, int nb_sectors)
423
{
424
    int ret;
425

    
426
    ret = raw_pread(bs, sector_num * 512, buf, nb_sectors * 512);
427
    if (ret == (nb_sectors * 512))
428
        ret = 0;
429
    return ret;
430
}
431

    
432
/*
433
 * offset and count are in bytes and possibly not aligned. For files opened
434
 * with O_DIRECT, necessary alignments are ensured before calling
435
 * raw_pwrite_aligned to do the actual write.
436
 */
437
static int raw_pwrite(BlockDriverState *bs, int64_t offset,
438
                      const uint8_t *buf, int count)
439
{
440
    BDRVRawState *s = bs->opaque;
441
    int size, ret, shift, sum;
442

    
443
    sum = 0;
444

    
445
    if (s->aligned_buf != NULL) {
446

    
447
        if (offset & 0x1ff) {
448
            /* align offset on a 512 bytes boundary */
449
            shift = offset & 0x1ff;
450
            ret = raw_pread_aligned(bs, offset - shift, s->aligned_buf, 512);
451
            if (ret < 0)
452
                return ret;
453

    
454
            size = 512 - shift;
455
            if (size > count)
456
                size = count;
457
            memcpy(s->aligned_buf + shift, buf, size);
458

    
459
            ret = raw_pwrite_aligned(bs, offset - shift, s->aligned_buf, 512);
460
            if (ret < 0)
461
                return ret;
462

    
463
            buf += size;
464
            offset += size;
465
            count -= size;
466
            sum += size;
467

    
468
            if (count == 0)
469
                return sum;
470
        }
471
        if (count & 0x1ff || (uintptr_t) buf & 0x1ff) {
472

    
473
            while ((size = (count & ~0x1ff)) != 0) {
474

    
475
                if (size > ALIGNED_BUFFER_SIZE)
476
                    size = ALIGNED_BUFFER_SIZE;
477

    
478
                memcpy(s->aligned_buf, buf, size);
479

    
480
                ret = raw_pwrite_aligned(bs, offset, s->aligned_buf, size);
481
                if (ret < 0)
482
                    return ret;
483

    
484
                buf += ret;
485
                offset += ret;
486
                count -= ret;
487
                sum += ret;
488
            }
489
            /* here, count < 512 because (count & ~0x1ff) == 0 */
490
            if (count) {
491
                ret = raw_pread_aligned(bs, offset, s->aligned_buf, 512);
492
                if (ret < 0)
493
                    return ret;
494
                 memcpy(s->aligned_buf, buf, count);
495

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

    
502
                 sum += ret;
503
            }
504
            return sum;
505
        }
506
    }
507
    return raw_pwrite_aligned(bs, offset, buf, count) + sum;
508
}
509

    
510
static int raw_write(BlockDriverState *bs, int64_t sector_num,
511
                     const uint8_t *buf, int nb_sectors)
512
{
513
    int ret;
514
    ret = raw_pwrite(bs, sector_num * 512, buf, nb_sectors * 512);
515
    if (ret == (nb_sectors * 512))
516
        ret = 0;
517
    return ret;
518
}
519

    
520
/*
521
 * Check if all memory in this vector is sector aligned.
522
 */
523
static int qiov_is_aligned(QEMUIOVector *qiov)
524
{
525
    int i;
526

    
527
    for (i = 0; i < qiov->niov; i++) {
528
        if ((uintptr_t) qiov->iov[i].iov_base % 512) {
529
            return 0;
530
        }
531
    }
532

    
533
    return 1;
534
}
535

    
536
static BlockDriverAIOCB *raw_aio_submit(BlockDriverState *bs,
537
        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
538
        BlockDriverCompletionFunc *cb, void *opaque, int type)
539
{
540
    BDRVRawState *s = bs->opaque;
541

    
542
    if (fd_open(bs) < 0)
543
        return NULL;
544

    
545
    /*
546
     * If O_DIRECT is used the buffer needs to be aligned on a sector
547
     * boundary.  Check if this is the case or telll the low-level
548
     * driver that it needs to copy the buffer.
549
     */
550
    if (s->aligned_buf) {
551
        if (!qiov_is_aligned(qiov)) {
552
            type |= QEMU_AIO_MISALIGNED;
553
#ifdef CONFIG_LINUX_AIO
554
        } else if (s->use_aio) {
555
            return laio_submit(bs, s->aio_ctx, s->fd, sector_num, qiov,
556
                               nb_sectors, cb, opaque, type);
557
#endif
558
        }
559
    }
560

    
561
    return paio_submit(bs, s->aio_ctx, s->fd, sector_num, qiov, nb_sectors,
562
                       cb, opaque, type);
563
}
564

    
565
static BlockDriverAIOCB *raw_aio_readv(BlockDriverState *bs,
566
        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
567
        BlockDriverCompletionFunc *cb, void *opaque)
568
{
569
    return raw_aio_submit(bs, sector_num, qiov, nb_sectors,
570
                          cb, opaque, QEMU_AIO_READ);
571
}
572

    
573
static BlockDriverAIOCB *raw_aio_writev(BlockDriverState *bs,
574
        int64_t sector_num, QEMUIOVector *qiov, int nb_sectors,
575
        BlockDriverCompletionFunc *cb, void *opaque)
576
{
577
    return raw_aio_submit(bs, sector_num, qiov, nb_sectors,
578
                          cb, opaque, QEMU_AIO_WRITE);
579
}
580

    
581
static BlockDriverAIOCB *raw_aio_flush(BlockDriverState *bs,
582
        BlockDriverCompletionFunc *cb, void *opaque)
583
{
584
    BDRVRawState *s = bs->opaque;
585

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

    
589
    return paio_submit(bs, s->aio_ctx, s->fd, 0, NULL, 0,
590
                           cb, opaque, QEMU_AIO_FLUSH);
591
}
592

    
593
static void raw_close(BlockDriverState *bs)
594
{
595
    BDRVRawState *s = bs->opaque;
596
    if (s->fd >= 0) {
597
        close(s->fd);
598
        s->fd = -1;
599
        if (s->aligned_buf != NULL)
600
            qemu_free(s->aligned_buf);
601
    }
602
}
603

    
604
static int raw_truncate(BlockDriverState *bs, int64_t offset)
605
{
606
    BDRVRawState *s = bs->opaque;
607
    if (s->type != FTYPE_FILE)
608
        return -ENOTSUP;
609
    if (ftruncate(s->fd, offset) < 0)
610
        return -errno;
611
    return 0;
612
}
613

    
614
#ifdef __OpenBSD__
615
static int64_t raw_getlength(BlockDriverState *bs)
616
{
617
    BDRVRawState *s = bs->opaque;
618
    int fd = s->fd;
619
    struct stat st;
620

    
621
    if (fstat(fd, &st))
622
        return -1;
623
    if (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode)) {
624
        struct disklabel dl;
625

    
626
        if (ioctl(fd, DIOCGDINFO, &dl))
627
            return -1;
628
        return (uint64_t)dl.d_secsize *
629
            dl.d_partitions[DISKPART(st.st_rdev)].p_size;
630
    } else
631
        return st.st_size;
632
}
633
#else /* !__OpenBSD__ */
634
static int64_t  raw_getlength(BlockDriverState *bs)
635
{
636
    BDRVRawState *s = bs->opaque;
637
    int fd = s->fd;
638
    int64_t size;
639
#ifdef CONFIG_BSD
640
    struct stat sb;
641
#ifdef __FreeBSD__
642
    int reopened = 0;
643
#endif
644
#endif
645
#ifdef __sun__
646
    struct dk_minfo minfo;
647
    int rv;
648
#endif
649
    int ret;
650

    
651
    ret = fd_open(bs);
652
    if (ret < 0)
653
        return ret;
654

    
655
#ifdef CONFIG_BSD
656
#ifdef __FreeBSD__
657
again:
658
#endif
659
    if (!fstat(fd, &sb) && (S_IFCHR & sb.st_mode)) {
660
#ifdef DIOCGMEDIASIZE
661
        if (ioctl(fd, DIOCGMEDIASIZE, (off_t *)&size))
662
#elif defined(DIOCGPART)
663
        {
664
                struct partinfo pi;
665
                if (ioctl(fd, DIOCGPART, &pi) == 0)
666
                        size = pi.media_size;
667
                else
668
                        size = 0;
669
        }
670
        if (size == 0)
671
#endif
672
#ifdef CONFIG_COCOA
673
        size = LONG_LONG_MAX;
674
#else
675
        size = lseek(fd, 0LL, SEEK_END);
676
#endif
677
#ifdef __FreeBSD__
678
        switch(s->type) {
679
        case FTYPE_CD:
680
            /* XXX FreeBSD acd returns UINT_MAX sectors for an empty drive */
681
            if (size == 2048LL * (unsigned)-1)
682
                size = 0;
683
            /* XXX no disc?  maybe we need to reopen... */
684
            if (size <= 0 && !reopened && cdrom_reopen(bs) >= 0) {
685
                reopened = 1;
686
                goto again;
687
            }
688
        }
689
#endif
690
    } else
691
#endif
692
#ifdef __sun__
693
    /*
694
     * use the DKIOCGMEDIAINFO ioctl to read the size.
695
     */
696
    rv = ioctl ( fd, DKIOCGMEDIAINFO, &minfo );
697
    if ( rv != -1 ) {
698
        size = minfo.dki_lbsize * minfo.dki_capacity;
699
    } else /* there are reports that lseek on some devices
700
              fails, but irc discussion said that contingency
701
              on contingency was overkill */
702
#endif
703
    {
704
        size = lseek(fd, 0, SEEK_END);
705
    }
706
    return size;
707
}
708
#endif
709

    
710
static int raw_create(const char *filename, QEMUOptionParameter *options)
711
{
712
    int fd;
713
    int result = 0;
714
    int64_t total_size = 0;
715

    
716
    /* Read out options */
717
    while (options && options->name) {
718
        if (!strcmp(options->name, BLOCK_OPT_SIZE)) {
719
            total_size = options->value.n / 512;
720
        }
721
        options++;
722
    }
723

    
724
    fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,
725
              0644);
726
    if (fd < 0) {
727
        result = -errno;
728
    } else {
729
        if (ftruncate(fd, total_size * 512) != 0) {
730
            result = -errno;
731
        }
732
        if (close(fd) != 0) {
733
            result = -errno;
734
        }
735
    }
736
    return result;
737
}
738

    
739
static void raw_flush(BlockDriverState *bs)
740
{
741
    BDRVRawState *s = bs->opaque;
742
    qemu_fdatasync(s->fd);
743
}
744

    
745

    
746
static QEMUOptionParameter raw_create_options[] = {
747
    {
748
        .name = BLOCK_OPT_SIZE,
749
        .type = OPT_SIZE,
750
        .help = "Virtual disk size"
751
    },
752
    { NULL }
753
};
754

    
755
static BlockDriver bdrv_raw = {
756
    .format_name = "raw",
757
    .instance_size = sizeof(BDRVRawState),
758
    .bdrv_probe = NULL, /* no probe for protocols */
759
    .bdrv_open = raw_open,
760
    .bdrv_read = raw_read,
761
    .bdrv_write = raw_write,
762
    .bdrv_close = raw_close,
763
    .bdrv_create = raw_create,
764
    .bdrv_flush = raw_flush,
765

    
766
    .bdrv_aio_readv = raw_aio_readv,
767
    .bdrv_aio_writev = raw_aio_writev,
768
    .bdrv_aio_flush = raw_aio_flush,
769

    
770
    .bdrv_truncate = raw_truncate,
771
    .bdrv_getlength = raw_getlength,
772

    
773
    .create_options = raw_create_options,
774
};
775

    
776
/***********************************************/
777
/* host device */
778

    
779
#ifdef CONFIG_COCOA
780
static kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator );
781
static kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize );
782

    
783
kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator )
784
{
785
    kern_return_t       kernResult;
786
    mach_port_t     masterPort;
787
    CFMutableDictionaryRef  classesToMatch;
788

    
789
    kernResult = IOMasterPort( MACH_PORT_NULL, &masterPort );
790
    if ( KERN_SUCCESS != kernResult ) {
791
        printf( "IOMasterPort returned %d\n", kernResult );
792
    }
793

    
794
    classesToMatch = IOServiceMatching( kIOCDMediaClass );
795
    if ( classesToMatch == NULL ) {
796
        printf( "IOServiceMatching returned a NULL dictionary.\n" );
797
    } else {
798
    CFDictionarySetValue( classesToMatch, CFSTR( kIOMediaEjectableKey ), kCFBooleanTrue );
799
    }
800
    kernResult = IOServiceGetMatchingServices( masterPort, classesToMatch, mediaIterator );
801
    if ( KERN_SUCCESS != kernResult )
802
    {
803
        printf( "IOServiceGetMatchingServices returned %d\n", kernResult );
804
    }
805

    
806
    return kernResult;
807
}
808

    
809
kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize )
810
{
811
    io_object_t     nextMedia;
812
    kern_return_t   kernResult = KERN_FAILURE;
813
    *bsdPath = '\0';
814
    nextMedia = IOIteratorNext( mediaIterator );
815
    if ( nextMedia )
816
    {
817
        CFTypeRef   bsdPathAsCFString;
818
    bsdPathAsCFString = IORegistryEntryCreateCFProperty( nextMedia, CFSTR( kIOBSDNameKey ), kCFAllocatorDefault, 0 );
819
        if ( bsdPathAsCFString ) {
820
            size_t devPathLength;
821
            strcpy( bsdPath, _PATH_DEV );
822
            strcat( bsdPath, "r" );
823
            devPathLength = strlen( bsdPath );
824
            if ( CFStringGetCString( bsdPathAsCFString, bsdPath + devPathLength, maxPathSize - devPathLength, kCFStringEncodingASCII ) ) {
825
                kernResult = KERN_SUCCESS;
826
            }
827
            CFRelease( bsdPathAsCFString );
828
        }
829
        IOObjectRelease( nextMedia );
830
    }
831

    
832
    return kernResult;
833
}
834

    
835
#endif
836

    
837
static int hdev_probe_device(const char *filename)
838
{
839
    struct stat st;
840

    
841
    /* allow a dedicated CD-ROM driver to match with a higher priority */
842
    if (strstart(filename, "/dev/cdrom", NULL))
843
        return 50;
844

    
845
    if (stat(filename, &st) >= 0 &&
846
            (S_ISCHR(st.st_mode) || S_ISBLK(st.st_mode))) {
847
        return 100;
848
    }
849

    
850
    return 0;
851
}
852

    
853
static int hdev_open(BlockDriverState *bs, const char *filename, int flags)
854
{
855
    BDRVRawState *s = bs->opaque;
856

    
857
#ifdef CONFIG_COCOA
858
    if (strstart(filename, "/dev/cdrom", NULL)) {
859
        kern_return_t kernResult;
860
        io_iterator_t mediaIterator;
861
        char bsdPath[ MAXPATHLEN ];
862
        int fd;
863

    
864
        kernResult = FindEjectableCDMedia( &mediaIterator );
865
        kernResult = GetBSDPath( mediaIterator, bsdPath, sizeof( bsdPath ) );
866

    
867
        if ( bsdPath[ 0 ] != '\0' ) {
868
            strcat(bsdPath,"s0");
869
            /* some CDs don't have a partition 0 */
870
            fd = open(bsdPath, O_RDONLY | O_BINARY | O_LARGEFILE);
871
            if (fd < 0) {
872
                bsdPath[strlen(bsdPath)-1] = '1';
873
            } else {
874
                close(fd);
875
            }
876
            filename = bsdPath;
877
        }
878

    
879
        if ( mediaIterator )
880
            IOObjectRelease( mediaIterator );
881
    }
882
#endif
883

    
884
    s->type = FTYPE_FILE;
885
#if defined(__linux__)
886
    if (strstart(filename, "/dev/sg", NULL)) {
887
        bs->sg = 1;
888
    }
889
#endif
890

    
891
    return raw_open_common(bs, filename, flags, 0);
892
}
893

    
894
#if defined(__linux__)
895
/* Note: we do not have a reliable method to detect if the floppy is
896
   present. The current method is to try to open the floppy at every
897
   I/O and to keep it opened during a few hundreds of ms. */
898
static int fd_open(BlockDriverState *bs)
899
{
900
    BDRVRawState *s = bs->opaque;
901
    int last_media_present;
902

    
903
    if (s->type != FTYPE_FD)
904
        return 0;
905
    last_media_present = (s->fd >= 0);
906
    if (s->fd >= 0 &&
907
        (qemu_get_clock(rt_clock) - s->fd_open_time) >= FD_OPEN_TIMEOUT) {
908
        close(s->fd);
909
        s->fd = -1;
910
#ifdef DEBUG_FLOPPY
911
        printf("Floppy closed\n");
912
#endif
913
    }
914
    if (s->fd < 0) {
915
        if (s->fd_got_error &&
916
            (qemu_get_clock(rt_clock) - s->fd_error_time) < FD_OPEN_TIMEOUT) {
917
#ifdef DEBUG_FLOPPY
918
            printf("No floppy (open delayed)\n");
919
#endif
920
            return -EIO;
921
        }
922
        s->fd = open(bs->filename, s->open_flags & ~O_NONBLOCK);
923
        if (s->fd < 0) {
924
            s->fd_error_time = qemu_get_clock(rt_clock);
925
            s->fd_got_error = 1;
926
            if (last_media_present)
927
                s->fd_media_changed = 1;
928
#ifdef DEBUG_FLOPPY
929
            printf("No floppy\n");
930
#endif
931
            return -EIO;
932
        }
933
#ifdef DEBUG_FLOPPY
934
        printf("Floppy opened\n");
935
#endif
936
    }
937
    if (!last_media_present)
938
        s->fd_media_changed = 1;
939
    s->fd_open_time = qemu_get_clock(rt_clock);
940
    s->fd_got_error = 0;
941
    return 0;
942
}
943

    
944
static int hdev_ioctl(BlockDriverState *bs, unsigned long int req, void *buf)
945
{
946
    BDRVRawState *s = bs->opaque;
947

    
948
    return ioctl(s->fd, req, buf);
949
}
950

    
951
static BlockDriverAIOCB *hdev_aio_ioctl(BlockDriverState *bs,
952
        unsigned long int req, void *buf,
953
        BlockDriverCompletionFunc *cb, void *opaque)
954
{
955
    BDRVRawState *s = bs->opaque;
956

    
957
    if (fd_open(bs) < 0)
958
        return NULL;
959
    return paio_ioctl(bs, s->fd, req, buf, cb, opaque);
960
}
961

    
962
#elif defined(__FreeBSD__)
963
static int fd_open(BlockDriverState *bs)
964
{
965
    BDRVRawState *s = bs->opaque;
966

    
967
    /* this is just to ensure s->fd is sane (its called by io ops) */
968
    if (s->fd >= 0)
969
        return 0;
970
    return -EIO;
971
}
972
#else /* !linux && !FreeBSD */
973

    
974
static int fd_open(BlockDriverState *bs)
975
{
976
    return 0;
977
}
978

    
979
#endif /* !linux && !FreeBSD */
980

    
981
static int hdev_create(const char *filename, QEMUOptionParameter *options)
982
{
983
    int fd;
984
    int ret = 0;
985
    struct stat stat_buf;
986
    int64_t total_size = 0;
987

    
988
    /* Read out options */
989
    while (options && options->name) {
990
        if (!strcmp(options->name, "size")) {
991
            total_size = options->value.n / 512;
992
        }
993
        options++;
994
    }
995

    
996
    fd = open(filename, O_WRONLY | O_BINARY);
997
    if (fd < 0)
998
        return -EIO;
999

    
1000
    if (fstat(fd, &stat_buf) < 0)
1001
        ret = -EIO;
1002
    else if (!S_ISBLK(stat_buf.st_mode) && !S_ISCHR(stat_buf.st_mode))
1003
        ret = -EIO;
1004
    else if (lseek(fd, 0, SEEK_END) < total_size * 512)
1005
        ret = -ENOSPC;
1006

    
1007
    close(fd);
1008
    return ret;
1009
}
1010

    
1011
static BlockDriver bdrv_host_device = {
1012
    .format_name        = "host_device",
1013
    .instance_size      = sizeof(BDRVRawState),
1014
    .bdrv_probe_device  = hdev_probe_device,
1015
    .bdrv_open          = hdev_open,
1016
    .bdrv_close         = raw_close,
1017
    .bdrv_create        = hdev_create,
1018
    .create_options     = raw_create_options,
1019
    .bdrv_flush         = raw_flush,
1020

    
1021
    .bdrv_aio_readv        = raw_aio_readv,
1022
    .bdrv_aio_writev        = raw_aio_writev,
1023
    .bdrv_aio_flush        = raw_aio_flush,
1024

    
1025
    .bdrv_read          = raw_read,
1026
    .bdrv_write         = raw_write,
1027
    .bdrv_getlength        = raw_getlength,
1028

    
1029
    /* generic scsi device */
1030
#ifdef __linux__
1031
    .bdrv_ioctl         = hdev_ioctl,
1032
    .bdrv_aio_ioctl     = hdev_aio_ioctl,
1033
#endif
1034
};
1035

    
1036
#ifdef __linux__
1037
static int floppy_open(BlockDriverState *bs, const char *filename, int flags)
1038
{
1039
    BDRVRawState *s = bs->opaque;
1040
    int ret;
1041

    
1042
    s->type = FTYPE_FD;
1043

    
1044
    /* open will not fail even if no floppy is inserted, so add O_NONBLOCK */
1045
    ret = raw_open_common(bs, filename, flags, O_NONBLOCK);
1046
    if (ret)
1047
        return ret;
1048

    
1049
    /* close fd so that we can reopen it as needed */
1050
    close(s->fd);
1051
    s->fd = -1;
1052
    s->fd_media_changed = 1;
1053

    
1054
    return 0;
1055
}
1056

    
1057
static int floppy_probe_device(const char *filename)
1058
{
1059
    if (strstart(filename, "/dev/fd", NULL))
1060
        return 100;
1061
    return 0;
1062
}
1063

    
1064

    
1065
static int floppy_is_inserted(BlockDriverState *bs)
1066
{
1067
    return fd_open(bs) >= 0;
1068
}
1069

    
1070
static int floppy_media_changed(BlockDriverState *bs)
1071
{
1072
    BDRVRawState *s = bs->opaque;
1073
    int ret;
1074

    
1075
    /*
1076
     * XXX: we do not have a true media changed indication.
1077
     * It does not work if the floppy is changed without trying to read it.
1078
     */
1079
    fd_open(bs);
1080
    ret = s->fd_media_changed;
1081
    s->fd_media_changed = 0;
1082
#ifdef DEBUG_FLOPPY
1083
    printf("Floppy changed=%d\n", ret);
1084
#endif
1085
    return ret;
1086
}
1087

    
1088
static int floppy_eject(BlockDriverState *bs, int eject_flag)
1089
{
1090
    BDRVRawState *s = bs->opaque;
1091
    int fd;
1092

    
1093
    if (s->fd >= 0) {
1094
        close(s->fd);
1095
        s->fd = -1;
1096
    }
1097
    fd = open(bs->filename, s->open_flags | O_NONBLOCK);
1098
    if (fd >= 0) {
1099
        if (ioctl(fd, FDEJECT, 0) < 0)
1100
            perror("FDEJECT");
1101
        close(fd);
1102
    }
1103

    
1104
    return 0;
1105
}
1106

    
1107
static BlockDriver bdrv_host_floppy = {
1108
    .format_name        = "host_floppy",
1109
    .instance_size      = sizeof(BDRVRawState),
1110
    .bdrv_probe_device        = floppy_probe_device,
1111
    .bdrv_open          = floppy_open,
1112
    .bdrv_close         = raw_close,
1113
    .bdrv_create        = hdev_create,
1114
    .create_options     = raw_create_options,
1115
    .bdrv_flush         = raw_flush,
1116

    
1117
    .bdrv_aio_readv     = raw_aio_readv,
1118
    .bdrv_aio_writev    = raw_aio_writev,
1119
    .bdrv_aio_flush        = raw_aio_flush,
1120

    
1121
    .bdrv_read          = raw_read,
1122
    .bdrv_write         = raw_write,
1123
    .bdrv_getlength        = raw_getlength,
1124

    
1125
    /* removable device support */
1126
    .bdrv_is_inserted   = floppy_is_inserted,
1127
    .bdrv_media_changed = floppy_media_changed,
1128
    .bdrv_eject         = floppy_eject,
1129
};
1130

    
1131
static int cdrom_open(BlockDriverState *bs, const char *filename, int flags)
1132
{
1133
    BDRVRawState *s = bs->opaque;
1134

    
1135
    s->type = FTYPE_CD;
1136

    
1137
    /* open will not fail even if no CD is inserted, so add O_NONBLOCK */
1138
    return raw_open_common(bs, filename, flags, O_NONBLOCK);
1139
}
1140

    
1141
static int cdrom_probe_device(const char *filename)
1142
{
1143
    if (strstart(filename, "/dev/cd", NULL))
1144
        return 100;
1145
    return 0;
1146
}
1147

    
1148
static int cdrom_is_inserted(BlockDriverState *bs)
1149
{
1150
    BDRVRawState *s = bs->opaque;
1151
    int ret;
1152

    
1153
    ret = ioctl(s->fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);
1154
    if (ret == CDS_DISC_OK)
1155
        return 1;
1156
    return 0;
1157
}
1158

    
1159
static int cdrom_eject(BlockDriverState *bs, int eject_flag)
1160
{
1161
    BDRVRawState *s = bs->opaque;
1162

    
1163
    if (eject_flag) {
1164
        if (ioctl(s->fd, CDROMEJECT, NULL) < 0)
1165
            perror("CDROMEJECT");
1166
    } else {
1167
        if (ioctl(s->fd, CDROMCLOSETRAY, NULL) < 0)
1168
            perror("CDROMEJECT");
1169
    }
1170

    
1171
    return 0;
1172
}
1173

    
1174
static int cdrom_set_locked(BlockDriverState *bs, int locked)
1175
{
1176
    BDRVRawState *s = bs->opaque;
1177

    
1178
    if (ioctl(s->fd, CDROM_LOCKDOOR, locked) < 0) {
1179
        /*
1180
         * Note: an error can happen if the distribution automatically
1181
         * mounts the CD-ROM
1182
         */
1183
        /* perror("CDROM_LOCKDOOR"); */
1184
    }
1185

    
1186
    return 0;
1187
}
1188

    
1189
static BlockDriver bdrv_host_cdrom = {
1190
    .format_name        = "host_cdrom",
1191
    .instance_size      = sizeof(BDRVRawState),
1192
    .bdrv_probe_device        = cdrom_probe_device,
1193
    .bdrv_open          = cdrom_open,
1194
    .bdrv_close         = raw_close,
1195
    .bdrv_create        = hdev_create,
1196
    .create_options     = raw_create_options,
1197
    .bdrv_flush         = raw_flush,
1198

    
1199
    .bdrv_aio_readv     = raw_aio_readv,
1200
    .bdrv_aio_writev    = raw_aio_writev,
1201
    .bdrv_aio_flush        = raw_aio_flush,
1202

    
1203
    .bdrv_read          = raw_read,
1204
    .bdrv_write         = raw_write,
1205
    .bdrv_getlength     = raw_getlength,
1206

    
1207
    /* removable device support */
1208
    .bdrv_is_inserted   = cdrom_is_inserted,
1209
    .bdrv_eject         = cdrom_eject,
1210
    .bdrv_set_locked    = cdrom_set_locked,
1211

    
1212
    /* generic scsi device */
1213
    .bdrv_ioctl         = hdev_ioctl,
1214
    .bdrv_aio_ioctl     = hdev_aio_ioctl,
1215
};
1216
#endif /* __linux__ */
1217

    
1218
#ifdef __FreeBSD__
1219
static int cdrom_open(BlockDriverState *bs, const char *filename, int flags)
1220
{
1221
    BDRVRawState *s = bs->opaque;
1222
    int ret;
1223

    
1224
    s->type = FTYPE_CD;
1225

    
1226
    ret = raw_open_common(bs, filename, flags, 0);
1227
    if (ret)
1228
        return ret;
1229

    
1230
    /* make sure the door isnt locked at this time */
1231
    ioctl(s->fd, CDIOCALLOW);
1232
    return 0;
1233
}
1234

    
1235
static int cdrom_probe_device(const char *filename)
1236
{
1237
    if (strstart(filename, "/dev/cd", NULL) ||
1238
            strstart(filename, "/dev/acd", NULL))
1239
        return 100;
1240
    return 0;
1241
}
1242

    
1243
static int cdrom_reopen(BlockDriverState *bs)
1244
{
1245
    BDRVRawState *s = bs->opaque;
1246
    int fd;
1247

    
1248
    /*
1249
     * Force reread of possibly changed/newly loaded disc,
1250
     * FreeBSD seems to not notice sometimes...
1251
     */
1252
    if (s->fd >= 0)
1253
        close(s->fd);
1254
    fd = open(bs->filename, s->open_flags, 0644);
1255
    if (fd < 0) {
1256
        s->fd = -1;
1257
        return -EIO;
1258
    }
1259
    s->fd = fd;
1260

    
1261
    /* make sure the door isnt locked at this time */
1262
    ioctl(s->fd, CDIOCALLOW);
1263
    return 0;
1264
}
1265

    
1266
static int cdrom_is_inserted(BlockDriverState *bs)
1267
{
1268
    return raw_getlength(bs) > 0;
1269
}
1270

    
1271
static int cdrom_eject(BlockDriverState *bs, int eject_flag)
1272
{
1273
    BDRVRawState *s = bs->opaque;
1274

    
1275
    if (s->fd < 0)
1276
        return -ENOTSUP;
1277

    
1278
    (void) ioctl(s->fd, CDIOCALLOW);
1279

    
1280
    if (eject_flag) {
1281
        if (ioctl(s->fd, CDIOCEJECT) < 0)
1282
            perror("CDIOCEJECT");
1283
    } else {
1284
        if (ioctl(s->fd, CDIOCCLOSE) < 0)
1285
            perror("CDIOCCLOSE");
1286
    }
1287

    
1288
    if (cdrom_reopen(bs) < 0)
1289
        return -ENOTSUP;
1290
    return 0;
1291
}
1292

    
1293
static int cdrom_set_locked(BlockDriverState *bs, int locked)
1294
{
1295
    BDRVRawState *s = bs->opaque;
1296

    
1297
    if (s->fd < 0)
1298
        return -ENOTSUP;
1299
    if (ioctl(s->fd, (locked ? CDIOCPREVENT : CDIOCALLOW)) < 0) {
1300
        /*
1301
         * Note: an error can happen if the distribution automatically
1302
         * mounts the CD-ROM
1303
         */
1304
        /* perror("CDROM_LOCKDOOR"); */
1305
    }
1306

    
1307
    return 0;
1308
}
1309

    
1310
static BlockDriver bdrv_host_cdrom = {
1311
    .format_name        = "host_cdrom",
1312
    .instance_size      = sizeof(BDRVRawState),
1313
    .bdrv_probe_device        = cdrom_probe_device,
1314
    .bdrv_open          = cdrom_open,
1315
    .bdrv_close         = raw_close,
1316
    .bdrv_create        = hdev_create,
1317
    .create_options     = raw_create_options,
1318
    .bdrv_flush         = raw_flush,
1319

    
1320
    .bdrv_aio_readv     = raw_aio_readv,
1321
    .bdrv_aio_writev    = raw_aio_writev,
1322
    .bdrv_aio_flush        = raw_aio_flush,
1323

    
1324
    .bdrv_read          = raw_read,
1325
    .bdrv_write         = raw_write,
1326
    .bdrv_getlength     = raw_getlength,
1327

    
1328
    /* removable device support */
1329
    .bdrv_is_inserted   = cdrom_is_inserted,
1330
    .bdrv_eject         = cdrom_eject,
1331
    .bdrv_set_locked    = cdrom_set_locked,
1332
};
1333
#endif /* __FreeBSD__ */
1334

    
1335
static void bdrv_raw_init(void)
1336
{
1337
    /*
1338
     * Register all the drivers.  Note that order is important, the driver
1339
     * registered last will get probed first.
1340
     */
1341
    bdrv_register(&bdrv_raw);
1342
    bdrv_register(&bdrv_host_device);
1343
#ifdef __linux__
1344
    bdrv_register(&bdrv_host_floppy);
1345
    bdrv_register(&bdrv_host_cdrom);
1346
#endif
1347
#ifdef __FreeBSD__
1348
    bdrv_register(&bdrv_host_cdrom);
1349
#endif
1350
}
1351

    
1352
block_init(bdrv_raw_init);