Beispiel #1
0
int qemuMonitorTextDriveDel(qemuMonitorPtr mon,
                            const char *drivestr)
{
    char *cmd = NULL;
    char *reply = NULL;
    char *safedev;
    int ret = -1;

    if (!(safedev = qemuMonitorEscapeArg(drivestr)))
        goto cleanup;

    if (virAsprintf(&cmd, "drive_del %s", safedev) < 0)
        goto cleanup;

    if (qemuMonitorHMPCommand(mon, cmd, &reply) < 0)
        goto cleanup;

    if (strstr(reply, "unknown command:")) {
        VIR_ERROR(_("deleting drive is not supported.  "
                    "This may leak data if disk is reassigned"));
        ret = 1;
        goto cleanup;

    /* (qemu) drive_del wark
     * Device 'wark' not found */
    } else if (strstr(reply, "Device '") && strstr(reply, "not found")) {
        /* NB: device not found errors mean the drive was auto-deleted and we
         * ignore the error */
    } else if (STRNEQ(reply, "")) {
        virReportError(VIR_ERR_OPERATION_FAILED,
                       _("deleting %s drive failed: %s"), drivestr, reply);
        goto cleanup;
    }

    ret = 0;

 cleanup:
    VIR_FREE(cmd);
    VIR_FREE(reply);
    VIR_FREE(safedev);
    return ret;
}
static int qemuAgentIOProcessData(qemuAgentPtr mon,
                                  char *data,
                                  size_t len,
                                  qemuAgentMessagePtr msg)
{
    int used = 0;
    int i = 0;
#if DEBUG_IO
# if DEBUG_RAW_IO
    char *str1 = qemuAgentEscapeNonPrintable(data);
    VIR_ERROR("[%s]", str1);
    VIR_FREE(str1);
# else
    VIR_DEBUG("Data %zu bytes [%s]", len, data);
# endif
#endif

    while (used < len) {
        char *nl = strstr(data + used, LINE_ENDING);

        if (nl) {
            int got = nl - (data + used);
            for (i = 0; i < strlen(LINE_ENDING); i++)
                data[used + got + i] = '\0';
            if (qemuAgentIOProcessLine(mon, data + used, msg) < 0) {
                return -1;
            }
            used += got + strlen(LINE_ENDING);
        } else {
            break;
        }
    }

    VIR_DEBUG("Total used %d bytes out of %zd available in buffer", used, len);
    return used;
}
Beispiel #3
0
static int daemonSetupNetworking(virNetServerPtr srv,
                                 struct daemonConfig *config,
                                 const char *sock_path,
                                 const char *sock_path_ro,
                                 bool ipsock,
                                 bool privileged)
{
    virNetServerServicePtr svc = NULL;
    virNetServerServicePtr svcRO = NULL;
    virNetServerServicePtr svcTCP = NULL;
#if WITH_GNUTLS
    virNetServerServicePtr svcTLS = NULL;
#endif
    gid_t unix_sock_gid = 0;
    int unix_sock_ro_mask = 0;
    int unix_sock_rw_mask = 0;

    if (config->unix_sock_group) {
        if (virGetGroupID(config->unix_sock_group, &unix_sock_gid) < 0)
            return -1;
    }

    if (virStrToLong_i(config->unix_sock_ro_perms, NULL, 8, &unix_sock_ro_mask) != 0) {
        VIR_ERROR(_("Failed to parse mode '%s'"), config->unix_sock_ro_perms);
        goto error;
    }

    if (virStrToLong_i(config->unix_sock_rw_perms, NULL, 8, &unix_sock_rw_mask) != 0) {
        VIR_ERROR(_("Failed to parse mode '%s'"), config->unix_sock_rw_perms);
        goto error;
    }

    VIR_DEBUG("Registering unix socket %s", sock_path);
    if (!(svc = virNetServerServiceNewUNIX(sock_path,
                                           unix_sock_rw_mask,
                                           unix_sock_gid,
                                           config->auth_unix_rw,
#if WITH_GNUTLS
                                           NULL,
#endif
                                           false,
                                           config->max_queued_clients,
                                           config->max_client_requests)))
        goto error;
    if (sock_path_ro) {
        VIR_DEBUG("Registering unix socket %s", sock_path_ro);
        if (!(svcRO = virNetServerServiceNewUNIX(sock_path_ro,
                                                 unix_sock_ro_mask,
                                                 unix_sock_gid,
                                                 config->auth_unix_ro,
#if WITH_GNUTLS
                                                 NULL,
#endif
                                                 true,
                                                 config->max_queued_clients,
                                                 config->max_client_requests)))
            goto error;
    }

    if (virNetServerAddService(srv, svc,
                               config->mdns_adv && !ipsock ?
                               "_libvirt._tcp" :
                               NULL) < 0)
        goto error;

    if (svcRO &&
        virNetServerAddService(srv, svcRO, NULL) < 0)
        goto error;

    if (ipsock) {
        if (config->listen_tcp) {
            VIR_DEBUG("Registering TCP socket %s:%s",
                      config->listen_addr, config->tcp_port);
            if (!(svcTCP = virNetServerServiceNewTCP(config->listen_addr,
                                                     config->tcp_port,
                                                     config->auth_tcp,
#if WITH_GNUTLS
                                                     NULL,
#endif
                                                     false,
                                                     config->max_queued_clients,
                                                     config->max_client_requests)))
                goto error;

            if (virNetServerAddService(srv, svcTCP,
                                       config->mdns_adv ? "_libvirt._tcp" : NULL) < 0)
                goto error;
        }

#if WITH_GNUTLS
        if (config->listen_tls) {
            virNetTLSContextPtr ctxt = NULL;

            if (config->ca_file ||
                config->cert_file ||
                config->key_file) {
                if (!(ctxt = virNetTLSContextNewServer(config->ca_file,
                                                       config->crl_file,
                                                       config->cert_file,
                                                       config->key_file,
                                                       (const char *const*)config->tls_allowed_dn_list,
                                                       config->tls_no_sanity_certificate ? false : true,
                                                       config->tls_no_verify_certificate ? false : true)))
                    goto error;
            } else {
                if (!(ctxt = virNetTLSContextNewServerPath(NULL,
                                                           !privileged,
                                                           (const char *const*)config->tls_allowed_dn_list,
                                                           config->tls_no_sanity_certificate ? false : true,
                                                           config->tls_no_verify_certificate ? false : true)))
                    goto error;
            }

            VIR_DEBUG("Registering TLS socket %s:%s",
                      config->listen_addr, config->tls_port);
            if (!(svcTLS =
                  virNetServerServiceNewTCP(config->listen_addr,
                                            config->tls_port,
                                            config->auth_tls,
                                            ctxt,
                                            false,
                                            config->max_queued_clients,
                                            config->max_client_requests))) {
                virObjectUnref(ctxt);
                goto error;
            }
            if (virNetServerAddService(srv, svcTLS,
                                       config->mdns_adv &&
                                       !config->listen_tcp ? "_libvirt._tcp" : NULL) < 0)
                goto error;

            virObjectUnref(ctxt);
        }
#else
        (void)privileged;
        if (config->listen_tls) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("This libvirtd build does not support TLS"));
            goto error;
        }
#endif
    }

#if WITH_SASL
    if (config->auth_unix_rw == REMOTE_AUTH_SASL ||
        config->auth_unix_ro == REMOTE_AUTH_SASL ||
# if WITH_GNUTLS
        config->auth_tls == REMOTE_AUTH_SASL ||
# endif
        config->auth_tcp == REMOTE_AUTH_SASL) {
        saslCtxt = virNetSASLContextNewServer(
            (const char *const*)config->sasl_allowed_username_list);
        if (!saslCtxt)
            goto error;
    }
#endif

    return 0;

 error:
#if WITH_GNUTLS
    virObjectUnref(svcTLS);
