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