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