#endif
    virObjectUnref(svcTCP);
    virObjectUnref(svc);
    virObjectUnref(svcRO);
    return -1;
}
Beispiel #4
0
int qemudLoadDriverConfig(struct qemud_driver *driver,
                          const char *filename) {
    virConfPtr conf;
    virConfValuePtr p;
    char *user;
    char *group;
    int i;

    /* Setup critical defaults */
    driver->dynamicOwnership = 1;
    driver->clearEmulatorCapabilities = 1;

    if (!(driver->vncListen = strdup("127.0.0.1"))) {
        virReportOOMError();
        return -1;
    }
    if (!(driver->vncTLSx509certdir = strdup(SYSCONFDIR "/pki/libvirt-vnc"))) {
        virReportOOMError();
        return -1;
    }

    if (!(driver->spiceListen = strdup("127.0.0.1"))) {
        virReportOOMError();
        return -1;
    }
    if (!(driver->spiceTLSx509certdir
          = strdup(SYSCONFDIR "/pki/libvirt-spice"))) {
        virReportOOMError();
        return -1;
    }

#if defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R
    /* For privileged driver, try and find hugepage mount automatically.
     * Non-privileged driver requires admin to create a dir for the
     * user, chown it, and then let user configure it manually */
    if (driver->privileged &&
        !(driver->hugetlbfs_mount = virFileFindMountPoint("hugetlbfs"))) {
        if (errno != ENOENT) {
            virReportSystemError(errno, "%s",
                                 _("unable to find hugetlbfs mountpoint"));
            return -1;
        }
    }
#endif


    /* Just check the file is readable before opening it, otherwise
     * libvirt emits an error.
     */
    if (access (filename, R_OK) == -1) {
        VIR_INFO("Could not read qemu config file %s", filename);
        return 0;
    }

    conf = virConfReadFile (filename, 0);
    if (!conf) {
        return -1;
    }


#define CHECK_TYPE(name,typ) if (p && p->type != (typ)) {               \
        qemuReportError(VIR_ERR_INTERNAL_ERROR,                         \
                        "%s: %s: expected type " #typ,                  \
                        filename, (name));                              \
        virConfFree(conf);                                              \
        return -1;                                                      \
    }

    p = virConfGetValue (conf, "vnc_auto_unix_socket");
    CHECK_TYPE ("vnc_auto_unix_socket", VIR_CONF_LONG);
    if (p) driver->vncAutoUnixSocket = p->l;

    p = virConfGetValue (conf, "vnc_tls");
    CHECK_TYPE ("vnc_tls", VIR_CONF_LONG);
    if (p) driver->vncTLS = p->l;

    p = virConfGetValue (conf, "vnc_tls_x509_verify");
    CHECK_TYPE ("vnc_tls_x509_verify", VIR_CONF_LONG);
    if (p) driver->vncTLSx509verify = p->l;

    p = virConfGetValue (conf, "vnc_tls_x509_cert_dir");
    CHECK_TYPE ("vnc_tls_x509_cert_dir", VIR_CONF_STRING);
    if (p && p->str) {
        VIR_FREE(driver->vncTLSx509certdir);
        if (!(driver->vncTLSx509certdir = strdup(p->str))) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }
    }

    p = virConfGetValue (conf, "vnc_listen");
    CHECK_TYPE ("vnc_listen", VIR_CONF_STRING);
    if (p && p->str) {
        VIR_FREE(driver->vncListen);
        if (!(driver->vncListen = strdup(p->str))) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }
    }

    p = virConfGetValue (conf, "vnc_password");
    CHECK_TYPE ("vnc_password", VIR_CONF_STRING);
    if (p && p->str) {
        VIR_FREE(driver->vncPassword);
        if (!(driver->vncPassword = strdup(p->str))) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }
    }

    p = virConfGetValue (conf, "security_driver");
    CHECK_TYPE ("security_driver", VIR_CONF_STRING);
    if (p && p->str) {
        if (!(driver->securityDriverName = strdup(p->str))) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }
    }

    p = virConfGetValue (conf, "vnc_sasl");
    CHECK_TYPE ("vnc_sasl", VIR_CONF_LONG);
    if (p) driver->vncSASL = p->l;

    p = virConfGetValue (conf, "vnc_sasl_dir");
    CHECK_TYPE ("vnc_sasl_dir", VIR_CONF_STRING);
    if (p && p->str) {
        VIR_FREE(driver->vncSASLdir);
        if (!(driver->vncSASLdir = strdup(p->str))) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }
    }

    p = virConfGetValue (conf, "spice_tls");
    CHECK_TYPE ("spice_tls", VIR_CONF_LONG);
    if (p) driver->spiceTLS = p->l;

    p = virConfGetValue (conf, "spice_tls_x509_cert_dir");
    CHECK_TYPE ("spice_tls_x509_cert_dir", VIR_CONF_STRING);
    if (p && p->str) {
        VIR_FREE(driver->spiceTLSx509certdir);
        if (!(driver->spiceTLSx509certdir = strdup(p->str))) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }
    }

    p = virConfGetValue (conf, "spice_listen");
    CHECK_TYPE ("spice_listen", VIR_CONF_STRING);
    if (p && p->str) {
        VIR_FREE(driver->spiceListen);
        if (!(driver->spiceListen = strdup(p->str))) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }
    }

    p = virConfGetValue (conf, "spice_password");
    CHECK_TYPE ("spice_password", VIR_CONF_STRING);
    if (p && p->str) {
        VIR_FREE(driver->spicePassword);
        if (!(driver->spicePassword = strdup(p->str))) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }
    }

    p = virConfGetValue (conf, "user");
    CHECK_TYPE ("user", VIR_CONF_STRING);
    if (!(user = strdup(p && p->str ? p->str : QEMU_USER))) {
        virReportOOMError();
        virConfFree(conf);
        return -1;
    }
    if (virGetUserID(user, &driver->user) < 0) {
        VIR_FREE(user);
        virConfFree(conf);
        return -1;
    }
    VIR_FREE(user);


    p = virConfGetValue (conf, "group");
    CHECK_TYPE ("group", VIR_CONF_STRING);
    if (!(group = strdup(p && p->str ? p->str : QEMU_GROUP))) {
        virReportOOMError();
        virConfFree(conf);
        return -1;
    }
    if (virGetGroupID(group, &driver->group) < 0) {
        VIR_FREE(group);
        virConfFree(conf);
        return -1;
    }
    VIR_FREE(group);


    p = virConfGetValue (conf, "dynamic_ownership");
    CHECK_TYPE ("dynamic_ownership", VIR_CONF_LONG);
    if (p) driver->dynamicOwnership = p->l;


    p = virConfGetValue (conf, "cgroup_controllers");
    CHECK_TYPE ("cgroup_controllers", VIR_CONF_LIST);
    if (p) {
        virConfValuePtr pp;
        for (i = 0, pp = p->list; pp; ++i, pp = pp->next) {
            int ctl;
            if (pp->type != VIR_CONF_STRING) {
                VIR_ERROR0(_("cgroup_controllers must be a list of strings"));
                virConfFree(conf);
                return -1;
            }
            ctl = virCgroupControllerTypeFromString(pp->str);
            if (ctl < 0) {
                VIR_ERROR(_("Unknown cgroup controller '%s'"), pp->str);
                virConfFree(conf);
                return -1;
            }
            driver->cgroupControllers |= (1 << ctl);
        }
    } else {
        driver->cgroupControllers =
            (1 << VIR_CGROUP_CONTROLLER_CPU) |
            (1 << VIR_CGROUP_CONTROLLER_DEVICES) |
            (1 << VIR_CGROUP_CONTROLLER_MEMORY) |
            (1 << VIR_CGROUP_CONTROLLER_BLKIO);
    }
    for (i = 0 ; i < VIR_CGROUP_CONTROLLER_LAST ; i++) {
        if (driver->cgroupControllers & (1 << i)) {
            VIR_INFO("Configured cgroup controller '%s'",
                     virCgroupControllerTypeToString(i));
        }
    }

    p = virConfGetValue (conf, "cgroup_device_acl");
    CHECK_TYPE ("cgroup_device_acl", VIR_CONF_LIST);
    if (p) {
        int len = 0;
        virConfValuePtr pp;
        for (pp = p->list; pp; pp = pp->next)
            len++;
        if (VIR_ALLOC_N(driver->cgroupDeviceACL, 1+len) < 0) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }
        for (i = 0, pp = p->list; pp; ++i, pp = pp->next) {
            if (pp->type != VIR_CONF_STRING) {
                VIR_ERROR0(_("cgroup_device_acl must be a list of strings"));
                virConfFree(conf);
                return -1;
            }
            driver->cgroupDeviceACL[i] = strdup (pp->str);
            if (driver->cgroupDeviceACL[i] == NULL) {
                virReportOOMError();
                virConfFree(conf);
                return -1;
            }

        }
        driver->cgroupDeviceACL[i] = NULL;
    }

    p = virConfGetValue (conf, "save_image_format");
    CHECK_TYPE ("save_image_format", VIR_CONF_STRING);
    if (p && p->str) {
        VIR_FREE(driver->saveImageFormat);
        if (!(driver->saveImageFormat = strdup(p->str))) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }
    }

    p = virConfGetValue (conf, "dump_image_format");
    CHECK_TYPE ("dump_image_format", VIR_CONF_STRING);
    if (p && p->str) {
        VIR_FREE(driver->dumpImageFormat);
        if (!(driver->dumpImageFormat = strdup(p->str))) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }
    }

    p = virConfGetValue (conf, "auto_dump_path");
    CHECK_TYPE ("auto_dump_path", VIR_CONF_STRING);
    if (p && p->str) {
        VIR_FREE(driver->autoDumpPath);
        if (!(driver->autoDumpPath = strdup(p->str))) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }
    }

     p = virConfGetValue (conf, "hugetlbfs_mount");
     CHECK_TYPE ("hugetlbfs_mount", VIR_CONF_STRING);
     if (p && p->str) {
         VIR_FREE(driver->hugetlbfs_mount);
         if (!(driver->hugetlbfs_mount = strdup(p->str))) {
             virReportOOMError();
             virConfFree(conf);
             return -1;
         }
     }

    p = virConfGetValue (conf, "mac_filter");
    CHECK_TYPE ("mac_filter", VIR_CONF_LONG);
    if (p && p->l) {
        driver->macFilter = p->l;
        if (!(driver->ebtables = ebtablesContextNew("qemu"))) {
            driver->macFilter = 0;
            virReportSystemError(errno,
                                 _("failed to enable mac filter in '%s'"),
                                 __FILE__);
        }

        if ((errno = networkDisableAllFrames(driver))) {
            virReportSystemError(errno,
                         _("failed to add rule to drop all frames in '%s'"),
                                 __FILE__);
        }
    }

    p = virConfGetValue (conf, "relaxed_acs_check");
    CHECK_TYPE ("relaxed_acs_check", VIR_CONF_LONG);
    if (p) driver->relaxedACS = p->l;

    p = virConfGetValue (conf, "vnc_allow_host_audio");
    CHECK_TYPE ("vnc_allow_host_audio", VIR_CONF_LONG);
    if (p) driver->vncAllowHostAudio = p->l;

    p = virConfGetValue (conf, "clear_emulator_capabilities");
    CHECK_TYPE ("clear_emulator_capabilities", VIR_CONF_LONG);
    if (p) driver->clearEmulatorCapabilities = p->l;

    p = virConfGetValue (conf, "allow_disk_format_probing");
    CHECK_TYPE ("allow_disk_format_probing", VIR_CONF_LONG);
    if (p) driver->allowDiskFormatProbing = p->l;

    p = virConfGetValue (conf, "set_process_name");
    CHECK_TYPE ("set_process_name", VIR_CONF_LONG);
    if (p) driver->setProcessName = p->l;

    p = virConfGetValue(conf, "max_processes");
    CHECK_TYPE("max_processes", VIR_CONF_LONG);
    if (p) driver->maxProcesses = p->l;

    virConfFree (conf);
    return 0;
}
Beispiel #5
0
static virDomainPtr
openvzDomainCreateXML(virConnectPtr conn, const char *xml,
                      unsigned int flags)
{
    struct openvz_driver *driver =  conn->privateData;
    virDomainDefPtr vmdef = NULL;
    virDomainObjPtr vm = NULL;
    virDomainPtr dom = NULL;
    const char *progstart[] = {VZCTL, "--quiet", "start", PROGRAM_SENTINAL, NULL};

    virCheckFlags(0, NULL);

    openvzDriverLock(driver);
    if ((vmdef = virDomainDefParseString(driver->caps, xml,
                                         1 << VIR_DOMAIN_VIRT_OPENVZ,
                                         VIR_DOMAIN_XML_INACTIVE)) == NULL)
        goto cleanup;

    vm = virDomainFindByName(&driver->domains, vmdef->name);
    if (vm) {
        openvzError(VIR_ERR_OPERATION_FAILED,
                    _("Already an OPENVZ VM defined with the id '%s'"),
                   vmdef->name);
        goto cleanup;
    }
    if (!(vm = virDomainAssignDef(driver->caps,
                                  &driver->domains, vmdef, false)))
        goto cleanup;
    vmdef = NULL;
    /* All OpenVZ domains seem to be persistent - this is a bit of a violation
     * of this libvirt API which is intended for transient domain creation */
    vm->persistent = 1;

    if (openvzSetInitialConfig(vm->def) < 0) {
        VIR_ERROR(_("Error creating initial configuration"));
        goto cleanup;
    }

    if (openvzSetDefinedUUID(strtoI(vm->def->name), vm->def->uuid) < 0) {
        openvzError(VIR_ERR_INTERNAL_ERROR, "%s",
                    _("Could not set UUID"));
        goto cleanup;
    }

    if (openvzDomainSetNetworkConfig(conn, vm->def) < 0)
        goto cleanup;

    openvzSetProgramSentinal(progstart, vm->def->name);

    if (virRun(progstart, NULL) < 0) {
        goto cleanup;
    }

    vm->pid = strtoI(vm->def->name);
    vm->def->id = vm->pid;
    virDomainObjSetState(vm, VIR_DOMAIN_RUNNING, VIR_DOMAIN_RUNNING_BOOTED);

    if (vm->def->maxvcpus > 0) {
        if (openvzDomainSetVcpusInternal(vm, vm->def->maxvcpus) < 0) {
            openvzError(VIR_ERR_INTERNAL_ERROR, "%s",
                        _("Could not set number of virtual cpu"));
            goto cleanup;
        }
    }

    dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
    if (dom)
        dom->id = vm->def->id;

cleanup:
    virDomainDefFree(vmdef);
    if (vm)
        virDomainObjUnlock(vm);
    openvzDriverUnlock(driver);
    return dom;
}
Beispiel #6
0
libxlDriverConfigPtr
libxlDriverConfigNew(void)
{
    libxlDriverConfigPtr cfg;
    char *log_file = NULL;
    char ebuf[1024];
    unsigned int free_mem;

    if (libxlConfigInitialize() < 0)
        return NULL;

    if (!(cfg = virObjectNew(libxlDriverConfigClass)))
        return NULL;

    if (VIR_STRDUP(cfg->configDir, LIBXL_CONFIG_DIR) < 0)
        goto error;
    if (VIR_STRDUP(cfg->autostartDir, LIBXL_AUTOSTART_DIR) < 0)
        goto error;
    if (VIR_STRDUP(cfg->logDir, LIBXL_LOG_DIR) < 0)
        goto error;
    if (VIR_STRDUP(cfg->stateDir, LIBXL_STATE_DIR) < 0)
        goto error;
    if (VIR_STRDUP(cfg->libDir, LIBXL_LIB_DIR) < 0)
        goto error;
    if (VIR_STRDUP(cfg->saveDir, LIBXL_SAVE_DIR) < 0)
        goto error;
    if (VIR_STRDUP(cfg->autoDumpDir, LIBXL_DUMP_DIR) < 0)
        goto error;

    if (virAsprintf(&log_file, "%s/libxl-driver.log", cfg->logDir) < 0)
        goto error;

    if (virFileMakePath(cfg->logDir) < 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("failed to create log dir '%s': %s"),
                       cfg->logDir,
                       virStrerror(errno, ebuf, sizeof(ebuf)));
        goto error;
    }

    if ((cfg->logger_file = fopen(log_file, "a")) == NULL)  {
        VIR_ERROR(_("Failed to create log file '%s': %s"),
                  log_file, virStrerror(errno, ebuf, sizeof(ebuf)));
        goto error;
    }
    VIR_FREE(log_file);

    cfg->logger =
        (xentoollog_logger *)xtl_createlogger_stdiostream(cfg->logger_file,
                                                          XTL_DEBUG, 0);
    if (!cfg->logger) {
        VIR_ERROR(_("cannot create logger for libxenlight, disabling driver"));
        goto error;
    }

    if (libxl_ctx_alloc(&cfg->ctx, LIBXL_VERSION, 0, cfg->logger)) {
        VIR_ERROR(_("cannot initialize libxenlight context, probably not "
                    "running in a Xen Dom0, disabling driver"));
        goto error;
    }

    if ((cfg->verInfo = libxl_get_version_info(cfg->ctx)) == NULL) {
        VIR_ERROR(_("cannot version information from libxenlight, "
                    "disabling driver"));
        goto error;
    }
    cfg->version = (cfg->verInfo->xen_version_major * 1000000) +
        (cfg->verInfo->xen_version_minor * 1000);

    /* This will fill xenstore info about free and dom0 memory if missing,
     * should be called before starting first domain */
    if (libxl_get_free_memory(cfg->ctx, &free_mem)) {
        VIR_ERROR(_("Unable to configure libxl's memory management parameters"));
        goto error;
    }

    /* setup autoballoon */
    if (libxlGetAutoballoonConf(cfg, &cfg->autoballoon) < 0)
        goto error;

    return cfg;

