/** * Open an emulation device or file. */ static int zbc_fake_open(const char *filename, int flags, struct zbc_device **pdev) { zbc_fake_device_t *fdev; int fd, ret; zbc_debug("%s: ########## Trying FAKE driver ##########\n", filename); /* Open emulation device/file */ fd = open(filename, zbc_open_flags(flags)); if ( fd < 0 ) { zbc_error("%s: open failed %d (%s)\n", filename, errno, strerror(errno)); ret = -errno; goto out; } /* Allocate a handle */ ret = -ENOMEM; fdev = calloc(1, sizeof(*fdev)); if ( ! fdev ) { goto out; } fdev->dev.zbd_fd = fd; fdev->zbd_meta_fd = -1; fdev->dev.zbd_filename = strdup(filename); if ( ! fdev->dev.zbd_filename ) { goto out_free_dev; } /* Set the fake device information */ ret = zbc_fake_set_info(&fdev->dev); if ( ret != 0 ) { goto out_free_filename; } /* Open metadata */ ret = zbc_fake_open_metadata(fdev); if ( ret ) { goto out_free_filename; } *pdev = &fdev->dev; zbc_debug("%s: ########## FAKE driver succeeded ##########\n", filename); return 0; out_free_filename: free(fdev->dev.zbd_filename); out_free_dev: free(fdev); out: if ( fd >= 0 ) { close(fd); } zbc_debug("%s: ########## FAKE driver failed %d ##########\n", filename, ret); return ret; }
/** * Open a disk. */ static int zbc_scsi_open(const char *filename, int flags, struct zbc_device **pdev) { struct zbc_device *dev; struct stat st; int fd, ret; zbc_debug("%s: ########## Trying SCSI driver ##########\n", filename); /* Open the device file */ fd = open(filename, zbc_open_flags(flags)); if ( fd < 0 ) { zbc_error("Open device file %s failed %d (%s)\n", filename, errno, strerror(errno)); ret = -errno; goto out; } /* Check device */ if ( fstat(fd, &st) != 0 ) { zbc_error("Stat device %s failed %d (%s)\n", filename, errno, strerror(errno)); ret = -errno; goto out; } if ( (! S_ISCHR(st.st_mode)) && (! S_ISBLK(st.st_mode)) ) { ret = -ENXIO; goto out; } /* Set device decriptor */ ret = -ENOMEM; dev = calloc(1, sizeof(struct zbc_device)); if ( ! dev ) { goto out; } dev->zbd_filename = strdup(filename); if ( ! dev->zbd_filename ) { goto out_free_dev; } dev->zbd_fd = fd; ret = zbc_scsi_get_info(dev); if ( ret ) { goto out_free_filename; } *pdev = dev; zbc_debug("%s: ########## SCSI driver succeeded ##########\n", filename); return( 0 ); out_free_filename: free(dev->zbd_filename); out_free_dev: free(dev); out: if ( fd >= 0 ) { close(fd); } zbc_debug("%s: ########## SCSI driver failed %d ##########\n", filename, ret); return( ret ); }