Example #1
0
/**
 * virStorageBackendZFSVolModeNeeded:
 *
 * Checks if it's necessary to specify 'volmode' (i.e. that
 * we're working with BSD ZFS implementation).
 *
 * Returns 1 if 'volmode' is need, 0 if not needed, -1 on error
 */
static int
virStorageBackendZFSVolModeNeeded(void)
{
    virCommandPtr cmd = NULL;
    int ret = -1, exit = -1;
    char *error = NULL;

    /* 'zfs get' without arguments prints out
     * usage information to stderr, including
     * list of supported options, and exits with
     * exit code 2
     */
    cmd = virCommandNewArgList(ZFS, "get", NULL);
    virCommandAddEnvString(cmd, "LC_ALL=C");
    virCommandSetErrorBuffer(cmd, &error);

    ret = virCommandRun(cmd, &exit);
    if ((ret < 0) || (exit != 2)) {
        VIR_WARN("Command 'zfs get' either failed "
                 "to run or exited with unexpected status");
        goto cleanup;
    }

    if (strstr(error, " volmode "))
        ret = 1;
    else
        ret = 0;

 cleanup:
    virCommandFree(cmd);
    VIR_FREE(error);
    return ret;
}
Example #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;
}
Example #3
0
int
vmwareExtractVersion(struct vmware_driver *driver)
{
    int ret = -1;
    virCommandPtr cmd = NULL;
    char * outbuf = NULL;
    char *bin = NULL;
    char *vmwarePath = NULL;

    if ((vmwarePath = mdir_name(driver->vmrun)) == NULL)
        goto cleanup;

    switch (driver->type) {
        case VMWARE_DRIVER_PLAYER:
            if (virAsprintf(&bin, "%s/%s", vmwarePath, "vmplayer") < 0)
                goto cleanup;
            break;

        case VMWARE_DRIVER_WORKSTATION:
            if (virAsprintf(&bin, "%s/%s", vmwarePath, "vmware") < 0)
                goto cleanup;
            break;

        case VMWARE_DRIVER_FUSION:
            if (virAsprintf(&bin, "%s/%s", vmwarePath, "vmware-vmx") < 0)
                goto cleanup;
            break;

        default:
            virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                           _("invalid driver type for version detection"));
            goto cleanup;
    }

    cmd = virCommandNewArgList(bin, "-v", NULL);
    virCommandSetOutputBuffer(cmd, &outbuf);
    virCommandSetErrorBuffer(cmd, &outbuf);

    if (virCommandRun(cmd, NULL) < 0)
        goto cleanup;

    if (vmwareParseVersionStr(driver->type, outbuf, &driver->version) < 0)
        goto cleanup;

    ret = 0;

 cleanup:
    virCommandFree(cmd);
    VIR_FREE(outbuf);
    VIR_FREE(bin);
    VIR_FREE(vmwarePath);
    return ret;
}
Example #4
0
char *
virISCSIGetSession(const char *devpath,
                   bool probe)
{
    /*
     * # iscsiadm --mode session
     * tcp: [1] 192.168.122.170:3260,1 demo-tgt-b
     * tcp: [2] 192.168.122.170:3260,1 demo-tgt-a
     *
     * Pull out 2nd and 4th fields
     */
    const char *regexes[] = {
        "^tcp:\\s+\\[(\\S+)\\]\\s+\\S+\\s+(\\S+).*$"
    };
    int vars[] = {
        2,
    };
    struct virISCSISessionData cbdata = {
        .session = NULL,
        .devpath = devpath,
    };
    char *error = NULL;
    int exitstatus = 0;

    virCommandPtr cmd = virCommandNewArgList(ISCSIADM, "--mode",
                                             "session", NULL);
    virCommandSetErrorBuffer(cmd, &error);

    if (virCommandRunRegex(cmd,
                           1,
                           regexes,
                           vars,
                           virISCSIExtractSession,
                           &cbdata, NULL, &exitstatus) < 0)
        goto cleanup;

    if (cbdata.session == NULL && !probe)
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("cannot find iscsiadm session: %s"),
                       NULLSTR(error));

 cleanup:
    VIR_FREE(error);
    virCommandFree(cmd);
    return cbdata.session;
}
Example #5
0
/*
 * qemuTPMEmulatorStop
 * @swtpmStateDir: A directory where the socket is located
 * @shortName: short and unique name of the domain
 *
 * Gracefully stop the swptm
 */
