/* FIXME Deprecate and remove keypairs or make it available in QMP. * password_secret should eventually be configurable in opts->location. Support * for it in .bdrv_open will make it work here as well. */ static int qemu_rbd_do_create(BlockdevCreateOptions *options, const char *keypairs, const char *password_secret, Error **errp) { BlockdevCreateOptionsRbd *opts = &options->u.rbd; rados_t cluster; rados_ioctx_t io_ctx; int obj_order = 0; int ret; assert(options->driver == BLOCKDEV_DRIVER_RBD); if (opts->location->has_snapshot) { error_setg(errp, "Can't use snapshot name for image creation"); return -EINVAL; } if (opts->has_cluster_size) { int64_t objsize = opts->cluster_size; if ((objsize - 1) & objsize) { /* not a power of 2? */ error_setg(errp, "obj size needs to be power of 2"); return -EINVAL; } if (objsize < 4096) { error_setg(errp, "obj size too small"); return -EINVAL; } obj_order = ctz32(objsize); } ret = qemu_rbd_connect(&cluster, &io_ctx, opts->location, false, keypairs, password_secret, errp); if (ret < 0) { return ret; } ret = rbd_create(io_ctx, opts->location->image, opts->size, &obj_order); if (ret < 0) { error_setg_errno(errp, -ret, "error rbd create"); goto out; } ret = 0; out: rados_ioctx_destroy(io_ctx); rados_shutdown(cluster); return ret; }
static ssize_t qio_channel_socket_readv(QIOChannel *ioc, const struct iovec *iov, size_t niov, int **fds, size_t *nfds, Error **errp) { QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc); ssize_t ret; struct msghdr msg = { NULL, }; char control[CMSG_SPACE(sizeof(int) * SOCKET_MAX_FDS)]; int sflags = 0; memset(control, 0, CMSG_SPACE(sizeof(int) * SOCKET_MAX_FDS)); #ifdef MSG_CMSG_CLOEXEC sflags |= MSG_CMSG_CLOEXEC; #endif msg.msg_iov = (struct iovec *)iov; msg.msg_iovlen = niov; if (fds && nfds) { msg.msg_control = control; msg.msg_controllen = sizeof(control); } retry: ret = recvmsg(sioc->fd, &msg, sflags); if (ret < 0) { if (errno == EAGAIN) { return QIO_CHANNEL_ERR_BLOCK; } if (errno == EINTR) { goto retry; } error_setg_errno(errp, errno, "Unable to read from socket"); return -1; } if (fds && nfds) { qio_channel_socket_copy_fds(&msg, fds, nfds); } return ret; }
static off_t qio_channel_file_seek(QIOChannel *ioc, off_t offset, int whence, Error **errp) { QIOChannelFile *fioc = QIO_CHANNEL_FILE(ioc); off_t ret; ret = lseek(fioc->fd, offset, whence); if (ret == (off_t)-1) { error_setg_errno(errp, errno, "Unable to seek to offset %lld whence %d in file", (long long int)offset, whence); return -1; } return ret; }
static ssize_t block_crypto_write_func(QCryptoBlock *block, size_t offset, const uint8_t *buf, size_t buflen, Error **errp, void *opaque) { struct BlockCryptoCreateData *data = opaque; ssize_t ret; ret = blk_pwrite(data->blk, offset, buf, buflen, 0); if (ret < 0) { error_setg_errno(errp, -ret, "Could not write encryption header"); return ret; } return ret; }
static ssize_t block_crypto_read_func(QCryptoBlock *block, size_t offset, uint8_t *buf, size_t buflen, Error **errp, void *opaque) { BlockDriverState *bs = opaque; ssize_t ret; ret = bdrv_pread(bs->file, offset, buf, buflen); if (ret < 0) { error_setg_errno(errp, -ret, "Could not read encryption header"); return ret; } return ret; }
int qemu_memfd_create(const char *name, size_t size, bool hugetlb, uint64_t hugetlbsize, unsigned int seals, Error **errp) { int htsize = hugetlbsize ? ctz64(hugetlbsize) : 0; if (htsize && 1ULL << htsize != hugetlbsize) { error_setg(errp, "Hugepage size must be a power of 2"); return -1; } htsize = htsize << MFD_HUGE_SHIFT; #ifdef CONFIG_LINUX int mfd = -1; unsigned int flags = MFD_CLOEXEC; if (seals) { flags |= MFD_ALLOW_SEALING; } if (hugetlb) { flags |= MFD_HUGETLB; flags |= htsize; } mfd = memfd_create(name, flags); if (mfd < 0) { goto err; } if (ftruncate(mfd, size) == -1) { goto err; } if (seals && fcntl(mfd, F_ADD_SEALS, seals) == -1) { goto err; } return mfd; err: if (mfd >= 0) { close(mfd); } #endif error_setg_errno(errp, errno, "failed to create memfd"); return -1; }
void socket_listen_cleanup(int fd, Error **errp) { SocketAddress *addr; addr = socket_local_address(fd, errp); if (addr->type == SOCKET_ADDRESS_KIND_UNIX && addr->u.q_unix.data->path) { if (unlink(addr->u.q_unix.data->path) < 0 && errno != ENOENT) { error_setg_errno(errp, errno, "Failed to unlink socket %s", addr->u.q_unix.data->path); } } qapi_free_SocketAddress(addr); }
static void ga_wait_child(pid_t pid, int *status, Error **err) { pid_t rpid; *status = 0; do { rpid = waitpid(pid, status, 0); } while (rpid == -1 && errno == EINTR); if (rpid == -1) { error_setg_errno(err, errno, "failed to wait for child (pid: %d)", pid); return; } g_assert(rpid == pid); }
static int check_constraints_on_bitmap(BlockDriverState *bs, const char *name, uint32_t granularity, Error **errp) { BDRVQcow2State *s = bs->opaque; int granularity_bits = ctz32(granularity); int64_t len = bdrv_getlength(bs); assert(granularity > 0); assert((granularity & (granularity - 1)) == 0); if (len < 0) { error_setg_errno(errp, -len, "Failed to get size of '%s'", bdrv_get_device_or_node_name(bs)); return len; } if (granularity_bits > BME_MAX_GRANULARITY_BITS) { error_setg(errp, "Granularity exceeds maximum (%llu bytes)", 1ULL << BME_MAX_GRANULARITY_BITS); return -EINVAL; } if (granularity_bits < BME_MIN_GRANULARITY_BITS) { error_setg(errp, "Granularity is under minimum (%llu bytes)", 1ULL << BME_MIN_GRANULARITY_BITS); return -EINVAL; } if ((len > (uint64_t)BME_MAX_PHYS_SIZE << granularity_bits) || (len > (uint64_t)BME_MAX_TABLE_SIZE * s->cluster_size << granularity_bits)) { error_setg(errp, "Too much space will be occupied by the bitmap. " "Use larger granularity"); return -EINVAL; } if (strlen(name) > BME_MAX_NAME_SIZE) { error_setg(errp, "Name length exceeds maximum (%u characters)", BME_MAX_NAME_SIZE); return -EINVAL; } return 0; }
/* * Open a netmap device. We assume there is only one queue * (which is the case for the VALE bridge). */ static struct nm_desc *netmap_open(const NetdevNetmapOptions *nm_opts, Error **errp) { struct nm_desc *nmd; struct nmreq req; memset(&req, 0, sizeof(req)); nmd = nm_open(nm_opts->ifname, &req, NETMAP_NO_TX_POLL, NULL); if (nmd == NULL) { error_setg_errno(errp, errno, "Failed to nm_open() %s", nm_opts->ifname); return NULL; } return nmd; }
ssize_t qio_channel_writev_full(QIOChannel *ioc, const struct iovec *iov, size_t niov, int *fds, size_t nfds, Error **errp) { QIOChannelClass *klass = QIO_CHANNEL_GET_CLASS(ioc); if ((fds || nfds) && !qio_channel_has_feature(ioc, QIO_CHANNEL_FEATURE_FD_PASS)) { error_setg_errno(errp, EINVAL, "Channel does not support file descriptor passing"); return -1; } return klass->io_writev(ioc, iov, niov, fds, nfds, errp); }
static void colo_send_message(QEMUFile *f, COLOMessage msg, Error **errp) { int ret; if (msg >= COLO_MESSAGE__MAX) { error_setg(errp, "%s: Invalid message", __func__); return; } qemu_put_be32(f, msg); qemu_fflush(f); ret = qemu_file_get_error(f); if (ret < 0) { error_setg_errno(errp, -ret, "Can't send COLO message"); } trace_colo_send_message(COLOMessage_lookup[msg]); }
static COLOMessage colo_receive_message(QEMUFile *f, Error **errp) { COLOMessage msg; int ret; msg = qemu_get_be32(f); ret = qemu_file_get_error(f); if (ret < 0) { error_setg_errno(errp, -ret, "Can't receive COLO message"); return msg; } if (msg >= COLO_MESSAGE__MAX) { error_setg(errp, "%s: Invalid message", __func__); return msg; } trace_colo_receive_message(COLOMessage_lookup[msg]); return msg; }
void os_mem_prealloc(int fd, char *area, size_t memory, Error **errp) { int ret; struct sigaction act, oldact; sigset_t set, oldset; memset(&act, 0, sizeof(act)); act.sa_handler = &sigbus_handler; act.sa_flags = 0; ret = sigaction(SIGBUS, &act, &oldact); if (ret) { error_setg_errno(errp, errno, "os_mem_prealloc: failed to install signal handler"); return; } /* unblock SIGBUS */ sigemptyset(&set); sigaddset(&set, SIGBUS); pthread_sigmask(SIG_UNBLOCK, &set, &oldset); if (sigsetjmp(sigjump, 1)) { error_setg(errp, "os_mem_prealloc: Insufficient free host memory " "pages available to allocate guest RAM\n"); } else { int i; size_t hpagesize = qemu_fd_getpagesize(fd); size_t numpages = DIV_ROUND_UP(memory, hpagesize); /* MAP_POPULATE silently ignores failures */ for (i = 0; i < numpages; i++) { memset(area + (hpagesize * i), 0, 1); } } ret = sigaction(SIGBUS, &oldact, NULL); if (ret) { /* Terminate QEMU since it can't recover from error */ perror("os_mem_prealloc: failed to reinstall signal handler"); exit(1); } pthread_sigmask(SIG_SETMASK, &oldset, NULL); }
QIOChannelSocket * qio_channel_socket_accept(QIOChannelSocket *ioc, Error **errp) { QIOChannelSocket *cioc; cioc = qio_channel_socket_new(); cioc->remoteAddrLen = sizeof(ioc->remoteAddr); cioc->localAddrLen = sizeof(ioc->localAddr); retry: trace_qio_channel_socket_accept(ioc); cioc->fd = qemu_accept(ioc->fd, (struct sockaddr *)&cioc->remoteAddr, &cioc->remoteAddrLen); if (cioc->fd < 0) { trace_qio_channel_socket_accept_fail(ioc); if (errno == EINTR) { goto retry; } goto error; } if (getsockname(cioc->fd, (struct sockaddr *)&cioc->localAddr, &cioc->localAddrLen) < 0) { error_setg_errno(errp, errno, "Unable to query local socket address"); goto error; } #ifndef WIN32 if (cioc->localAddr.ss_family == AF_UNIX) { QIOChannel *ioc_local = QIO_CHANNEL(cioc); qio_channel_set_feature(ioc_local, QIO_CHANNEL_FEATURE_FD_PASS); } #endif /* WIN32 */ trace_qio_channel_socket_accept_complete(ioc, cioc, cioc->fd); return cioc; error: object_unref(OBJECT(cioc)); return NULL; }
static int64_t ivshmem_recv_msg(IVShmemState *s, int *pfd, Error **errp) { int64_t msg; int n, ret; n = 0; do { ret = qemu_chr_fe_read_all(s->server_chr, (uint8_t *)&msg + n, sizeof(msg) - n); if (ret < 0 && ret != -EINTR) { error_setg_errno(errp, -ret, "read from server failed"); return INT64_MIN; } n += ret; } while (n < sizeof(msg)); *pfd = qemu_chr_fe_get_msgfd(s->server_chr); return msg; }
static int qemu_rbd_truncate(BlockDriverState *bs, int64_t offset, PreallocMode prealloc, Error **errp) { BDRVRBDState *s = bs->opaque; int r; if (prealloc != PREALLOC_MODE_OFF) { error_setg(errp, "Unsupported preallocation mode '%s'", PreallocMode_str(prealloc)); return -ENOTSUP; } r = rbd_resize(s->image, offset); if (r < 0) { error_setg_errno(errp, -r, "Failed to resize file"); return r; } return 0; }
static void colo_send_message_value(QEMUFile *f, COLOMessage msg, uint64_t value, Error **errp) { Error *local_err = NULL; int ret; colo_send_message(f, msg, &local_err); if (local_err) { error_propagate(errp, local_err); return; } qemu_put_be64(f, value); qemu_fflush(f); ret = qemu_file_get_error(f); if (ret < 0) { error_setg_errno(errp, -ret, "Failed to send value for message:%s", COLOMessage_lookup[msg]); } }
static int qio_channel_socket_close(QIOChannel *ioc, Error **errp) { QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc); if (sioc->fd != -1) { #ifdef WIN32 WSAEventSelect(sioc->fd, NULL, 0); #endif if (closesocket(sioc->fd) < 0) { sioc->fd = -1; error_setg_errno(errp, errno, "Unable to close socket"); return -1; } sioc->fd = -1; } return 0; }
static void kvm_arm_gicv3_realize(DeviceState *dev, Error **errp) { GICv3State *s = KVM_ARM_GICV3(dev); KVMARMGICv3Class *kgc = KVM_ARM_GICV3_GET_CLASS(s); Error *local_err = NULL; DPRINTF("kvm_arm_gicv3_realize\n"); kgc->parent_realize(dev, &local_err); if (local_err) { error_propagate(errp, local_err); return; } if (s->security_extn) { error_setg(errp, "the in-kernel VGICv3 does not implement the " "security extensions"); return; } gicv3_init_irqs_and_mmio(s, kvm_arm_gicv3_set_irq, NULL); /* Try to create the device via the device control API */ s->dev_fd = kvm_create_device(kvm_state, KVM_DEV_TYPE_ARM_VGIC_V3, false); if (s->dev_fd < 0) { error_setg_errno(errp, -s->dev_fd, "error creating in-kernel VGIC"); return; } kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_NR_IRQS, 0, &s->num_irq, true); /* Tell the kernel to complete VGIC initialization now */ kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CTRL, KVM_DEV_ARM_VGIC_CTRL_INIT, NULL, true); kvm_arm_register_device(&s->iomem_dist, -1, KVM_DEV_ARM_VGIC_GRP_ADDR, KVM_VGIC_V3_ADDR_TYPE_DIST, s->dev_fd); kvm_arm_register_device(&s->iomem_redist, -1, KVM_DEV_ARM_VGIC_GRP_ADDR, KVM_VGIC_V3_ADDR_TYPE_REDIST, s->dev_fd); }
static int qio_channel_command_abort(QIOChannelCommand *ioc, Error **errp) { pid_t ret; int status; int step = 0; /* See if intermediate process has exited; if not, try a nice * SIGTERM followed by a more severe SIGKILL. */ rewait: trace_qio_channel_command_abort(ioc, ioc->pid); ret = waitpid(ioc->pid, &status, WNOHANG); trace_qio_channel_command_wait(ioc, ioc->pid, ret, status); if (ret == (pid_t)-1) { if (errno == EINTR) { goto rewait; } else { error_setg_errno(errp, errno, "Cannot wait on pid %llu", (unsigned long long)ioc->pid); return -1; } } else if (ret == 0) { if (step == 0) { kill(ioc->pid, SIGTERM); } else if (step == 1) { kill(ioc->pid, SIGKILL); } else { error_setg(errp, "Process %llu refused to die", (unsigned long long)ioc->pid); return -1; } step++; usleep(10 * 1000); goto rewait; } return 0; }
/* * This is a best-effort helper for shared memory allocation, with * optional sealing. The helper will do his best to allocate using * memfd with sealing, but may fallback on other methods without * sealing. */ void *qemu_memfd_alloc(const char *name, size_t size, unsigned int seals, int *fd, Error **errp) { void *ptr; int mfd = qemu_memfd_create(name, size, false, 0, seals, NULL); /* some systems have memfd without sealing */ if (mfd == -1) { mfd = qemu_memfd_create(name, size, false, 0, 0, NULL); } if (mfd == -1) { const char *tmpdir = g_get_tmp_dir(); gchar *fname; fname = g_strdup_printf("%s/memfd-XXXXXX", tmpdir); mfd = mkstemp(fname); unlink(fname); g_free(fname); if (mfd == -1 || ftruncate(mfd, size) == -1) { goto err; } } ptr = mmap(0, size, PROT_READ | PROT_WRITE, MAP_SHARED, mfd, 0); if (ptr == MAP_FAILED) { goto err; } *fd = mfd; return ptr; err: error_setg_errno(errp, errno, "failed to allocate shared memory"); if (mfd >= 0) { close(mfd); } return NULL; }
static ssize_t qio_channel_socket_writev(QIOChannel *ioc, const struct iovec *iov, size_t niov, int *fds, size_t nfds, Error **errp) { QIOChannelSocket *sioc = QIO_CHANNEL_SOCKET(ioc); ssize_t done = 0; ssize_t i; for (i = 0; i < niov; i++) { ssize_t ret; retry: ret = send(sioc->fd, iov[i].iov_base, iov[i].iov_len, 0); if (ret < 0) { if (errno == EAGAIN) { if (done) { return done; } else { return QIO_CHANNEL_ERR_BLOCK; } } else if (errno == EINTR) { goto retry; } else { error_setg_errno(errp, errno, "Unable to write to socket"); return -1; } } done += ret; if (ret < iov[i].iov_len) { return done; } } return done; }
static uint64_t colo_receive_message_value(QEMUFile *f, uint32_t expect_msg, Error **errp) { Error *local_err = NULL; uint64_t value; int ret; colo_receive_check_message(f, expect_msg, &local_err); if (local_err) { error_propagate(errp, local_err); return 0; } value = qemu_get_be64(f); ret = qemu_file_get_error(f); if (ret < 0) { error_setg_errno(errp, -ret, "Failed to get value for COLO message: %s", COLOMessage_lookup[expect_msg]); } return value; }
void xs_node_vprintf(struct xs_handle *xsh, xs_transaction_t tid, const char *node, const char *key, Error **errp, const char *fmt, va_list ap) { char *path, *value; int len; path = (strlen(node) != 0) ? g_strdup_printf("%s/%s", node, key) : g_strdup(key); len = g_vasprintf(&value, fmt, ap); trace_xs_node_vprintf(path, value); if (!xs_write(xsh, tid, path, value, len)) { error_setg_errno(errp, errno, "failed to write '%s' to '%s'", value, path); } g_free(value); g_free(path); }
int qcrypto_tls_creds_get_path(QCryptoTLSCreds *creds, const char *filename, bool required, char **cred, Error **errp) { struct stat sb; int ret = -1; if (!creds->dir) { if (required) { error_setg(errp, "Missing 'dir' property value"); return -1; } else { return 0; } } *cred = g_strdup_printf("%s/%s", creds->dir, filename); if (stat(*cred, &sb) < 0) { if (errno == ENOENT && !required) { ret = 0; } else { error_setg_errno(errp, errno, "Unable to access credentials %s", *cred); } g_free(*cred); *cred = NULL; goto cleanup; } ret = 0; cleanup: trace_qcrypto_tls_creds_get_path(creds, filename, *cred ? *cred : "<none>"); return ret; }
static void launch_script(const char *setup_script, const char *ifname, int fd, Error **errp) { int pid, status; char *args[3]; char **parg; /* try to launch network script */ pid = fork(); if (pid < 0) { error_setg_errno(errp, errno, "could not launch network script %s", setup_script); return; } if (pid == 0) { int open_max = sysconf(_SC_OPEN_MAX), i; for (i = 3; i < open_max; i++) { if (i != fd) { close(i); } } parg = args; *parg++ = (char *)setup_script; *parg++ = (char *)ifname; *parg = NULL; execv(setup_script, args); _exit(1); } else { while (waitpid(pid, &status, 0) != pid) { /* loop */ } if (WIFEXITED(status) && WEXITSTATUS(status) == 0) { return; } error_setg(errp, "network script %s failed with status %d", setup_script, status); } }
static void kvm_arm_its_realize(DeviceState *dev, Error **errp) { GICv3ITSState *s = ARM_GICV3_ITS_COMMON(dev); Error *local_err = NULL; s->dev_fd = kvm_create_device(kvm_state, KVM_DEV_TYPE_ARM_VGIC_ITS, false); if (s->dev_fd < 0) { error_setg_errno(errp, -s->dev_fd, "error creating in-kernel ITS"); return; } /* explicit init of the ITS */ kvm_device_access(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_CTRL, KVM_DEV_ARM_VGIC_CTRL_INIT, NULL, true, &error_abort); /* register the base address */ kvm_arm_register_device(&s->iomem_its_cntrl, -1, KVM_DEV_ARM_VGIC_GRP_ADDR, KVM_VGIC_ITS_ADDR_TYPE, s->dev_fd); gicv3_its_init_mmio(s, NULL); if (!kvm_device_check_attr(s->dev_fd, KVM_DEV_ARM_VGIC_GRP_ITS_REGS, GITS_CTLR)) { error_setg(&s->migration_blocker, "This operating system kernel " "does not support vITS migration"); migrate_add_blocker(s->migration_blocker, &local_err); if (local_err) { error_propagate(errp, local_err); error_free(s->migration_blocker); return; } } else { qemu_add_vm_change_state_handler(vm_change_state_handler, s); } kvm_msi_use_devid = true; kvm_gsi_direct_mapping = false; kvm_msi_via_irqfd_allowed = kvm_irqfds_enabled(); }
/* create the shared memory BAR when we are not using the server, so we can * create the BAR and map the memory immediately */ static int create_shared_memory_BAR(IVShmemState *s, int fd, uint8_t attr, Error **errp) { void * ptr; ptr = mmap(0, s->ivshmem_size, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); if (ptr == MAP_FAILED) { error_setg_errno(errp, errno, "Failed to mmap shared memory"); return -1; } memory_region_init_ram_ptr(&s->ivshmem, OBJECT(s), "ivshmem.bar2", s->ivshmem_size, ptr); qemu_set_ram_fd(s->ivshmem.ram_addr, fd); vmstate_register_ram(&s->ivshmem, DEVICE(s)); memory_region_add_subregion(&s->bar, 0, &s->ivshmem); /* region for shared memory */ pci_register_bar(PCI_DEVICE(s), 2, attr, &s->bar); return 0; }
AioContext *aio_context_new(Error **errp) { int ret; AioContext *ctx; ctx = (AioContext *) g_source_new(&aio_source_funcs, sizeof(AioContext)); ret = event_notifier_init(&ctx->notifier, false); if (ret < 0) { g_source_destroy(&ctx->source); error_setg_errno(errp, -ret, "Failed to initialize event notifier"); return NULL; } aio_set_event_notifier(ctx, &ctx->notifier, (EventNotifierHandler *) event_notifier_test_and_clear); ctx->pollfds = g_array_new(FALSE, FALSE, sizeof(GPollFD)); ctx->thread_pool = NULL; qemu_mutex_init(&ctx->bh_lock); rfifolock_init(&ctx->lock, aio_rfifolock_cb, ctx); timerlistgroup_init(&ctx->tlg, aio_timerlist_notify, ctx); return ctx; }