Пример #1
0
/*
 * qemuTPMEmulatorInit
 *
 * Initialize the Emulator functions by searching for necessary
 * executables that we will use to start and setup the swtpm
 */
static int
qemuTPMEmulatorInit(void)
{
    if (!swtpm_path) {
        swtpm_path = virFindFileInPath("swtpm");
        if (!swtpm_path) {
            virReportSystemError(ENOENT, "%s",
                                 _("Unable to find 'swtpm' binary in $PATH"));
            return -1;
        }
        if (!virFileIsExecutable(swtpm_path)) {
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("TPM emulator %s is not an executable"),
                           swtpm_path);
            VIR_FREE(swtpm_path);
            return -1;
        }
    }

    if (!swtpm_setup) {
        swtpm_setup = virFindFileInPath("swtpm_setup");
        if (!swtpm_setup) {
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("Could not find 'swtpm_setup' in PATH"));
            return -1;
        }
        if (!virFileIsExecutable(swtpm_setup)) {
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("'%s' is not an executable"),
                           swtpm_setup);
            VIR_FREE(swtpm_setup);
            return -1;
        }
    }

    if (!swtpm_ioctl) {
        swtpm_ioctl = virFindFileInPath("swtpm_ioctl");
        if (!swtpm_ioctl) {
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("Could not find swtpm_ioctl in PATH"));
            return -1;
        }
        if (!virFileIsExecutable(swtpm_ioctl)) {
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("swtpm_ioctl program %s is not an executable"),
                           swtpm_ioctl);
            VIR_FREE(swtpm_ioctl);
            return -1;
        }
    }

    return 0;
}
Пример #2
0
int
virBhyveProbeCaps(unsigned int *caps)
{
    char *binary, *help;
    virCommandPtr cmd = NULL;
    int ret = 0, exit;

    binary = virFindFileInPath("bhyve");
    if (binary == NULL)
        goto out;
    if (!virFileIsExecutable(binary))
        goto out;

    cmd = virCommandNew(binary);
    virCommandAddArg(cmd, "-h");
    virCommandSetErrorBuffer(cmd, &help);
    if (virCommandRun(cmd, &exit) < 0) {
        ret = -1;
        goto out;
    }

    if (strstr(help, "-u:") != NULL)
        *caps |= BHYVE_CAP_RTC_UTC;

 out:
    VIR_FREE(help);
    virCommandFree(cmd);
    VIR_FREE(binary);
    return ret;
}
Пример #3
0
int
virBhyveProbeGrubCaps(virBhyveGrubCapsFlags *caps)
{
    char *binary, *help;
    virCommandPtr cmd;
    int ret, exit;

    ret = 0;
    *caps = 0;
    cmd = NULL;
    help = NULL;

    binary = virFindFileInPath("grub-bhyve");
    if (binary == NULL)
        goto out;
    if (!virFileIsExecutable(binary))
        goto out;

    cmd = virCommandNew(binary);
    virCommandAddArg(cmd, "--help");
    virCommandSetOutputBuffer(cmd, &help);
    if (virCommandRun(cmd, &exit) < 0) {
        ret = -1;
        goto out;
    }

    if (strstr(help, "--cons-dev") != NULL)
        *caps |= BHYVE_GRUB_CAP_CONSDEV;

 out:
    VIR_FREE(help);
    virCommandFree(cmd);
    VIR_FREE(binary);
    return ret;
}
Пример #4
0
virSysinfoDefPtr
virSysinfoRead(void) {
    char *path;
    virSysinfoDefPtr ret = NULL;
    char *outbuf = NULL;
    virCommandPtr cmd;

    path = virFindFileInPath(SYSINFO_SMBIOS_DECODER);
    if (path == NULL) {
        virSmbiosReportError(VIR_ERR_INTERNAL_ERROR,
                             _("Failed to find path for %s binary"),
                             SYSINFO_SMBIOS_DECODER);
        return NULL;
    }

    cmd = virCommandNewArgList(path, "-q", "-t", "0,1,4,17", NULL);
    VIR_FREE(path);
    virCommandSetOutputBuffer(cmd, &outbuf);
    if (virCommandRun(cmd, NULL) < 0) {
        virSmbiosReportError(VIR_ERR_INTERNAL_ERROR,
                             _("Failed to execute command %s"),
                             path);
        goto cleanup;
    }

    if (VIR_ALLOC(ret) < 0)
        goto no_memory;

    ret->type = VIR_SYSINFO_SMBIOS;

    if (virSysinfoParseBIOS(outbuf, ret) < 0)
        goto no_memory;

    if (virSysinfoParseSystem(outbuf, ret) < 0)
        goto no_memory;

    ret->nprocessor = 0;
    ret->processor = NULL;
    if (virSysinfoParseProcessor(outbuf, ret) < 0)
        goto no_memory;

    ret->nmemory = 0;
    ret->memory = NULL;
    if (virSysinfoParseMemory(outbuf, ret) < 0)
        goto no_memory;

cleanup:
    VIR_FREE(outbuf);
    virCommandFree(cmd);

    return ret;

no_memory:
    virReportOOMError();

    virSysinfoDefFree(ret);
    ret = NULL;
    goto cleanup;
}
Пример #5
0
static int
virIpTablesOnceInit(void)
{
    virCommandPtr cmd;
    int status;

#if HAVE_FIREWALLD
    firewall_cmd_path = virFindFileInPath("firewall-cmd");
    if (!firewall_cmd_path) {
        VIR_INFO("firewall-cmd not found on system. "
                 "firewalld support disabled for iptables.");
    } else {
        cmd = virCommandNew(firewall_cmd_path);

        virCommandAddArgList(cmd, "--state", NULL);
        /* don't log non-zero status */
        if (virCommandRun(cmd, &status) < 0 || status != 0) {
            VIR_INFO("firewall-cmd found but disabled for iptables");
            VIR_FREE(firewall_cmd_path);
            firewall_cmd_path = NULL;
        } else {
            VIR_INFO("using firewalld for iptables commands");
        }
        virCommandFree(cmd);
    }

    if (firewall_cmd_path)
        return 0;

#endif

    cmd = virCommandNew(IPTABLES_PATH);
    virCommandAddArgList(cmd, "-w", "-L", "-n", NULL);
    /* don't log non-zero status */
    if (virCommandRun(cmd, &status) < 0 || status != 0) {
        VIR_INFO("xtables locking not supported by your iptables");
    } else {
        VIR_INFO("using xtables locking for iptables");
        iptables_supports_xlock = true;
    }
    virCommandFree(cmd);
    return 0;
}
Пример #6
0
static int
virEbTablesOnceInit(void)
{
    firewall_cmd_path = virFindFileInPath("firewall-cmd");
    if (!firewall_cmd_path) {
        VIR_INFO("firewall-cmd not found on system. "
                 "firewalld support disabled for ebtables.");
    } else {
        virCommandPtr cmd = virCommandNew(firewall_cmd_path);
        int status;

        virCommandAddArgList(cmd, "--state", NULL);
        if (virCommandRun(cmd, &status) < 0 || status != 0) {
            VIR_INFO("firewall-cmd found but disabled for ebtables");
            VIR_FREE(firewall_cmd_path);
            firewall_cmd_path = NULL;
        } else {
            VIR_INFO("using firewalld for ebtables commands");
        }
        virCommandFree(cmd);
    }
    return 0;
}
Пример #7
0
static int
testPrepImages(void)
{
    int ret = EXIT_FAILURE;
    virCommandPtr cmd = NULL;

    qemuimg = virFindFileInPath("kvm-img");
    if (!qemuimg)
        qemuimg = virFindFileInPath("qemu-img");
    if (!qemuimg)
        goto skip;

    if (virAsprintf(&absraw, "%s/raw", datadir) < 0 ||
        virAsprintf(&absqcow2, "%s/qcow2", datadir) < 0 ||
        virAsprintf(&abswrap, "%s/wrap", datadir) < 0 ||
        virAsprintf(&absqed, "%s/qed", datadir) < 0 ||
        virAsprintf(&abslink2, "%s/sub/link2", datadir) < 0) {
        virReportOOMError();
        goto cleanup;
    }

    if (virFileMakePath(datadir "/sub") < 0) {
        fprintf(stderr, "unable to create directory %s\n", datadir "/sub");
        goto cleanup;
    }

    if (chdir(datadir) < 0) {
        fprintf(stderr, "unable to test relative backing chains\n");
        goto cleanup;
    }

    /* I'm lazy enough to use a shell one-liner instead of open/write/close */
    virCommandFree(cmd);
    cmd = virCommandNewArgList("sh", "-c", "printf %1024d 0 > raw", NULL);
    if (virCommandRun(cmd, NULL) < 0) {
        fprintf(stderr, "unable to create raw file\n");
        goto cleanup;
    }
    if (!(canonraw = canonicalize_file_name(absraw))) {
        virReportOOMError();
        goto cleanup;
    }

    /* Create a qcow2 wrapping relative raw; later on, we modify its
     * metadata to test other configurations */
    virCommandFree(cmd);
    cmd = virCommandNewArgList(qemuimg, "create", "-f", "qcow2",
                               "-obacking_file=raw,backing_fmt=raw", "qcow2",
                               NULL);
    if (virCommandRun(cmd, NULL) < 0)
        goto skip;
    /* Make sure our later uses of 'qemu-img rebase' will work */
    virCommandFree(cmd);
    cmd = virCommandNewArgList(qemuimg, "rebase", "-u", "-f", "qcow2",
                               "-F", "raw", "-b", "raw", "qcow2", NULL);
    if (virCommandRun(cmd, NULL) < 0)
        goto skip;
    if (!(canonqcow2 = canonicalize_file_name(absqcow2))) {
        virReportOOMError();
        goto cleanup;
    }

    /* Create a second qcow2 wrapping the first, to be sure that we
     * can correctly avoid insecure probing.  */
    virCommandFree(cmd);
    cmd = virCommandNewArgList(qemuimg, "create", "-f", "qcow2", NULL);
    virCommandAddArgFormat(cmd, "-obacking_file=%s,backing_fmt=qcow2",
                           absqcow2);
    virCommandAddArg(cmd, "wrap");
    if (virCommandRun(cmd, NULL) < 0)
        goto skip;

    /* Create a qed file. */
    virCommandFree(cmd);
    cmd = virCommandNewArgList(qemuimg, "create", "-f", "qed", NULL);
    virCommandAddArgFormat(cmd, "-obacking_file=%s,backing_fmt=raw",
                           absraw);
    virCommandAddArg(cmd, "qed");
    if (virCommandRun(cmd, NULL) < 0)
        goto skip;

    /* Create some symlinks in a sub-directory. */
    if (symlink("../qcow2", datadir "/sub/link1") < 0 ||
        symlink("../wrap", datadir "/sub/link2") < 0) {
        fprintf(stderr, "unable to create symlink");
        goto cleanup;
    }

    ret = 0;
cleanup:
    virCommandFree(cmd);
    if (ret)
        testCleanupImages();
    return ret;

skip:
    fputs("qemu-img is too old; skipping this test\n", stderr);
    ret = EXIT_AM_SKIP;
    goto cleanup;
}
Пример #8
0
static int
qemuCapsInitGuest(virCapsPtr caps,
                  virCapsPtr old_caps,
                  const char *hostmachine,
                  const struct qemu_arch_info *info,
                  int hvm)
{
    virCapsGuestPtr guest;
    int i;
    int haskvm = 0;
    int haskqemu = 0;
    char *kvmbin = NULL;
    char *binary = NULL;
    time_t binary_mtime;
    virCapsGuestMachinePtr *machines = NULL;
    int nmachines = 0;
    struct stat st;
    unsigned int ncpus;
    virBitmapPtr qemuCaps = NULL;
    int ret = -1;

    /* Check for existance of base emulator, or alternate base
     * which can be used with magic cpu choice
     */
    binary = virFindFileInPath(info->binary);

    if (binary == NULL || !virFileIsExecutable(binary)) {
        VIR_FREE(binary);
        binary = virFindFileInPath(info->altbinary);
    }

    /* Can use acceleration for KVM/KQEMU if
     *  - host & guest arches match
     * Or
     *  - hostarch is x86_64 and guest arch is i686
     * The latter simply needs "-cpu qemu32"
     */
    if (STREQ(info->arch, hostmachine) ||
        (STREQ(hostmachine, "x86_64") && STREQ(info->arch, "i686"))) {
        if (access("/dev/kvm", F_OK) == 0) {
            const char *const kvmbins[] = { "/usr/libexec/qemu-kvm", /* RHEL */
                                            "qemu-kvm", /* Fedora */
                                            "kvm" }; /* Upstream .spec */

            for (i = 0; i < ARRAY_CARDINALITY(kvmbins); ++i) {
                kvmbin = virFindFileInPath(kvmbins[i]);

                if (!kvmbin)
                    continue;

                haskvm = 1;
                if (!binary)
                    binary = kvmbin;

                break;
            }
        }

        if (access("/dev/kqemu", F_OK) == 0)
            haskqemu = 1;
    }

    if (!binary)
        return 0;

    /* Ignore binary if extracting version info fails */
    if (qemuCapsExtractVersionInfo(binary, info->arch, NULL, &qemuCaps) < 0) {
        ret = 0;
        goto cleanup;
    }

    if (stat(binary, &st) == 0) {
        binary_mtime = st.st_mtime;
    } else {
        char ebuf[1024];
        VIR_WARN("Failed to stat %s, most peculiar : %s",
                 binary, virStrerror(errno, ebuf, sizeof(ebuf)));
        binary_mtime = 0;
    }

    if (info->machine) {
        virCapsGuestMachinePtr machine;

        if (VIR_ALLOC(machine) < 0) {
            goto no_memory;
        }

        if (!(machine->name = strdup(info->machine))) {
            VIR_FREE(machine);
            goto no_memory;
        }

        nmachines = 1;

        if (VIR_ALLOC_N(machines, nmachines) < 0) {
            VIR_FREE(machine->name);
            VIR_FREE(machine);
            goto no_memory;
        }

        machines[0] = machine;
    } else {
        int probe = 1;
        if (old_caps && binary_mtime)
            probe = !qemuCapsGetOldMachines(hvm ? "hvm" : "xen", info->arch,
                                            info->wordsize, binary, binary_mtime,
                                            old_caps, &machines, &nmachines);
        if (probe &&
            qemuCapsProbeMachineTypes(binary, &machines, &nmachines) < 0)
            goto error;
    }

    /* We register kvm as the base emulator too, since we can
     * just give -no-kvm to disable acceleration if required */
    if ((guest = virCapabilitiesAddGuest(caps,
                                         hvm ? "hvm" : "xen",
                                         info->arch,
                                         info->wordsize,
                                         binary,
                                         NULL,
                                         nmachines,
                                         machines)) == NULL)
        goto error;

    machines = NULL;
    nmachines = 0;

    guest->arch.defaultInfo.emulator_mtime = binary_mtime;

    if (caps->host.cpu &&
        qemuCapsProbeCPUModels(binary, NULL, info->arch, &ncpus, NULL) == 0 &&
        ncpus > 0 &&
        !virCapabilitiesAddGuestFeature(guest, "cpuselection", 1, 0))
        goto error;

    if (qemuCapsGet(qemuCaps, QEMU_CAPS_BOOTINDEX) &&
        !virCapabilitiesAddGuestFeature(guest, "deviceboot", 1, 0))
        goto error;

    if (hvm) {
        if (virCapabilitiesAddGuestDomain(guest,
                                          "qemu",
                                          NULL,
                                          NULL,
                                          0,
                                          NULL) == NULL)
            goto error;

        if (haskqemu &&
            virCapabilitiesAddGuestDomain(guest,
                                          "kqemu",
                                          NULL,
                                          NULL,
                                          0,
                                          NULL) == NULL)
            goto error;

        if (haskvm) {
            virCapsGuestDomainPtr dom;

            if (stat(kvmbin, &st) == 0) {
                binary_mtime = st.st_mtime;
            } else {
                char ebuf[1024];
                VIR_WARN("Failed to stat %s, most peculiar : %s",
                         binary, virStrerror(errno, ebuf, sizeof(ebuf)));
                binary_mtime = 0;
            }

            if (!STREQ(binary, kvmbin)) {
                int probe = 1;
                if (old_caps && binary_mtime)
                    probe = !qemuCapsGetOldMachines("hvm", info->arch, info->wordsize,
                                                    kvmbin, binary_mtime,
                                                    old_caps, &machines, &nmachines);
                if (probe &&
                    qemuCapsProbeMachineTypes(kvmbin, &machines, &nmachines) < 0)
                    goto error;
            }

            if ((dom = virCapabilitiesAddGuestDomain(guest,
                                                     "kvm",
                                                     kvmbin,
                                                     NULL,
                                                     nmachines,
                                                     machines)) == NULL) {
                goto error;
            }

            machines = NULL;
            nmachines = 0;

            dom->info.emulator_mtime = binary_mtime;
        }
    } else {
        if (virCapabilitiesAddGuestDomain(guest,
                                          "kvm",
                                          NULL,
                                          NULL,
                                          0,
                                          NULL) == NULL)
            goto error;
    }

    if (info->nflags) {
        for (i = 0 ; i < info->nflags ; i++) {
            if (virCapabilitiesAddGuestFeature(guest,
                                               info->flags[i].name,
                                               info->flags[i].default_on,
                                               info->flags[i].toggle) == NULL)
                goto error;
        }
    }

    ret = 0;

cleanup:
    if (binary == kvmbin) {
        /* don't double free */
        VIR_FREE(binary);
    } else {
        VIR_FREE(binary);
        VIR_FREE(kvmbin);
    }
    qemuCapsFree(qemuCaps);

    return ret;

no_memory:
    virReportOOMError();

error:
    virCapabilitiesFreeMachines(machines, nmachines);

    goto cleanup;
}
Пример #9
0
static int
testPrepImages(void)
{
    int ret = EXIT_FAILURE;
    virCommandPtr cmd = NULL;
    char *buf = NULL;
    bool compat = false;

    qemuimg = virFindFileInPath("kvm-img");
    if (!qemuimg)
        qemuimg = virFindFileInPath("qemu-img");
    if (!qemuimg)
        goto skip;

    /* Clean up from any earlier failed tests */
    virFileDeleteTree(datadir);

    /* See if qemu-img supports '-o compat=xxx'.  If so, we force the
     * use of both v2 and v3 files; if not, it is v2 only but the test
     * still works. */
    cmd = virCommandNewArgList(qemuimg, "create", "-f", "qcow2",
                               "-o?", "/dev/null", NULL);
    virCommandSetOutputBuffer(cmd, &buf);
    if (virCommandRun(cmd, NULL) < 0)
        goto skip;
    if (strstr(buf, "compat "))
        compat = true;
    VIR_FREE(buf);

    if (virAsprintf(&absraw, "%s/raw", datadir) < 0 ||
        virAsprintf(&absqcow2, "%s/qcow2", datadir) < 0 ||
        virAsprintf(&abswrap, "%s/wrap", datadir) < 0 ||
        virAsprintf(&absqed, "%s/qed", datadir) < 0 ||
        virAsprintf(&absdir, "%s/dir", datadir) < 0 ||
        virAsprintf(&abslink2, "%s/sub/link2", datadir) < 0)
        goto cleanup;

    if (virFileMakePath(datadir "/sub") < 0) {
        fprintf(stderr, "unable to create directory %s\n", datadir "/sub");
        goto cleanup;
    }
    if (virFileMakePath(datadir "/dir") < 0) {
        fprintf(stderr, "unable to create directory %s\n", datadir "/dir");
        goto cleanup;
    }
    if (!(canondir = canonicalize_file_name(absdir))) {
        virReportOOMError();
        goto cleanup;
    }

    if (chdir(datadir) < 0) {
        fprintf(stderr, "unable to test relative backing chains\n");
        goto cleanup;
    }

    if (virAsprintf(&buf, "%1024d", 0) < 0 ||
        virFileWriteStr("raw", buf, 0600) < 0) {
        fprintf(stderr, "unable to create raw file\n");
        goto cleanup;
    }
    if (!(canonraw = canonicalize_file_name(absraw))) {
        virReportOOMError();
        goto cleanup;
    }

    /* Create a qcow2 wrapping relative raw; later on, we modify its
     * metadata to test other configurations */
    virCommandFree(cmd);
    cmd = virCommandNewArgList(qemuimg, "create", "-f", "qcow2", NULL);
    virCommandAddArgFormat(cmd, "-obacking_file=raw,backing_fmt=raw%s",
                           compat ? ",compat=0.10" : "");
    virCommandAddArg(cmd, "qcow2");
    if (virCommandRun(cmd, NULL) < 0)
        goto skip;
    /* Make sure our later uses of 'qemu-img rebase' will work */
    virCommandFree(cmd);
    cmd = virCommandNewArgList(qemuimg, "rebase", "-u", "-f", "qcow2",
                               "-F", "raw", "-b", "raw", "qcow2", NULL);
    if (virCommandRun(cmd, NULL) < 0)
        goto skip;
    if (!(canonqcow2 = canonicalize_file_name(absqcow2))) {
        virReportOOMError();
        goto cleanup;
    }

    /* Create a second qcow2 wrapping the first, to be sure that we
     * can correctly avoid insecure probing.  */
    virCommandFree(cmd);
    cmd = virCommandNewArgList(qemuimg, "create", "-f", "qcow2", NULL);
    virCommandAddArgFormat(cmd, "-obacking_file=%s,backing_fmt=qcow2%s",
                           absqcow2, compat ? ",compat=1.1" : "");
    virCommandAddArg(cmd, "wrap");
    if (virCommandRun(cmd, NULL) < 0)
        goto skip;
    if (!(canonwrap = canonicalize_file_name(abswrap))) {
        virReportOOMError();
        goto cleanup;
    }

    /* Create a qed file. */
    virCommandFree(cmd);
    cmd = virCommandNewArgList(qemuimg, "create", "-f", "qed", NULL);
    virCommandAddArgFormat(cmd, "-obacking_file=%s,backing_fmt=raw",
                           absraw);
    virCommandAddArg(cmd, "qed");
    if (virCommandRun(cmd, NULL) < 0)
        goto skip;
    if (!(canonqed = canonicalize_file_name(absqed))) {
        virReportOOMError();
        goto cleanup;
    }

#ifdef HAVE_SYMLINK
    /* Create some symlinks in a sub-directory. */
    if (symlink("../qcow2", datadir "/sub/link1") < 0 ||
        symlink("../wrap", datadir "/sub/link2") < 0) {
        fprintf(stderr, "unable to create symlink");
        goto cleanup;
    }
#endif

    ret = 0;
 cleanup:
    VIR_FREE(buf);
    virCommandFree(cmd);
    if (ret)
        testCleanupImages();
    return ret;

 skip:
    fputs("qemu-img is too old; skipping this test\n", stderr);
    ret = EXIT_AM_SKIP;
    goto cleanup;
}
Пример #10
0
static virDrvOpenStatus
vmwareOpen(virConnectPtr conn,
           virConnectAuthPtr auth ATTRIBUTE_UNUSED,
           unsigned int flags)
{
    struct vmware_driver *driver;
    char * vmrun = NULL;

    virCheckFlags(VIR_CONNECT_RO, VIR_DRV_OPEN_ERROR);

    if (conn->uri == NULL) {
        /* @TODO accept */
        return VIR_DRV_OPEN_DECLINED;
    } else {
        if (conn->uri->scheme == NULL ||
            (STRNEQ(conn->uri->scheme, "vmwareplayer") &&
             STRNEQ(conn->uri->scheme, "vmwarews")))
            return VIR_DRV_OPEN_DECLINED;

        /* If server name is given, its for remote driver */
        if (conn->uri->server != NULL)
            return VIR_DRV_OPEN_DECLINED;

        /* If path isn't /session, then they typoed, so tell them correct path */
        if (conn->uri->path == NULL || STRNEQ(conn->uri->path, "/session")) {
            virReportError(VIR_ERR_INTERNAL_ERROR,
                           _("unexpected VMware URI path '%s', try vmwareplayer:///session or vmwarews:///session"),
                           NULLSTR(conn->uri->path));
            return VIR_DRV_OPEN_ERROR;
        }
    }

    /* We now know the URI is definitely for this driver, so beyond
     * here, don't return DECLINED, always use ERROR */

    vmrun = virFindFileInPath(VMRUN);

    if (vmrun == NULL) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("%s utility is missing"), VMRUN);
        return VIR_DRV_OPEN_ERROR;
    } else {
        VIR_FREE(vmrun);
    }

    if (VIR_ALLOC(driver) < 0) {
        virReportOOMError();
        return VIR_DRV_OPEN_ERROR;
    }

    if (virMutexInit(&driver->lock) < 0)
        goto cleanup;

    driver->type = STRNEQ(conn->uri->scheme, "vmwareplayer") ?
      TYPE_WORKSTATION : TYPE_PLAYER;

    if (!(driver->domains = virDomainObjListNew()))
        goto cleanup;

    if (!(driver->caps = vmwareCapsInit()))
        goto cleanup;

    driver->caps->privateDataAllocFunc = vmwareDataAllocFunc;
    driver->caps->privateDataFreeFunc = vmwareDataFreeFunc;

    if (vmwareLoadDomains(driver) < 0)
        goto cleanup;

    if (vmwareExtractVersion(driver) < 0)
        goto cleanup;

    conn->privateData = driver;

    return VIR_DRV_OPEN_SUCCESS;

  cleanup:
    vmwareFreeDriver(driver);
    return VIR_DRV_OPEN_ERROR;
};