static void
qemuTPMEmulatorStop(const char *swtpmStateDir,
                    const char *shortName)
{
    virCommandPtr cmd;
    char *pathname;
    char *errbuf = NULL;

    if (qemuTPMEmulatorInit() < 0)
        return;

    if (!(pathname = qemuTPMCreateEmulatorSocket(swtpmStateDir, shortName)))
        return;

    if (!virFileExists(pathname))
        goto cleanup;

    cmd = virCommandNew(swtpm_ioctl);
    if (!cmd)
        goto cleanup;

    virCommandAddArgList(cmd, "--unix", pathname, "-s", NULL);

    virCommandSetErrorBuffer(cmd, &errbuf);

    ignore_value(virCommandRun(cmd, NULL));

    virCommandFree(cmd);

    /* clean up the socket */
    unlink(pathname);

 cleanup:
    VIR_FREE(pathname);
    VIR_FREE(errbuf);
}
Example #6
0
/**
 * qemuCreateInBridgePortWithHelper:
 * @cfg: the configuration object in which the helper name is looked up
 * @brname: the bridge name
 * @ifname: the returned interface name
 * @macaddr: the returned MAC address
 * @tapfd: file descriptor return value for the new tap device
 * @flags: OR of virNetDevTapCreateFlags:

 *   VIR_NETDEV_TAP_CREATE_VNET_HDR
 *     - Enable IFF_VNET_HDR on the tap device
 *
 * This function creates a new tap device on a bridge using an external
 * helper.  The final name for the bridge will be stored in @ifname.
 *
 * Returns 0 in case of success or -1 on failure
 */
static int
qemuCreateInBridgePortWithHelper(virQEMUDriverConfigPtr cfg,
                                 const char *brname,
                                 char **ifname,
                                 int *tapfd,
                                 unsigned int flags)
{
    virCommandPtr cmd;
    char *errbuf = NULL, *cmdstr = NULL;
    int pair[2] = { -1, -1 };

    if ((flags & ~VIR_NETDEV_TAP_CREATE_VNET_HDR) != VIR_NETDEV_TAP_CREATE_IFUP)
        return -1;

    if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) < 0) {
        virReportSystemError(errno, "%s", _("failed to create socket"));
        return -1;
    }

    if (!virFileIsExecutable(cfg->bridgeHelperName)) {
        virReportSystemError(errno, _("'%s' is not a suitable bridge helper"),
                             cfg->bridgeHelperName);
        return -1;
    }

    cmd = virCommandNew(cfg->bridgeHelperName);
    if (flags & VIR_NETDEV_TAP_CREATE_VNET_HDR)
        virCommandAddArgFormat(cmd, "--use-vnet");
    virCommandAddArgFormat(cmd, "--br=%s", brname);
    virCommandAddArgFormat(cmd, "--fd=%d", pair[1]);
    virCommandSetErrorBuffer(cmd, &errbuf);
    virCommandDoAsyncIO(cmd);
    virCommandPassFD(cmd, pair[1],
                     VIR_COMMAND_PASS_FD_CLOSE_PARENT);
    virCommandClearCaps(cmd);
#ifdef CAP_NET_ADMIN
    virCommandAllowCap(cmd, CAP_NET_ADMIN);