error:
    VIR_FREE(log_file);
    virObjectUnref(cfg);
    return NULL;
}
Beispiel #7
0
void *
virDriverLoadModule(const char *name)
{
    char *modfile = NULL, *regfunc = NULL, *fixedname = NULL;
    char *tmp;
    void *handle = NULL;
    int (*regsym)(void);

    VIR_DEBUG("Module load %s", name);

    if (!(modfile = virFileFindResourceFull(name,
                                            "libvirt_driver_",
                                            ".so",
                                            abs_topbuilddir "/src/.libs",
                                            DEFAULT_DRIVER_DIR,
                                            "LIBVIRT_DRIVER_DIR")))
        return NULL;

    if (access(modfile, R_OK) < 0) {
        VIR_INFO("Module %s not accessible", modfile);
        goto cleanup;
    }

    virUpdateSelfLastChanged(modfile);

    handle = dlopen(modfile, RTLD_NOW | RTLD_GLOBAL);
    if (!handle) {
        VIR_ERROR(_("failed to load module %s %s"), modfile, dlerror());
        goto cleanup;
    }

    if (VIR_STRDUP_QUIET(fixedname, name) < 0) {
        VIR_ERROR(_("out of memory"));
        goto cleanup;
    }

    /* convert something_like_this into somethingLikeThis */
    while ((tmp = strchr(fixedname, '_'))) {
        memmove(tmp, tmp + 1, strlen(tmp));
        *tmp = c_toupper(*tmp);
    }

    if (virAsprintfQuiet(&regfunc, "%sRegister", fixedname) < 0)
        goto cleanup;

    regsym = dlsym(handle, regfunc);
    if (!regsym) {
        VIR_ERROR(_("Missing module registration symbol %s"), regfunc);
        goto cleanup;
    }

    if ((*regsym)() < 0) {
        VIR_ERROR(_("Failed module registration %s"), regfunc);
        goto cleanup;
    }

    VIR_FREE(modfile);
    VIR_FREE(regfunc);
    VIR_FREE(fixedname);
    return handle;

 cleanup:
    VIR_FREE(modfile);
    VIR_FREE(regfunc);
    VIR_FREE(fixedname);
    if (handle)
        dlclose(handle);
    return NULL;
}
void qemuDomainReAttachHostdevDevices(struct qemud_driver *driver,
                                      const char *name,
                                      virDomainHostdevDefPtr *hostdevs,
                                      int nhostdevs)
{
    pciDeviceList *pcidevs;
    int i;

    if (!(pcidevs = qemuGetActivePciHostDeviceList(driver,
                                                   hostdevs,
                                                   nhostdevs))) {
        virErrorPtr err = virGetLastError();
        VIR_ERROR(_("Failed to allocate pciDeviceList: %s"),
                  err ? err->message : _("unknown error"));
        virResetError(err);
        return;
    }

    /* Again 4 loops; mark all devices as inactive before reset
     * them and reset all the devices before re-attach.
     * Attach mac and port profile parameters to devices
     */
    for (i = 0; i < pciDeviceListCount(pcidevs); i++) {
        pciDevice *dev = pciDeviceListGet(pcidevs, i);
        pciDevice *activeDev = NULL;

        /* Never delete the dev from list driver->activePciHostdevs
         * if it's used by other domain.
         */
        activeDev = pciDeviceListFind(driver->activePciHostdevs, dev);
        if (activeDev &&
            STRNEQ_NULLABLE(name, pciDeviceGetUsedBy(activeDev))) {
            pciDeviceListSteal(pcidevs, dev);
            continue;
        }

        /* pciDeviceListFree() will take care of freeing the dev. */
        pciDeviceListSteal(driver->activePciHostdevs, dev);
    }

    /*
     * For SRIOV net host devices, unset mac and port profile before
     * reset and reattach device
     */
    for (i = 0; i < nhostdevs; i++) {
         virDomainHostdevDefPtr hostdev = hostdevs[i];
         if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
             continue;
         if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
             continue;
         if (hostdev->parent.type == VIR_DOMAIN_DEVICE_NET &&
             hostdev->parent.data.net) {
             qemuDomainHostdevNetConfigRestore(hostdev, driver->stateDir);
         }
    }

    for (i = 0; i < pciDeviceListCount(pcidevs); i++) {
        pciDevice *dev = pciDeviceListGet(pcidevs, i);
        if (pciResetDevice(dev, driver->activePciHostdevs,
                           driver->inactivePciHostdevs) < 0) {
            virErrorPtr err = virGetLastError();
            VIR_ERROR(_("Failed to reset PCI device: %s"),
                      err ? err->message : _("unknown error"));
            virResetError(err);
        }
    }

    while (pciDeviceListCount(pcidevs) > 0) {
        pciDevice *dev = pciDeviceListStealIndex(pcidevs, 0);
        qemuReattachPciDevice(dev, driver);
    }

    pciDeviceListFree(pcidevs);
}
Beispiel #9
0
int
vshRunConsole(vshControl *ctl,
              virDomainPtr dom,
              const char *dev_name,
              unsigned int flags)
{
    virConsolePtr con = NULL;
    int ret = -1;

    struct sigaction old_sigquit;
    struct sigaction old_sigterm;
    struct sigaction old_sigint;
    struct sigaction old_sighup;
    struct sigaction old_sigpipe;
    struct sigaction sighandler = {.sa_handler = virConsoleHandleSignal,
                                   .sa_flags = SA_SIGINFO };

    sigemptyset(&sighandler.sa_mask);

    /* Put STDIN into raw mode so that stuff typed does not echo to the screen
     * (the TTY reads will result in it being echoed back already), and also
     * ensure Ctrl-C, etc is blocked, and misc other bits */
    if (vshTTYMakeRaw(ctl, true) < 0)
        goto resettty;

    /* Trap all common signals so that we can safely restore the original
     * terminal settings on STDIN before the process exits - people don't like
     * being left with a messed up terminal ! */
    sigaction(SIGQUIT, &sighandler, &old_sigquit);
    sigaction(SIGTERM, &sighandler, &old_sigterm);
    sigaction(SIGINT,  &sighandler, &old_sigint);
    sigaction(SIGHUP,  &sighandler, &old_sighup);
    sigaction(SIGPIPE, &sighandler, &old_sigpipe);

    if (VIR_ALLOC(con) < 0)
        goto cleanup;

    con->escapeChar = vshGetEscapeChar(ctl->escapeChar);
    con->st = virStreamNew(virDomainGetConnect(dom),
                           VIR_STREAM_NONBLOCK);
    if (!con->st)
        goto cleanup;

    if (virDomainOpenConsole(dom, dev_name, con->st, flags) < 0)
        goto cleanup;

    if (virCondInit(&con->cond) < 0 || virMutexInit(&con->lock) < 0)
        goto cleanup;

    virMutexLock(&con->lock);

    con->stdinWatch = virEventAddHandle(STDIN_FILENO,
                                        VIR_EVENT_HANDLE_READABLE,
                                        virConsoleEventOnStdin,
                                        con,
                                        NULL);
    con->stdoutWatch = virEventAddHandle(STDOUT_FILENO,
                                         0,
                                         virConsoleEventOnStdout,
                                         con,
                                         NULL);

    virStreamEventAddCallback(con->st,
                              VIR_STREAM_EVENT_READABLE,
                              virConsoleEventOnStream,
                              con,
                              NULL);

    while (!con->quit) {
        if (virCondWait(&con->cond, &con->lock) < 0) {
            virMutexUnlock(&con->lock);
            VIR_ERROR(_("unable to wait on console condition"));
            goto cleanup;
        }
    }

    virMutexUnlock(&con->lock);

    ret = 0;

 cleanup:
    virConsoleFree(con);

    /* Restore original signal handlers */
    sigaction(SIGQUIT, &old_sigquit, NULL);
    sigaction(SIGTERM, &old_sigterm, NULL);
    sigaction(SIGINT,  &old_sigint,  NULL);
    sigaction(SIGHUP,  &old_sighup,  NULL);
    sigaction(SIGPIPE, &old_sigpipe, NULL);

 resettty:
    /* Put STDIN back into the (sane?) state we found
       it in before starting */
    vshTTYRestore(ctl);

    return ret;
}
Beispiel #10
0
void
qemuDomainReAttachHostdevDevices(virQEMUDriverPtr driver,
                                 const char *name,
                                 virDomainHostdevDefPtr *hostdevs,
                                 int nhostdevs)
{
    virPCIDeviceListPtr pcidevs;
    size_t i;
    virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);

    virObjectLock(driver->activePciHostdevs);
    virObjectLock(driver->inactivePciHostdevs);

    if (!(pcidevs = qemuGetActivePciHostDeviceList(driver,
                                                   hostdevs,
                                                   nhostdevs))) {
        virErrorPtr err = virGetLastError();
        VIR_ERROR(_("Failed to allocate PCI device list: %s"),
                  err ? err->message : _("unknown error"));
        virResetError(err);
        goto cleanup;
    }

    /* Again 4 loops; mark all devices as inactive before reset
     * them and reset all the devices before re-attach.
     * Attach mac and port profile parameters to devices
     */
    for (i = 0; i < virPCIDeviceListCount(pcidevs); i++) {
        virPCIDevicePtr dev = virPCIDeviceListGet(pcidevs, i);
        virPCIDevicePtr activeDev = NULL;

        /* delete the copy of the dev from pcidevs if it's used by
         * other domain. Or delete it from activePciHostDevs if it had
         * been used by this domain.
         */
        activeDev = virPCIDeviceListFind(driver->activePciHostdevs, dev);
        if (activeDev &&
            STRNEQ_NULLABLE(name, virPCIDeviceGetUsedBy(activeDev))) {
            virPCIDeviceListDel(pcidevs, dev);
            continue;
        }

        virPCIDeviceListDel(driver->activePciHostdevs, dev);
    }

    /* At this point, any device that had been used by the guest is in
     * pcidevs, but has been removed from activePciHostdevs.
     */

    /*
     * For SRIOV net host devices, unset mac and port profile before
     * reset and reattach device
     */
    for (i = 0; i < nhostdevs; i++) {
         virDomainHostdevDefPtr hostdev = hostdevs[i];
         if (hostdev->mode != VIR_DOMAIN_HOSTDEV_MODE_SUBSYS)
             continue;
         if (hostdev->source.subsys.type != VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PCI)
             continue;
         if (hostdev->parent.type == VIR_DOMAIN_DEVICE_NET &&
             hostdev->parent.data.net) {
             qemuDomainHostdevNetConfigRestore(hostdev, cfg->stateDir);
         }
    }

    for (i = 0; i < virPCIDeviceListCount(pcidevs); i++) {
        virPCIDevicePtr dev = virPCIDeviceListGet(pcidevs, i);

        if (virPCIDeviceReset(dev, driver->activePciHostdevs,
                              driver->inactivePciHostdevs) < 0) {
            virErrorPtr err = virGetLastError();
            VIR_ERROR(_("Failed to reset PCI device: %s"),
                      err ? err->message : _("unknown error"));
            virResetError(err);
        }
    }

    while (virPCIDeviceListCount(pcidevs) > 0) {
        virPCIDevicePtr dev = virPCIDeviceListStealIndex(pcidevs, 0);
        qemuReattachPciDevice(dev, driver);
    }

    virObjectUnref(pcidevs);
