コード例 #1
0
ファイル: vmware_driver.c プロジェクト: bigclouds/libvirt
static int
vmwareUpdateVMStatus(struct vmware_driver *driver, virDomainObjPtr vm)
{
    virCommandPtr cmd;
    char *outbuf = NULL;
    char *vmxAbsolutePath = NULL;
    char *parsedVmxPath = NULL;
    char *str;
    char *saveptr = NULL;
    bool found = false;
    int oldState = virDomainObjGetState(vm, NULL);
    int newState;
    int ret = -1;

    cmd = virCommandNewArgList(VMRUN, "-T", vmw_types[driver->type],
                               "list", NULL);
    virCommandSetOutputBuffer(cmd, &outbuf);
    if (virCommandRun(cmd, NULL) < 0)
        goto cleanup;

    if (virFileResolveAllLinks(((vmwareDomainPtr) vm->privateData)->vmxPath,
                               &vmxAbsolutePath) < 0)
        goto cleanup;

    for (str = outbuf ; (parsedVmxPath = strtok_r(str, "\n", &saveptr)) != NULL;
         str = NULL) {

        if (parsedVmxPath[0] != '/')
            continue;

        if (STREQ(parsedVmxPath, vmxAbsolutePath)) {
            found = true;
            /* If the vmx path is in the output, the domain is running or
             * is paused but we have no way to detect if it is paused or not. */
            if (oldState == VIR_DOMAIN_PAUSED)
                newState = oldState;
            else
                newState = VIR_DOMAIN_RUNNING;
            break;
        }
    }

    if (!found) {
        vm->def->id = -1;
        newState = VIR_DOMAIN_SHUTOFF;
    }

    virDomainObjSetState(vm, newState, 0);

    ret = 0;

cleanup:
    virCommandFree(cmd);
    VIR_FREE(outbuf);
    VIR_FREE(vmxAbsolutePath);
    return ret;
}
コード例 #2
0
ファイル: virpidfile.c プロジェクト: merijnkr/libvirt
/**
 * virPidFileReadPathIfAlive:
 * @path: path to pidfile
 * @pid: variable to return pid in
 * @binpath: path of executable associated with the pidfile
 *
 * This will attempt to read a pid from @path, and store it
 * in @pid. The @pid will only be set, however, if the
 * pid in @path is running, and its executable path
 * resolves to @binpath. This adds protection against
 * recycling of previously reaped pids.
 *
 * If @binpath is NULL the check for the executable path
 * is skipped.
 *
 * Returns -errno upon error, or zero on successful
 * reading of the pidfile. If the PID was not still
 * alive, zero will be returned, but @pid will be
 * set to -1.
 */
int virPidFileReadPathIfAlive(const char *path,
                              pid_t *pid,
                              const char *binPath)
{
    int ret;
    bool isLink;
    char *procPath = NULL;
    char *procLink = NULL;
    size_t procLinkLen;
    char *resolvedBinPath = NULL;
    char *resolvedProcLink = NULL;
    const char deletedText[] = " (deleted)";
    size_t deletedTextLen = strlen(deletedText);
    pid_t retPid;

    /* only set this at the very end on success */
    *pid = -1;

    if ((ret = virPidFileReadPath(path, &retPid)) < 0)
        goto cleanup;

#ifndef WIN32
    /* Check that it's still alive.  Safe to skip this sanity check on
     * mingw, which lacks kill().  */
    if (kill(retPid, 0) < 0) {
        ret = 0;
        retPid = -1;
        goto cleanup;
    }
#endif

    if (!binPath) {
        /* we only knew the pid, and that pid is alive, so we can
         * return it.
         */
        ret = 0;
        goto cleanup;
    }

    if (virAsprintf(&procPath, "/proc/%lld/exe", (long long)retPid) < 0) {
        ret = -ENOMEM;
        goto cleanup;
    }

    if ((ret = virFileIsLink(procPath)) < 0)
        goto cleanup;
    isLink = ret;

    if (isLink && virFileLinkPointsTo(procPath, binPath)) {
        /* the link in /proc/$pid/exe is a symlink to a file
         * that has the same inode as the file at binpath.
         */
        ret = 0;
        goto cleanup;
    }

    /* Even if virFileLinkPointsTo returns a mismatch, it could be
     * that the binary was deleted/replaced after it was executed. In
     * that case the link in /proc/$pid/exe will contain
     * "$procpath (deleted)".  Read that link, remove the " (deleted)"
     * part, and see if it has the same canonicalized name as binpath.
     */
    if (!(procLink = areadlink(procPath))) {
        ret = -errno;
        goto cleanup;
    }
    procLinkLen = strlen(procLink);
    if (procLinkLen > deletedTextLen)
        procLink[procLinkLen - deletedTextLen] = 0;

    if ((ret = virFileResolveAllLinks(binPath, &resolvedBinPath)) < 0)
        goto cleanup;
    if ((ret = virFileResolveAllLinks(procLink, &resolvedProcLink)) < 0)
        goto cleanup;

    ret = STREQ(resolvedBinPath, resolvedProcLink) ? 0 : -1;

 cleanup:
    VIR_FREE(procPath);
    VIR_FREE(procLink);
    VIR_FREE(resolvedProcLink);
    VIR_FREE(resolvedBinPath);

    /* return the originally set pid of -1 unless we proclaim success */
    if (ret == 0)
        *pid = retPid;
    return ret;
}