#endif
    if (virCommandRunAsync(cmd, NULL) < 0) {
        *tapfd = -1;
        goto cleanup;
    }

    do {
        *tapfd = recvfd(pair[0], 0);
    } while (*tapfd < 0 && errno == EINTR);

    if (*tapfd < 0) {
        char ebuf[1024];
        char *errstr = NULL;

        if (!(cmdstr = virCommandToString(cmd)))
            goto cleanup;
        virCommandAbort(cmd);

        if (errbuf && *errbuf &&
            virAsprintf(&errstr, "\nstderr=%s", errbuf) < 0)
            goto cleanup;

        virReportError(VIR_ERR_INTERNAL_ERROR,
            _("%s: failed to communicate with bridge helper: %s%s"),
            cmdstr, virStrerror(errno, ebuf, sizeof(ebuf)),
            errstr ? errstr : "");
        VIR_FREE(errstr);
        goto cleanup;
    }

    if (virNetDevTapGetName(*tapfd, ifname) < 0 ||
        virCommandWait(cmd, NULL) < 0) {
        VIR_FORCE_CLOSE(*tapfd);
        *tapfd = -1;
    }

 cleanup:
    VIR_FREE(cmdstr);
    VIR_FREE(errbuf);
    virCommandFree(cmd);
    VIR_FORCE_CLOSE(pair[0]);
    return *tapfd < 0 ? -1 : 0;
}
Example #7
0
/*
 * qemuExtTPMStartEmulator:
 *
 * @driver: QEMU driver
 * @def: domain definition
 * @logCtxt: log context
 *
 * Start the external TPM Emulator:
 * - have the command line built
 * - start the external TPM Emulator and sync with it before QEMU start
 */
static int
qemuExtTPMStartEmulator(virQEMUDriverPtr driver,
                        virDomainDefPtr def,
                        qemuDomainLogContextPtr logCtxt)
{
    int ret = -1;
    virCommandPtr cmd = NULL;
    int exitstatus = 0;
    char *errbuf = NULL;
    virQEMUDriverConfigPtr cfg;
    virDomainTPMDefPtr tpm = def->tpm;
    char *shortName = virDomainDefGetShortName(def);
    int cmdret = 0, timeout, rc;
    pid_t pid;

    if (!shortName)
        return -1;

    cfg = virQEMUDriverGetConfig(driver);

    /* stop any left-over TPM emulator for this VM */
    qemuTPMEmulatorStop(cfg->swtpmStateDir, shortName);

    if (!(cmd = qemuTPMEmulatorBuildCommand(tpm, def->name, def->uuid,
                                            driver->privileged,
                                            cfg->swtpm_user,
                                            cfg->swtpm_group,
                                            cfg->swtpmStateDir, shortName)))
        goto cleanup;

    if (qemuExtDeviceLogCommand(logCtxt, cmd, "TPM Emulator") < 0)
        goto cleanup;

    virCommandSetErrorBuffer(cmd, &errbuf);

    if (qemuSecurityStartTPMEmulator(driver, def, cmd,
                                     cfg->swtpm_user, cfg->swtpm_group,
                                     &exitstatus, &cmdret) < 0)
        goto cleanup;

    if (cmdret < 0 || exitstatus != 0) {
        virReportError(VIR_ERR_INTERNAL_ERROR,
                       _("Could not start 'swtpm'. exitstatus: %d, "
                         "error: %s"), exitstatus, errbuf);
        goto cleanup;
    }

    /* check that the swtpm has written its pid into the file */
    timeout = 1000; /* ms */
    while (timeout > 0) {
        rc = qemuTPMEmulatorGetPid(cfg->swtpmStateDir, shortName, &pid);
        if (rc < 0) {
            timeout -= 50;
            usleep(50 * 1000);
            continue;
        }
        if (rc == 0 && pid == (pid_t)-1)
            goto error;
        break;
    }
    if (timeout <= 0)
        goto error;

    ret = 0;

 cleanup:
    VIR_FREE(shortName);
    VIR_FREE(errbuf);
    virCommandFree(cmd);

    virObjectUnref(cfg);

    return ret;

 error:
    virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
                   _("swtpm failed to start"));
    goto cleanup;
}