Beispiel #1
0
Datei: misc.c Projekt: 50wu/gpdb
/*
 * Functions to send signals to other backends.
 */
static bool
pg_signal_backend(int pid, int sig)
{
	if (!superuser())
		ereport(ERROR,
				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
			(errmsg("must be superuser to signal other server processes"))));

	if (!IsBackendPid(pid))
	{
		/*
		 * This is just a warning so a loop-through-resultset will not abort
		 * if one backend terminated on it's own during the run
		 */
		ereport(WARNING,
				(errmsg("PID %d is not a PostgreSQL server process", pid)));
		return false;
	}

	/* If we have setsid(), signal the backend's whole process group */
#ifdef HAVE_SETSID
	if (kill(-pid, sig))
#else
	if (kill(pid, sig))
#endif
	{
		/* Again, just a warning to allow loops */
		ereport(WARNING,
				(errmsg("could not send signal to process %d: %m", pid)));
		return false;
	}
	return true;
}
Beispiel #2
0
static int
pg_signal_backend(int pid, int sig)
{
	PGPROC	   *proc;

	if (!superuser())
	{
		/*
		 * Since the user is not superuser, check for matching roles. Trust
		 * that BackendPidGetProc will return NULL if the pid isn't valid,
		 * even though the check for whether it's a backend process is below.
		 * The IsBackendPid check can't be relied on as definitive even if it
		 * was first. The process might end between successive checks
		 * regardless of their order. There's no way to acquire a lock on an
		 * arbitrary process to prevent that. But since so far all the callers
		 * of this mechanism involve some request for ending the process
		 * anyway, that it might end on its own first is not a problem.
		 */
		proc = BackendPidGetProc(pid);

		if (proc == NULL || proc->roleId != GetUserId())
			return SIGNAL_BACKEND_NOPERMISSION;
	}

	if (!IsBackendPid(pid))
	{
		/*
		 * This is just a warning so a loop-through-resultset will not abort
		 * if one backend terminated on it's own during the run
		 */
		ereport(WARNING,
				(errmsg("PID %d is not a PostgreSQL server process", pid)));
		return SIGNAL_BACKEND_ERROR;
	}

	/*
	 * Can the process we just validated above end, followed by the pid being
	 * recycled for a new process, before reaching here?  Then we'd be trying
	 * to kill the wrong thing.  Seems near impossible when sequential pid
	 * assignment and wraparound is used.  Perhaps it could happen on a system
	 * where pid re-use is randomized.	That race condition possibility seems
	 * too unlikely to worry about.
	 */

	/* If we have setsid(), signal the backend's whole process group */
#ifdef HAVE_SETSID
	if (kill(-pid, sig))
#else
	if (kill(pid, sig))
#endif
	{
		/* Again, just a warning to allow loops */
		ereport(WARNING,
				(errmsg("could not send signal to process %d: %m", pid)));
		return SIGNAL_BACKEND_ERROR;
	}
	return SIGNAL_BACKEND_SUCCESS;
}