⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 block-raw.c

📁 qemu性能直逼VMware的仿真器QEMU 的模擬速度約為實機的 25%;約為 Bochs 的 60 倍。Plex86、User-Mode-Linux、VMware 和 Virtual PC 則比
💻 C
📖 第 1 页 / 共 3 页
字号:
    int fd;    if (flags || backing_file)        return -ENOTSUP;    fd = open(filename, O_WRONLY | O_CREAT | O_TRUNC | O_BINARY,               0644);    if (fd < 0)        return -EIO;    ftruncate(fd, total_size * 512);    close(fd);    return 0;}static void raw_flush(BlockDriverState *bs){    BDRVRawState *s = bs->opaque;    fsync(s->fd);}BlockDriver bdrv_raw = {    "raw",    sizeof(BDRVRawState),    NULL, /* no probe for protocols */    raw_open,    NULL,    NULL,    raw_close,    raw_create,    raw_flush,        .bdrv_aio_read = raw_aio_read,    .bdrv_aio_write = raw_aio_write,    .bdrv_aio_cancel = raw_aio_cancel,    .aiocb_size = sizeof(RawAIOCB),    .protocol_name = "file",    .bdrv_pread = raw_pread,    .bdrv_pwrite = raw_pwrite,    .bdrv_truncate = raw_truncate,    .bdrv_getlength = raw_getlength,};/***********************************************//* host device */#ifdef CONFIG_COCOAstatic kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator );static kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize );kern_return_t FindEjectableCDMedia( io_iterator_t *mediaIterator ){    kern_return_t       kernResult;     mach_port_t     masterPort;    CFMutableDictionaryRef  classesToMatch;    kernResult = IOMasterPort( MACH_PORT_NULL, &masterPort );    if ( KERN_SUCCESS != kernResult ) {        printf( "IOMasterPort returned %d\n", kernResult );    }        classesToMatch = IOServiceMatching( kIOCDMediaClass );     if ( classesToMatch == NULL ) {        printf( "IOServiceMatching returned a NULL dictionary.\n" );    } else {    CFDictionarySetValue( classesToMatch, CFSTR( kIOMediaEjectableKey ), kCFBooleanTrue );    }    kernResult = IOServiceGetMatchingServices( masterPort, classesToMatch, mediaIterator );    if ( KERN_SUCCESS != kernResult )    {        printf( "IOServiceGetMatchingServices returned %d\n", kernResult );    }        return kernResult;}kern_return_t GetBSDPath( io_iterator_t mediaIterator, char *bsdPath, CFIndex maxPathSize ){    io_object_t     nextMedia;    kern_return_t   kernResult = KERN_FAILURE;    *bsdPath = '\0';    nextMedia = IOIteratorNext( mediaIterator );    if ( nextMedia )    {        CFTypeRef   bsdPathAsCFString;    bsdPathAsCFString = IORegistryEntryCreateCFProperty( nextMedia, CFSTR( kIOBSDNameKey ), kCFAllocatorDefault, 0 );        if ( bsdPathAsCFString ) {            size_t devPathLength;            strcpy( bsdPath, _PATH_DEV );            strcat( bsdPath, "r" );            devPathLength = strlen( bsdPath );            if ( CFStringGetCString( bsdPathAsCFString, bsdPath + devPathLength, maxPathSize - devPathLength, kCFStringEncodingASCII ) ) {                kernResult = KERN_SUCCESS;            }            CFRelease( bsdPathAsCFString );        }        IOObjectRelease( nextMedia );    }        return kernResult;}#endifstatic int hdev_open(BlockDriverState *bs, const char *filename, int flags){    BDRVRawState *s = bs->opaque;    int fd, open_flags, ret;#ifdef CONFIG_COCOA    if (strstart(filename, "/dev/cdrom", NULL)) {        kern_return_t kernResult;        io_iterator_t mediaIterator;        char bsdPath[ MAXPATHLEN ];        int fd;         kernResult = FindEjectableCDMedia( &mediaIterator );        kernResult = GetBSDPath( mediaIterator, bsdPath, sizeof( bsdPath ) );            if ( bsdPath[ 0 ] != '\0' ) {            strcat(bsdPath,"s0");            /* some CDs don't have a partition 0 */            fd = open(bsdPath, O_RDONLY | O_BINARY | O_LARGEFILE);            if (fd < 0) {                bsdPath[strlen(bsdPath)-1] = '1';            } else {                close(fd);            }            filename = bsdPath;        }                if ( mediaIterator )            IOObjectRelease( mediaIterator );    }#endif    open_flags = O_BINARY;    if ((flags & BDRV_O_ACCESS) == O_RDWR) {        open_flags |= O_RDWR;    } else {        open_flags |= O_RDONLY;        bs->read_only = 1;    }    s->type = FTYPE_FILE;#if defined(__linux__)    if (strstart(filename, "/dev/cd", NULL)) {        /* open will not fail even if no CD is inserted */        open_flags |= O_NONBLOCK;        s->type = FTYPE_CD;    } else if (strstart(filename, "/dev/fd", NULL)) {        s->type = FTYPE_FD;        s->fd_open_flags = open_flags;        /* open will not fail even if no floppy is inserted */        open_flags |= O_NONBLOCK;    }#endif    fd = open(filename, open_flags, 0644);    if (fd < 0) {        ret = -errno;        if (ret == -EROFS)            ret = -EACCES;        return ret;    }    s->fd = fd;#if defined(__linux__)    /* close fd so that we can reopen it as needed */    if (s->type == FTYPE_FD) {        close(s->fd);        s->fd = -1;        s->fd_media_changed = 1;    }#endif    return 0;}#if defined(__linux__) && !defined(QEMU_TOOL)/* Note: we do not have a reliable method to detect if the floppy is   present. The current method is to try to open the floppy at every   I/O and to keep it opened during a few hundreds of ms. */static int fd_open(BlockDriverState *bs){    BDRVRawState *s = bs->opaque;    int last_media_present;    if (s->type != FTYPE_FD)        return 0;    last_media_present = (s->fd >= 0);    if (s->fd >= 0 &&         (qemu_get_clock(rt_clock) - s->fd_open_time) >= FD_OPEN_TIMEOUT) {        close(s->fd);        s->fd = -1;#ifdef DEBUG_FLOPPY        printf("Floppy closed\n");#endif    }    if (s->fd < 0) {        if (s->fd_got_error &&             (qemu_get_clock(rt_clock) - s->fd_error_time) < FD_OPEN_TIMEOUT) {#ifdef DEBUG_FLOPPY            printf("No floppy (open delayed)\n");#endif            return -EIO;        }        s->fd = open(bs->filename, s->fd_open_flags);        if (s->fd < 0) {            s->fd_error_time = qemu_get_clock(rt_clock);            s->fd_got_error = 1;            if (last_media_present)                s->fd_media_changed = 1;#ifdef DEBUG_FLOPPY            printf("No floppy\n");#endif            return -EIO;        }#ifdef DEBUG_FLOPPY        printf("Floppy opened\n");#endif    }    if (!last_media_present)        s->fd_media_changed = 1;    s->fd_open_time = qemu_get_clock(rt_clock);    s->fd_got_error = 0;    return 0;}#elsestatic int fd_open(BlockDriverState *bs){    return 0;}#endif#if defined(__linux__)static int raw_is_inserted(BlockDriverState *bs){    BDRVRawState *s = bs->opaque;    int ret;    switch(s->type) {    case FTYPE_CD:        ret = ioctl(s->fd, CDROM_DRIVE_STATUS, CDSL_CURRENT);        if (ret == CDS_DISC_OK)            return 1;        else            return 0;        break;    case FTYPE_FD:        ret = fd_open(bs);        return (ret >= 0);    default:        return 1;    }}/* currently only used by fdc.c, but a CD version would be good too */static int raw_media_changed(BlockDriverState *bs){    BDRVRawState *s = bs->opaque;    switch(s->type) {    case FTYPE_FD:        {            int ret;            /* XXX: we do not have a true media changed indication. It               does not work if the floppy is changed without trying               to read it */            fd_open(bs);            ret = s->fd_media_changed;            s->fd_media_changed = 0;#ifdef DEBUG_FLOPPY            printf("Floppy changed=%d\n", ret);#endif            return ret;        }    default:        return -ENOTSUP;    }}static int raw_eject(BlockDriverState *bs, int eject_flag){    BDRVRawState *s = bs->opaque;    switch(s->type) {    case FTYPE_CD:        if (eject_flag) {            if (ioctl (s->fd, CDROMEJECT, NULL) < 0)                perror("CDROMEJECT");        } else {            if (ioctl (s->fd, CDROMCLOSETRAY, NULL) < 0)                perror("CDROMEJECT");        }        break;    case FTYPE_FD:        {            int fd;            if (s->fd >= 0) {                close(s->fd);                s->fd = -1;            }            fd = open(bs->filename, s->fd_open_flags | O_NONBLOCK);            if (fd >= 0) {                if (ioctl(fd, FDEJECT, 0) < 0)                    perror("FDEJECT");                close(fd);            }        }        break;    default:        return -ENOTSUP;    }    return 0;}static int raw_set_locked(BlockDriverState *bs, int locked){    BDRVRawState *s = bs->opaque;    switch(s->type) {    case FTYPE_CD:        if (ioctl (s->fd, CDROM_LOCKDOOR, locked) < 0) {            /* Note: an error can happen if the distribution automatically               mounts the CD-ROM */            //        perror("CDROM_LOCKDOOR");        }        break;    default:        return -ENOTSUP;    }    return 0;}#elsestatic int raw_is_inserted(BlockDriverState *bs){    return 1;}static int raw_media_changed(BlockDriverState *bs){    return -ENOTSUP;}static int raw_eject(BlockDriverState *bs, int eject_flag){    return -ENOTSUP;}static int raw_set_locked(BlockDriverState *bs, int locked){    return -ENOTSUP;}#endif /* !linux */BlockDriver bdrv_host_device = {    "host_device",    sizeof(BDRVRawState),    NULL, /* no probe for protocols */    hdev_open,    NULL,    NULL,    raw_close,    NULL,    raw_flush,        .bdrv_aio_read = raw_aio_read,    .bdrv_aio_write = raw_aio_write,    .bdrv_aio_cancel = raw_aio_cancel,    .aiocb_size = sizeof(RawAIOCB),    .bdrv_pread = raw_pread,    .bdrv_pwrite = raw_pwrite,    .bdrv_getlength = raw_getlength,    /* removable device support */    .bdrv_is_inserted = raw_is_inserted,    .bdrv_media_changed = raw_media_changed,    .bdrv_eject = raw_eject,    .bdrv_set_locked = raw_set_locked,};#else /* _WIN32 *//* XXX: use another file ? */#include <winioctl.h>#define FTYPE_FILE 0#define FTYPE_CD     1#define FTYPE_HARDDISK 2typedef struct BDRVRawState {    HANDLE hfile;    int type;    char drive_path[16]; /* format: "d:\" */} BDRVRawState;typedef struct RawAIOCB {    BlockDriverAIOCB common;    HANDLE hEvent;    OVERLAPPED ov;    int count;} RawAIOCB;int qemu_ftruncate64(int fd, int64_t length){    LARGE_INTEGER li;    LONG high;    HANDLE h;    BOOL res;    if ((GetVersion() & 0x80000000UL) && (length >> 32) != 0)	return -1;    h = (HANDLE)_get_osfhandle(fd);    /* get current position, ftruncate do not change position */    li.HighPart = 0;    li.LowPart = SetFilePointer (h, 0, &li.HighPart, FILE_CURRENT);    if (li.LowPart == 0xffffffffUL && GetLastError() != NO_ERROR)	return -1;    high = length >> 32;    if (!SetFilePointer(h, (DWORD) length, &high, FILE_BEGIN))	return -1;    res = SetEndOfFile(h);    /* back to old position */    SetFilePointer(h, li.LowPart, &li.HighPart, FILE_BEGIN);    return res ? 0 : -1;}static int set_sparse(int fd){    DWORD returned;    return (int) DeviceIoControl((HANDLE)_get_osfhandle(fd), FSCTL_SET_SPARSE,				 NULL, 0, NULL, 0, &returned, NULL);}static int raw_open(BlockDriverState *bs, const char *filename, int flags){    BDRVRawState *s = bs->opaque;    int access_flags, create_flags;    DWORD overlapped;    s->type = FTYPE_FILE;    if ((flags & BDRV_O_ACCESS) == O_RDWR) {        access_flags = GENERIC_READ | GENERIC_WRITE;    } else {        access_flags = GENERIC_READ;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -