Browse Source

#IQRV #comment [Guardian] 优化监护进程与SpShell的退出启动关系

gifur 4 years ago
parent
commit
ed674e8bb1
1 changed files with 153 additions and 15 deletions
  1. 153 15
      Tool/guardian/guardian.cpp

+ 153 - 15
Tool/guardian/guardian.cpp

@@ -8,6 +8,7 @@
 #include <sys/epoll.h>
 #include <netinet/in.h>
 #include <arpa/inet.h>
+#include <assert.h>
 #include <dirent.h>
 #include <fcntl.h>
 #include <unistd.h>
@@ -23,7 +24,10 @@
 #include <sys/wait.h>
 
 #include "toolkit.h"
+#include "osutil.h"
+#include "memutil.h"
 #include <winpr/library.h>
+#include <winpr/synch.h>
 
 int epfd;
 struct epoll_event ev;
@@ -55,6 +59,20 @@ struct epoll_event ev;
 	#define MAX_PATH 260
 #endif
 
+#ifdef RVC_OS_WIN
+static char spshell_execute_name[] = "SpShell.exe";
+static char sphost_execute_name[] = "SpHost.exe";
+static char guardian_execute_name[] = "Guardian.exe";
+static char cefclient_execute_name[] = "cefclient.exe";
+#else
+static char spshell_execute_name[] = "spshell";
+static char sphost_execute_name[] = "sphost";
+static char guardian_execute_name[] = "guardian";
+static char cefclient_execute_name[] = "cefclient";
+#endif //_WIN32
+char* relate_processes[] = { spshell_execute_name };
+char* relate_processes_ex[] = { spshell_execute_name, sphost_execute_name, cefclient_execute_name };
+
 using namespace std;
 #define  NET_TYPE_WIRELESS  1
 #define  NET_TYPE_ETHERNET  2
@@ -66,18 +84,19 @@ typedef DWORD(*pWlanConnect)(BOOL bConnect, int nType);
 typedef DWORD (*pDisableBluetooth)(BOOL bDisable);
 
 #ifdef linux
-int g_sListen;
-pthread_mutex_t g_cs, g_cs_event, g_cs_log;
-#define EnterCriticalSectionRVC(xType) pthread_mutex_lock(&xType)
-#define LeaveCriticalSectionRVC(xType) pthread_mutex_unlock(&xType)
+	int g_sListen;
+	pthread_mutex_t g_cs, g_cs_event, g_cs_log;
+	#define EnterCriticalSectionRVC(xType) pthread_mutex_lock(&xType)
+	#define LeaveCriticalSectionRVC(xType) pthread_mutex_unlock(&xType)
 #else
-SOCKET g_sListen = INVALID_SOCKET;
-#pragma comment (lib, "Ws2_32.lib")
-unsigned int __stdcall DoNetControl(void *pData);
-CRITICAL_SECTION g_cs,g_cs_event,g_cs_log;
-#define EnterCriticalSectionRVC(xType) EnterCriticalSection(&xType)
-#define LeaveCriticalSectionRVC(xType) LeaveCriticalSection(&xType)
+	SOCKET g_sListen = INVALID_SOCKET;
+	#pragma comment (lib, "Ws2_32.lib")
+	unsigned int __stdcall DoNetControl(void* pData);
+	CRITICAL_SECTION g_cs, g_cs_event, g_cs_log;
+	#define EnterCriticalSectionRVC(xType) EnterCriticalSection(&xType)
+	#define LeaveCriticalSectionRVC(xType) LeaveCriticalSection(&xType)
 #endif //linux
+
 //unsigned int __stdcall DoLog(void *pData);
 const int DEFAULT_BUFLEN = 512;
 const int SHAKEHAND_BUFZIE = 32;
@@ -99,6 +118,8 @@ const int MAX_WAIT_TIME_TO_RESTART_UPGRADE = 110000;
 int g_startDay = 0;
 //HANDLE g_logHandle;
 char g_allMsg[1024];