cleanup:
    virObjectUnlock(driver->activePciHostdevs);
    virObjectUnlock(driver->inactivePciHostdevs);
    virObjectUnref(cfg);
}
Beispiel #11
0
static int lxctoolsReadFSConfig(lxctoolsConffilePtr conffile, virDomainDefPtr def)
{

    virDomainFSDefPtr fs = NULL;
    char* item_str = NULL;
    size_t tokencnt;
    char** splitlist = NULL;

    if ((item_str = lxctoolsConffileGetItem(conffile, "lxc.rootfs.path")) == NULL || item_str[0] == '\0') {
        VIR_WARN("Could not find key lxc.rootfs.path. Trying legacy key lxc.rootfs.");
        if ((item_str = lxctoolsConffileGetItem(conffile, "lxc.rootfs")) == NULL) {
            VIR_ERROR("Could not find key lxc.rootfs");
            goto error;
        }
    }
    if (item_str[0] == '\0') {
        VIR_ERROR("Domain has no rootfs config-item.");
        goto error;
    }
    if (VIR_ALLOC(fs) < 0) {
        VIR_ERROR("Could not allocate for virDomainFSDefPtr fs.");
        goto error;
    }
    fs->type = VIR_DOMAIN_FS_TYPE_MOUNT;
    if (VIR_ALLOC(fs->src) < 0) {
        VIR_ERROR("Could not allocate for virStorageSourcePtr fs->src.");
        goto error;
    }
    splitlist = virStringSplitCount(item_str, ":", 3, &tokencnt);
    
    // Simple path
    if (tokencnt == 1) {
        fs->fsdriver = VIR_DOMAIN_FS_DRIVER_TYPE_PATH;
        if (virAsprintf(&fs->src->path, "dir:%s", splitlist[0]) < 0) {
            VIR_ERROR("Could not print string in fs->src->path.");
            goto error;
        }
    // dir
    } else if (tokencnt == 2 && strcmp(splitlist[0], "dir") == 0) {
        fs->fsdriver = VIR_DOMAIN_FS_DRIVER_TYPE_PATH;
        if (virAsprintf(&fs->src->path, "%s:%s", splitlist[0], splitlist[1]) < 0) {
            VIR_ERROR("Could not print string in fs->src->path.");
            goto error;
        }
    // overlay or overlayfs
    } else if (tokencnt == 3 && (strcmp(splitlist[0], "overlay") == 0 || strcmp(splitlist[0], "overlayfs") == 0)) {
        // We could add a new FS type like VIR_DOMAIN_FS_DRIVER_TYPE_OVERLAY, but this requires minor changes in the
        // libvirt interface and the qemu driver.
        // Also, we could either save "lowerdir:upperdir" in fs->src or create additional members to hold each seperately
        // splitlist[0] -> overlayfs/overlay
        // splitlist[1] -> lowerdir path
        // splitlist[2] -> upperdir path
        // For now, this implements overlayfs using VIR_DOMAIN_FS_DRIVER_TYPE_PATH and saving "overlayfs:lowerdir:upperdir"
        // in fs->src, which does not require lxctools external changes, but is a little bit ugly.
        fs->fsdriver = VIR_DOMAIN_FS_DRIVER_TYPE_PATH;
        if (virAsprintf(&fs->src->path, "%s:%s:%s", splitlist[0], splitlist[1], splitlist[2]) < 0) {
            VIR_ERROR("Could not print string in fs->src->path.");
            goto error;
        }
    } else {
        VIR_ERROR("Domain rootfs type is currently not supported");
        goto error;
    }
    if (VIR_STRDUP(fs->dst, "/") != 1) {
        VIR_ERROR("Could not duplicate string.");
        goto error;
    }
    if (virDomainFSInsert(def, fs) < 0) {
        VIR_ERROR("Could not insert filesystem desc into domain.");
        goto error;
    }
    fs = NULL;
    VIR_FREE(item_str);
    virStringListFree(splitlist);
    splitlist = NULL;

    if ((splitlist = lxctoolsConffileGetItemlist(conffile, "lxc.mount.entry", &tokencnt)) == NULL) {
        goto error;
    }
    if (splitlist[0] != NULL) {
        size_t param_cnt;
        char** params;
        while (tokencnt-- > 0) {
            params = virStringSplitCount(splitlist[tokencnt], " ", 6, &param_cnt);
            if (param_cnt != 6) {
                VIR_ERROR("The following entry has to few parameters: '%s'", splitlist[tokencnt]);
                goto error;
            }
            if (VIR_ALLOC(fs) < 0) {
                VIR_ERROR("Could not allocate for virDomainFSDefPtr fs.");
                goto error;
            }
            if (strcmp(params[2], "none") == 0 && strstr(params[3],"bind") != NULL) {
                fs->type = VIR_DOMAIN_FS_TYPE_MOUNT;
                fs->fsdriver = VIR_DOMAIN_FS_DRIVER_TYPE_PATH;
                if (VIR_ALLOC(fs->src) < 0) {
                    VIR_ERROR("Could not allocate for virStorageSourcePtr fs->src.");
                    goto error;
                }
                if (VIR_STRDUP(fs->src->path, params[0]) < 0) {
                    VIR_ERROR("Could not copy src string.");
                    goto error;
                }
                if (virAsprintf(&fs->dst, "/%s", params[1]) < 0) {
                    VIR_ERROR("Could not copy dst string.");
                    goto error;
                }
                if (strstr(params[3], "ro") != NULL) {
                    fs->readonly = true;
                }
                if (virDomainFSInsert(def, fs) < 0) {
                    VIR_ERROR("Could not insert filesystem desc into domain.");
                    goto error;
                }
                fs = NULL;
            }
            VIR_FREE(fs);
            virStringListFree(params);
        }
        virStringListFree(splitlist);
        splitlist = NULL;
    }
    return 0;

error:
    virStringListFree(splitlist);
    splitlist = NULL;
    VIR_FREE(item_str);
    if (fs)
        VIR_FREE(fs->src);
    VIR_FREE(fs);
    return -1;
}
Beispiel #12
0
int qemudLoadDriverConfig(struct qemud_driver *driver,
                          const char *filename) {
    virConfPtr conf;
    virConfValuePtr p;
    char *user;
    char *group;
    int i;

    /* Setup critical defaults */
    driver->securityDefaultConfined = true;
    driver->securityRequireConfined = false;
    driver->dynamicOwnership = 1;
    driver->clearEmulatorCapabilities = 1;

    if (!(driver->vncListen = strdup("127.0.0.1"))) {
        virReportOOMError();
        return -1;
    }

    driver->remotePortMin = QEMU_REMOTE_PORT_MIN;
    driver->remotePortMax = QEMU_REMOTE_PORT_MAX;

    if (!(driver->vncTLSx509certdir = strdup(SYSCONFDIR "/pki/libvirt-vnc"))) {
        virReportOOMError();
        return -1;
    }

    if (!(driver->spiceListen = strdup("127.0.0.1"))) {
        virReportOOMError();
        return -1;
    }
    if (!(driver->spiceTLSx509certdir
          = strdup(SYSCONFDIR "/pki/libvirt-spice"))) {
        virReportOOMError();
        return -1;
    }

#if defined HAVE_MNTENT_H && defined HAVE_GETMNTENT_R
    /* For privileged driver, try and find hugepage mount automatically.
     * Non-privileged driver requires admin to create a dir for the
     * user, chown it, and then let user configure it manually */
    if (driver->privileged &&
        !(driver->hugetlbfs_mount = virFileFindMountPoint("hugetlbfs"))) {
        if (errno != ENOENT) {
            virReportSystemError(errno, "%s",
                                 _("unable to find hugetlbfs mountpoint"));
            return -1;
        }
    }
#endif

    if (!(driver->lockManager =
          virLockManagerPluginNew("nop", NULL, 0)))
        return -1;

    driver->keepAliveInterval = 5;
    driver->keepAliveCount = 5;

    /* Just check the file is readable before opening it, otherwise
     * libvirt emits an error.
     */
    if (access (filename, R_OK) == -1) {
        VIR_INFO("Could not read qemu config file %s", filename);
        return 0;
    }

    conf = virConfReadFile (filename, 0);
    if (!conf) {
        return -1;
    }


#define CHECK_TYPE(name,typ) if (p && p->type != (typ)) {               \
        virReportError(VIR_ERR_INTERNAL_ERROR,                          \
                       "%s: %s: expected type " #typ,                   \
                       filename, (name));                               \
        virConfFree(conf);                                              \
        return -1;                                                      \
    }

    p = virConfGetValue (conf, "vnc_auto_unix_socket");
    CHECK_TYPE ("vnc_auto_unix_socket", VIR_CONF_LONG);
    if (p) driver->vncAutoUnixSocket = p->l;

    p = virConfGetValue (conf, "vnc_tls");
    CHECK_TYPE ("vnc_tls", VIR_CONF_LONG);
    if (p) driver->vncTLS = p->l;

    p = virConfGetValue (conf, "vnc_tls_x509_verify");
    CHECK_TYPE ("vnc_tls_x509_verify", VIR_CONF_LONG);
    if (p) driver->vncTLSx509verify = p->l;

    p = virConfGetValue (conf, "vnc_tls_x509_cert_dir");
    CHECK_TYPE ("vnc_tls_x509_cert_dir", VIR_CONF_STRING);
    if (p && p->str) {
        VIR_FREE(driver->vncTLSx509certdir);
        if (!(driver->vncTLSx509certdir = strdup(p->str))) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }
    }

    p = virConfGetValue (conf, "vnc_listen");
    CHECK_TYPE ("vnc_listen", VIR_CONF_STRING);
    if (p && p->str) {
        VIR_FREE(driver->vncListen);
        if (!(driver->vncListen = strdup(p->str))) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }
    }

    p = virConfGetValue (conf, "vnc_password");
    CHECK_TYPE ("vnc_password", VIR_CONF_STRING);
    if (p && p->str) {
        VIR_FREE(driver->vncPassword);
        if (!(driver->vncPassword = strdup(p->str))) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }
    }

    p = virConfGetValue (conf, "security_driver");
    if (p && p->type == VIR_CONF_LIST) {
        size_t len;
        virConfValuePtr pp;

        /* Calc lenght and check items */
        for (len = 0, pp = p->list; pp; len++, pp = pp->next) {
            if (pp->type != VIR_CONF_STRING) {
                VIR_ERROR(_("security_driver be a list of strings"));
                virConfFree(conf);
                return -1;
            }
        }

        if (VIR_ALLOC_N(driver->securityDriverNames, len + 1) < 0) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }

        for (i = 0, pp = p->list; pp; i++, pp = pp->next) {
            driver->securityDriverNames[i] = strdup(pp->str);
            if (driver->securityDriverNames == NULL) {
                virReportOOMError();
                virConfFree(conf);
                return -1;
            }
        }
        driver->securityDriverNames[len] = NULL;
    } else {
        CHECK_TYPE ("security_driver", VIR_CONF_STRING);
        if (p && p->str) {
            if (VIR_ALLOC_N(driver->securityDriverNames, 2) < 0 ||
                !(driver->securityDriverNames[0] = strdup(p->str))) {
                virReportOOMError();
                virConfFree(conf);
                return -1;
            }
            driver->securityDriverNames[1] = NULL;
        }
    }

    p = virConfGetValue (conf, "security_default_confined");
    CHECK_TYPE ("security_default_confined", VIR_CONF_LONG);
    if (p) driver->securityDefaultConfined = p->l;

    p = virConfGetValue (conf, "security_require_confined");
    CHECK_TYPE ("security_require_confined", VIR_CONF_LONG);
    if (p) driver->securityRequireConfined = p->l;


    p = virConfGetValue (conf, "vnc_sasl");
    CHECK_TYPE ("vnc_sasl", VIR_CONF_LONG);
    if (p) driver->vncSASL = p->l;

    p = virConfGetValue (conf, "vnc_sasl_dir");
    CHECK_TYPE ("vnc_sasl_dir", VIR_CONF_STRING);
    if (p && p->str) {
        VIR_FREE(driver->vncSASLdir);
        if (!(driver->vncSASLdir = strdup(p->str))) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }
    }

    p = virConfGetValue (conf, "spice_tls");
    CHECK_TYPE ("spice_tls", VIR_CONF_LONG);
    if (p) driver->spiceTLS = p->l;

    p = virConfGetValue (conf, "spice_tls_x509_cert_dir");
    CHECK_TYPE ("spice_tls_x509_cert_dir", VIR_CONF_STRING);
    if (p && p->str) {
        VIR_FREE(driver->spiceTLSx509certdir);
        if (!(driver->spiceTLSx509certdir = strdup(p->str))) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }
    }

    p = virConfGetValue (conf, "spice_listen");
    CHECK_TYPE ("spice_listen", VIR_CONF_STRING);
    if (p && p->str) {
        VIR_FREE(driver->spiceListen);
        if (!(driver->spiceListen = strdup(p->str))) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }
    }

    p = virConfGetValue (conf, "spice_password");
    CHECK_TYPE ("spice_password", VIR_CONF_STRING);
    if (p && p->str) {
        VIR_FREE(driver->spicePassword);
        if (!(driver->spicePassword = strdup(p->str))) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }
    }

    p = virConfGetValue (conf, "remote_display_port_min");
    CHECK_TYPE ("remote_display_port_min", VIR_CONF_LONG);
    if (p) {
        if (p->l < QEMU_REMOTE_PORT_MIN) {
            /* if the port is too low, we can't get the display name
             * to tell to vnc (usually subtract 5900, e.g. localhost:1
             * for port 5901) */
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("%s: remote_display_port_min: port must be greater than or equal to %d"),
                            filename, QEMU_REMOTE_PORT_MIN);
            virConfFree(conf);
            return -1;
        }
        driver->remotePortMin = p->l;
    }

    p = virConfGetValue (conf, "remote_display_port_max");
    CHECK_TYPE ("remote_display_port_max", VIR_CONF_LONG);
    if (p) {
        if (p->l > QEMU_REMOTE_PORT_MAX ||
            p->l < driver->remotePortMin) {
            virReportError(VIR_ERR_INTERNAL_ERROR,
                            _("%s: remote_display_port_max: port must be between the minimal port and %d"),
                            filename, QEMU_REMOTE_PORT_MAX);
            virConfFree(conf);
            return -1;
        }
        /* increasing the value by 1 makes all the loops going through
        the bitmap (i = remotePortMin; i < remotePortMax; i++), work as
        expected. */
        driver->remotePortMax = p->l + 1;
    }

    if (driver->remotePortMin > driver->remotePortMax) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                        _("%s: remote_display_port_min: min port must not be greater than max port"),
                        filename);
        virConfFree(conf);
        return -1;
    }

    p = virConfGetValue (conf, "user");
    CHECK_TYPE ("user", VIR_CONF_STRING);
    if (!(user = strdup(p && p->str ? p->str : QEMU_USER))) {
        virReportOOMError();
        virConfFree(conf);
        return -1;
    }
    if (virGetUserID(user, &driver->user) < 0) {
        VIR_FREE(user);
        virConfFree(conf);
        return -1;
    }
    VIR_FREE(user);


    p = virConfGetValue (conf, "group");
    CHECK_TYPE ("group", VIR_CONF_STRING);
    if (!(group = strdup(p && p->str ? p->str : QEMU_GROUP))) {
        virReportOOMError();
        virConfFree(conf);
        return -1;
    }
    if (virGetGroupID(group, &driver->group) < 0) {
        VIR_FREE(group);
        virConfFree(conf);
        return -1;
    }
    VIR_FREE(group);


    p = virConfGetValue (conf, "dynamic_ownership");
    CHECK_TYPE ("dynamic_ownership", VIR_CONF_LONG);
    if (p) driver->dynamicOwnership = p->l;


    p = virConfGetValue (conf, "cgroup_controllers");
    CHECK_TYPE ("cgroup_controllers", VIR_CONF_LIST);
    if (p) {
        virConfValuePtr pp;
        for (i = 0, pp = p->list; pp; ++i, pp = pp->next) {
            int ctl;
            if (pp->type != VIR_CONF_STRING) {
                VIR_ERROR(_("cgroup_controllers must be a list of strings"));
                virConfFree(conf);
                return -1;
            }
            ctl = virCgroupControllerTypeFromString(pp->str);
            if (ctl < 0) {
                VIR_ERROR(_("Unknown cgroup controller '%s'"), pp->str);
                virConfFree(conf);
                return -1;
            }
            driver->cgroupControllers |= (1 << ctl);
        }
    } else {
        driver->cgroupControllers =
            (1 << VIR_CGROUP_CONTROLLER_CPU) |
            (1 << VIR_CGROUP_CONTROLLER_DEVICES) |
            (1 << VIR_CGROUP_CONTROLLER_MEMORY) |
            (1 << VIR_CGROUP_CONTROLLER_BLKIO) |
            (1 << VIR_CGROUP_CONTROLLER_CPUSET) |
            (1 << VIR_CGROUP_CONTROLLER_CPUACCT);
    }
    for (i = 0 ; i < VIR_CGROUP_CONTROLLER_LAST ; i++) {
        if (driver->cgroupControllers & (1 << i)) {
            VIR_INFO("Configured cgroup controller '%s'",
                     virCgroupControllerTypeToString(i));
        }
    }

    p = virConfGetValue (conf, "cgroup_device_acl");
    CHECK_TYPE ("cgroup_device_acl", VIR_CONF_LIST);
    if (p) {
        int len = 0;
        virConfValuePtr pp;
        for (pp = p->list; pp; pp = pp->next)
            len++;
        if (VIR_ALLOC_N(driver->cgroupDeviceACL, 1+len) < 0) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }
        for (i = 0, pp = p->list; pp; ++i, pp = pp->next) {
            if (pp->type != VIR_CONF_STRING) {
                VIR_ERROR(_("cgroup_device_acl must be a list of strings"));
                virConfFree(conf);
                return -1;
            }
            driver->cgroupDeviceACL[i] = strdup (pp->str);
            if (driver->cgroupDeviceACL[i] == NULL) {
                virReportOOMError();
                virConfFree(conf);
                return -1;
            }

        }
        driver->cgroupDeviceACL[i] = NULL;
    }

    p = virConfGetValue (conf, "save_image_format");
    CHECK_TYPE ("save_image_format", VIR_CONF_STRING);
    if (p && p->str) {
        VIR_FREE(driver->saveImageFormat);
        if (!(driver->saveImageFormat = strdup(p->str))) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }
    }

    p = virConfGetValue (conf, "dump_image_format");
    CHECK_TYPE ("dump_image_format", VIR_CONF_STRING);
    if (p && p->str) {
        VIR_FREE(driver->dumpImageFormat);
        if (!(driver->dumpImageFormat = strdup(p->str))) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }
    }

    p = virConfGetValue (conf, "auto_dump_path");
    CHECK_TYPE ("auto_dump_path", VIR_CONF_STRING);
    if (p && p->str) {
        VIR_FREE(driver->autoDumpPath);
        if (!(driver->autoDumpPath = strdup(p->str))) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }
    }

    p = virConfGetValue (conf, "auto_dump_bypass_cache");
    CHECK_TYPE ("auto_dump_bypass_cache", VIR_CONF_LONG);
    if (p) driver->autoDumpBypassCache = true;

    p = virConfGetValue (conf, "auto_start_bypass_cache");
    CHECK_TYPE ("auto_start_bypass_cache", VIR_CONF_LONG);
    if (p) driver->autoStartBypassCache = true;

    p = virConfGetValue (conf, "hugetlbfs_mount");
    CHECK_TYPE ("hugetlbfs_mount", VIR_CONF_STRING);
    if (p && p->str) {
        VIR_FREE(driver->hugetlbfs_mount);
        if (!(driver->hugetlbfs_mount = strdup(p->str))) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }
    }

    p = virConfGetValue (conf, "mac_filter");
    CHECK_TYPE ("mac_filter", VIR_CONF_LONG);
    if (p && p->l) {
        driver->macFilter = p->l;
        if (!(driver->ebtables = ebtablesContextNew("qemu"))) {
            driver->macFilter = 0;
            virReportSystemError(errno,
                                 _("failed to enable mac filter in '%s'"),
                                 __FILE__);
            virConfFree(conf);
            return -1;
        }

        if ((errno = networkDisableAllFrames(driver))) {
            virReportSystemError(errno,
                         _("failed to add rule to drop all frames in '%s'"),
                                 __FILE__);
            virConfFree(conf);
            return -1;
        }
    }

    p = virConfGetValue (conf, "relaxed_acs_check");
    CHECK_TYPE ("relaxed_acs_check", VIR_CONF_LONG);
    if (p) driver->relaxedACS = p->l;

    p = virConfGetValue (conf, "vnc_allow_host_audio");
    CHECK_TYPE ("vnc_allow_host_audio", VIR_CONF_LONG);
    if (p) driver->vncAllowHostAudio = p->l;

    p = virConfGetValue (conf, "clear_emulator_capabilities");
    CHECK_TYPE ("clear_emulator_capabilities", VIR_CONF_LONG);
    if (p) driver->clearEmulatorCapabilities = p->l;

    p = virConfGetValue (conf, "allow_disk_format_probing");
    CHECK_TYPE ("allow_disk_format_probing", VIR_CONF_LONG);
    if (p) driver->allowDiskFormatProbing = p->l;

    p = virConfGetValue (conf, "set_process_name");
    CHECK_TYPE ("set_process_name", VIR_CONF_LONG);
    if (p) driver->setProcessName = p->l;

    p = virConfGetValue(conf, "max_processes");
    CHECK_TYPE("max_processes", VIR_CONF_LONG);
    if (p) driver->maxProcesses = p->l;

    p = virConfGetValue(conf, "max_files");
    CHECK_TYPE("max_files", VIR_CONF_LONG);
    if (p) driver->maxFiles = p->l;

    p = virConfGetValue (conf, "lock_manager");
    CHECK_TYPE ("lock_manager", VIR_CONF_STRING);
    if (p && p->str) {
        char *lockConf;
        virLockManagerPluginUnref(driver->lockManager);
        if (virAsprintf(&lockConf, "%s/libvirt/qemu-%s.conf", SYSCONFDIR, p->str) < 0) {
            virReportOOMError();
            virConfFree(conf);
            return -1;
        }
        if (!(driver->lockManager =
              virLockManagerPluginNew(p->str, lockConf, 0)))
            VIR_ERROR(_("Failed to load lock manager %s"), p->str);
        VIR_FREE(lockConf);
    }

    p = virConfGetValue(conf, "max_queued");
    CHECK_TYPE("max_queued", VIR_CONF_LONG);
    if (p) driver->max_queued = p->l;

    p = virConfGetValue(conf, "keepalive_interval");
    CHECK_TYPE("keepalive_interval", VIR_CONF_LONG);
    if (p) driver->keepAliveInterval = p->l;

    p = virConfGetValue(conf, "keepalive_count");
    CHECK_TYPE("keepalive_count", VIR_CONF_LONG);
    if (p) driver->keepAliveCount = p->l;

    virConfFree (conf);
    return 0;
}
Beispiel #13
0
daemonSetupNetworking(virNetServerPtr srv,
                      virNetServerPtr srvAdm,
                      struct daemonConfig *config,
                      const char *sock_path,
                      const char *sock_path_ro,
                      const char *sock_path_adm,
                      bool ipsock,
                      bool privileged)
{
    virNetServerServicePtr svc = NULL;
    virNetServerServicePtr svcAdm = NULL;
    virNetServerServicePtr svcRO = NULL;
    virNetServerServicePtr svcTCP = NULL;
#if WITH_GNUTLS
    virNetServerServicePtr svcTLS = NULL;
#endif
    gid_t unix_sock_gid = 0;
    int unix_sock_ro_mask = 0;
    int unix_sock_rw_mask = 0;
    int unix_sock_adm_mask = 0;
    int ret = -1;

    unsigned int cur_fd = STDERR_FILENO + 1;
    unsigned int nfds = virGetListenFDs();

    if (config->unix_sock_group) {
        if (virGetGroupID(config->unix_sock_group, &unix_sock_gid) < 0)
            return ret;
    }

    if (nfds > (sock_path_ro ? 2 : 1)) {
        VIR_ERROR(_("Too many (%u) FDs passed from caller"), nfds);
        return ret;
    }

    if (virStrToLong_i(config->unix_sock_ro_perms, NULL, 8, &unix_sock_ro_mask) != 0) {
        VIR_ERROR(_("Failed to parse mode '%s'"), config->unix_sock_ro_perms);
        goto cleanup;
    }

    if (virStrToLong_i(config->unix_sock_admin_perms, NULL, 8, &unix_sock_adm_mask) != 0) {
        VIR_ERROR(_("Failed to parse mode '%s'"), config->unix_sock_admin_perms);
        goto cleanup;
    }

    if (virStrToLong_i(config->unix_sock_rw_perms, NULL, 8, &unix_sock_rw_mask) != 0) {
        VIR_ERROR(_("Failed to parse mode '%s'"), config->unix_sock_rw_perms);
        goto cleanup;
    }

    if (!(svc = virNetServerServiceNewFDOrUNIX(sock_path,
                                               unix_sock_rw_mask,
                                               unix_sock_gid,
                                               config->auth_unix_rw,
#if WITH_GNUTLS
                                               NULL,
#endif
                                               false,
                                               config->max_queued_clients,
                                               config->max_client_requests,
                                               nfds, &cur_fd)))
        goto cleanup;
    if (sock_path_ro) {
        if (!(svcRO = virNetServerServiceNewFDOrUNIX(sock_path_ro,
                                                     unix_sock_ro_mask,
                                                     unix_sock_gid,
                                                     config->auth_unix_ro,
#if WITH_GNUTLS
                                                     NULL,
#endif
                                                     true,
                                                     config->max_queued_clients,
                                                     config->max_client_requests,
                                                     nfds, &cur_fd)))
            goto cleanup;
    }

    if (virNetServerAddService(srv, svc,
                               config->mdns_adv && !ipsock ?
                               "_libvirt._tcp" :
                               NULL) < 0)
        goto cleanup;

    if (svcRO &&
        virNetServerAddService(srv, svcRO, NULL) < 0)
        goto cleanup;

    /* Temporarily disabled */
    if (sock_path_adm && false) {
        VIR_DEBUG("Registering unix socket %s", sock_path_adm);
        if (!(svcAdm = virNetServerServiceNewUNIX(sock_path_adm,
                                                  unix_sock_adm_mask,
                                                  unix_sock_gid,
                                                  REMOTE_AUTH_NONE,
#if WITH_GNUTLS
                                                  NULL,
#endif
                                                  true,
                                                  config->admin_max_queued_clients,
                                                  config->admin_max_client_requests)))
            goto cleanup;

        if (virNetServerAddService(srvAdm, svcAdm, NULL) < 0)
            goto cleanup;
    }

    if (ipsock) {
        if (config->listen_tcp) {
            VIR_DEBUG("Registering TCP socket %s:%s",
                      config->listen_addr, config->tcp_port);
            if (!(svcTCP = virNetServerServiceNewTCP(config->listen_addr,
                                                     config->tcp_port,
                                                     AF_UNSPEC,
                                                     config->auth_tcp,
#if WITH_GNUTLS
                                                     NULL,
#endif
                                                     false,
                                                     config->max_queued_clients,
                                                     config->max_client_requests)))
                goto cleanup;

            if (virNetServerAddService(srv, svcTCP,
                                       config->mdns_adv ? "_libvirt._tcp" : NULL) < 0)
                goto cleanup;
        }

#if WITH_GNUTLS
        if (config->listen_tls) {
            virNetTLSContextPtr ctxt = NULL;

            if (config->ca_file ||
                config->cert_file ||
                config->key_file) {
                if (!(ctxt = virNetTLSContextNewServer(config->ca_file,
                                                       config->crl_file,
                                                       config->cert_file,
                                                       config->key_file,
                                                       (const char *const*)config->tls_allowed_dn_list,
                                                       config->tls_no_sanity_certificate ? false : true,
                                                       config->tls_no_verify_certificate ? false : true)))
                    goto cleanup;
            } else {
                if (!(ctxt = virNetTLSContextNewServerPath(NULL,
                                                           !privileged,
                                                           (const char *const*)config->tls_allowed_dn_list,
                                                           config->tls_no_sanity_certificate ? false : true,
                                                           config->tls_no_verify_certificate ? false : true)))
                    goto cleanup;
            }

            VIR_DEBUG("Registering TLS socket %s:%s",
                      config->listen_addr, config->tls_port);
            if (!(svcTLS =
                  virNetServerServiceNewTCP(config->listen_addr,
                                            config->tls_port,
                                            AF_UNSPEC,
                                            config->auth_tls,
                                            ctxt,
                                            false,
                                            config->max_queued_clients,
                                            config->max_client_requests))) {
                virObjectUnref(ctxt);
                goto cleanup;
            }
            if (virNetServerAddService(srv, svcTLS,
                                       config->mdns_adv &&
                                       !config->listen_tcp ? "_libvirt._tcp" : NULL) < 0)
                goto cleanup;

            virObjectUnref(ctxt);
        }
#else
        (void)privileged;
        if (config->listen_tls) {
            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                           _("This libvirtd build does not support TLS"));
            goto cleanup;
        }
#endif
    }

