int qmp_marshal_input_query_version(Monitor *mon, const QDict *qdict, QObject **ret) { Error *local_err = NULL; Error **errp = &local_err; QDict *args = (QDict *)qdict; VersionInfo * retval = NULL; (void)args; if (error_is_set(errp)) { goto out; } retval = qmp_query_version(errp); if (!error_is_set(errp)) { qmp_marshal_output_query_version(retval, ret, errp); } out: if (local_err) { qerror_report_err(local_err); error_free(local_err); return -1; } return 0; }
void assert_no_error(Error *err) { if (err) { qerror_report_err(err); abort(); } }
int qmp_marshal_input_cpu(Monitor *mon, const QDict *qdict, QObject **ret) { Error *local_err = NULL; Error **errp = &local_err; QDict *args = (QDict *)qdict; QmpInputVisitor *mi; QapiDeallocVisitor *md; Visitor *v; int64_t index; mi = qmp_input_visitor_new(QOBJECT(args)); v = qmp_input_get_visitor(mi); visit_type_int(v, &index, "index", errp); qmp_input_visitor_cleanup(mi); if (error_is_set(errp)) { goto out; } qmp_cpu(index, errp); out: md = qapi_dealloc_visitor_new(); v = qapi_dealloc_get_visitor(md); visit_type_int(v, &index, "index", errp); qapi_dealloc_visitor_cleanup(md); if (local_err) { qerror_report_err(local_err); error_free(local_err); return -1; } return 0; }
static int raw_open_common(BlockDriverState *bs, QDict *options, int bdrv_flags, int open_flags) { BDRVRawState *s = bs->opaque; QemuOpts *opts; Error *local_err = NULL; const char *filename; int fd, ret; opts = qemu_opts_create_nofail(&raw_runtime_opts); qemu_opts_absorb_qdict(opts, options, &local_err); if (error_is_set(&local_err)) { qerror_report_err(local_err); error_free(local_err); ret = -EINVAL; goto fail; } filename = qemu_opt_get(opts, "filename"); ret = raw_normalize_devicepath(&filename); if (ret != 0) { goto fail; } s->open_flags = open_flags; raw_parse_flags(bdrv_flags, &s->open_flags); s->fd = -1; fd = qemu_open(filename, s->open_flags, 0644); if (fd < 0) { ret = -errno; if (ret == -EROFS) { ret = -EACCES; } goto fail; } s->fd = fd; #ifdef CONFIG_LINUX_AIO if (raw_set_aio(&s->aio_ctx, &s->use_aio, bdrv_flags)) { qemu_close(fd); ret = -errno; goto fail; } #endif s->has_discard = 1; #ifdef CONFIG_XFS if (platform_test_xfs_fd(s->fd)) { s->is_xfs = 1; } #endif ret = 0; fail: qemu_opts_del(opts); return ret; }
static int ssh_create(const char *filename, QEMUOptionParameter *options) { int r, ret; Error *local_err = NULL; int64_t total_size = 0; QDict *uri_options = NULL; BDRVSSHState s; ssize_t r2; char c[1] = { '\0' }; ssh_state_init(&s); /* Get desired file size. */ while (options && options->name) { if (!strcmp(options->name, BLOCK_OPT_SIZE)) { total_size = options->value.n; } options++; } DPRINTF("total_size=%" PRIi64, total_size); uri_options = qdict_new(); r = parse_uri(filename, uri_options, &local_err); if (r < 0) { qerror_report_err(local_err); error_free(local_err); ret = r; goto out; } r = connect_to_ssh(&s, uri_options, LIBSSH2_FXF_READ|LIBSSH2_FXF_WRITE| LIBSSH2_FXF_CREAT|LIBSSH2_FXF_TRUNC, 0644); if (r < 0) { ret = r; goto out; } if (total_size > 0) { libssh2_sftp_seek64(s.sftp_handle, total_size-1); r2 = libssh2_sftp_write(s.sftp_handle, c, 1); if (r2 < 0) { sftp_error_report(&s, "truncate failed"); ret = -EINVAL; goto out; } s.attrs.filesize = total_size; } ret = 0; out: ssh_state_free(&s); if (uri_options != NULL) { QDECREF(uri_options); } return ret; }
int do_migrate(Monitor *mon, const QDict *qdict, QObject **ret_data) { MigrationState *s = migrate_get_current(); const char *p; int detach = qdict_get_try_bool(qdict, "detach", 0); int blk = qdict_get_try_bool(qdict, "blk", 0); int inc = qdict_get_try_bool(qdict, "inc", 0); const char *uri = qdict_get_str(qdict, "uri"); int ret; if (s->state == MIG_STATE_ACTIVE) { monitor_printf(mon, "migration already in progress\n"); return -1; } if (qemu_savevm_state_blocked(mon)) { return -1; } if (migration_blockers) { Error *err = migration_blockers->data; qerror_report_err(err); return -1; } s = migrate_init(mon, detach, blk, inc); if (strstart(uri, "tcp:", &p)) { ret = tcp_start_outgoing_migration(s, p); #if !defined(WIN32) } else if (strstart(uri, "exec:", &p)) { ret = exec_start_outgoing_migration(s, p); } else if (strstart(uri, "unix:", &p)) { ret = unix_start_outgoing_migration(s, p); } else if (strstart(uri, "fd:", &p)) { ret = fd_start_outgoing_migration(s, p); #endif } else { monitor_printf(mon, "unknown migration protocol: %s\n", uri); ret = -EINVAL; } if (ret < 0) { monitor_printf(mon, "migration failed: %s\n", strerror(-ret)); return ret; } if (detach) { s->mon = NULL; } notifier_list_notify(&migration_state_notifiers, s); return 0; }
static int unix_socket_incoming(const char *path) { Error *local_err = NULL; int fd = unix_listen(path, NULL, 0, &local_err); if (local_err != NULL) { qerror_report_err(local_err); error_free(local_err); } return fd; }
static int unix_socket_outgoing(const char *path) { Error *local_err = NULL; int fd = unix_connect(path, &local_err); if (local_err != NULL) { qerror_report_err(local_err); error_free(local_err); } return fd; }
static int raw_create(const char *filename, QEMUOptionParameter *options, Error **errp) { Error *local_err = NULL; int ret; ret = bdrv_create_file(filename, options, &local_err); if (error_is_set(&local_err)) { qerror_report_err(local_err); error_free(local_err); } return ret; }
static int tcp_socket_incoming(const char *address, uint16_t port) { char address_and_port[128]; Error *local_err = NULL; combine_addr(address_and_port, 128, address, port); int fd = inet_listen(address_and_port, NULL, 0, SOCK_STREAM, 0, &local_err); if (local_err != NULL) { qerror_report_err(local_err); error_free(local_err); } return fd; }
int qdev_prop_set_drive(DeviceState *dev, const char *name, BlockDriverState *value) { Error *errp = NULL; const char *bdrv_name = value ? bdrv_get_device_name(value) : ""; object_property_set_str(OBJECT(dev), bdrv_name, name, &errp); if (errp) { qerror_report_err(errp); error_free(errp); return -1; } return 0; }
static int blkverify_open(BlockDriverState *bs, QDict *options, int flags) { BDRVBlkverifyState *s = bs->opaque; QemuOpts *opts; Error *local_err = NULL; const char *filename, *raw; int ret; opts = qemu_opts_create_nofail(&runtime_opts); qemu_opts_absorb_qdict(opts, options, &local_err); if (error_is_set(&local_err)) { qerror_report_err(local_err); error_free(local_err); ret = -EINVAL; goto fail; } /* Parse the raw image filename */ raw = qemu_opt_get(opts, "x-raw"); if (raw == NULL) { ret = -EINVAL; goto fail; } ret = bdrv_file_open(&bs->file, raw, NULL, flags); if (ret < 0) { goto fail; } /* Open the test file */ filename = qemu_opt_get(opts, "x-image"); if (filename == NULL) { ret = -EINVAL; goto fail; } s->test_file = bdrv_new(""); ret = bdrv_open(s->test_file, filename, NULL, flags, NULL); if (ret < 0) { bdrv_unref(s->test_file); s->test_file = NULL; goto fail; } ret = 0; fail: return ret; }
static PCIDevice *qemu_pci_hot_add_nic(Monitor *mon, const char *devaddr, const char *opts_str) { Error *local_err = NULL; QemuOpts *opts; PCIBus *root = pci_find_primary_bus(); PCIBus *bus; int ret, devfn; if (!root) { monitor_printf(mon, "no primary PCI bus (if there are multiple" " PCI roots, you must use device_add instead)"); return NULL; } bus = pci_get_bus_devfn(&devfn, root, devaddr); if (!bus) { monitor_printf(mon, "Invalid PCI device address %s\n", devaddr); return NULL; } if (!((BusState*)bus)->allow_hotplug) { monitor_printf(mon, "PCI bus doesn't support hotplug\n"); return NULL; } opts = qemu_opts_parse(qemu_find_opts("net"), opts_str ? opts_str : "", 0); if (!opts) { return NULL; } qemu_opt_set(opts, "type", "nic"); ret = net_client_init(opts, 0, &local_err); if (error_is_set(&local_err)) { qerror_report_err(local_err); error_free(local_err); return NULL; } if (nd_table[ret].devaddr) { monitor_printf(mon, "Parameter addr not supported\n"); return NULL; } return pci_nic_init(&nd_table[ret], root, "rtl8139", devaddr); }
static int multi_serial_pci_init(PCIDevice *dev) { PCIDeviceClass *pc = PCI_DEVICE_GET_CLASS(dev); PCIMultiSerialState *pci = DO_UPCAST(PCIMultiSerialState, dev, dev); SerialState *s; Error *err = NULL; int i; switch (pc->device_id) { case 0x0003: pci->ports = 2; break; case 0x0004: pci->ports = 4; break; } assert(pci->ports > 0); assert(pci->ports <= PCI_SERIAL_MAX_PORTS); pci->dev.config[PCI_INTERRUPT_PIN] = 0x01; memory_region_init(&pci->iobar, OBJECT(pci), "multiserial", 8 * pci->ports); pci_register_bar(&pci->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &pci->iobar); pci->irqs = qemu_allocate_irqs(multi_serial_irq_mux, pci, pci->ports); for (i = 0; i < pci->ports; i++) { s = pci->state + i; s->baudbase = 115200; serial_realize_core(s, &err); if (err != NULL) { qerror_report_err(err); error_free(err); return -1; } s->irq = pci->irqs[i]; pci->name[i] = g_strdup_printf("uart #%d", i+1); memory_region_init_io(&s->io, OBJECT(pci), &serial_io_ops, s, pci->name[i], 8); memory_region_add_subregion(&pci->iobar, 8 * i, &s->io); } return 0; }
int qmp_marshal_input_system_powerdown(Monitor *mon, const QDict *qdict, QObject **ret) { Error *local_err = NULL; Error **errp = &local_err; QDict *args = (QDict *)qdict; (void)args; if (error_is_set(errp)) { goto out; } qmp_system_powerdown(errp); out: if (local_err) { qerror_report_err(local_err); error_free(local_err); return -1; } return 0; }
static int serial_pci_init(PCIDevice *dev) { PCISerialState *pci = DO_UPCAST(PCISerialState, dev, dev); SerialState *s = &pci->state; Error *err = NULL; s->baudbase = 115200; serial_realize_core(s, &err); if (err != NULL) { qerror_report_err(err); error_free(err); return -1; } pci->dev.config[PCI_INTERRUPT_PIN] = 0x01; s->irq = pci_allocate_irq(&pci->dev); memory_region_init_io(&s->io, OBJECT(pci), &serial_io_ops, s, "serial", 8); pci_register_bar(&pci->dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->io); return 0; }
/* * We support iscsi url's on the form * iscsi://[<username>%<password>@]<host>[:<port>]/<targetname>/<lun> */ static int iscsi_open(BlockDriverState *bs, QDict *options, int flags) { IscsiLun *iscsilun = bs->opaque; struct iscsi_context *iscsi = NULL; struct iscsi_url *iscsi_url = NULL; struct scsi_task *task = NULL; struct scsi_inquiry_standard *inq = NULL; char *initiator_name = NULL; QemuOpts *opts; Error *local_err = NULL; const char *filename; int ret; if ((BDRV_SECTOR_SIZE % 512) != 0) { error_report("iSCSI: Invalid BDRV_SECTOR_SIZE. " "BDRV_SECTOR_SIZE(%lld) is not a multiple " "of 512", BDRV_SECTOR_SIZE); return -EINVAL; } opts = qemu_opts_create_nofail(&runtime_opts); qemu_opts_absorb_qdict(opts, options, &local_err); if (error_is_set(&local_err)) { qerror_report_err(local_err); error_free(local_err); ret = -EINVAL; goto out; } filename = qemu_opt_get(opts, "filename"); iscsi_url = iscsi_parse_full_url(iscsi, filename); if (iscsi_url == NULL) { error_report("Failed to parse URL : %s", filename); ret = -EINVAL; goto out; } memset(iscsilun, 0, sizeof(IscsiLun)); initiator_name = parse_initiator_name(iscsi_url->target); iscsi = iscsi_create_context(initiator_name); if (iscsi == NULL) { error_report("iSCSI: Failed to create iSCSI context."); ret = -ENOMEM; goto out; } if (iscsi_set_targetname(iscsi, iscsi_url->target)) { error_report("iSCSI: Failed to set target name."); ret = -EINVAL; goto out; } if (iscsi_url->user != NULL) { ret = iscsi_set_initiator_username_pwd(iscsi, iscsi_url->user, iscsi_url->passwd); if (ret != 0) { error_report("Failed to set initiator username and password"); ret = -EINVAL; goto out; } } /* check if we got CHAP username/password via the options */ if (parse_chap(iscsi, iscsi_url->target) != 0) { error_report("iSCSI: Failed to set CHAP user/password"); ret = -EINVAL; goto out; } if (iscsi_set_session_type(iscsi, ISCSI_SESSION_NORMAL) != 0) { error_report("iSCSI: Failed to set session type to normal."); ret = -EINVAL; goto out; } iscsi_set_header_digest(iscsi, ISCSI_HEADER_DIGEST_NONE_CRC32C); /* check if we got HEADER_DIGEST via the options */ parse_header_digest(iscsi, iscsi_url->target); if (iscsi_full_connect_sync(iscsi, iscsi_url->portal, iscsi_url->lun) != 0) { error_report("iSCSI: Failed to connect to LUN : %s", iscsi_get_error(iscsi)); ret = -EINVAL; goto out; } iscsilun->iscsi = iscsi; iscsilun->lun = iscsi_url->lun; task = iscsi_inquiry_sync(iscsi, iscsilun->lun, 0, 0, 36); if (task == NULL || task->status != SCSI_STATUS_GOOD) { error_report("iSCSI: failed to send inquiry command."); ret = -EINVAL; goto out; } inq = scsi_datain_unmarshall(task); if (inq == NULL) { error_report("iSCSI: Failed to unmarshall inquiry data."); ret = -EINVAL; goto out; } iscsilun->type = inq->periperal_device_type; if ((ret = iscsi_readcapacity_sync(iscsilun)) != 0) { goto out; } bs->total_sectors = sector_lun2qemu(iscsilun->num_blocks, iscsilun); /* Medium changer or tape. We dont have any emulation for this so this must * be sg ioctl compatible. We force it to be sg, otherwise qemu will try * to read from the device to guess the image format. */ if (iscsilun->type == TYPE_MEDIUM_CHANGER || iscsilun->type == TYPE_TAPE) { bs->sg = 1; } #if defined(LIBISCSI_FEATURE_NOP_COUNTER) /* Set up a timer for sending out iSCSI NOPs */ iscsilun->nop_timer = qemu_new_timer_ms(rt_clock, iscsi_nop_timed_event, iscsilun); qemu_mod_timer(iscsilun->nop_timer, qemu_get_clock_ms(rt_clock) + NOP_INTERVAL); #endif out: qemu_opts_del(opts); if (initiator_name != NULL) { g_free(initiator_name); } if (iscsi_url != NULL) { iscsi_destroy_url(iscsi_url); } if (task != NULL) { scsi_free_scsi_task(task); } if (ret) { if (iscsi != NULL) { iscsi_destroy_context(iscsi); } memset(iscsilun, 0, sizeof(IscsiLun)); } return ret; }
static int connect_to_ssh(BDRVSSHState *s, QDict *options, int ssh_flags, int creat_mode) { int r, ret; Error *err = NULL; const char *host, *user, *path, *host_key_check; int port; host = qdict_get_str(options, "host"); if (qdict_haskey(options, "port")) { port = qdict_get_int(options, "port"); } else { port = 22; } path = qdict_get_str(options, "path"); if (qdict_haskey(options, "user")) { user = qdict_get_str(options, "user"); } else { user = g_get_user_name(); if (!user) { ret = -errno; goto err; } } if (qdict_haskey(options, "host_key_check")) { host_key_check = qdict_get_str(options, "host_key_check"); } else { host_key_check = "yes"; } /* Construct the host:port name for inet_connect. */ g_free(s->hostport); s->hostport = g_strdup_printf("%s:%d", host, port); /* Open the socket and connect. */ s->sock = inet_connect(s->hostport, &err); if (err != NULL) { ret = -errno; qerror_report_err(err); error_free(err); goto err; } /* Create SSH session. */ s->session = libssh2_session_init(); if (!s->session) { ret = -EINVAL; session_error_report(s, "failed to initialize libssh2 session"); goto err; } #if TRACE_LIBSSH2 != 0 libssh2_trace(s->session, TRACE_LIBSSH2); #endif r = libssh2_session_handshake(s->session, s->sock); if (r != 0) { ret = -EINVAL; session_error_report(s, "failed to establish SSH session"); goto err; } /* Check the remote host's key against known_hosts. */ ret = check_host_key(s, host, port, host_key_check); if (ret < 0) { goto err; } /* Authenticate. */ ret = authenticate(s, user); if (ret < 0) { goto err; } /* Start SFTP. */ s->sftp = libssh2_sftp_init(s->session); if (!s->sftp) { session_error_report(s, "failed to initialize sftp handle"); ret = -EINVAL; goto err; } /* Open the remote file. */ DPRINTF("opening file %s flags=0x%x creat_mode=0%o", path, ssh_flags, creat_mode); s->sftp_handle = libssh2_sftp_open(s->sftp, path, ssh_flags, creat_mode); if (!s->sftp_handle) { session_error_report(s, "failed to open remote file '%s'", path); ret = -EINVAL; goto err; } r = libssh2_sftp_fstat(s->sftp_handle, &s->attrs); if (r < 0) { sftp_error_report(s, "failed to read file attributes"); return -EINVAL; } /* Delete the options we've used; any not deleted will cause the * block layer to give an error about unused options. */ qdict_del(options, "host"); qdict_del(options, "port"); qdict_del(options, "user"); qdict_del(options, "path"); qdict_del(options, "host_key_check"); return 0; err: if (s->sftp_handle) { libssh2_sftp_close(s->sftp_handle); } s->sftp_handle = NULL; if (s->sftp) { libssh2_sftp_shutdown(s->sftp); } s->sftp = NULL; if (s->session) { libssh2_session_disconnect(s->session, "from qemu ssh client: " "error opening connection"); libssh2_session_free(s->session); } s->session = NULL; return ret; }
static int qemu_gluster_open(BlockDriverState *bs, QDict *options, int bdrv_flags) { BDRVGlusterState *s = bs->opaque; int open_flags = O_BINARY; int ret = 0; GlusterConf *gconf = g_malloc0(sizeof(GlusterConf)); QemuOpts *opts; Error *local_err = NULL; const char *filename; opts = qemu_opts_create_nofail(&runtime_opts); qemu_opts_absorb_qdict(opts, options, &local_err); if (error_is_set(&local_err)) { qerror_report_err(local_err); error_free(local_err); ret = -EINVAL; goto out; } filename = qemu_opt_get(opts, "filename"); s->glfs = qemu_gluster_init(gconf, filename); if (!s->glfs) { ret = -errno; goto out; } if (bdrv_flags & BDRV_O_RDWR) { open_flags |= O_RDWR; } else { open_flags |= O_RDONLY; } if ((bdrv_flags & BDRV_O_NOCACHE)) { open_flags |= O_DIRECT; } s->fd = glfs_open(s->glfs, gconf->image, open_flags); if (!s->fd) { ret = -errno; goto out; } ret = qemu_pipe(s->fds); if (ret < 0) { ret = -errno; goto out; } fcntl(s->fds[GLUSTER_FD_READ], F_SETFL, O_NONBLOCK); qemu_aio_set_fd_handler(s->fds[GLUSTER_FD_READ], qemu_gluster_aio_event_reader, NULL, s); out: qemu_opts_del(opts); qemu_gluster_gconf_free(gconf); if (!ret) { return ret; } if (s->fd) { glfs_close(s->fd); } if (s->glfs) { glfs_fini(s->glfs); } return ret; }
static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags, Error **errp) { BDRVRBDState *s = bs->opaque; char pool[RBD_MAX_POOL_NAME_SIZE]; char snap_buf[RBD_MAX_SNAP_NAME_SIZE]; char conf[RBD_MAX_CONF_SIZE]; char clientname_buf[RBD_MAX_CONF_SIZE]; char *clientname; QemuOpts *opts; Error *local_err = NULL; const char *filename; int r; opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort); qemu_opts_absorb_qdict(opts, options, &local_err); if (local_err) { qerror_report_err(local_err); error_free(local_err); qemu_opts_del(opts); return -EINVAL; } filename = qemu_opt_get(opts, "filename"); if (qemu_rbd_parsename(filename, pool, sizeof(pool), snap_buf, sizeof(snap_buf), s->name, sizeof(s->name), conf, sizeof(conf)) < 0) { r = -EINVAL; goto failed_opts; } clientname = qemu_rbd_parse_clientname(conf, clientname_buf); r = rados_create(&s->cluster, clientname); if (r < 0) { error_report("error initializing"); goto failed_opts; } s->snap = NULL; if (snap_buf[0] != '\0') { s->snap = g_strdup(snap_buf); } /* * Fallback to more conservative semantics if setting cache * options fails. Ignore errors from setting rbd_cache because the * only possible error is that the option does not exist, and * librbd defaults to no caching. If write through caching cannot * be set up, fall back to no caching. */ if (flags & BDRV_O_NOCACHE) { rados_conf_set(s->cluster, "rbd_cache", "false"); } else { rados_conf_set(s->cluster, "rbd_cache", "true"); } if (strstr(conf, "conf=") == NULL) { /* try default location, but ignore failure */ rados_conf_read_file(s->cluster, NULL); } if (conf[0] != '\0') { r = qemu_rbd_set_conf(s->cluster, conf); if (r < 0) { error_report("error setting config options"); goto failed_shutdown; } } r = rados_connect(s->cluster); if (r < 0) { error_report("error connecting"); goto failed_shutdown; } r = rados_ioctx_create(s->cluster, pool, &s->io_ctx); if (r < 0) { error_report("error opening pool %s", pool); goto failed_shutdown; } r = rbd_open(s->io_ctx, s->name, &s->image, s->snap); if (r < 0) { error_report("error reading header from %s", s->name); goto failed_open; } bs->read_only = (s->snap != NULL); qemu_opts_del(opts); return 0; failed_open: rados_ioctx_destroy(s->io_ctx); failed_shutdown: rados_shutdown(s->cluster); g_free(s->snap); failed_opts: qemu_opts_del(opts); return r; }
static int curl_open(BlockDriverState *bs, QDict *options, int flags) { BDRVCURLState *s = bs->opaque; CURLState *state = NULL; QemuOpts *opts; Error *local_err = NULL; const char *file; double d; static int inited = 0; if (flags & BDRV_O_RDWR) { qerror_report(ERROR_CLASS_GENERIC_ERROR, "curl block device does not support writes"); return -EROFS; } opts = qemu_opts_create_nofail(&runtime_opts); qemu_opts_absorb_qdict(opts, options, &local_err); if (error_is_set(&local_err)) { qerror_report_err(local_err); error_free(local_err); goto out_noclean; } s->readahead_size = qemu_opt_get_size(opts, "readahead", READ_AHEAD_SIZE); if ((s->readahead_size & 0x1ff) != 0) { fprintf(stderr, "HTTP_READAHEAD_SIZE %zd is not a multiple of 512\n", s->readahead_size); goto out_noclean; } file = qemu_opt_get(opts, "url"); if (file == NULL) { qerror_report(ERROR_CLASS_GENERIC_ERROR, "curl block driver requires " "an 'url' option"); goto out_noclean; } if (!inited) { curl_global_init(CURL_GLOBAL_ALL); inited = 1; } DPRINTF("CURL: Opening %s\n", file); s->url = g_strdup(file); state = curl_init_state(s); if (!state) goto out_noclean; // Get file size s->accept_range = false; curl_easy_setopt(state->curl, CURLOPT_NOBODY, 1); curl_easy_setopt(state->curl, CURLOPT_HEADERFUNCTION, curl_header_cb); curl_easy_setopt(state->curl, CURLOPT_HEADERDATA, s); if (curl_easy_perform(state->curl)) goto out; curl_easy_getinfo(state->curl, CURLINFO_CONTENT_LENGTH_DOWNLOAD, &d); if (d) s->len = (size_t)d; else if(!s->len) goto out; if ((!strncasecmp(s->url, "http://", strlen("http://")) || !strncasecmp(s->url, "https://", strlen("https://"))) && !s->accept_range) { pstrcpy(state->errmsg, CURL_ERROR_SIZE, "Server does not support 'range' (byte ranges)."); goto out; } DPRINTF("CURL: Size = %zd\n", s->len); curl_clean_state(state); curl_easy_cleanup(state->curl); state->curl = NULL; // Now we know the file exists and its size, so let's // initialize the multi interface! s->multi = curl_multi_init(); curl_multi_setopt(s->multi, CURLMOPT_SOCKETDATA, s); curl_multi_setopt(s->multi, CURLMOPT_SOCKETFUNCTION, curl_sock_cb); curl_multi_do(s); qemu_opts_del(opts); return 0; out: fprintf(stderr, "CURL: Error opening file: %s\n", state->errmsg); curl_easy_cleanup(state->curl); state->curl = NULL; out_noclean: g_free(s->url); qemu_opts_del(opts); return -EINVAL; }
MigrationState *migrate_get_current(void) { static MigrationState current_migration = { .state = MIG_STATE_NONE, .bandwidth_limit = MAX_THROTTLE, .xbzrle_cache_size = DEFAULT_MIGRATE_CACHE_SIZE, .mbps = -1, }; return ¤t_migration; } void qemu_start_incoming_migration(const char *uri, Error **errp) { const char *p; if (strstart(uri, "tcp:", &p)) tcp_start_incoming_migration(p, errp); #ifdef CONFIG_RDMA else if (strstart(uri, "rdma:", &p)) rdma_start_incoming_migration(p, errp); #endif #if !defined(WIN32) else if (strstart(uri, "exec:", &p)) exec_start_incoming_migration(p, errp); else if (strstart(uri, "unix:", &p)) unix_start_incoming_migration(p, errp); else if (strstart(uri, "fd:", &p)) fd_start_incoming_migration(p, errp); #endif else { error_setg(errp, "unknown migration protocol: %s", uri); } } static void process_incoming_migration_co(void *opaque) { QEMUFile *f = opaque; Error *local_err = NULL; int ret; ret = qemu_loadvm_state(f); qemu_fclose(f); free_xbzrle_decoded_buf(); if (ret < 0) { fprintf(stderr, "load of migration failed\n"); exit(EXIT_FAILURE); } qemu_announce_self(); bdrv_clear_incoming_migration_all(); /* Make sure all file formats flush their mutable metadata */ bdrv_invalidate_cache_all(&local_err); if (local_err) { qerror_report_err(local_err); error_free(local_err); exit(EXIT_FAILURE); } if (autostart) { vm_start(); } else { runstate_set(RUN_STATE_PAUSED); } }