+static int g_SpShellPID = 0;
+
 #ifdef linux
 extern "C"
 {
@@ -114,7 +135,6 @@ typedef struct
 	CHAR Buffer[DATA_BUFSIZE];
 } PER_IO_OPERATION_DATA, * LPPER_IO_OPERATION_DATA;
 
-
 typedef struct 
 {
 	SOCKET Socket;
@@ -311,19 +331,91 @@ bool VersionRollback()
 
 	return true;
 }
+
+#ifndef _WIN32
+static int GetSpshellProcID()
+{
+	int result(0);
+    char* spshell[] = { spshell_execute_name };
+    alive_process_info processes[1];
+    memset(processes, 0, sizeof(processes));
+    int count = 1;
+	if (!osutil_detect_unique_app(spshell, array_size(spshell), &count, processes)) {
+		result = processes[0].pid;
+	}
+	return result;
+}
+
+static void ComfirmSpShellDead()
+{
+    char* spshell[] = { spshell_execute_name };
+    alive_process_info processes[1];
+    memset(processes, 0, sizeof(processes));
+    int count = 1;
+    if (!osutil_detect_unique_app(spshell, array_size(spshell), &count, processes)) {
+        g_SpShellPID = processes[0].pid;
+        LogSingleMsg("has spshell process alive! and to kill it", 0);
+        assert(count > 0);
+        if (kill(processes[0].pid, SIGTERM) != 0) {
+            LogToFile(false, true, true, "kill with term for spshell failed", NULL, processes[0].pid, errno, 0);
+            if (errno != 3 /**not exit */) {
+                LogSingleMsg("to kill stronglely!");
+                kill(processes[0].pid, SIGKILL);
+            }
+        } else {
+            LogToFile(false, true, false, "kill with term for spshell succ.", NULL, processes[0].pid);
+        }
+
+        const int waitTimes = 100;
+        const int eachTime = 300;
+        int curTimes = 0;
+        while (g_SpShellPID != 0 && curTimes < waitTimes) {
+			if (osutil_detect_unique_app(spshell, array_size(spshell), NULL, NULL)) {
+				g_SpShellPID = 0;
+				break;
+			}
+            Sleep(eachTime);
+            curTimes++;
+        }
+
+        if (g_SpShellPID == 0) {
+            LogSingleMsg("spshell has gone!");
+        }
+
+    } else {
+        LogSingleMsg("There are no any spshell process existed!", 0);
+    }
+
+    //////////////////////////////////////////////////////////////////////////
+    count = MAX_ALIVE_PROCESS_COUNT;
+    alive_process_info processes2[MAX_ALIVE_PROCESS_COUNT];
+    memset(processes2, 0, sizeof(processes2));
+    if (!osutil_detect_unique_app(relate_processes_ex, array_size(relate_processes_ex), &count, processes2)) {
+        for (int i = 0; i < count; ++i) {
+            LogToFile(true, true, false, processes2[i].name, processes2[i].path, processes2[i].pid);
+        }
+        osutil_terminate_related_process(relate_processes_ex, array_size(relate_processes_ex));
+        Sleep(1000);
+    }
+}
+
+#endif //NOT _WIN32
+
 int FrameworkShutdown(bool bUpgrade=false,bool bRestart = true)
 {
 	cout << "in FrameworkShutdown,bUpgrade:" << bUpgrade << ",bRestart:" << bRestart <<  endl;
 	if (!bUpgrade)
 		g_dwTimeBegin = GetTickCountRVC();
 	NetControl();
+
 #ifdef linux
+
 	//todo oiltestlinux
-	LogSingleMsg("to kill spshell");
+	LogSingleMsg("to kill spshell", 0);
 	ServerReportEvent("FrameworkShutdown linux");
-	system("killall -9 sphost");
-	system("killall -9 spshell");
-	sleep(2);
+
+	ComfirmSpShellDead();
+
 	char tmp[MAX_PATH];
 	char* pos = NULL;
 	GetModuleFileNameA(NULL, tmp, MAX_PATH);
@@ -342,6 +434,9 @@ int FrameworkShutdown(bool bUpgrade=false,bool bRestart = true)
         if (0 == process_spawn(&option, &process)) {
             FREE(process);
 			LogSingleMsg("run spexplorer.sh scripts succ.");
+			Sleep(1000);
+			g_SpShellPID = GetSpshellProcID();
+			LogToFile(false, true, false, "get spshell proc id", NULL, g_SpShellPID);
             return 0;
 		} else {
 			FREE(process);
@@ -588,6 +683,8 @@ void DataProcessLinux(int socket,const char*data)
 		if (!g_bFrameOnline)
 		{
 			g_bFrameOnline = true;
+            g_SpShellPID = GetSpshellProcID();
+            LogToFile(false, true, false, "get spshell proc id", NULL, g_SpShellPID);
 			StartDoNetControlRVC();
 		}
 		int rc, err;
@@ -615,6 +712,8 @@ void DataProcessLinux(int socket,const char*data)
 		if (!g_bFrameOnline)
 		{
 			g_bFrameOnline = true;
+            g_SpShellPID = GetSpshellProcID();
+            LogToFile(false, true, false, "get spshell proc id", NULL, g_SpShellPID);
 			//_beginthreadex(NULL,0,DoNetControl,NULL,0,NULL);
 			StartDoNetControlRVC();
 		}
@@ -625,6 +724,8 @@ void DataProcessLinux(int socket,const char*data)
 		if (!g_bFrameOnline)
 		{
 			g_bFrameOnline = true;
+            g_SpShellPID = GetSpshellProcID();
+            LogToFile(false, true, false, "get spshell proc id", NULL, g_SpShellPID);
 			//_beginthreadex(NULL,0,DoNetControl,NULL,0,NULL);
 			StartDoNetControlRVC();
 		}
@@ -657,6 +758,8 @@ void DataProcessLinux(int socket,const char*data)
 			LogSingleMsg("framework is starting...");
 			cout << "framework is starting..." << endl;
 			g_bFrameOnline = true;
+            g_SpShellPID = GetSpshellProcID();
+            LogToFile(false, true, false, "get spshell proc id", NULL, g_SpShellPID);
 			g_bAuthSuc = false;
 			//_beginthreadex(NULL,0,DoNetControl,NULL,0,NULL);
 			StartDoNetControlRVC();
@@ -673,6 +776,8 @@ void DataProcessLinux(int socket,const char*data)
 		if (!g_bFrameOnline)
 		{
 			g_bFrameOnline = true;
+            g_SpShellPID = GetSpshellProcID();
+            LogToFile(false, true, false, "get spshell proc id", NULL, g_SpShellPID);
 			//_beginthreadex(NULL,0,DoNetControl,NULL,0,NULL);
 			StartDoNetControlRVC();
 		}
@@ -713,6 +818,8 @@ void DataProcessLinux(int socket,const char*data)
 		if (!g_bFrameOnline)
 		{
 			g_bFrameOnline = true;
+            g_SpShellPID = GetSpshellProcID();
+            LogToFile(false, true, false, "get spshell proc id", NULL, g_SpShellPID);
 			//_beginthreadex(NULL,0,DoNetControl,NULL,0,NULL);
 			StartDoNetControlRVC();
 		}
@@ -740,6 +847,10 @@ void DataProcess(LPPER_HANDLE_DATA pPerHandleData,LPPER_IO_OPERATION_DATA pPerIo
 			if (!g_bFrameOnline)
 			{
 				g_bFrameOnline = true;
+#ifndef _WIN32
+                g_SpShellPID = GetSpshellProcID();
+                LogToFile(false, true, false, "get spshell proc id", NULL, g_SpShellPID);
+#endif //NOT _WIN32
 				StartDoNetControlRVC();
 			}
 			int rc,err;
@@ -767,6 +878,10 @@ void DataProcess(LPPER_HANDLE_DATA pPerHandleData,LPPER_IO_OPERATION_DATA pPerIo
 			if (!g_bFrameOnline)
 			{
 				g_bFrameOnline = true;
+#ifndef _WIN32
+                g_SpShellPID = GetSpshellProcID();
+                LogToFile(false, true, false, "get spshell proc id", NULL, g_SpShellPID);
+#endif //NOT _WIN32
 				//_beginthreadex(NULL,0,DoNetControl,NULL,0,NULL);
 				StartDoNetControlRVC();
 			}
@@ -777,6 +892,10 @@ void DataProcess(LPPER_HANDLE_DATA pPerHandleData,LPPER_IO_OPERATION_DATA pPerIo
 			if (!g_bFrameOnline)
 			{
 				g_bFrameOnline = true;
+#ifndef _WIN32
+                g_SpShellPID = GetSpshellProcID();
+                LogToFile(false, true, false, "get spshell proc id", NULL, g_SpShellPID);
+#endif //NOT _WIN32
 				//_beginthreadex(NULL,0,DoNetControl,NULL,0,NULL);
 				StartDoNetControlRVC();
 			}
@@ -800,6 +919,10 @@ void DataProcess(LPPER_HANDLE_DATA pPerHandleData,LPPER_IO_OPERATION_DATA pPerIo
 			{
 				LogSingleMsg("framework is starting...");
 				g_bFrameOnline = true;
+#ifndef _WIN32
+                g_SpShellPID = GetSpshellProcID();
+                LogToFile(false, true, false, "get spshell proc id", NULL, g_SpShellPID);
+#endif //NOT _WIN32
 				g_bAuthSuc = false;
 				//_beginthreadex(NULL,0,DoNetControl,NULL,0,NULL);
 				StartDoNetControlRVC();
@@ -814,6 +937,10 @@ void DataProcess(LPPER_HANDLE_DATA pPerHandleData,LPPER_IO_OPERATION_DATA pPerIo
 			if (!g_bFrameOnline)
 			{
 				g_bFrameOnline = true;
+#ifndef _WIN32
+                g_SpShellPID = GetSpshellProcID();
+                LogToFile(false, true, false, "get spshell proc id", NULL, g_SpShellPID);
+#endif //NOT _WIN32
 				//_beginthreadex(NULL,0,DoNetControl,NULL,0,NULL);
 				StartDoNetControlRVC();
 			}
@@ -853,6 +980,10 @@ void DataProcess(LPPER_HANDLE_DATA pPerHandleData,LPPER_IO_OPERATION_DATA pPerIo
 		if (!g_bFrameOnline)
 		{
 			g_bFrameOnline = true;
+#ifndef _WIN32
+            g_SpShellPID = GetSpshellProcID();
+            LogToFile(false, true, false, "get spshell proc id", NULL, g_SpShellPID);
+#endif //NOT _WIN32
 			//_beginthreadex(NULL,0,DoNetControl,NULL,0,NULL);
 			StartDoNetControlRVC();
 		}
@@ -1374,6 +1505,10 @@ static void sig_handle(int signo)
 				sprintf(szMsg, "child process %d has been terminated unexpectly by signal %d", pid, WTERMSIG(status));
 			}
 			LogSingleMsg(szMsg);
+            if (g_SpShellPID != 0 && g_SpShellPID == pid) {
+				LogSingleMsg("Specified spshell process has exited!");
+				g_SpShellPID = 0;
+            }
         }
 		break;
 	}
@@ -1410,6 +1545,9 @@ int main()
 	CheckGuardianDbgDirAndCreateDbgFile();
 
 #if linux
+    g_SpShellPID = GetSpshellProcID();
+    LogToFile(false, true, false, "get spshell proc id", NULL, g_SpShellPID);
+
     if (signal(SIGCHLD, sig_handle) == SIG_ERR) {
 		LogToFile(false, false, false, "register for SIGCHLD failed", "", errno, 0, 0);
     } else {