add openGauss 3.1.0 feature code

This commit is contained in:
yanghao
2022-09-03 16:22:35 +08:00
parent 801d945a3d
commit b919f404e8
2759 changed files with 521358 additions and 366321 deletions

View File

@ -41,12 +41,12 @@
#include "postmaster/autovacuum.h"
#include "postmaster/postmaster.h"
#include "postmaster/snapcapturer.h"
#include "postmaster/cfs_shrinker.h"
#include "postmaster/rbcleaner.h"
#include "storage/smgr/fd.h"
#include "storage/ipc.h"
#include "storage/pg_shmem.h"
#include "storage/proc.h"
#include "storage/procarray.h"
#include "utils/builtins.h"
#include "utils/guc.h"
#include "utils/memutils.h"
@ -72,6 +72,8 @@
#define INIT_SESSION_MAX_INT32_BUFF 20
#define InvalidPid ((pid_t)(-1))
Alarm alarmItemTooManyDbUserConn[1] = {ALM_AI_Unknown, ALM_AS_Normal, 0, 0, 0, 0, {0}, {0}, NULL};
/* ----------------------------------------------------------------
@ -340,6 +342,24 @@ Oid GetCurrentUserId(void)
return u_sess->misc_cxt.CurrentUserId;
}
Oid GetOldUserId(bool isReceive)
{
if (isReceive) {
return u_sess->misc_cxt.RecOldUserId;
} else {
return u_sess->misc_cxt.SendOldUserId;
}
}
void SetOldUserId(Oid userId, bool isReceive)
{
if (isReceive) {
u_sess->misc_cxt.RecOldUserId = userId;
} else {
u_sess->misc_cxt.SendOldUserId = userId;
}
}
/*
* GetOuterUserId/SetOuterUserId - get/set the outer-level user ID.
*/
@ -674,15 +694,21 @@ static void RegisterNodeGroupCacheCallback()
* with guc.c's internal state, so SET ROLE has to be disallowed.
*
* SECURITY_RESTRICTED_OPERATION indicates that we are inside an operation
* that does not wish to trust called user-defined functions at all. This
* bit prevents not only SET ROLE, but various other changes of session state
* that normally is unprotected but might possibly be used to subvert the
* calling session later. An example is replacing an existing prepared
* statement with new code, which will then be executed with the outer
* session's permissions when the prepared statement is next used. Since
* these restrictions are fairly draconian, we apply them only in contexts
* where the called functions are really supposed to be side-effect-free
* anyway, such as VACUUM/ANALYZE/REINDEX.
* that does not wish to trust called user-defined functions at all. The
* policy is to use this before operations, e.g. autovacuum and REINDEX, that
* enumerate relations of a database or schema and run functions associated
* with each found relation. The relation owner is the new user ID. Set this
* as soon as possible after locking the relation. Restore the old user ID as
* late as possible before closing the relation; restoring it shortly after
* close is also tolerable. If a command has both relation-enumerating and
* non-enumerating modes, e.g. ANALYZE, both modes set this bit. This bit
* prevents not only SET ROLE, but various other changes of session state that
* normally is unprotected but might possibly be used to subvert the calling
* session later. An example is replacing an existing prepared statement with
* new code, which will then be executed with the outer session's permissions
* when the prepared statement is next used. These restrictions are fairly
* draconian, but the functions called in relation-enumerating operations are
* really supposed to be side-effect-free anyway.
*
* Unlike GetUserId, GetUserIdAndSecContext does *not* Assert that the current
* value of u_sess->misc_cxt.CurrentUserId is valid; nor does SetUserIdAndSecContext require
@ -721,6 +747,21 @@ bool InSecurityRestrictedOperation(void)
return (u_sess->misc_cxt.SecurityRestrictionContext & SECURITY_RESTRICTED_OPERATION) != 0;
}
/*
* InReceivingLocalUserIdChange - are we inside a dn get cn's userid change?
*/
bool InReceivingLocalUserIdChange()
{
return (u_sess->misc_cxt.SecurityRestrictionContext & RECEIVER_LOCAL_USERID_CHANGE) != 0;
}
/*
* InSendingLocalUserIdChange - are we inside cn send user to dn change?
*/
bool InSendingLocalUserIdChange()
{
return (u_sess->misc_cxt.SecurityRestrictionContext & SENDER_LOCAL_USERID_CHANGE) != 0;
}
/*
* These are obsolete versions of Get/SetUserIdAndSecContext that are
* only provided for bug-compatibility with some rather dubious code in
@ -968,13 +1009,14 @@ void InitializeSessionUserIdStandalone(void)
*/
#ifdef ENABLE_MULTIPLE_NODES
AssertState(!IsUnderPostmaster || IsAutoVacuumWorkerProcess() || IsJobSchedulerProcess() || IsJobWorkerProcess() ||
AM_WAL_SENDER || IsTxnSnapCapturerProcess() || IsTxnSnapWorkerProcess() || IsUndoWorkerProcess() ||
AM_WAL_SENDER || IsTxnSnapCapturerProcess() || IsTxnSnapWorkerProcess() || IsUndoWorkerProcess() || IsCfsShrinkerProcess() ||
CompactionProcess::IsTsCompactionProcess() || IsRbCleanerProcess() || IsRbWorkerProcess() ||
t_thrd.role == PARALLEL_DECODE || t_thrd.role == LOGICAL_READ_RECORD);
#else /* ENABLE_MULTIPLE_NODES */
AssertState(!IsUnderPostmaster || IsAutoVacuumWorkerProcess() || IsJobSchedulerProcess() || IsJobWorkerProcess() ||
AM_WAL_SENDER || IsTxnSnapCapturerProcess() || IsTxnSnapWorkerProcess() || IsUndoWorkerProcess() || IsRbCleanerProcess() ||
IsRbWorkerProcess() || t_thrd.role == PARALLEL_DECODE || t_thrd.role == LOGICAL_READ_RECORD);
AM_WAL_SENDER || IsTxnSnapCapturerProcess() || IsTxnSnapWorkerProcess() || IsUndoWorkerProcess() ||
IsRbCleanerProcess() || IsCfsShrinkerProcess() ||
IsRbWorkerProcess() || t_thrd.role == PARALLEL_DECODE || t_thrd.role == LOGICAL_READ_RECORD);
#endif /* ENABLE_MULTIPLE_NODES */
/* In pooler stateless reuse mode, to reset session userid */
@ -1173,6 +1215,41 @@ static void CreatePidLockFile(const char* filename)
on_proc_exit(UnLockPidLockFile, Int32GetDatum(fd));
}
/* Get tgid of input process id */
pid_t getProcessTgid(pid_t pid)
{
#define TGID_ITEM_NUM 2
char pid_path[MAXPGPATH];
FILE *fp = NULL;
char getBuff[MAXPGPATH];
char paraName[MAXPGPATH];
pid_t tgid = InvalidPid;
int rc;
rc = snprintf_s(pid_path, MAXPGPATH, MAXPGPATH - 1, "/proc/%d/status", pid);
securec_check_ss(rc, "\0", "\0");
/* may fail because of ENOENT or privilege */
fp = fopen(pid_path, "r");
if (fp == NULL) {
return InvalidPid;
}
/* parse process's status file */
while (fgets(getBuff, MAXPGPATH, fp) != NULL) {
if (strstr(getBuff, "Tgid:") != NULL &&
sscanf_s(getBuff, "%s %d", paraName, MAXPGPATH, &tgid) == TGID_ITEM_NUM) {
break;
} else {
tgid = InvalidPid;
}
}
(void)fclose(fp);
return tgid;
}
/*
* Create a lockfile.
*
@ -1188,6 +1265,7 @@ static void CreateLockFile(const char* filename, bool amPostmaster, bool isDDLoc
int len;
int encoded_pid;
pid_t other_pid;
pid_t other_tgid;
pid_t my_pid, my_p_pid, my_gp_pid;
const char* envvar = NULL;
@ -1304,6 +1382,8 @@ static void CreateLockFile(const char* filename, bool amPostmaster, bool isDDLoc
buffer)));
}
other_tgid = getProcessTgid(other_pid);
/*
* Check to see if the other process still exists
*
@ -1329,7 +1409,8 @@ static void CreateLockFile(const char* filename, bool amPostmaster, bool isDDLoc
* someone else, at least on machines where /tmp hasn't got a
* stickybit.)
*/
if (other_pid != my_pid && other_pid != my_p_pid && other_pid != my_gp_pid) {
if (other_pid != my_pid && other_pid != my_p_pid && other_pid != my_gp_pid &&
(other_tgid == InvalidPid || (other_tgid != my_pid && other_tgid != my_p_pid && other_tgid != my_gp_pid))) {
if (kill(other_pid, 0) == 0 || (errno != ESRCH && errno != EPERM)) {
/* lockfile belongs to a live process */
#ifndef WIN32