static void vhost_scsi_instance_init(Object *obj) { VHostSCSI *dev = VHOST_SCSI(obj); device_add_bootindex_property(obj, &dev->bootindex, "bootindex", NULL, DEVICE(dev), NULL); }
static void vhost_scsi_realize(DeviceState *dev, Error **errp) { VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(dev); VHostSCSI *s = VHOST_SCSI(dev); Error *err = NULL; int vhostfd = -1; int ret; if (!vs->conf.wwpn) { error_setg(errp, "vhost-scsi: missing wwpn"); return; } if (vs->conf.vhostfd) { vhostfd = monitor_fd_param(cur_mon, vs->conf.vhostfd, errp); if (vhostfd == -1) { error_prepend(errp, "vhost-scsi: unable to parse vhostfd: "); return; } } else { vhostfd = open("/dev/vhost-scsi", O_RDWR); if (vhostfd < 0) { error_setg(errp, "vhost-scsi: open vhost char device failed: %s", strerror(errno)); return; } } virtio_scsi_common_realize(dev, &err, vhost_dummy_handle_output, vhost_dummy_handle_output, vhost_dummy_handle_output); if (err != NULL) { error_propagate(errp, err); close(vhostfd); return; } s->dev.nvqs = VHOST_SCSI_VQ_NUM_FIXED + vs->conf.num_queues; s->dev.vqs = g_new(struct vhost_virtqueue, s->dev.nvqs); s->dev.vq_index = 0; s->dev.backend_features = 0; ret = vhost_dev_init(&s->dev, (void *)(uintptr_t)vhostfd, VHOST_BACKEND_TYPE_KERNEL); if (ret < 0) { error_setg(errp, "vhost-scsi: vhost initialization failed: %s", strerror(-ret)); return; } /* At present, channel and lun both are 0 for bootable vhost-scsi disk */ s->channel = 0; s->lun = 0; /* Note: we can also get the minimum tpgt from kernel */ s->target = vs->conf.boot_tpgt; error_setg(&s->migration_blocker, "vhost-scsi does not support migration"); migrate_add_blocker(s->migration_blocker); }
static uint64_t vhost_scsi_get_features(VirtIODevice *vdev, uint64_t features) { VHostSCSI *s = VHOST_SCSI(vdev); return vhost_get_features(&s->dev, kernel_feature_bits, features); }
/* * Implementation of an interface to adjust firmware path * for the bootindex property handling. */ static char *vhost_scsi_get_fw_dev_path(FWPathProvider *p, BusState *bus, DeviceState *dev) { VHostSCSI *s = VHOST_SCSI(dev); /* format: channel@channel/vhost-scsi@target,lun */ return g_strdup_printf("/channel@%x/%s@%x,%x", s->channel, qdev_fw_name(dev), s->target, s->lun); }
static int vhost_scsi_exit(DeviceState *qdev) { VirtIODevice *vdev = VIRTIO_DEVICE(qdev); VHostSCSI *s = VHOST_SCSI(qdev); VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(qdev); migrate_del_blocker(s->migration_blocker); error_free(s->migration_blocker); /* This will stop vhost backend. */ vhost_scsi_set_status(vdev, 0); g_free(s->dev.vqs); return virtio_scsi_common_exit(vs); }
static void vhost_scsi_unrealize(DeviceState *dev, Error **errp) { VirtIODevice *vdev = VIRTIO_DEVICE(dev); VHostSCSI *s = VHOST_SCSI(dev); migrate_del_blocker(s->migration_blocker); error_free(s->migration_blocker); /* This will stop vhost backend. */ vhost_scsi_set_status(vdev, 0); g_free(s->dev.vqs); virtio_scsi_common_unrealize(dev, errp); }
static int vhost_scsi_init(VirtIODevice *vdev) { VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(vdev); VHostSCSI *s = VHOST_SCSI(vdev); int vhostfd = -1; int ret; if (!vs->conf.wwpn) { error_report("vhost-scsi: missing wwpn\n"); return -EINVAL; } if (vs->conf.vhostfd) { vhostfd = monitor_handle_fd_param(cur_mon, vs->conf.vhostfd); if (vhostfd == -1) { error_report("vhost-scsi: unable to parse vhostfd\n"); return -EINVAL; } } ret = virtio_scsi_common_init(vs); if (ret < 0) { return ret; } s->dev.nvqs = VHOST_SCSI_VQ_NUM_FIXED + vs->conf.num_queues; s->dev.vqs = g_new(struct vhost_virtqueue, s->dev.nvqs); s->dev.vq_index = 0; ret = vhost_dev_init(&s->dev, vhostfd, "/dev/vhost-scsi", true); if (ret < 0) { error_report("vhost-scsi: vhost initialization failed: %s\n", strerror(-ret)); return ret; } s->dev.backend_features = 0; error_setg(&s->migration_blocker, "vhost-scsi does not support migration"); migrate_add_blocker(s->migration_blocker); return 0; }
static void vhost_scsi_realize(DeviceState *dev, Error **errp) { VirtIOSCSICommon *vs = VIRTIO_SCSI_COMMON(dev); VHostSCSI *s = VHOST_SCSI(dev); Error *err = NULL; int vhostfd = -1; int ret; if (!vs->conf.wwpn) { error_setg(errp, "vhost-scsi: missing wwpn"); return; } if (vs->conf.vhostfd) { vhostfd = monitor_handle_fd_param(cur_mon, vs->conf.vhostfd); if (vhostfd == -1) { error_setg(errp, "vhost-scsi: unable to parse vhostfd"); return; } } virtio_scsi_common_realize(dev, &err); if (err != NULL) { error_propagate(errp, err); return; } s->dev.nvqs = VHOST_SCSI_VQ_NUM_FIXED + vs->conf.num_queues; s->dev.vqs = g_new(struct vhost_virtqueue, s->dev.nvqs); s->dev.vq_index = 0; ret = vhost_dev_init(&s->dev, vhostfd, "/dev/vhost-scsi", true); if (ret < 0) { error_setg(errp, "vhost-scsi: vhost initialization failed: %s", strerror(-ret)); return; } s->dev.backend_features = 0; error_setg(&s->migration_blocker, "vhost-scsi does not support migration"); migrate_add_blocker(s->migration_blocker); }
static uint32_t vhost_scsi_get_features(VirtIODevice *vdev, uint32_t features) { VHostSCSI *s = VHOST_SCSI(vdev); /* Clear features not supported by host kernel. */ if (!(s->dev.features & (1 << VIRTIO_F_NOTIFY_ON_EMPTY))) { features &= ~(1 << VIRTIO_F_NOTIFY_ON_EMPTY); } if (!(s->dev.features & (1 << VIRTIO_RING_F_INDIRECT_DESC))) { features &= ~(1 << VIRTIO_RING_F_INDIRECT_DESC); } if (!(s->dev.features & (1 << VIRTIO_RING_F_EVENT_IDX))) { features &= ~(1 << VIRTIO_RING_F_EVENT_IDX); } if (!(s->dev.features & (1 << VIRTIO_SCSI_F_HOTPLUG))) { features &= ~(1 << VIRTIO_SCSI_F_HOTPLUG); } return features; }