#if WITH_SASL
    if (config->auth_unix_rw == REMOTE_AUTH_SASL ||
        config->auth_unix_ro == REMOTE_AUTH_SASL ||
# if WITH_GNUTLS
        config->auth_tls == REMOTE_AUTH_SASL ||
# endif
        config->auth_tcp == REMOTE_AUTH_SASL) {
        saslCtxt = virNetSASLContextNewServer(
            (const char *const*)config->sasl_allowed_username_list);
        if (!saslCtxt)
            goto cleanup;
    }
#endif

    ret = 0;

 cleanup:
#if WITH_GNUTLS
    virObjectUnref(svcTLS);
#endif
    virObjectUnref(svcTCP);
    virObjectUnref(svcRO);
    virObjectUnref(svcAdm);
    virObjectUnref(svc);
    return ret;
}
static int daemonSetupNetworking(virNetServerPtr srv,
                                 struct daemonConfig *config,
                                 const char *sock_path,
                                 const char *sock_path_ro,
                                 bool ipsock,
                                 bool privileged)
{
    virNetServerServicePtr svc = NULL;
    virNetServerServicePtr svcRO = NULL;
    virNetServerServicePtr svcTCP = NULL;
    virNetServerServicePtr svcTLS = NULL;
    gid_t unix_sock_gid = 0;
    int unix_sock_ro_mask = 0;
    int unix_sock_rw_mask = 0;

    if (config->unix_sock_group) {
        if (virGetGroupID(config->unix_sock_group, &unix_sock_gid) < 0)
            return -1;
    }

    if (virStrToLong_i(config->unix_sock_ro_perms, NULL, 8, &unix_sock_ro_mask) != 0) {
        VIR_ERROR(_("Failed to parse mode '%s'"), config->unix_sock_ro_perms);
        goto error;
    }

    if (virStrToLong_i(config->unix_sock_rw_perms, NULL, 8, &unix_sock_rw_mask) != 0) {
        VIR_ERROR(_("Failed to parse mode '%s'"), config->unix_sock_rw_perms);
        goto error;
    }

    if (!(svc = virNetServerServiceNewUNIX(sock_path,
                                           unix_sock_rw_mask,
                                           unix_sock_gid,
                                           config->auth_unix_rw,
                                           false,
                                           config->max_client_requests,
                                           NULL)))
        goto error;
    if (sock_path_ro &&
        !(svcRO = virNetServerServiceNewUNIX(sock_path_ro,
                                             unix_sock_ro_mask,
                                             unix_sock_gid,
                                             config->auth_unix_ro,
                                             true,
                                             config->max_client_requests,
                                             NULL)))
        goto error;

    if (virNetServerAddService(srv, svc,
                               config->mdns_adv && !ipsock ?
                               "_libvirt._tcp" :
                               NULL) < 0)
        goto error;

    if (svcRO &&
        virNetServerAddService(srv, svcRO, NULL) < 0)
        goto error;

    if (ipsock) {
        if (config->listen_tcp) {
            if (!(svcTCP = virNetServerServiceNewTCP(config->listen_addr,
                                                     config->tcp_port,
                                                     config->auth_tcp,
                                                     false,
                                                     config->max_client_requests,
                                                     NULL)))
                goto error;

            if (virNetServerAddService(srv, svcTCP,
                                       config->mdns_adv ? "_libvirt._tcp" : NULL) < 0)
                goto error;
        }

        if (config->listen_tls) {
            virNetTLSContextPtr ctxt = NULL;

            if (config->ca_file ||
                config->cert_file ||
                config->key_file) {
                if (!(ctxt = virNetTLSContextNewServer(config->ca_file,
                                                       config->crl_file,
                                                       config->cert_file,
                                                       config->key_file,
                                                       (const char *const*)config->tls_allowed_dn_list,
                                                       config->tls_no_sanity_certificate ? false : true,
                                                       config->tls_no_verify_certificate ? false : true)))
                    goto error;
            } else {
                if (!(ctxt = virNetTLSContextNewServerPath(NULL,
                                                           !privileged,
                                                           (const char *const*)config->tls_allowed_dn_list,
                                                           config->tls_no_sanity_certificate ? false : true,
                                                           config->tls_no_verify_certificate ? false : true)))
                    goto error;
            }

            if (!(svcTLS =
                  virNetServerServiceNewTCP(config->listen_addr,
                                            config->tls_port,
                                            config->auth_tls,
                                            false,
                                            config->max_client_requests,
                                            ctxt))) {
                virNetTLSContextFree(ctxt);
                goto error;
            }
            if (virNetServerAddService(srv, svcTLS,
                                       config->mdns_adv &&
                                       !config->listen_tcp ? "_libvirt._tcp" : NULL) < 0)
                goto error;

            virNetTLSContextFree(ctxt);
        }
    }

#if HAVE_SASL
    if (config->auth_unix_rw == REMOTE_AUTH_SASL ||
        config->auth_unix_ro == REMOTE_AUTH_SASL ||
        config->auth_tcp == REMOTE_AUTH_SASL ||
        config->auth_tls == REMOTE_AUTH_SASL) {
        saslCtxt = virNetSASLContextNewServer(
            (const char *const*)config->sasl_allowed_username_list);
        if (!saslCtxt)
            goto error;
    }
#endif

    return 0;

error:
    virNetServerServiceFree(svcTLS);
    virNetServerServiceFree(svcTCP);
    virNetServerServiceFree(svc);
    virNetServerServiceFree(svcRO);
    return -1;
}
Beispiel #15
0
int vshRunConsole(virDomainPtr dom,
                  const char *dev_name,
                  const char *escape_seq,
                  unsigned int flags)
{
    int ret = -1;
    struct termios ttyattr;
    void (*old_sigquit)(int);
    void (*old_sigterm)(int);
    void (*old_sigint)(int);
    void (*old_sighup)(int);
    void (*old_sigpipe)(int);
    virConsolePtr con = NULL;

    /* Put STDIN into raw mode so that stuff typed
       does not echo to the screen (the TTY reads will
       result in it being echoed back already), and
       also ensure Ctrl-C, etc is blocked, and misc
       other bits */
    if (vshMakeStdinRaw(&ttyattr, true) < 0)
        goto resettty;

    /* Trap all common signals so that we can safely restore
       the original terminal settings on STDIN before the
       process exits - people don't like being left with a
       messed up terminal ! */
    old_sigquit = signal(SIGQUIT, do_signal);
    old_sigterm = signal(SIGTERM, do_signal);
    old_sigint = signal(SIGINT, do_signal);
    old_sighup = signal(SIGHUP, do_signal);
    old_sigpipe = signal(SIGPIPE, do_signal);
    got_signal = 0;

    if (VIR_ALLOC(con) < 0) {
        virReportOOMError();
        goto cleanup;
    }

    con->escapeChar = vshGetEscapeChar(escape_seq);
    con->st = virStreamNew(virDomainGetConnect(dom),
                           VIR_STREAM_NONBLOCK);
    if (!con->st)
        goto cleanup;

    if (virDomainOpenConsole(dom, dev_name, con->st, flags) < 0)
        goto cleanup;

    if (virCondInit(&con->cond) < 0 || virMutexInit(&con->lock) < 0)
        goto cleanup;

    con->stdinWatch = virEventAddHandle(STDIN_FILENO,
                                        VIR_EVENT_HANDLE_READABLE,
                                        virConsoleEventOnStdin,
                                        con,
                                        NULL);
    con->stdoutWatch = virEventAddHandle(STDOUT_FILENO,
                                         0,
                                         virConsoleEventOnStdout,
                                         con,
                                         NULL);

    virStreamEventAddCallback(con->st,
                              VIR_STREAM_EVENT_READABLE,
                              virConsoleEventOnStream,
                              con,
                              NULL);

    while (!con->quit) {
        if (virCondWait(&con->cond, &con->lock) < 0) {
            VIR_ERROR(_("unable to wait on console condition"));
            goto cleanup;
        }
    }

    ret = 0;

 cleanup:

    if (con) {
        if (con->st)
            virStreamFree(con->st);
        virMutexDestroy(&con->lock);
        ignore_value(virCondDestroy(&con->cond));
        VIR_FREE(con);
    }

    /* Restore original signal handlers */
    signal(SIGPIPE, old_sigpipe);
    signal(SIGHUP, old_sighup);
    signal(SIGINT, old_sigint);
    signal(SIGTERM, old_sigterm);
    signal(SIGQUIT, old_sigquit);

resettty:
    /* Put STDIN back into the (sane?) state we found
       it in before starting */
    tcsetattr(STDIN_FILENO, TCSAFLUSH, &ttyattr);

    return ret;
}
int
detect_scsi_host_caps(union _virNodeDevCapData *d)
{
    char *max_vports = NULL;
    char *vports = NULL;
    int ret = -1;

    VIR_DEBUG("Checking if host%d is an FC HBA", d->scsi_host.host);

    if (virIsCapableFCHost(NULL, d->scsi_host.host)) {
        d->scsi_host.flags |= VIR_NODE_DEV_CAP_FLAG_HBA_FC_HOST;

        if (virReadFCHost(NULL,
                          d->scsi_host.host,
                          "port_name",
                          &d->scsi_host.wwpn) < 0) {
            VIR_ERROR(_("Failed to read WWPN for host%d"), d->scsi_host.host);
            goto cleanup;
        }

        if (virReadFCHost(NULL,
                          d->scsi_host.host,
                          "node_name",
                          &d->scsi_host.wwnn) < 0) {
            VIR_ERROR(_("Failed to read WWNN for host%d"), d->scsi_host.host);
            goto cleanup;
        }

        if (virReadFCHost(NULL,
                          d->scsi_host.host,
                          "fabric_name",
                          &d->scsi_host.fabric_wwn) < 0) {
            VIR_ERROR(_("Failed to read fabric WWN for host%d"),
                      d->scsi_host.host);
            goto cleanup;
        }
    }

    if (virIsCapableVport(NULL, d->scsi_host.host)) {
        d->scsi_host.flags |= VIR_NODE_DEV_CAP_FLAG_HBA_VPORT_OPS;

        if (virReadFCHost(NULL,
                          d->scsi_host.host,
                          "max_npiv_vports",
                          &max_vports) < 0) {
            VIR_ERROR(_("Failed to read max_npiv_vports for host%d"),
                      d->scsi_host.host);
            goto cleanup;
        }

         if (virReadFCHost(NULL,
                          d->scsi_host.host,
                          "npiv_vports_inuse",
                          &vports) < 0) {
            VIR_ERROR(_("Failed to read npiv_vports_inuse for host%d"),
                      d->scsi_host.host);
            goto cleanup;
        }

        if (virStrToLong_i(max_vports, NULL, 10,
                           &d->scsi_host.max_vports) < 0) {
            VIR_ERROR(_("Failed to parse value of max_npiv_vports '%s'"),
                      max_vports);
            goto cleanup;
        }

        if (virStrToLong_i(vports, NULL, 10,
                           &d->scsi_host.vports) < 0) {
            VIR_ERROR(_("Failed to parse value of npiv_vports_inuse '%s'"),
                      vports);
            goto cleanup;
        }
    }

    ret = 0;
cleanup:
    if (ret < 0) {
        /* Clear the two flags in case of producing confusing XML output */
        d->scsi_host.flags &= ~(VIR_NODE_DEV_CAP_FLAG_HBA_FC_HOST |
                                VIR_NODE_DEV_CAP_FLAG_HBA_VPORT_OPS);

        VIR_FREE(d->scsi_host.wwnn);
        VIR_FREE(d->scsi_host.wwpn);
        VIR_FREE(d->scsi_host.fabric_wwn);
    }
    VIR_FREE(max_vports);
    VIR_FREE(vports);
    return ret;
}
Beispiel #17
0
static int openvzSetInitialConfig(virDomainDefPtr vmdef)
{
    int ret = -1;
    int vpsid;
    char * confdir = NULL;
    const char *prog[OPENVZ_MAX_ARG];
    prog[0] = NULL;

    if (vmdef->nfss > 1) {
        openvzError(VIR_ERR_INTERNAL_ERROR, "%s",
                    _("only one filesystem supported"));
        goto cleanup;
    }

    if (vmdef->nfss == 1 &&
        vmdef->fss[0]->type != VIR_DOMAIN_FS_TYPE_TEMPLATE &&
        vmdef->fss[0]->type != VIR_DOMAIN_FS_TYPE_MOUNT)
    {
        openvzError(VIR_ERR_INTERNAL_ERROR, "%s",
                    _("filesystem is not of type 'template' or 'mount'"));
        goto cleanup;
    }


    if (vmdef->nfss == 1 &&
        vmdef->fss[0]->type == VIR_DOMAIN_FS_TYPE_MOUNT)
    {

        if (virStrToLong_i(vmdef->name, NULL, 10, &vpsid) < 0) {
            openvzError(VIR_ERR_INTERNAL_ERROR, "%s",
                        _("Could not convert domain name to VEID"));
            goto cleanup;
        }

        if (openvzCopyDefaultConfig(vpsid) < 0) {
            openvzError(VIR_ERR_INTERNAL_ERROR, "%s",
                        _("Could not copy default config"));
            goto cleanup;
        }

        if (openvzWriteVPSConfigParam(vpsid, "VE_PRIVATE", vmdef->fss[0]->src) < 0) {
            openvzError(VIR_ERR_INTERNAL_ERROR, "%s",
                        _("Could not set the source dir for the filesystem"));
            goto cleanup;
        }
    }
    else
    {
        if (openvzDomainDefineCmd(prog, OPENVZ_MAX_ARG, vmdef) < 0) {
            VIR_ERROR(_("Error creating command for container"));
            goto cleanup;
        }

        if (virRun(prog, NULL) < 0) {
            goto cleanup;
        }
    }

    ret = 0;

cleanup:
  VIR_FREE(confdir);
  cmdExecFree(prog);
  return ret;
}
Beispiel #18
0
/* This function guarantees that query is freed, even on failure */
int
hypervEnumAndPull(hypervPrivate *priv, virBufferPtr query, const char *root,
                  XmlSerializerInfo *serializerInfo, const char *resourceUri,
                  const char *className, hypervObject **list)
{
    int result = -1;
    WsSerializerContextH serializerContext;
    client_opt_t *options = NULL;
    char *query_string = NULL;
    filter_t *filter = NULL;
    WsXmlDocH response = NULL;
    char *enumContext = NULL;
    hypervObject *head = NULL;
    hypervObject *tail = NULL;
    WsXmlNodeH node = NULL;
    XML_TYPE_PTR data = NULL;
    hypervObject *object;

    if (virBufferCheckError(query) < 0) {
        virBufferFreeAndReset(query);
        return -1;
    }
    query_string = virBufferContentAndReset(query);

    if (list == NULL || *list != NULL) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s", _("Invalid argument"));
        VIR_FREE(query_string);
        return -1;
    }

    serializerContext = wsmc_get_serialization_context(priv->client);

    options = wsmc_options_init();

    if (options == NULL) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("Could not initialize options"));
        goto cleanup;
    }

    filter = filter_create_simple(WSM_WQL_FILTER_DIALECT, query_string);

    if (filter == NULL) {
        virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                       _("Could not create filter"));
        goto cleanup;
    }

    response = wsmc_action_enumerate(priv->client, root, options, filter);

    if (hyperyVerifyResponse(priv->client, response, "enumeration") < 0)
        goto cleanup;

    enumContext = wsmc_get_enum_context(response);

    ws_xml_destroy_doc(response);
    response = NULL;

    while (enumContext != NULL && *enumContext != '\0') {
        response = wsmc_action_pull(priv->client, resourceUri, options,
                                    filter, enumContext);

        if (hyperyVerifyResponse(priv->client, response, "pull") < 0)
            goto cleanup;

        node = ws_xml_get_soap_body(response);

        if (node == NULL) {
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("Could not lookup SOAP body"));
            goto cleanup;
        }

        node = ws_xml_get_child(node, 0, XML_NS_ENUMERATION, WSENUM_PULL_RESP);

        if (node == NULL) {
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("Could not lookup pull response"));
            goto cleanup;
        }

        node = ws_xml_get_child(node, 0, XML_NS_ENUMERATION, WSENUM_ITEMS);

        if (node == NULL) {
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("Could not lookup pull response items"));
            goto cleanup;
        }

        if (ws_xml_get_child(node, 0, resourceUri, className) == NULL)
            break;

        data = ws_deserialize(serializerContext, node, serializerInfo,
                              className, resourceUri, NULL, 0, 0);

        if (data == NULL) {
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("Could not deserialize pull response item"));
            goto cleanup;
        }

        if (VIR_ALLOC(object) < 0)
            goto cleanup;

        object->serializerInfo = serializerInfo;
        object->data = data;

        data = NULL;

        if (head == NULL) {
            head = object;
        } else {
            tail->next = object;
        }

        tail = object;

        VIR_FREE(enumContext);
        enumContext = wsmc_get_enum_context(response);

        ws_xml_destroy_doc(response);
        response = NULL;
    }

    *list = head;
    head = NULL;

    result = 0;

 cleanup:
    if (options != NULL)
        wsmc_options_destroy(options);

    if (filter != NULL)
        filter_destroy(filter);

    if (data != NULL) {
#if WS_SERIALIZER_FREE_MEM_WORKS
        /* FIXME: ws_serializer_free_mem is broken in openwsman <= 2.2.6,
         *        see hypervFreeObject for a detailed explanation. */
        if (ws_serializer_free_mem(serializerContext, data,
                                   serializerInfo) < 0) {
            VIR_ERROR(_("Could not free deserialized data"));
        }
#endif
    }

    VIR_FREE(query_string);
    ws_xml_destroy_doc(response);
    VIR_FREE(enumContext);
    hypervFreeObject(priv, head);

    return result;
}
Beispiel #19
0
static virDomainPtr
openvzDomainDefineXML(virConnectPtr conn, const char *xml)
{
    struct openvz_driver *driver =  conn->privateData;
    virDomainDefPtr vmdef = NULL;
    virDomainObjPtr vm = NULL;
    virDomainPtr dom = NULL;

    openvzDriverLock(driver);
    if ((vmdef = virDomainDefParseString(driver->caps, xml,
                                         1 << VIR_DOMAIN_VIRT_OPENVZ,
                                         VIR_DOMAIN_XML_INACTIVE)) == NULL)
        goto cleanup;

    vm = virDomainFindByName(&driver->domains, vmdef->name);
    if (vm) {
        openvzError(VIR_ERR_OPERATION_FAILED,
                    _("Already an OPENVZ VM active with the id '%s'"),
                    vmdef->name);
        goto cleanup;
    }
    if (!(vm = virDomainAssignDef(driver->caps,
                                  &driver->domains, vmdef, false)))
        goto cleanup;
    vmdef = NULL;
    vm->persistent = 1;

    if (openvzSetInitialConfig(vm->def) < 0) {
        VIR_ERROR(_("Error creating initial configuration"));
        goto cleanup;
    }

    /* TODO: set quota */

    if (openvzSetDefinedUUID(strtoI(vm->def->name), vm->def->uuid) < 0) {
        openvzError(VIR_ERR_INTERNAL_ERROR, "%s",
                    _("Could not set UUID"));
        goto cleanup;
    }

    if (openvzDomainSetNetworkConfig(conn, vm->def) < 0)
        goto cleanup;

    if (vm->def->vcpus != vm->def->maxvcpus) {
        openvzError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
                    _("current vcpu count must equal maximum"));
        goto cleanup;
    }
    if (vm->def->maxvcpus > 0) {
        if (openvzDomainSetVcpusInternal(vm, vm->def->maxvcpus) < 0) {
            openvzError(VIR_ERR_INTERNAL_ERROR, "%s",
                        _("Could not set number of virtual cpu"));
             goto cleanup;
        }
    }

    if (vm->def->mem.cur_balloon > 0) {
        if (openvzDomainSetMemoryInternal(vm, vm->def->mem.cur_balloon) < 0) {
            openvzError(VIR_ERR_INTERNAL_ERROR, "%s",
                        _("Could not set memory size"));
             goto cleanup;
        }
    }

    dom = virGetDomain(conn, vm->def->name, vm->def->uuid);
    if (dom)
        dom->id = -1;

