Exemplo n.º 1
0
/*
 * qemuTPMEmulatorGetPid
 *
 * @swtpmStateDir: the directory where swtpm writes the pidfile into
 * @shortName: short name of the domain
 * @pid: pointer to pid
 *
 * Return -errno upon error, or zero on successful reading of the pidfile.
 * If the PID was not still alive, zero will be returned, and @pid will be
 * set to -1;
 */
static int
qemuTPMEmulatorGetPid(const char *swtpmStateDir,
                      const char *shortName,
                      pid_t *pid)
{
    int ret;
    char *pidfile = qemuTPMEmulatorCreatePidFilename(swtpmStateDir,
                                                     shortName);
    if (!pidfile)
        return -ENOMEM;

    ret = virPidFileReadPathIfAlive(pidfile, pid, swtpm_path);

    VIR_FREE(pidfile);

    return ret;
}
Exemplo n.º 2
0
/**
 * virPidFileReadIfAlive:
 * @dir: directory containing pidfile
 * @name: base filename of pidfile
 * @pid: variable to return pid in
 * @binpath: path of executable associated with the pidfile
 *
 * This will attempt to read a pid from the pidfile @name
 * in directory @dir, and store it in @pid. The @pid will
 * only be set, however, if the pid in @name is running,
 * and its executable path resolves to @binpath. This adds
 * protection against recycling of previously reaped pids.
 *
 * 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 virPidFileReadIfAlive(const char *dir,
                          const char *name,
                          pid_t *pid,
                          const char *binpath)
{
    int rc = 0;
    char *pidfile = NULL;

    if (name == NULL || dir == NULL) {
        rc = -EINVAL;
        goto cleanup;
    }

    if (!(pidfile = virPidFileBuildPath(dir, name))) {
        rc = -ENOMEM;
        goto cleanup;
    }

    rc = virPidFileReadPathIfAlive(pidfile, pid, binpath);

cleanup:
    VIR_FREE(pidfile);
    return rc;
}
Exemplo n.º 3
0
/**
 * Verify and create a lock file for a character device
 *
 * @dev Path of the character device
 *
 * Returns 0 on success, -1 on error
 */
static int virChrdevLockFileCreate(const char *dev)
{
    char *path = NULL;
    int ret = -1;
    int lockfd = -1;
    char *pidStr = NULL;
    pid_t pid;

    /* build lock file path */
    if (!(path = virChrdevLockFilePath(dev)))
        goto cleanup;

    /* check if a log file and process holding the lock still exists */
    if (virPidFileReadPathIfAlive(path, &pid, NULL) == 0 && pid >= 0) {
        /* the process exists, the lockfile is valid */
        virReportError(VIR_ERR_OPERATION_FAILED,
                       _("Requested device '%s' is locked by "
                         "lock file '%s' held by process %lld"),
                       dev, path, (long long) pid);
        goto cleanup;
    } else {
        /* clean up the stale/corrupted/nonexistent lockfile */
        unlink(path);
    }
    /* lockfile doesn't (shouldn't) exist */

    /* ensure correct format according to filesystem hierarchy standard */
    /* http://www.pathname.com/fhs/pub/fhs-2.3.html#VARLOCKLOCKFILES */
    if (virAsprintf(&pidStr, "%10lld\n", (long long) getpid()) < 0)
        goto cleanup;

    /* create the lock file */
    if ((lockfd = open(path, O_WRONLY | O_CREAT | O_EXCL, 00644)) < 0) {
        /* If we run in session mode, we might have no access to the lock
         * file directory. We have to check for an permission denied error
         * and see if we can reach it. This should cause an error only if
         * we run in daemon mode and thus privileged.
         */
        if (errno == EACCES && geteuid() != 0) {
            VIR_DEBUG("Skipping lock file creation for device '%s in path '%s'.",
                      dev, path);
            ret = 0;
            goto cleanup;
        }
        virReportSystemError(errno,
                             _("Couldn't create lock file for "
                               "device '%s' in path '%s'"),
                             dev, path);
        goto cleanup;
    }

    /* write the pid to the file */
    if (safewrite(lockfd, pidStr, strlen(pidStr)) < 0) {
        virReportSystemError(errno,
                             _("Couldn't write to lock file for "
                               "device '%s' in path '%s'"),
                             dev, path);
        VIR_FORCE_CLOSE(lockfd);
        unlink(path);
        goto cleanup;
    }

    /* we hold the lock */
    ret = 0;

cleanup:
    VIR_FORCE_CLOSE(lockfd);
    VIR_FREE(path);
    VIR_FREE(pidStr);

    return ret;
}