guardian.cpp 44 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682
  1. // guardian.cpp : Defines the entry point for the console application.
  2. //
  3. #include "stdafx.h"
  4. #ifdef linux
  5. #include <sys/types.h>
  6. #include <sys/stat.h>
  7. #include <sys/socket.h>
  8. #include <sys/epoll.h>
  9. #include <netinet/in.h>
  10. #include <arpa/inet.h>
  11. #include <assert.h>
  12. #include <dirent.h>
  13. #include <fcntl.h>
  14. #include <unistd.h>
  15. #include <stdio.h>
  16. #include <errno.h>
  17. #include <string.h>
  18. #include <syslog.h>
  19. #include <signal.h>
  20. #include <pthread.h>
  21. #include <pwd.h>
  22. #include <signal.h>
  23. #include <sys/types.h>
  24. #include <sys/wait.h>
  25. #include "toolkit.h"
  26. #include "osutil.h"
  27. #include "memutil.h"
  28. #include <winpr/library.h>
  29. #include <winpr/synch.h>
  30. #include <winpr/environment.h>
  31. int epfd;
  32. struct epoll_event ev;
  33. #define MAXLINE 128
  34. #define OPEN_MAX 100
  35. #define LISTENQ 20
  36. #define INFTIM 1000
  37. #else
  38. #undef UNICODE
  39. #pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" )
  40. #ifndef WIN32_LEAN_AND_MEAN
  41. #define WIN32_LEAN_AND_MEAN
  42. #endif
  43. #include <windows.h>
  44. #include <winsock2.h>
  45. #include <ws2tcpip.h>
  46. #include <TlHelp32.h>
  47. #include <direct.h>
  48. #include <ctime>
  49. #endif //linux
  50. #include <iostream>
  51. #include <fstream>
  52. #include <string>
  53. #include <vector>
  54. #include "GuardianBase.h"
  55. #include "guardian.h"
  56. #include "log4rvcother.h"
  57. #ifndef MAX_PATH
  58. #define MAX_PATH 260
  59. #endif
  60. #define GUARDIAN_VERSION_STR "0.0.2"
  61. #ifdef RVC_OS_WIN
  62. static char spshell_execute_name[] = "SpShell.exe";
  63. static char sphost_execute_name[] = "SpHost.exe";
  64. static char guardian_execute_name[] = "Guardian.exe";
  65. static char cefclient_execute_name[] = "cefclient.exe";
  66. #else
  67. static char spshell_execute_name[] = "spshell";
  68. static char sphost_execute_name[] = "sphost";
  69. static char guardian_execute_name[] = "guardian";
  70. static char cefclient_execute_name[] = "cefclient";
  71. #endif //_WIN32
  72. char* relate_processes[] = { spshell_execute_name };
  73. char* relate_processes_ex[] = { spshell_execute_name, sphost_execute_name, cefclient_execute_name };
  74. using namespace std;
  75. #define NET_TYPE_WIRELESS 1
  76. #define NET_TYPE_ETHERNET 2
  77. #define NET_TYPE_3G 3
  78. #define NET_TYPE_4G 4
  79. #define NET_TYPE_BLUETOOTH 5
  80. #define DLL_PATH "C:\\RVC\\SystemInit\\CmbPadDll.dll"
  81. typedef DWORD(*pWlanConnect)(BOOL bConnect, int nType);
  82. typedef DWORD (*pDisableBluetooth)(BOOL bDisable);
  83. #ifdef linux
  84. int g_sListen;
  85. pthread_mutex_t g_cs, g_cs_event, g_cs_log;
  86. #define EnterCriticalSectionRVC(xType) pthread_mutex_lock(&xType)
  87. #define LeaveCriticalSectionRVC(xType) pthread_mutex_unlock(&xType)
  88. static int GetProcID()
  89. {
  90. return getpid();
  91. }
  92. #else
  93. SOCKET g_sListen = INVALID_SOCKET;
  94. DWORD WINAPI DoNetControl(void* pData);
  95. CRITICAL_SECTION g_cs, g_cs_event, g_cs_log;
  96. #define EnterCriticalSectionRVC(xType) EnterCriticalSection(&xType)
  97. #define LeaveCriticalSectionRVC(xType) LeaveCriticalSection(&xType)
  98. static int GetProcID()
  99. {
  100. return GetCurrentProcessId();
  101. }
  102. #endif //linux
  103. const int DEFAULT_BUFLEN = 512;
  104. const int SHAKEHAND_BUFZIE = 32;
  105. #define DEFAULT_PORT "30005"
  106. const int default_port = 30005;
  107. int g_needToRollBack = 0;
  108. bool g_needUpgradeGuardianOnly = false;
  109. bool g_bFrameQuit = false,g_bFrameOnline = false,g_bAuthSuc = false,g_bInUpgrade = false;
  110. ULONGLONG g_dwTimeBegin = 0;
  111. ULONGLONG g_dwUpgradeRestartTimeBegin = 0;
  112. int cnt = 0;
  113. char chDisk[2];
  114. char currDirBuf[256];
  115. void NetControl();
  116. const int MAX_WAIT_TIME_TO_RESTART = 600000;
  117. //oilyang@20211208 change value from 110000 to 180000
  118. const int MAX_WAIT_TIME_TO_RESTART_UPGRADE = 180000;
  119. static int g_SpShellPID = 0;
  120. #ifdef linux
  121. extern "C"
  122. {
  123. void* DoWorkLinux(void* arg);
  124. void* DoNetControlLinux(void* arg);
  125. }
  126. #define FUNCTION_STDCALL
  127. typedef unsigned short WORD;
  128. #else
  129. typedef struct
  130. {
  131. OVERLAPPED Overlapped;
  132. WSABUF DataBuf;
  133. CHAR Buffer[DATA_BUFSIZE];
  134. } PER_IO_OPERATION_DATA, * LPPER_IO_OPERATION_DATA;
  135. typedef struct
  136. {
  137. SOCKET Socket;
  138. } PER_HANDLE_DATA, * LPPER_HANDLE_DATA;
  139. DWORD WINAPI DoWork(void* pData);
  140. #define FUNCTION_STDCALL __stdcall
  141. #endif
  142. unsigned long long GetTickCountRVC() {
  143. #ifdef linux
  144. struct timespec ts;
  145. clock_gettime(CLOCK_MONOTONIC, &ts);
  146. return (ts.tv_sec * 1000 + ts.tv_nsec / 1000000);
  147. #else
  148. return GetTickCount64();
  149. #endif //RVC_OS_WIN
  150. }
  151. void GetLocalTimeRVC(SYSTEMTIME& stTime)
  152. {
  153. #ifdef linux
  154. time_t ct = 0;
  155. struct tm* ltm = NULL;
  156. WORD wMilliseconds = 0;
  157. DWORD ticks = 0;
  158. struct timespec ts;
  159. ct = time(NULL);
  160. ltm = localtime(&ct);
  161. if (!clock_gettime(CLOCK_MONOTONIC_RAW, &ts)) {
  162. ticks = (ts.tv_sec * 1000) + (ts.tv_nsec / 1000000);
  163. wMilliseconds = (WORD)(ticks % 1000);
  164. }
  165. memset(&stTime, 0, sizeof(SYSTEMTIME));
  166. if (ltm) {
  167. stTime.wYear = (WORD)(ltm->tm_year + 1900);
  168. stTime.wMonth = (WORD)(ltm->tm_mon + 1);
  169. stTime.wDayOfWeek = (WORD)ltm->tm_wday;
  170. stTime.wDay = (WORD)ltm->tm_mday;
  171. stTime.wHour = (WORD)ltm->tm_hour;
  172. stTime.wMinute = (WORD)ltm->tm_min;
  173. stTime.wSecond = (WORD)ltm->tm_sec;
  174. stTime.wMilliseconds = wMilliseconds;
  175. }
  176. #else
  177. GetLocalTime(&stTime);
  178. #endif
  179. }
  180. int BeginThreadRVC(void* (*pFuncLinux)(void*), LPTHREAD_START_ROUTINE pFuncWin)
  181. {
  182. #if defined(_MSC_VER)
  183. CreateThread(NULL, 0, pFuncWin, NULL, 0, NULL);
  184. return 0;
  185. #else
  186. pthread_t tidp;
  187. if ((pthread_create(&tidp, NULL, pFuncLinux, NULL) == -1)) {
  188. return 1;
  189. }
  190. cout << "after pthread_create of linux thread" << endl;
  191. return 0;
  192. #endif //_MSC_VER
  193. }
  194. void EndThreadRVC()
  195. {
  196. #ifdef linux
  197. pthread_exit(0);
  198. #endif //linux
  199. }
  200. void StartDoNetControlRVC()
  201. {
  202. #ifdef linux
  203. BeginThreadRVC(DoNetControlLinux, NULL);
  204. #else
  205. BeginThreadRVC(NULL, DoNetControl);
  206. #endif //linux
  207. }
  208. void StartDoWorkRVC()
  209. {
  210. #ifdef linux
  211. BeginThreadRVC(DoWorkLinux, NULL);
  212. #else
  213. BeginThreadRVC(NULL, DoWork);
  214. #endif //linux
  215. }
  216. void ServerReportEvent(const char* szFunction,const char* szName="guardian")
  217. {
  218. #ifdef linux
  219. return;//oiltest
  220. #else
  221. HANDLE hEventSource;
  222. LPCTSTR lpszStrings[2];
  223. char Buffer[1024] = {0};
  224. hEventSource = RegisterEventSource(NULL, szName);
  225. if( NULL != hEventSource )
  226. {
  227. strcpy_s(Buffer,1024,szFunction);
  228. lpszStrings[0] = szName;
  229. lpszStrings[1] = Buffer;
  230. ReportEvent(hEventSource, // event log handle
  231. EVENTLOG_ERROR_TYPE, // event type
  232. 0, // event category
  233. 0xe0000001, // event identifier
  234. NULL, // no security identifier
  235. 2, // size of lpszStrings array
  236. 0, // no binary data
  237. lpszStrings, // array of strings
  238. NULL); // no binary data
  239. DeregisterEventSource(hEventSource);
  240. }
  241. #endif //linux
  242. }
  243. bool VersionRollback()
  244. {
  245. const int VersionLenMax = 64;
  246. fstream verFile,verBak;//to confirm
  247. string strActiveTxtPath, strVersionDatPath;
  248. #ifdef linux
  249. char tmp[MAX_PATH];
  250. char* pos = NULL;
  251. GetModuleFileNameA(NULL, tmp, MAX_PATH);
  252. LOG4VTM(INFO, "rollback" << tmp);
  253. if ((pos = strstr(tmp, "/Run/")) != NULL) {
  254. pos[strlen("/Run/")] = '\0';
  255. strActiveTxtPath = string(tmp) + "version/active.txt";
  256. strVersionDatPath = string(tmp) + "runinfo/runcfg/version.dat";
  257. }
  258. else {
  259. strActiveTxtPath = "/opt/Run/version/active.txt";
  260. strVersionDatPath = "/opt/Run/runinfo/runcfg/version.dat";
  261. }
  262. #else
  263. string strDisk(chDisk);
  264. strActiveTxtPath = strDisk + ":\\Run\\version\\active.txt";
  265. strVersionDatPath = strDisk + ":\\Run\\runinfo\\runcfg\\version.dat";
  266. #endif //linux
  267. verFile.open(strActiveTxtPath,std::fstream::in|std::fstream::out|std::fstream::binary);
  268. verBak.open(strVersionDatPath,std::fstream::in|std::fstream::out|std::fstream::binary);
  269. if (!verFile.is_open() || !verBak.is_open())
  270. return false;
  271. char *pVerBak,*pNULL,*pCurrVer;
  272. pVerBak = new char[VersionLenMax];
  273. pNULL = new char[VersionLenMax];
  274. pCurrVer = new char[VersionLenMax];
  275. memset(pVerBak,0,VersionLenMax);
  276. memset(pNULL,0,VersionLenMax);
  277. memset(pCurrVer,0,VersionLenMax);
  278. verBak.seekg(0,verBak.end);
  279. int lenBak = verBak.tellg();
  280. verBak.seekg(0,verBak.beg);
  281. verBak.read(pVerBak,lenBak);
  282. //need to consider atomic op? oilyang
  283. verFile.seekg(0,verFile.end);
  284. int len = verFile.tellg();
  285. verFile.seekg(0,verFile.beg);
  286. verFile.read(pCurrVer,len);
  287. LOG4VTM(INFO, pVerBak);
  288. LOG4VTM(INFO, pCurrVer);
  289. LOG4VTM(INFO, pNULL);
  290. if (strcmp(pVerBak,pCurrVer) == 0)
  291. {
  292. ServerReportEvent(pVerBak);
  293. verFile.close();
  294. verBak.close();
  295. delete []pVerBak;
  296. delete []pNULL;
  297. return false;
  298. }
  299. //verBak.write(pNULL,len);
  300. //verFile.write(pNULL,len);
  301. //how foolish?
  302. verFile.close();
  303. verFile.open(strActiveTxtPath,std::fstream::in|std::fstream::out|std::fstream::binary|std::fstream::trunc);
  304. verFile.seekg(0,verFile.beg);
  305. verFile.write(pVerBak,lenBak);
  306. LOG4VTM(INFO, "terminal app version will rollback from " << pCurrVer << " to " << pVerBak);
  307. verFile.close();
  308. verBak.close();
  309. delete []pVerBak;
  310. delete []pNULL;
  311. return true;
  312. }
  313. #ifndef _WIN32
  314. static int GetSpshellProcID()
  315. {
  316. int result(0);
  317. char* spshell[] = { spshell_execute_name };
  318. alive_process_info processes[1];
  319. memset(processes, 0, sizeof(processes));
  320. int count = 1;
  321. if (!osutil_detect_unique_app(spshell, array_size(spshell), &count, processes)) {
  322. result = processes[0].pid;
  323. }
  324. return result;
  325. }
  326. static void ComfirmSpShellDead()
  327. {
  328. char* spshell[] = { spshell_execute_name };
  329. alive_process_info processes[1];
  330. memset(processes, 0, sizeof(processes));
  331. int count = 1;
  332. if (!osutil_detect_unique_app(spshell, array_size(spshell), &count, processes)) {
  333. if(g_SpShellPID == 0) g_SpShellPID = processes[0].pid;
  334. LOG4VTM(WARN, "has spshell process alive! and to kill it");
  335. assert(count > 0);
  336. if (kill(processes[0].pid, SIGTERM) != 0) {
  337. LOG4VTM(WARN, "kill with term for spshell failed, process id: " << processes[0].pid << ", err: " << errno);
  338. if (errno != 3 /**not exist */) {
  339. LOG4VTM(INFO, "to kill stronglely!");
  340. kill(processes[0].pid, SIGKILL);
  341. }
  342. } else {
  343. LOG4VTM(DEBUG, "kill with term for spshell succ. process id: " << processes[0].pid);
  344. }
  345. const int waitTimes = 100;
  346. const int eachTime = 300;
  347. int curTimes = 0;
  348. while (g_SpShellPID != 0 && curTimes < waitTimes) {
  349. if (osutil_detect_unique_app(spshell, array_size(spshell), NULL, NULL)) {
  350. g_SpShellPID = 0;
  351. break;
  352. }
  353. Sleep(eachTime);
  354. curTimes++;
  355. }
  356. if (g_SpShellPID == 0) {
  357. LOG4VTM(DEBUG, "spshell has gone!");
  358. }
  359. } else {
  360. LOG4VTM(INFO, "There are no any spshell process existed!");
  361. }
  362. //////////////////////////////////////////////////////////////////////////
  363. count = MAX_ALIVE_PROCESS_COUNT;
  364. alive_process_info processes2[MAX_ALIVE_PROCESS_COUNT];
  365. memset(processes2, 0, sizeof(processes2));
  366. if (!osutil_detect_unique_app(relate_processes_ex, array_size(relate_processes_ex), &count, processes2)) {
  367. for (int i = 0; i < count; ++i) {
  368. LOG4VTM(INFO, processes2[i].name << " " << processes2[i].path << " " << processes2[i].pid);
  369. }
  370. osutil_terminate_related_process(relate_processes_ex, array_size(relate_processes_ex), 0);
  371. Sleep(1000);
  372. }
  373. }
  374. inline static std::vector<std::string> Split(std::string str, char splitElem)
  375. {
  376. std::vector<std::string> strs;
  377. std::string::size_type pos1, pos2;
  378. pos2 = str.find(splitElem);
  379. pos1 = 0;
  380. while (std::string::npos != pos2) {
  381. strs.push_back(str.substr(pos1, pos2 - pos1));
  382. pos1 = pos2 + 1;
  383. pos2 = str.find(splitElem, pos1);
  384. }
  385. strs.push_back(str.substr(pos1));
  386. return strs;
  387. }
  388. static bool IsSpPathType(const std::string& value)
  389. {
  390. const int leastLength = strlen("Run/version/1.0.0.0/");
  391. std::string path(value.c_str());
  392. if (path.empty() || path.size() < leastLength) return false;
  393. const std::size_t sionPos = path.find("version");
  394. const std::size_t verPos = sionPos + strlen("version\\");
  395. if (sionPos == std::string::npos) return false;
  396. std::size_t suffixPos = std::string::npos, i;
  397. std::size_t dotCnt = 0;
  398. bool lastIsNum = false;
  399. for (i = verPos; i < path.size() && (path[i] >= '0' && path[i] <= '9' || path[i] == '.'); ++i) {
  400. lastIsNum = !(path[i] == '.');
  401. if (!lastIsNum) dotCnt++;
  402. }
  403. if (i >= path.size() || dotCnt != 3 || !lastIsNum)
  404. return false;
  405. return true;
  406. }
  407. /** 移除跟版本目录相关的环境变量信息*/
  408. static std::string CutSpPathFromPathValue(const char* value)
  409. {
  410. std::string path(value);
  411. std::string result("");
  412. std::vector<std::string> values = Split(path, ':');
  413. if (values.size() <= 0) {
  414. return path;
  415. }
  416. for (auto i = values.cbegin(); i != values.cend(); i++) {
  417. if (!IsSpPathType(*i)) {
  418. if (!result.empty()) result += ":";
  419. result += (*i);
  420. }
  421. }
  422. if (!result.empty() && path[path.size() - 1] == ':') {
  423. result += ":";
  424. }
  425. return result;
  426. }
  427. static void ResetEnviromentVars(const char* env)
  428. {
  429. DWORD size;
  430. char* buf;
  431. int len = 0;
  432. size = GetEnvironmentVariableA(env, NULL, 0);
  433. if (size == 0) {
  434. return;
  435. }
  436. len = size + MAX_PATH * 3;
  437. buf = (char*)malloc(len);
  438. memset(buf, 0, sizeof(buf));
  439. size = GetEnvironmentVariableA(env, buf, len);
  440. std::string newValue = CutSpPathFromPathValue(buf);
  441. if (newValue.empty()) {
  442. SetEnvironmentVariableA(env, NULL);
  443. } else if (newValue.size() < size) {
  444. strcpy(buf, newValue.c_str());
  445. SetEnvironmentVariableA(env, buf);
  446. }
  447. #if 1
  448. memset(buf, 0, sizeof(buf));
  449. size = GetEnvironmentVariableA(env, buf, len);
  450. LOG4VTM(INFO, buf << "env: " << env << " size: " << size);
  451. #endif
  452. FREE(buf);
  453. }
  454. static void ResetRelateEnviromentVars( const char* prefix)
  455. {
  456. LOG4VTM(INFO, prefix);
  457. ResetEnviromentVars("LD_LIBRARY_PATH");
  458. ResetEnviromentVars("PATH");
  459. }
  460. #endif //NOT _WIN32
  461. int FrameworkShutdown(bool bUpgrade=false,bool bRestart = true)
  462. {
  463. LOG4VTM(INFO, "in FrameworkShutdown,bUpgrade:" << bUpgrade << ",bRestart:" << bRestart);
  464. if (!bUpgrade)
  465. g_dwTimeBegin = GetTickCountRVC();
  466. NetControl();
  467. #ifdef linux
  468. //todo oiltestlinux
  469. LOG4VTM(DEBUG, "to kill spshell");
  470. ServerReportEvent("FrameworkShutdown linux");
  471. ComfirmSpShellDead();
  472. char tmp[MAX_PATH];
  473. char* pos = NULL;
  474. GetModuleFileNameA(NULL, tmp, MAX_PATH);
  475. LOG4VTM(INFO, "FrameworkShutdown: " << tmp);
  476. if ((pos = strstr(tmp, "/version")) != NULL) {
  477. pos[strlen("/version")+1] = '\0';
  478. ResetRelateEnviromentVars(tmp);
  479. char path[MAX_PATH] = { '\0' };
  480. bool toResetCWD(false);
  481. LOG4VTM(DEBUG, "to get current directory...");
  482. GetCurrentDirectoryA(MAX_PATH, path);
  483. LOG4VTM(DEBUG, path);
  484. if (strlen(path) <= 0 || strcmp(path, tmp) != 0) {
  485. LOG4VTM(INFO, "to set current directory...");
  486. SetCurrentDirectoryA(tmp);
  487. toResetCWD = true;
  488. }
  489. strcat(tmp, "spexplorer.sh --restart");
  490. LOG4VTM(DEBUG, tmp);
  491. tk_process_t* process = NULL;
  492. tk_process_option_t option;
  493. option.exit_cb = NULL;
  494. option.file = NULL;
  495. option.flags = 0;
  496. option.params = tmp;
  497. if (0 == process_spawn(&option, &process)) {
  498. FREE(process);
  499. LOG4VTM(INFO, "run spexplorer.sh scripts succ.");
  500. Sleep(1000);
  501. g_SpShellPID = GetSpshellProcID();
  502. LOG4VTM(INFO, "get spshell proc id: " << g_SpShellPID);
  503. if (toResetCWD) {
  504. SetCurrentDirectoryA(path);
  505. }
  506. return 0;
  507. } else {
  508. FREE(process);
  509. LOG4VTM(ERROR, "run spexplorer.sh scripts failed!");
  510. if (toResetCWD) {
  511. SetCurrentDirectoryA(path);
  512. }
  513. return -1;
  514. }
  515. }
  516. LOG4VTM(WARN, "get regular version path failed!");
  517. return 0;
  518. #else
  519. STARTUPINFO si;
  520. PROCESS_INFORMATION pi;
  521. ZeroMemory( &si, sizeof(si) );
  522. si.cb = sizeof(si);
  523. ZeroMemory( &pi, sizeof(pi) );
  524. // Start the child process.
  525. std::string csRestart,csVerPath,csAll,csSep("\""),csBlank(" "),csScript("wscript.exe"),csReFlag("r");
  526. csRestart = "sprestart.exe ";
  527. csVerPath = chDisk;
  528. csVerPath = csVerPath + std::string(":\\Run\\version");
  529. csVerPath = csVerPath + std::string("\\VTM.exe");
  530. if (!bRestart)
  531. csReFlag = "n";
  532. csAll = csSep + csRestart + csSep + csBlank + csSep + csVerPath + csSep
  533. + csBlank + csSep + csReFlag + csSep;
  534. char* szCmdline = new char[csAll.length() + 1];
  535. memset(szCmdline, '\0', csAll.length() + 1);
  536. strcpy(szCmdline, csAll.c_str());
  537. if( !CreateProcess( NULL,szCmdline,NULL,NULL,FALSE,CREATE_NEW_CONSOLE,NULL,NULL,&si,&pi))
  538. {
  539. delete[] szCmdline;
  540. return -1;
  541. }
  542. DWORD dwErr = GetLastError();
  543. // Wait until child process exits.
  544. WaitForSingleObject( pi.hProcess, INFINITE );
  545. // Close process and thread handles.
  546. CloseHandle( pi.hProcess );
  547. CloseHandle( pi.hThread );
  548. delete[] szCmdline;
  549. return 0;
  550. #endif //linux
  551. }
  552. bool FrameworkRollBack()
  553. {
  554. bool bVerRollback = VersionRollback();
  555. LOG4VTM(INFO, "version rollback ");
  556. if (true)
  557. FrameworkShutdown();
  558. return true;
  559. }
  560. bool ReadRuninfoContent(string &strData)
  561. {
  562. fstream runinfo;
  563. string strGdRuninfoPath;
  564. #ifdef linux
  565. //todo oiltestlinux
  566. char tmp[MAX_PATH];
  567. char* pos = NULL;
  568. GetModuleFileNameA(NULL, tmp, MAX_PATH);
  569. if ((pos = strstr(tmp, "/Run/")) != NULL) {
  570. pos[strlen("/Run/")] = '\0';
  571. strGdRuninfoPath = string(tmp) + "runinfo/runcfg/gdruninfo";
  572. }
  573. else {
  574. strGdRuninfoPath = "/opt/Run/runinfo/runcfg/gdruninfo";
  575. }
  576. #else
  577. string strDisk(chDisk);
  578. strGdRuninfoPath = strDisk + ":\\Run\\runinfo\\runcfg\\gdruninfo";
  579. #endif //linux
  580. LOG4VTM(INFO, strGdRuninfoPath.c_str());
  581. runinfo.open(strGdRuninfoPath,std::fstream::in|std::fstream::out|std::fstream::binary);
  582. if (!runinfo.is_open())
  583. {
  584. LOG4VTM(INFO, "open gdruninfo(read) failed.");
  585. return false;
  586. }
  587. runinfo.seekg(0,ios::end);
  588. int size = runinfo.tellg();
  589. if (size <= 0)
  590. return false;
  591. char *pData = new char[size+1];
  592. memset(pData,0,size+1);
  593. runinfo.seekg(0,ios::beg);
  594. runinfo.read(pData,size);
  595. strData = string(pData);
  596. LOG4VTM(INFO, "read runinfo " << strData);
  597. return true;
  598. }
  599. bool WriteRunInfoContent(const char* pData)
  600. {
  601. ofstream runinfo;
  602. string strGdRuninfoPath;
  603. #ifdef linux
  604. //todo oiltestlinux
  605. char tmp[MAX_PATH];
  606. char* pos = NULL;
  607. GetModuleFileNameA(NULL, tmp, MAX_PATH);
  608. LOG4VTM(INFO, tmp);
  609. if ((pos = strstr(tmp, "/Run/")) != NULL) {
  610. pos[strlen("/Run/")] = '\0';
  611. strGdRuninfoPath = string(tmp) + "runinfo/runcfg/gdruninfo";
  612. }
  613. else {
  614. strGdRuninfoPath = "/opt/Run/runinfo/runcfg/gdruninfo";
  615. }
  616. LOG4VTM(INFO, strGdRuninfoPath.c_str());
  617. #else
  618. string strDisk(chDisk);
  619. strGdRuninfoPath = strDisk + ":\\Run\\runinfo\\runcfg\\gdruninfo";
  620. #endif //linux
  621. runinfo.open(strGdRuninfoPath,std::ofstream::in|std::ofstream::binary|std::ofstream::trunc);
  622. if (!runinfo.is_open())
  623. {
  624. LOG4VTM(INFO, "open gdruninfo(write) failed.");
  625. ServerReportEvent("open gdruninfo(write) failed.");
  626. return false;
  627. }
  628. runinfo.write(pData,strlen(pData));
  629. runinfo.close();
  630. LOG4VTM(INFO, "write " << strGdRuninfoPath << " done");
  631. return true;
  632. }
  633. bool IsStartTimeFileExist()
  634. {
  635. ofstream runinfo;
  636. string strStartTimePath;
  637. #ifdef linux
  638. //todo oiltestlinux
  639. char tmp[MAX_PATH];
  640. char* pos = NULL;
  641. GetModuleFileNameA(NULL, tmp, MAX_PATH);
  642. LOG4VTM(INFO, "IsStartTimeFileExist: " << tmp);
  643. if ((pos = strstr(tmp, "/Run/")) != NULL) {
  644. pos[strlen("/Run/")] = '\0';
  645. strStartTimePath = string(tmp) + "runinfo/runcfg/starttime.dat";
  646. }
  647. else {
  648. strStartTimePath = "/opt/Run/runinfo/runcfg/starttime.dat";
  649. }
  650. #else
  651. string strDisk(chDisk);
  652. strStartTimePath = strDisk + ":\\Run\\runinfo\\runcfg\\starttime.dat";
  653. #endif //linux
  654. runinfo.open(strStartTimePath, std::fstream::in | std::fstream::out | std::fstream::binary);
  655. if (!runinfo.is_open()) {
  656. LOG4VTM(ERROR, "open starttime.dat failed");
  657. return false;
  658. }
  659. else
  660. {
  661. runinfo.close();
  662. LOG4VTM(DEBUG, "open starttime.dat succ");
  663. return true;
  664. }
  665. }
  666. #ifdef linux
  667. void CheckDoWork(int sig)
  668. {
  669. cout << "CheckDoWork" << endl;
  670. if (SIGALRM == sig)
  671. {
  672. EnterCriticalSectionRVC(g_cs);
  673. if (!g_bFrameQuit)
  674. {
  675. ULONGLONG dwTmpBegin = g_dwTimeBegin;
  676. ULONGLONG dwUpgradeTmpBegin = g_dwUpgradeRestartTimeBegin;
  677. LeaveCriticalSectionRVC(g_cs);
  678. ULONGLONG dwTimeEnd = GetTickCountRVC();
  679. //oilyang@20190828 add
  680. //升级重启后,在10分钟内,只要离最后一次交互时间大于2分钟,重启框架
  681. if ((g_bInUpgrade && ((dwTimeEnd - dwUpgradeTmpBegin) < MAX_WAIT_TIME_TO_RESTART))
  682. && (!g_bAuthSuc && ((dwTimeEnd - dwTmpBegin) > MAX_WAIT_TIME_TO_RESTART_UPGRADE)))
  683. {
  684. LOG4VTM(WARN, "**in upgrade restart**,to restart framework(linux).");
  685. FrameworkShutdown(true, true);
  686. }
  687. if ((dwTimeEnd - dwTmpBegin) > MAX_WAIT_TIME_TO_RESTART)
  688. {
  689. LOG4VTM(ERROR, "framework maybe down.");
  690. string strRunInfo;
  691. if (ReadRuninfoContent(strRunInfo))
  692. {
  693. LOG4VTM(INFO, "to check if need rollback.");
  694. LOG4VTM(INFO, (char*)strRunInfo.c_str());
  695. if (strRunInfo.compare("111") == 0 && IsStartTimeFileExist())
  696. {
  697. EnterCriticalSectionRVC(g_cs);
  698. g_needToRollBack = 1;
  699. LeaveCriticalSectionRVC(g_cs);
  700. }
  701. }
  702. else
  703. LOG4VTM(WARN, "read run info failed.");
  704. if (g_needToRollBack)
  705. {
  706. LOG4VTM(INFO, "after upgrade,time elapse,but can't wait the shake hands,so rollback.");
  707. FrameworkRollBack();
  708. }
  709. else
  710. {
  711. //framework is down,to restart it! oilyang 20150413
  712. FrameworkShutdown();
  713. }
  714. }
  715. }
  716. else
  717. LeaveCriticalSectionRVC(g_cs);
  718. alarm(2 * 60); //we contimue set the timer
  719. }
  720. return;
  721. }
  722. void* DoWorkLinux(void* arg)
  723. {
  724. LOG4VTM(DEBUG, "DoWorkLinux");
  725. signal(SIGALRM, CheckDoWork); //relate the signal and function
  726. alarm(2 * 60); //trigger the timer
  727. EndThreadRVC();
  728. }
  729. void* DoNetControlLinux(void* arg)
  730. {
  731. LOG4VTM(DEBUG, "to end DoNetControlLinux");
  732. EndThreadRVC();
  733. LOG4VTM(DEBUG, "after end DoNetControlLinux");
  734. }
  735. void DataProcessLinux(int socket,const char*data)
  736. {
  737. GuardianInfo* pInfo = (GuardianInfo*)data;
  738. LOG4VTM(DEBUG, "eType:" << pInfo->eType << ",p1:" << pInfo->dwParam1 << ",p2:" << pInfo->dwParam2 << ",dwSize:" << pInfo->dwSize);
  739. switch (pInfo->eType)
  740. {
  741. case GdOpShakeHand:
  742. {
  743. if (!g_bFrameOnline)
  744. {
  745. g_bFrameOnline = true;
  746. g_SpShellPID = GetSpshellProcID();
  747. LOG4VTM(INFO, "get spshell proc id" << g_SpShellPID);
  748. StartDoNetControlRVC();
  749. }
  750. int rc, err;
  751. EnterCriticalSectionRVC(g_cs);
  752. g_bFrameQuit = false;
  753. g_dwTimeBegin = GetTickCountRVC();
  754. LeaveCriticalSectionRVC(g_cs);
  755. char* pBuf = new char[8];
  756. memset(pBuf, 0, 8);
  757. //get guardian state
  758. //ex:u(update),g(guardian),r(reboot),b(rollback)
  759. if (cnt % 2 == 0)
  760. memcpy(pBuf, "g", 1);
  761. else
  762. memcpy(pBuf, "u", 1);
  763. cnt++;
  764. rc = send(socket, pBuf, 8, 0);
  765. delete[]pBuf;
  766. close(socket);
  767. }
  768. break;
  769. case GdOpUpdateTask:
  770. {
  771. if (!g_bFrameOnline)
  772. {
  773. g_bFrameOnline = true;
  774. g_SpShellPID = GetSpshellProcID();
  775. LOG4VTM(INFO, "get spshell proc id" << g_SpShellPID);
  776. StartDoNetControlRVC();
  777. }
  778. }
  779. break;
  780. case GdOpQueryInstall:
  781. {
  782. if (!g_bFrameOnline)
  783. {
  784. g_bFrameOnline = true;
  785. g_SpShellPID = GetSpshellProcID();
  786. LOG4VTM(INFO, "get spshell proc id" << g_SpShellPID);
  787. StartDoNetControlRVC();
  788. }
  789. int rc, err;
  790. char* pBuf = new char[8];
  791. memset(pBuf, 0, 8);
  792. if (cnt % 2 == 0)
  793. memcpy(pBuf, "y", 1);
  794. else
  795. memcpy(pBuf, "n", 1);
  796. cnt++;
  797. rc = send(socket, pBuf, 8, 0);
  798. delete[]pBuf;
  799. close(socket);
  800. }
  801. break;
  802. case GdOpUpgradeRestart:
  803. {
  804. if (pInfo->dwParam1 == 6)//HealthManager call guardian to quit
  805. {
  806. LOG4VTM(INFO, "HealthManager call guardian to quit");
  807. close(socket);
  808. close(g_sListen);
  809. exit(0);//baoli?
  810. break;
  811. }
  812. if (pInfo->dwParam1 == 4)//just know framework is starting...
  813. {
  814. LOG4VTM(INFO, "framework is starting...");
  815. g_bFrameOnline = true;
  816. g_SpShellPID = GetSpshellProcID();
  817. LOG4VTM(INFO, "get spshell proc id" << g_SpShellPID);
  818. g_bAuthSuc = false;
  819. StartDoNetControlRVC();
  820. LOG4VTM(DEBUG, "to break upgrade...");
  821. close(socket);
  822. break;
  823. }
  824. if (pInfo->dwParam1 == 5)
  825. {
  826. LOG4VTM(INFO, "framework auth ok.");
  827. g_bInUpgrade = false;
  828. g_bAuthSuc = true;
  829. }
  830. if (!g_bFrameOnline)
  831. {
  832. g_bFrameOnline = true;
  833. g_SpShellPID = GetSpshellProcID();
  834. LOG4VTM(INFO, "get spshell proc id" << g_SpShellPID);
  835. StartDoNetControlRVC();
  836. }
  837. if (pInfo->dwParam1 == 1 || pInfo->dwParam1 == 3)
  838. g_dwTimeBegin = GetTickCountRVC();
  839. ServerReportEvent("upgrade restart");
  840. LOG4VTM(INFO, "upgrade restart " << pInfo->dwParam1);
  841. if (pInfo->dwParam1 == 1)//framework to restart after upgrade
  842. {
  843. g_bInUpgrade = true;
  844. WriteRunInfoContent("111");
  845. g_dwUpgradeRestartTimeBegin = GetTickCountRVC();
  846. }
  847. else if (pInfo->dwParam1 == 2)//need rollback after upgrade
  848. {
  849. LOG4VTM(INFO, "upgrade restart 222");
  850. WriteRunInfoContent("222");
  851. //rollback
  852. EnterCriticalSectionRVC(g_cs);
  853. g_needToRollBack = 0;
  854. LeaveCriticalSectionRVC(g_cs);
  855. LOG4VTM(INFO, "healthmanager said to rollback");
  856. FrameworkRollBack();
  857. }
  858. else if (pInfo->dwParam1 == 3)//upgrade succeeded
  859. {
  860. LOG4VTM(INFO, "upgrade restart ok");
  861. WriteRunInfoContent("333");
  862. EnterCriticalSectionRVC(g_cs);
  863. g_needToRollBack = 0;
  864. LeaveCriticalSectionRVC(g_cs);
  865. }
  866. //runinfo.close();
  867. close(socket);
  868. }
  869. break;
  870. case GdOpFrameQuit:
  871. if (!g_bFrameOnline)
  872. {
  873. g_bFrameOnline = true;
  874. g_SpShellPID = GetSpshellProcID();
  875. LOG4VTM(INFO, "get spshell proc id" << g_SpShellPID);
  876. StartDoNetControlRVC();
  877. }
  878. EnterCriticalSectionRVC(g_cs);
  879. g_bFrameQuit = true;
  880. LeaveCriticalSectionRVC(g_cs);
  881. close(socket);
  882. break;
  883. default:
  884. break;
  885. }
  886. LOG4VTM(DEBUG, "quit of DataProcessLinux");
  887. }
  888. #else
  889. void DataProcess(LPPER_HANDLE_DATA pPerHandleData,LPPER_IO_OPERATION_DATA pPerIoData)
  890. {
  891. GuardianInfo* pInfo = (GuardianInfo*)pPerIoData->Buffer;
  892. switch(pInfo->eType)
  893. {
  894. case GdOpShakeHand:
  895. {
  896. if (!g_bFrameOnline)
  897. {
  898. g_bFrameOnline = true;
  899. StartDoNetControlRVC();
  900. }
  901. int rc,err;
  902. EnterCriticalSectionRVC(g_cs);
  903. g_bFrameQuit = false;
  904. g_dwTimeBegin = GetTickCountRVC();
  905. LeaveCriticalSectionRVC(g_cs);
  906. char* pBuf = new char[8];
  907. memset(pBuf,0,8);
  908. //get guardian state
  909. //ex:u(update),g(guardian),r(reboot),b(rollback)
  910. if (cnt%2 == 0)
  911. memcpy(pBuf,"g",1);
  912. else
  913. memcpy(pBuf,"u",1);
  914. cnt++;
  915. rc = send(pPerHandleData->Socket,pBuf,8,0);
  916. delete []pBuf;
  917. closesocket(pPerHandleData->Socket);
  918. }
  919. break;
  920. case GdOpUpdateTask:
  921. {
  922. if (!g_bFrameOnline)
  923. {
  924. g_bFrameOnline = true;
  925. StartDoNetControlRVC();
  926. }
  927. }
  928. break;
  929. case GdOpQueryInstall:
  930. {
  931. if (!g_bFrameOnline)
  932. {
  933. g_bFrameOnline = true;
  934. StartDoNetControlRVC();
  935. }
  936. int rc,err;
  937. char* pBuf = new char[8];
  938. memset(pBuf,0,8);
  939. if (cnt%2 == 0)
  940. memcpy(pBuf,"y",1);
  941. else
  942. memcpy(pBuf,"n",1);
  943. cnt++;
  944. rc = send(pPerHandleData->Socket,pBuf,8,0);
  945. delete []pBuf;
  946. closesocket(pPerHandleData->Socket);
  947. }
  948. break;
  949. case GdOpUpgradeRestart:
  950. {
  951. if (pInfo->dwParam1 == 6)//need Upgrade guardian !!!Only!!!
  952. {
  953. g_needUpgradeGuardianOnly = true;
  954. }
  955. if (pInfo->dwParam1 == 4)//just know framework is starting...
  956. {
  957. LOG4VTM(INFO, "framework is starting...");
  958. //oilyang@20211208 add the following if receive framework is starting ,reset g_dwUpgradeRestartTimeBegin
  959. //in order to skip the cost time of "kill spshell"
  960. g_dwUpgradeRestartTimeBegin = GetTickCountRVC();
  961. g_bFrameOnline = true;
  962. g_bAuthSuc = false;
  963. StartDoNetControlRVC();
  964. break;
  965. }
  966. if (pInfo->dwParam1 == 5)
  967. {
  968. LOG4VTM(INFO, "framework auth ok.");
  969. g_bInUpgrade = false;
  970. g_bAuthSuc = true;
  971. }
  972. if (!g_bFrameOnline)
  973. {
  974. g_bFrameOnline = true;
  975. StartDoNetControlRVC();
  976. }
  977. if (pInfo->dwParam1 == 1 || pInfo->dwParam1 == 3)
  978. g_dwTimeBegin = GetTickCountRVC();
  979. ServerReportEvent("upgrade restart");
  980. LOG4VTM(INFO, "upgrade restart " << pInfo->dwParam1);
  981. if (pInfo->dwParam1 == 1)//framework to restart after upgrade
  982. {
  983. g_bInUpgrade = true;
  984. WriteRunInfoContent("111");
  985. g_dwUpgradeRestartTimeBegin = GetTickCountRVC();
  986. }
  987. else if (pInfo->dwParam1 == 2)//need rollback after upgrade
  988. {
  989. LOG4VTM(INFO, "upgrade restart 222");
  990. WriteRunInfoContent("222");
  991. //rollback
  992. EnterCriticalSectionRVC(g_cs);
  993. g_needToRollBack = 0;
  994. LeaveCriticalSectionRVC(g_cs);
  995. LOG4VTM(INFO, "healthmanager said to rollback");
  996. FrameworkRollBack();
  997. }else if (pInfo->dwParam1 == 3)//upgrade succeeded
  998. {
  999. LOG4VTM(INFO, "upgrade restart ok");
  1000. WriteRunInfoContent("333");
  1001. EnterCriticalSectionRVC(g_cs);
  1002. g_needToRollBack = 0;
  1003. LeaveCriticalSectionRVC(g_cs);
  1004. }
  1005. //runinfo.close();
  1006. closesocket(pPerHandleData->Socket);
  1007. }
  1008. break;
  1009. case GdOpFrameQuit:
  1010. if (!g_bFrameOnline)
  1011. {
  1012. g_bFrameOnline = true;
  1013. StartDoNetControlRVC();
  1014. }
  1015. EnterCriticalSectionRVC(g_cs);
  1016. g_bFrameQuit = true;
  1017. LeaveCriticalSectionRVC(g_cs);
  1018. closesocket(pPerHandleData->Socket);
  1019. break;
  1020. default:
  1021. break;
  1022. }
  1023. }
  1024. DWORD WINAPI ProcessIO(LPVOID lpParam)
  1025. {
  1026. HANDLE CompletionPort = (HANDLE)lpParam;
  1027. DWORD BytesTransferred;
  1028. LPPER_HANDLE_DATA PerHandleData;
  1029. LPPER_IO_OPERATION_DATA PerIoData;
  1030. while(true)
  1031. {
  1032. if(0 == GetQueuedCompletionStatus(CompletionPort, &BytesTransferred, (LPDWORD)&PerHandleData, (LPOVERLAPPED*)&PerIoData, INFINITE))
  1033. {
  1034. if( (GetLastError() == WAIT_TIMEOUT) || (GetLastError() == ERROR_NETNAME_DELETED) )
  1035. {
  1036. LOG4VTM(INFO, "closing socket(1) " << PerHandleData->Socket);
  1037. closesocket(PerHandleData->Socket);
  1038. delete PerIoData;
  1039. delete PerHandleData;
  1040. continue;
  1041. }
  1042. else
  1043. {
  1044. //OutErr("GetQueuedCompletionStatus failed!");
  1045. }
  1046. return 0;
  1047. }
  1048. // client quit
  1049. if(BytesTransferred == 0)
  1050. {
  1051. LOG4VTM(INFO, "closing socket(2) " <<PerHandleData->Socket);
  1052. closesocket(PerHandleData->Socket);
  1053. delete PerIoData;
  1054. delete PerHandleData;
  1055. continue;
  1056. }
  1057. // receiving data process
  1058. DataProcess(PerHandleData,PerIoData);
  1059. // socket WSARecv
  1060. DWORD Flags = 0;
  1061. DWORD dwRecv = 0;
  1062. ZeroMemory(PerIoData, sizeof(PER_IO_OPERATION_DATA));
  1063. PerIoData->DataBuf.buf = PerIoData->Buffer;
  1064. PerIoData->DataBuf.len = DATA_BUFSIZE;
  1065. WSARecv(PerHandleData->Socket, &PerIoData->DataBuf, 1, &dwRecv, &Flags, &PerIoData->Overlapped, NULL);
  1066. }
  1067. return 0;
  1068. }
  1069. DWORD WINAPI DoWork(void* pData)
  1070. {
  1071. LOG4VTM(INFO, "to wait.");
  1072. HANDLE hTimer;
  1073. LARGE_INTEGER li;
  1074. hTimer = CreateWaitableTimer(NULL,FALSE,NULL);
  1075. const int nTimerUnitsPerSecond = 10000000;
  1076. li.QuadPart = -(1*60*nTimerUnitsPerSecond);//oiltmp 1 minute
  1077. SetWaitableTimer(hTimer,&li,2*60*1000,NULL,NULL,FALSE);
  1078. while(1)
  1079. {
  1080. WaitForSingleObject(hTimer,INFINITE);
  1081. EnterCriticalSectionRVC(g_cs);
  1082. if (!g_bFrameQuit)
  1083. {
  1084. ULONGLONG dwTmpBegin = g_dwTimeBegin;
  1085. ULONGLONG dwUpgradeTmpBegin = g_dwUpgradeRestartTimeBegin;
  1086. LeaveCriticalSectionRVC(g_cs);
  1087. ULONGLONG dwTimeEnd = GetTickCountRVC();
  1088. //oilyang@20190828 add
  1089. //升级重启后,在10分钟内,只要离最后一次交互时间大于MAX_WAIT_TIME_TO_RESTART_UPGRADE,重启框架
  1090. if (g_bInUpgrade && ((dwTimeEnd - dwTmpBegin) < MAX_WAIT_TIME_TO_RESTART)
  1091. && (!g_bAuthSuc && ((dwTimeEnd - dwUpgradeTmpBegin) > MAX_WAIT_TIME_TO_RESTART_UPGRADE)))
  1092. {
  1093. LOG4VTM(WARN, "**in upgrade restart**,to restart framework.");
  1094. FrameworkShutdown(true,true);
  1095. }
  1096. if ((dwTimeEnd-dwTmpBegin) > MAX_WAIT_TIME_TO_RESTART)
  1097. {
  1098. LOG4VTM(ERROR, "framework maybe down.");
  1099. string strRunInfo;
  1100. if (ReadRuninfoContent(strRunInfo))
  1101. {
  1102. LOG4VTM(INFO, "to check if need rollback.");
  1103. LOG4VTM(INFO, "runinfo:" << strRunInfo);
  1104. if (strRunInfo.compare("111") == 0 && IsStartTimeFileExist())
  1105. {
  1106. EnterCriticalSectionRVC(g_cs);
  1107. g_needToRollBack = 1;
  1108. LeaveCriticalSectionRVC(g_cs);
  1109. }
  1110. }
  1111. else
  1112. LOG4VTM(WARN, "read run info failed.");
  1113. if (g_needToRollBack)
  1114. {
  1115. LOG4VTM(INFO, "after upgrade,time elapse,but can't wait the shake hands,so rollback.");
  1116. FrameworkRollBack();
  1117. }
  1118. else
  1119. {
  1120. //framework is down,to restart it! oilyang 20150413
  1121. //oilyang@20211221 if Upgrade guardian !!!Only!!! ,just reset dwTmpBegin
  1122. if (!g_needUpgradeGuardianOnly)
  1123. FrameworkShutdown();
  1124. else
  1125. dwTmpBegin = GetTickCountRVC();
  1126. }
  1127. }
  1128. }
  1129. else
  1130. LeaveCriticalSectionRVC(g_cs);
  1131. }
  1132. EndThreadRVC();
  1133. return 0;
  1134. }
  1135. DWORD WINAPI DoNetControl(LPVOID pData)
  1136. {
  1137. ServerReportEvent("DoNetControl start");
  1138. HANDLE hSnapshot;
  1139. //find spshell.exe
  1140. hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  1141. if (hSnapshot)
  1142. {
  1143. PROCESSENTRY32 pe;
  1144. pe.dwSize = sizeof(pe);
  1145. if (Process32First(hSnapshot, &pe))
  1146. {
  1147. do {
  1148. if (_stricmp(&pe.szExeFile[0], "spshell.exe") == 0)
  1149. {
  1150. //ServerReportEvent("find spshell.exe");
  1151. LOG4VTM(INFO, "find spshell.exe");
  1152. //DWORD dwExit = 0;
  1153. //do
  1154. //{
  1155. // GetExitCodeProcess(&pe.th32ProcessID,&dwExit);
  1156. // if (dwExit != STILL_ACTIVE)
  1157. // break;
  1158. //}while(1);
  1159. HANDLE hP = OpenProcess( PROCESS_ALL_ACCESS, FALSE, pe.th32ProcessID );
  1160. WaitForSingleObject(hP, INFINITE );
  1161. LOG4VTM(INFO, "spshell.exe quit");
  1162. //ServerReportEvent("spshell.exe quit");
  1163. NetControl();
  1164. break;
  1165. }
  1166. } while (Process32Next(hSnapshot, &pe));
  1167. }
  1168. CloseHandle(hSnapshot);
  1169. }
  1170. else
  1171. ServerReportEvent("create snapshot failed.");
  1172. EndThreadRVC();
  1173. return 0;
  1174. }
  1175. #endif //linux
  1176. int InitListenSocketRVC()
  1177. {
  1178. #ifdef linux
  1179. socklen_t clilen;
  1180. epfd = epoll_create(256);
  1181. struct sockaddr_in clientaddr;
  1182. struct sockaddr_in serveraddr;
  1183. g_sListen = socket(AF_INET, SOCK_STREAM, 0);
  1184. //setnonblocking(listenfd);
  1185. ev.data.fd = g_sListen;
  1186. ev.events = EPOLLIN | EPOLLET;
  1187. epoll_ctl(epfd, EPOLL_CTL_ADD, g_sListen, &ev);
  1188. memset(&serveraddr, 0, sizeof(serveraddr));
  1189. serveraddr.sin_family = AF_INET;
  1190. char* local_addr = "127.0.0.1";
  1191. inet_aton(local_addr, &(serveraddr.sin_addr));
  1192. serveraddr.sin_port = htons(default_port);
  1193. int tmpuse = 1;
  1194. if (setsockopt(g_sListen, SOL_SOCKET, SO_REUSEPORT, (char*)&tmpuse, sizeof(tmpuse)) < 0)
  1195. {
  1196. LOG4VTM(ERROR, "setsockopt failed. "<< errno);
  1197. LOG4VTM(ERROR, strerror(errno));
  1198. close(g_sListen);
  1199. return -1;
  1200. }
  1201. int ret = bind(g_sListen, (sockaddr*)& serveraddr, sizeof(serveraddr));
  1202. if (ret != 0)
  1203. {
  1204. LOG4VTM(ERROR, "bind failed: " << errno);
  1205. LOG4VTM(ERROR, strerror(errno));
  1206. close(g_sListen);
  1207. return -1;
  1208. }
  1209. ret= listen(g_sListen, LISTENQ);
  1210. if (ret != 0)
  1211. {
  1212. LOG4VTM(ERROR, "listen failed: " << errno);
  1213. LOG4VTM(ERROR, strerror(errno));
  1214. close(g_sListen);
  1215. return -1;
  1216. }
  1217. LOG4VTM(INFO, "(linux)listen ok: " << g_sListen);
  1218. cout << "listen on:" << g_sListen << endl;
  1219. return g_sListen;
  1220. #else
  1221. WSADATA wsaData;
  1222. int iResult;
  1223. struct addrinfo* result = NULL;
  1224. struct addrinfo hints;
  1225. int iSendResult;
  1226. char recvbuf[DEFAULT_BUFLEN];
  1227. int recvbuflen = DEFAULT_BUFLEN;
  1228. // Initialize Winsock
  1229. iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
  1230. if (iResult != 0) {
  1231. LOG4VTM(ERROR, "WSAStartup failed with error:" << iResult);
  1232. return 1;
  1233. }
  1234. ZeroMemory(&hints, sizeof(hints));
  1235. hints.ai_family = AF_INET;
  1236. hints.ai_socktype = SOCK_STREAM;
  1237. hints.ai_protocol = IPPROTO_TCP;
  1238. hints.ai_flags = AI_PASSIVE;
  1239. // Resolve the server address and port
  1240. iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
  1241. if (iResult != 0) {
  1242. LOG4VTM(ERROR, "getaddrinfo failed with error:" << iResult);
  1243. WSACleanup();
  1244. return 1;
  1245. }
  1246. // get system info to create work thread
  1247. SYSTEM_INFO SystemInfo;
  1248. GetSystemInfo(&SystemInfo);
  1249. // Create a SOCKET for connecting to server
  1250. g_sListen = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
  1251. if (g_sListen == INVALID_SOCKET) {
  1252. LOG4VTM(ERROR, "socket failed with error:" << WSAGetLastError());
  1253. freeaddrinfo(result);
  1254. WSACleanup();
  1255. return 1;
  1256. }
  1257. // Setup the TCP listening socket
  1258. struct sockaddr_in* sockaddr_ipv4 = (struct sockaddr_in*) result->ai_addr;
  1259. LOG4VTM(INFO, "ip:"<< inet_ntoa(sockaddr_ipv4->sin_addr));
  1260. iResult = bind(g_sListen, result->ai_addr, (int)result->ai_addrlen);
  1261. if (iResult == SOCKET_ERROR) {
  1262. LOG4VTM(ERROR, "bind failed with error:" << WSAGetLastError());
  1263. freeaddrinfo(result);
  1264. closesocket(g_sListen);
  1265. WSACleanup();
  1266. return 1;
  1267. }
  1268. freeaddrinfo(result);
  1269. LOG4VTM(INFO, "to listen.");
  1270. iResult = listen(g_sListen, SOMAXCONN);
  1271. if (iResult == SOCKET_ERROR) {
  1272. LOG4VTM(ERROR, "listen failed with error: " << WSAGetLastError());
  1273. closesocket(g_sListen);
  1274. WSACleanup();
  1275. return 1;
  1276. }
  1277. LOG4VTM(INFO, "listen ok.");
  1278. return g_sListen;
  1279. #endif //linux
  1280. }
  1281. void AcceptReqRVC()
  1282. {
  1283. #ifdef linux
  1284. StartDoWorkRVC();
  1285. LOG4VTM(DEBUG, "AcceptReqRVC:after StartDoWorkRVC");
  1286. int maxi, connfd, sockfd, nfds;
  1287. struct epoll_event events[20];
  1288. struct sockaddr_in clientaddr;
  1289. socklen_t clilen = sizeof(struct sockaddr);
  1290. ssize_t n;
  1291. maxi = 0;
  1292. char line[MAXLINE];
  1293. for (; ; ) {
  1294. //等待epoll事件的发生
  1295. nfds = epoll_wait(epfd, events, 20, 500);
  1296. //处理所发生的所有事件
  1297. for (int i = 0; i < nfds; ++i)
  1298. {
  1299. LOG4VTM(DEBUG, "nfds: " << nfds);
  1300. if (events[i].data.fd == g_sListen)//new connection
  1301. {
  1302. connfd = accept(g_sListen, (sockaddr*)& clientaddr, &clilen);
  1303. if (connfd < 0) {
  1304. LOG4VTM(ERROR, "connfd<0");
  1305. perror("connfd<0");
  1306. exit(1);
  1307. }
  1308. //setnonblocking(connfd);
  1309. char* str = inet_ntoa(clientaddr.sin_addr);
  1310. LOG4VTM(DEBUG, "accapt a connection from " << str);
  1311. ev.data.fd = connfd;
  1312. ev.events = EPOLLIN | EPOLLET;
  1313. //ev.events=EPOLLIN;
  1314. epoll_ctl(epfd, EPOLL_CTL_ADD, connfd, &ev);
  1315. }
  1316. else if (events[i].events & EPOLLIN)
  1317. {
  1318. LOG4VTM(DEBUG, "EPOLLIN,i:" << i << ",sock:" << events[i].data.fd);
  1319. if ((sockfd = events[i].data.fd) < 0)
  1320. continue;
  1321. if ((n = read(sockfd, line, MAXLINE)) < 0) {
  1322. if (errno == ECONNRESET) {
  1323. close(sockfd);
  1324. events[i].data.fd = -1;
  1325. }
  1326. else
  1327. LOG4VTM(ERROR, "readline error: " << strerror(errno));
  1328. }
  1329. else if (n == 0) {
  1330. close(sockfd);
  1331. events[i].data.fd = -1;
  1332. }
  1333. DataProcessLinux(sockfd,line);
  1334. line[n] = '\0';
  1335. ev.data.fd = sockfd;
  1336. ev.events = EPOLLOUT | EPOLLET;
  1337. epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev);
  1338. LOG4VTM(DEBUG, "out DataProcessLinux");
  1339. }
  1340. else if (events[i].events & EPOLLOUT)
  1341. {
  1342. LOG4VTM(DEBUG, "epoll out");
  1343. sockfd = events[i].data.fd;
  1344. write(sockfd, line, n);
  1345. ev.data.fd = sockfd;
  1346. ev.events = EPOLLIN | EPOLLET;
  1347. epoll_ctl(epfd, EPOLL_CTL_MOD, sockfd, &ev);
  1348. }
  1349. }
  1350. }
  1351. #else
  1352. HANDLE hCompletionPort;
  1353. hCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
  1354. // get system info to create work thread
  1355. SYSTEM_INFO SystemInfo;
  1356. GetSystemInfo(&SystemInfo);
  1357. for (int i = 0; i < SystemInfo.dwNumberOfProcessors * 2; i++)
  1358. {
  1359. HANDLE hProcessIO = CreateThread(NULL, 0, ProcessIO, hCompletionPort, 0, NULL);
  1360. if (hProcessIO)
  1361. CloseHandle(hProcessIO);
  1362. }
  1363. //waiting thread
  1364. StartDoWorkRVC();
  1365. SOCKET sClient;
  1366. LPPER_HANDLE_DATA PerHandleData;
  1367. LPPER_IO_OPERATION_DATA PerIoData;
  1368. while (true)
  1369. {
  1370. //sClient = WSAAccept(sListen, NULL, NULL, NULL, 0);
  1371. sClient = accept(g_sListen, NULL, NULL);
  1372. //cout << "Socket " << sClient << "connect" << endl;
  1373. PerHandleData = new PER_HANDLE_DATA();
  1374. PerHandleData->Socket = sClient;
  1375. // client completion port
  1376. CreateIoCompletionPort((HANDLE)sClient, hCompletionPort, (DWORD)PerHandleData, 0);
  1377. //
  1378. PerIoData = new PER_IO_OPERATION_DATA();
  1379. ZeroMemory(PerIoData, sizeof(PER_IO_OPERATION_DATA));
  1380. PerIoData->DataBuf.buf = PerIoData->Buffer;
  1381. PerIoData->DataBuf.len = DATA_BUFSIZE;
  1382. // WSARecv
  1383. DWORD Flags = 0;
  1384. DWORD dwRecv = 0;
  1385. WSARecv(sClient, &PerIoData->DataBuf, 1, &dwRecv, &Flags, &PerIoData->Overlapped, NULL);
  1386. LOG4VTM(DEBUG, "hold");
  1387. }
  1388. DWORD dwByteTrans;
  1389. PostQueuedCompletionStatus(hCompletionPort, dwByteTrans, 0, 0);
  1390. closesocket(g_sListen);
  1391. #endif //linux
  1392. }
  1393. #if linux
  1394. static void sig_handle(int signo)
  1395. {
  1396. switch (signo) {
  1397. case SIGSEGV:
  1398. {
  1399. LOG4VTM(INFO, "=========>>> capture signal SIGSEGV <<<=========");
  1400. break;
  1401. }
  1402. case SIGTERM:
  1403. LOG4VTM(INFO, "=========>>> capture signal SIGTERM <<<=========");
  1404. break;
  1405. case SIGCHLD:
  1406. {
  1407. LOG4VTM(INFO, "=========>>> capture signal SIGCHLD <<<=========");
  1408. if (signal(SIGCHLD, sig_handle) == SIG_ERR)
  1409. LOG4VTM(ERROR, "signal error.");
  1410. int status;
  1411. pid_t pid;
  1412. while ((pid = waitpid(0, &status, WNOHANG)) > 0) {
  1413. char szMsg[256] = { '\0' };
  1414. bool excep(false);
  1415. if (WIFEXITED(status)) {
  1416. sprintf(szMsg, "child process %d terminated normal with exit code: %d", pid, WEXITSTATUS(status));
  1417. } else {
  1418. const int signum = WTERMSIG(status);
  1419. sprintf(szMsg, "child process %d has been terminated unexpectly by signal %d", pid, signum);
  1420. //if(signum != SIGKILL)
  1421. excep = true;
  1422. }
  1423. LOG4VTM(INFO, szMsg);
  1424. if (g_SpShellPID != 0 && g_SpShellPID == pid) {
  1425. LOG4VTM(INFO, "Specified spshell process has exited!");
  1426. g_SpShellPID = 0;
  1427. if (excep) {
  1428. LOG4VTM(INFO, "Confirm other relate process has been terminated.");
  1429. int count = 60;
  1430. alive_process_info processes[60];
  1431. memset(processes, 0, sizeof(processes));
  1432. if (!osutil_detect_unique_app(relate_processes_ex, array_size(relate_processes_ex), &count, processes)) {
  1433. bool spshell_exist(false);
  1434. for (int i = 0; i < count; ++i) {
  1435. if (strcmp(processes[i].name, spshell_execute_name) == 0) {
  1436. spshell_exist = true;
  1437. break;
  1438. }
  1439. }
  1440. for (int i = 0; !spshell_exist && i < count; ++i) {
  1441. kill(processes[i].pid, SIGKILL);
  1442. LOG4VTM(INFO, "kill " << processes[i].name << ", pid: " << processes[i].pid << ", err: " <<errno);
  1443. }
  1444. }
  1445. }
  1446. }
  1447. }
  1448. break;
  1449. }
  1450. default:
  1451. char szMsg[256] = { '\0' };
  1452. sprintf(szMsg, "=========>>> capture signal %d <<<=========", signo);
  1453. LOG4VTM(INFO, szMsg);
  1454. break;
  1455. }
  1456. return;
  1457. }
  1458. #endif
  1459. int main(int argc, char* argv[])
  1460. {
  1461. //attach file descriptors 0,1,2 to /dev/null(for deamon app)
  1462. std::string terminalno;
  1463. int fd0, fd1, fd2;
  1464. g_bFrameOnline = true;
  1465. //MessageBox(NULL, NULL, NULL, 0);
  1466. if (argc > 1)
  1467. terminalno = argv[1];
  1468. #ifdef linux
  1469. fd0 = open("/dev/null", O_RDWR);
  1470. fd1 = dup(0);
  1471. fd2 = dup(0);
  1472. pthread_mutex_init(&g_cs_event,NULL);
  1473. pthread_mutex_init(&g_cs_log,NULL);
  1474. pthread_mutex_init(&g_cs,NULL);
  1475. #else
  1476. InitializeCriticalSectionAndSpinCount(&g_cs_event, 100);
  1477. InitializeCriticalSectionAndSpinCount(&g_cs_log, 100);
  1478. InitializeCriticalSectionAndSpinCount(&g_cs, 100);
  1479. ZeroMemory(currDirBuf, sizeof(currDirBuf));
  1480. ZeroMemory(chDisk, sizeof(chDisk));
  1481. GetCurrentDirectory(256, currDirBuf);
  1482. chDisk[0] = currDirBuf[0];
  1483. #endif
  1484. cmb::log_init_config config;
  1485. config.dev_name = "guardian";
  1486. config.terminalno = terminalno;
  1487. ///*TODO: 依赖上层提供环境变量来控制路径和开关,可以考虑厂商的方式 (80374374@1/4/2024)*/
  1488. #if defined(_MSC_VER)
  1489. config.log_dir = ("C:\\rvc\\dbg\\");
  1490. #else
  1491. config.log_dir = ("/opt/rvc/dbg/");
  1492. #endif //_MSC_VER
  1493. std::string str;
  1494. cmb::log4rvcother::init(config, str);
  1495. g_dwTimeBegin = GetTickCountRVC();
  1496. int i=1000;
  1497. LOG4VTM(INFO, "guardian version: " << GUARDIAN_VERSION_STR);
  1498. #if linux
  1499. g_SpShellPID = GetSpshellProcID();
  1500. LOG4VTM(INFO, ("get spshell proc id: ") << g_SpShellPID);
  1501. if (signal(SIGCHLD, sig_handle) == SIG_ERR) {
  1502. LOG4VTM(WARN, ("register for SIGCHLD failed: ") << errno);
  1503. } else {
  1504. LOG4VTM(DEBUG, ("register for SIGCHLD succ."));
  1505. }
  1506. #endif
  1507. StartDoNetControlRVC();
  1508. InitListenSocketRVC();
  1509. AcceptReqRVC();
  1510. }
  1511. void NetControl()
  1512. {
  1513. return;//oiltmp 20150724 for zl don't forbid net for now
  1514. #ifdef linux
  1515. //todo oiltestlinux
  1516. #else
  1517. HINSTANCE hmod = ::LoadLibrary(DLL_PATH);
  1518. if(hmod != NULL)
  1519. {
  1520. LOG4VTM(INFO, "NetControl start");
  1521. pWlanConnect WlanConnect = (pWlanConnect)GetProcAddress(hmod, "WlanConnect");
  1522. pDisableBluetooth BluetoothConnect = (pDisableBluetooth)GetProcAddress(hmod, "DisableBluetooth");
  1523. if (WlanConnect != NULL && BluetoothConnect != NULL)
  1524. {
  1525. DWORD dwRetWire,dwRetEther,dwRet3G,dwRet4G,dwRetBT;
  1526. dwRetWire = dwRetEther = dwRet3G = dwRet4G = dwRetBT = 0;
  1527. dwRetWire = WlanConnect(FALSE, NET_TYPE_WIRELESS);
  1528. LOG4VTM(DEBUG, "after wireless");
  1529. dwRetEther = WlanConnect(FALSE, NET_TYPE_ETHERNET);
  1530. LOG4VTM(DEBUG, "after ether");
  1531. dwRet3G = WlanConnect(FALSE, NET_TYPE_3G);
  1532. LOG4VTM(DEBUG, "after 3g");
  1533. dwRet4G = WlanConnect(FALSE, NET_TYPE_4G);
  1534. LOG4VTM(DEBUG, "after 4g");
  1535. dwRetBT = BluetoothConnect(TRUE);
  1536. LOG4VTM(DEBUG, "after bluetooth");
  1537. char buf[128];
  1538. ZeroMemory(buf,sizeof(buf));
  1539. sprintf(buf,"Wire Net open state:Wireless[%d],Ethernet[%d],3G[%d],4G[%d],Blue tooth[%d]",dwRetWire,dwRetEther,dwRet3G,dwRet4G,dwRetBT);
  1540. LOG4VTM(INFO, buf);
  1541. }
  1542. else
  1543. LOG4VTM(WARN, "Get function from CmbPadDll failed!");
  1544. }
  1545. else
  1546. LOG4VTM(WARN, "load CmbPadDll failed!");
  1547. #endif //linux
  1548. }