cleanup:
    virDomainDefFree(vmdef);
    if (vm)
        virDomainObjUnlock(vm);
    openvzDriverUnlock(driver);
    return dom;
}
Beispiel #20
0
/**
 * Try load VBoxXPCOMC.so/dylib/dll from the specified location and resolve all
 * the symbols we need.
 *
 * @returns 0 on success, -1 on failure and 1 if VBoxXPCOMC was not found.
 * @param   dir           The directory where to try load VBoxXPCOMC from. Can
 *                        be NULL.
 * @param   setAppHome    Whether to set the VBOX_APP_HOME env.var. or not.
 * @param   ignoreMissing Whether to ignore missing library or not.
 * @param   version       Version number of the loaded API.
 */
static int
tryLoadOne(const char *dir, bool setAppHome, bool ignoreMissing,
           unsigned int *version)
{
    int result = -1;
    char *name = NULL;
    PFNVBOXGETXPCOMCFUNCTIONS pfnGetFunctions;

    if (dir != NULL) {
        if (virAsprintf(&name, "%s/%s", dir, DYNLIB_NAME) < 0)
            return -1;

        if (!virFileExists(name)) {
            if (!ignoreMissing)
                VIR_ERROR(_("Library '%s' doesn't exist"), name);

            VIR_FREE(name);
            return -1;
        }
    } else {
        if (VIR_STRDUP(name, DYNLIB_NAME) < 0)
            return -1;
    }

    /*
     * Try load it by that name, setting the VBOX_APP_HOME first (for now).
     * Then resolve and call the function table getter.
     */
    if (setAppHome) {
        if (dir != NULL) {
            setenv("VBOX_APP_HOME", dir, 1 /* always override */);
        } else {
            unsetenv("VBOX_APP_HOME");
        }
    }

    hVBoxXPCOMC = dlopen(name, RTLD_NOW | RTLD_LOCAL);

    if (hVBoxXPCOMC == NULL) {
        /*
         * FIXME: Don't warn in this case as it currently breaks make check
         *        on systems without VirtualBox.
         */
        if (dir != NULL)
            VIR_WARN("Could not dlopen '%s': %s", name, dlerror());

        goto cleanup;
    }

    pfnGetFunctions = (PFNVBOXGETXPCOMCFUNCTIONS)
        dlsym(hVBoxXPCOMC, VBOX_GET_XPCOMC_FUNCTIONS_SYMBOL_NAME);

    if (pfnGetFunctions == NULL) {
        VIR_ERROR(_("Could not dlsym %s from '%s': %s"),
                  VBOX_GET_XPCOMC_FUNCTIONS_SYMBOL_NAME, name, dlerror());
        goto cleanup;
    }

    pVBoxFuncs_v2_2 = pfnGetFunctions(VBOX_XPCOMC_VERSION);

    if (pVBoxFuncs_v2_2 == NULL) {
        VIR_ERROR(_("Calling %s from '%s' failed"),
                  VBOX_GET_XPCOMC_FUNCTIONS_SYMBOL_NAME, name);
        goto cleanup;
    }

    *version = pVBoxFuncs_v2_2->pfnGetVersion();
    g_pfnGetFunctions = pfnGetFunctions;
    result = 0;

    if (dir != NULL) {
        VIR_DEBUG("Found %s in '%s'", DYNLIB_NAME, dir);
    } else {
        VIR_DEBUG("Found %s in dynamic linker search path", DYNLIB_NAME);
    }

 cleanup:
    if (hVBoxXPCOMC != NULL && result < 0) {
        dlclose(hVBoxXPCOMC);
        hVBoxXPCOMC = NULL;
    }

    VIR_FREE(name);

    return result;
}
Beispiel #21
0
static int
nodeDeviceVportCreateDelete(const int parent_host,
                            const char *wwpn,
                            const char *wwnn,
                            int operation)
{
    int retval = 0;
    char *operation_path = NULL, *vport_name = NULL;
    const char *operation_file = NULL;
    struct stat st;

    switch (operation) {
    case VPORT_CREATE:
        operation_file = LINUX_SYSFS_VPORT_CREATE_POSTFIX;
        break;
    case VPORT_DELETE:
        operation_file = LINUX_SYSFS_VPORT_DELETE_POSTFIX;
        break;
    default:
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Invalid vport operation (%d)"), operation);
        retval = -1;
        goto cleanup;
        break;
    }

    if (virAsprintf(&operation_path,
                    "%shost%d%s",
                    LINUX_SYSFS_FC_HOST_PREFIX,
                    parent_host,
                    operation_file) < 0) {

        virReportOOMError();
        retval = -1;
        goto cleanup;
    }

    if (stat(operation_path, &st) != 0) {
        VIR_FREE(operation_path);
        if (virAsprintf(&operation_path,
                        "%shost%d%s",
                        LINUX_SYSFS_SCSI_HOST_PREFIX,
                        parent_host,
                        operation_file) < 0) {
            virReportOOMError();
            retval = -1;
            goto cleanup;
        }

        if (stat(operation_path, &st) != 0) {
            VIR_ERROR(_("No vport operation path found for host%d"),
                      parent_host);
            retval = -1;
            goto cleanup;
        }
    }

    VIR_DEBUG("Vport operation path is '%s'", operation_path);

    if (virAsprintf(&vport_name,
                    "%s:%s",
                    wwpn,
                    wwnn) < 0) {

        virReportOOMError();
        retval = -1;
        goto cleanup;
    }

    if (virFileWriteStr(operation_path, vport_name, 0) == -1) {
        virReportSystemError(errno,
                             _("Write of '%s' to '%s' during "
                               "vport create/delete failed"),
                             vport_name, operation_path);
        retval = -1;
    }

cleanup:
    VIR_FREE(vport_name);
    VIR_FREE(operation_path);
    VIR_DEBUG("%s", _("Vport operation complete"));
    return retval;
}