guardian.cpp 44 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688
  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. #if defined(RVC_OS_WIN)
  391. const int leastLength = strlen("C:\\version\\1.0.0.0\\");
  392. #else
  393. const int leastLength = strlen("Run/version/1.0.0.0/");
  394. #endif //RVC_OS_WIN
  395. std::string path(value.c_str());
  396. if (path.empty() || path.size() < leastLength) return false;
  397. const std::size_t sionPos = path.find("version");
  398. const std::size_t verPos = sionPos + strlen("version\\");
  399. if (sionPos == std::string::npos) return false;
  400. std::size_t suffixPos = std::string::npos, i;
  401. std::size_t dotCnt = 0;
  402. bool lastIsNum = false;
  403. for (i = verPos; i < path.size() && (path[i] >= '0' && path[i] <= '9' || path[i] == '.'); ++i) {
  404. lastIsNum = !(path[i] == '.');
  405. if (!lastIsNum) dotCnt++;
  406. }
  407. if (i >= path.size() || dotCnt != 3 || !lastIsNum)
  408. return false;
  409. return true;
  410. }
  411. /** 移除跟版本目录相关的环境变量信息*/
  412. static std::string CutSpPathFromPathValue(const char* value)
  413. {
  414. std::string path(value);
  415. std::string result("");
  416. std::vector<std::string> values = Split(path, ':');
  417. if (values.size() <= 0) {
  418. return path;
  419. }
  420. for (auto i = values.cbegin(); i != values.cend(); i++) {
  421. if (!IsSpPathType(*i)) {
  422. if (!result.empty()) result += ":";
  423. result += (*i);
  424. }
  425. }
  426. if (!result.empty() && path[path.size() - 1] == ':') {
  427. result += ":";
  428. }
  429. return result;
  430. }
  431. static void ResetEnviromentVars(const char* env)
  432. {
  433. DWORD size;
  434. char* buf;
  435. int len = 0;
  436. size = GetEnvironmentVariableA(env, NULL, 0);
  437. if (size == 0) {
  438. return;
  439. }
  440. len = size + MAX_PATH * 3;
  441. buf = (char*)malloc(len);
  442. memset(buf, 0, sizeof(buf));
  443. size = GetEnvironmentVariableA(env, buf, len);
  444. std::string newValue = CutSpPathFromPathValue(buf);
  445. if (newValue.empty()) {
  446. SetEnvironmentVariableA(env, NULL);
  447. } else if (newValue.size() < size) {
  448. strcpy(buf, newValue.c_str());
  449. SetEnvironmentVariableA(env, buf);
  450. }
  451. #if 1
  452. memset(buf, 0, sizeof(buf));
  453. size = GetEnvironmentVariableA(env, buf, len);
  454. LOG4VTM(INFO, buf << "env: " << env << " size: " << size);
  455. #endif
  456. FREE(buf);
  457. }
  458. static void ResetRelateEnviromentVars( const char* prefix)
  459. {
  460. LOG4VTM(INFO, prefix);
  461. ResetEnviromentVars("LD_LIBRARY_PATH");
  462. ResetEnviromentVars("PATH");
  463. }
  464. #endif //NOT _WIN32
  465. int FrameworkShutdown(bool bUpgrade=false,bool bRestart = true)
  466. {
  467. LOG4VTM(INFO, "in FrameworkShutdown,bUpgrade:" << bUpgrade << ",bRestart:" << bRestart);
  468. if (!bUpgrade)
  469. g_dwTimeBegin = GetTickCountRVC();
  470. NetControl();
  471. #ifdef linux
  472. //todo oiltestlinux
  473. LOG4VTM(DEBUG, "to kill spshell");
  474. ServerReportEvent("FrameworkShutdown linux");
  475. ComfirmSpShellDead();
  476. char tmp[MAX_PATH];
  477. char* pos = NULL;
  478. GetModuleFileNameA(NULL, tmp, MAX_PATH);
  479. LOG4VTM(INFO, "FrameworkShutdown: " << tmp);
  480. if ((pos = strstr(tmp, "/version")) != NULL) {
  481. pos[strlen("/version")+1] = '\0';
  482. ResetRelateEnviromentVars(tmp);
  483. char path[MAX_PATH] = { '\0' };
  484. bool toResetCWD(false);
  485. LOG4VTM(DEBUG, "to get current directory...");
  486. GetCurrentDirectoryA(MAX_PATH, path);
  487. LOG4VTM(DEBUG, path);
  488. if (strlen(path) <= 0 || strcmp(path, tmp) != 0) {
  489. LOG4VTM(INFO, "to set current directory...");
  490. SetCurrentDirectoryA(tmp);
  491. toResetCWD = true;
  492. }
  493. strcat(tmp, "spexplorer.sh --restart");
  494. LOG4VTM(DEBUG, tmp);
  495. tk_process_t* process = NULL;
  496. tk_process_option_t option;
  497. option.exit_cb = NULL;
  498. option.file = NULL;
  499. option.flags = 0;
  500. option.params = tmp;
  501. if (0 == process_spawn(&option, &process)) {
  502. FREE(process);
  503. LOG4VTM(INFO, "run spexplorer.sh scripts succ.");
  504. Sleep(1000);
  505. g_SpShellPID = GetSpshellProcID();
  506. LOG4VTM(INFO, "get spshell proc id: " << g_SpShellPID);
  507. if (toResetCWD) {
  508. SetCurrentDirectoryA(path);
  509. }
  510. return 0;
  511. } else {
  512. FREE(process);
  513. LOG4VTM(ERROR, "run spexplorer.sh scripts failed!");
  514. if (toResetCWD) {
  515. SetCurrentDirectoryA(path);
  516. }
  517. return -1;
  518. }
  519. }
  520. LOG4VTM(WARN, "get regular version path failed!");
  521. return 0;
  522. #else
  523. STARTUPINFO si;
  524. PROCESS_INFORMATION pi;
  525. ZeroMemory( &si, sizeof(si) );
  526. si.cb = sizeof(si);
  527. ZeroMemory( &pi, sizeof(pi) );
  528. // Start the child process.
  529. std::string csRestart,csVerPath,csAll,csSep("\""),csBlank(" "),csScript("wscript.exe"),csReFlag("r");
  530. csRestart = "sprestart.exe ";
  531. csVerPath = chDisk;
  532. csVerPath = csVerPath + std::string(":\\Run\\version");
  533. csVerPath = csVerPath + std::string("\\VTM.exe");
  534. if (!bRestart)
  535. csReFlag = "n";
  536. csAll = csSep + csRestart + csSep + csBlank + csSep + csVerPath + csSep
  537. + csBlank + csSep + csReFlag + csSep;
  538. char* szCmdline = new char[csAll.length() + 1];
  539. memset(szCmdline, '\0', csAll.length() + 1);
  540. strcpy(szCmdline, csAll.c_str());
  541. if( !CreateProcess( NULL,szCmdline,NULL,NULL,FALSE,CREATE_NEW_CONSOLE,NULL,NULL,&si,&pi))
  542. {
  543. delete[] szCmdline;
  544. return -1;
  545. }
  546. DWORD dwErr = GetLastError();
  547. // Wait until child process exits.
  548. WaitForSingleObject( pi.hProcess, INFINITE );
  549. // Close process and thread handles.
  550. CloseHandle( pi.hProcess );
  551. CloseHandle( pi.hThread );
  552. delete[] szCmdline;
  553. return 0;
  554. #endif //linux
  555. }
  556. bool FrameworkRollBack()
  557. {
  558. bool bVerRollback = VersionRollback();
  559. LOG4VTM(INFO, "version rollback ");
  560. if (true)
  561. FrameworkShutdown();
  562. return true;
  563. }
  564. bool ReadRuninfoContent(string &strData)
  565. {
  566. fstream runinfo;
  567. string strGdRuninfoPath;
  568. #ifdef linux
  569. //todo oiltestlinux
  570. char tmp[MAX_PATH];
  571. char* pos = NULL;
  572. GetModuleFileNameA(NULL, tmp, MAX_PATH);
  573. if ((pos = strstr(tmp, "/Run/")) != NULL) {
  574. pos[strlen("/Run/")] = '\0';
  575. strGdRuninfoPath = string(tmp) + "runinfo/runcfg/gdruninfo";
  576. }
  577. else {
  578. strGdRuninfoPath = "/opt/Run/runinfo/runcfg/gdruninfo";
  579. }
  580. #else
  581. string strDisk(chDisk);
  582. strGdRuninfoPath = strDisk + ":\\Run\\runinfo\\runcfg\\gdruninfo";
  583. #endif //linux
  584. LOG4VTM(INFO, strGdRuninfoPath.c_str());
  585. runinfo.open(strGdRuninfoPath,std::fstream::in|std::fstream::out|std::fstream::binary);
  586. if (!runinfo.is_open())
  587. {
  588. LOG4VTM(INFO, "open gdruninfo(read) failed.");
  589. return false;
  590. }
  591. runinfo.seekg(0,ios::end);
  592. int size = runinfo.tellg();
  593. if (size <= 0)
  594. return false;
  595. char *pData = new char[size+1];
  596. memset(pData,0,size+1);
  597. runinfo.seekg(0,ios::beg);
  598. runinfo.read(pData,size);
  599. strData = string(pData);
  600. LOG4VTM(INFO, "read runinfo " << strData);
  601. return true;
  602. }
  603. bool WriteRunInfoContent(const char* pData)
  604. {
  605. ofstream runinfo;
  606. string strGdRuninfoPath;
  607. #ifdef linux
  608. //todo oiltestlinux
  609. char tmp[MAX_PATH];
  610. char* pos = NULL;
  611. GetModuleFileNameA(NULL, tmp, MAX_PATH);
  612. LOG4VTM(INFO, tmp);
  613. if ((pos = strstr(tmp, "/Run/")) != NULL) {
  614. pos[strlen("/Run/")] = '\0';
  615. strGdRuninfoPath = string(tmp) + "runinfo/runcfg/gdruninfo";
  616. }
  617. else {
  618. strGdRuninfoPath = "/opt/Run/runinfo/runcfg/gdruninfo";
  619. }
  620. LOG4VTM(INFO, strGdRuninfoPath.c_str());
  621. #else
  622. string strDisk(chDisk);
  623. strGdRuninfoPath = strDisk + ":\\Run\\runinfo\\runcfg\\gdruninfo";
  624. #endif //linux
  625. runinfo.open(strGdRuninfoPath,std::ofstream::in|std::ofstream::binary|std::ofstream::trunc);
  626. if (!runinfo.is_open())
  627. {
  628. LOG4VTM(INFO, "open gdruninfo(write) failed.");
  629. ServerReportEvent("open gdruninfo(write) failed.");
  630. return false;
  631. }
  632. runinfo.write(pData,strlen(pData));
  633. runinfo.close();
  634. LOG4VTM(INFO, "write " << strGdRuninfoPath << " done");
  635. return true;
  636. }
  637. bool IsStartTimeFileExist()
  638. {
  639. ofstream runinfo;
  640. string strStartTimePath;
  641. #ifdef linux
  642. //todo oiltestlinux
  643. char tmp[MAX_PATH];
  644. char* pos = NULL;
  645. GetModuleFileNameA(NULL, tmp, MAX_PATH);
  646. LOG4VTM(INFO, "IsStartTimeFileExist: " << tmp);
  647. if ((pos = strstr(tmp, "/Run/")) != NULL) {
  648. pos[strlen("/Run/")] = '\0';
  649. strStartTimePath = string(tmp) + "runinfo/runcfg/starttime.dat";
  650. }
  651. else {
  652. strStartTimePath = "/opt/Run/runinfo/runcfg/starttime.dat";
  653. }
  654. #else
  655. string strDisk(chDisk);
  656. strStartTimePath = strDisk + ":\\Run\\runinfo\\runcfg\\starttime.dat";
  657. #endif //linux
  658. runinfo.open(strStartTimePath, std::fstream::in | std::fstream::out | std::fstream::binary);
  659. if (!runinfo.is_open()) {
  660. LOG4VTM(ERROR, "open starttime.dat failed");
  661. return false;
  662. }
  663. else
  664. {
  665. runinfo.close();
  666. LOG4VTM(DEBUG, "open starttime.dat succ");
  667. return true;
  668. }
  669. }
  670. #ifdef linux
  671. void CheckDoWork(int sig)
  672. {
  673. cout << "CheckDoWork" << endl;
  674. if (SIGALRM == sig)
  675. {
  676. EnterCriticalSectionRVC(g_cs);
  677. if (!g_bFrameQuit)
  678. {
  679. ULONGLONG dwTmpBegin = g_dwTimeBegin;
  680. ULONGLONG dwUpgradeTmpBegin = g_dwUpgradeRestartTimeBegin;
  681. LeaveCriticalSectionRVC(g_cs);
  682. ULONGLONG dwTimeEnd = GetTickCountRVC();
  683. //oilyang@20190828 add
  684. //升级重启后,在10分钟内,只要离最后一次交互时间大于2分钟,重启框架
  685. if ((g_bInUpgrade && ((dwTimeEnd - dwUpgradeTmpBegin) < MAX_WAIT_TIME_TO_RESTART))
  686. && (!g_bAuthSuc && ((dwTimeEnd - dwTmpBegin) > MAX_WAIT_TIME_TO_RESTART_UPGRADE)))
  687. {
  688. LOG4VTM(WARN, "**in upgrade restart**,to restart framework(linux).");
  689. FrameworkShutdown(true, true);
  690. }
  691. if ((dwTimeEnd - dwTmpBegin) > MAX_WAIT_TIME_TO_RESTART)
  692. {
  693. LOG4VTM(ERROR, "framework maybe down.");
  694. string strRunInfo;
  695. if (ReadRuninfoContent(strRunInfo))
  696. {
  697. LOG4VTM(INFO, "to check if need rollback.");
  698. LOG4VTM(INFO, (char*)strRunInfo.c_str());
  699. if (strRunInfo.compare("111") == 0 && IsStartTimeFileExist())
  700. {
  701. EnterCriticalSectionRVC(g_cs);
  702. g_needToRollBack = 1;
  703. LeaveCriticalSectionRVC(g_cs);
  704. }
  705. }
  706. else
  707. LOG4VTM(WARN, "read run info failed.");
  708. if (g_needToRollBack)
  709. {
  710. LOG4VTM(INFO, "after upgrade,time elapse,but can't wait the shake hands,so rollback.");
  711. FrameworkRollBack();
  712. }
  713. else
  714. {
  715. //framework is down,to restart it! oilyang 20150413
  716. FrameworkShutdown();
  717. }
  718. }
  719. }
  720. else
  721. LeaveCriticalSectionRVC(g_cs);
  722. alarm(2 * 60); //we contimue set the timer
  723. }
  724. return;
  725. }
  726. void* DoWorkLinux(void* arg)
  727. {
  728. LOG4VTM(DEBUG, "DoWorkLinux");
  729. signal(SIGALRM, CheckDoWork); //relate the signal and function
  730. alarm(2 * 60); //trigger the timer
  731. EndThreadRVC();
  732. }
  733. void* DoNetControlLinux(void* arg)
  734. {
  735. LOG4VTM(DEBUG, "to end DoNetControlLinux");
  736. EndThreadRVC();
  737. LOG4VTM(DEBUG, "after end DoNetControlLinux");
  738. }
  739. void DataProcessLinux(int socket,const char*data)
  740. {
  741. GuardianInfo* pInfo = (GuardianInfo*)data;
  742. LOG4VTM(DEBUG, "eType:" << pInfo->eType << ",p1:" << pInfo->dwParam1 << ",p2:" << pInfo->dwParam2 << ",dwSize:" << pInfo->dwSize);
  743. switch (pInfo->eType)
  744. {
  745. case GdOpShakeHand:
  746. {
  747. if (!g_bFrameOnline)
  748. {
  749. g_bFrameOnline = true;
  750. g_SpShellPID = GetSpshellProcID();
  751. LOG4VTM(INFO, "get spshell proc id" << g_SpShellPID);
  752. StartDoNetControlRVC();
  753. }
  754. int rc, err;
  755. EnterCriticalSectionRVC(g_cs);
  756. g_bFrameQuit = false;
  757. g_dwTimeBegin = GetTickCountRVC();
  758. LeaveCriticalSectionRVC(g_cs);
  759. char* pBuf = new char[8];
  760. memset(pBuf, 0, 8);
  761. //get guardian state
  762. //ex:u(update),g(guardian),r(reboot),b(rollback)
  763. if (cnt % 2 == 0)
  764. memcpy(pBuf, "g", 1);
  765. else
  766. memcpy(pBuf, "u", 1);
  767. cnt++;
  768. rc = send(socket, pBuf, 8, 0);
  769. delete[]pBuf;
  770. close(socket);
  771. }
  772. break;
  773. case GdOpUpdateTask:
  774. {
  775. if (!g_bFrameOnline)
  776. {
  777. g_bFrameOnline = true;
  778. g_SpShellPID = GetSpshellProcID();
  779. LOG4VTM(INFO, "get spshell proc id" << g_SpShellPID);
  780. StartDoNetControlRVC();
  781. }
  782. }
  783. break;
  784. case GdOpQueryInstall:
  785. {
  786. if (!g_bFrameOnline)
  787. {
  788. g_bFrameOnline = true;
  789. g_SpShellPID = GetSpshellProcID();
  790. LOG4VTM(INFO, "get spshell proc id" << g_SpShellPID);
  791. StartDoNetControlRVC();
  792. }
  793. int rc, err;
  794. char* pBuf = new char[8];
  795. memset(pBuf, 0, 8);
  796. if (cnt % 2 == 0)
  797. memcpy(pBuf, "y", 1);
  798. else
  799. memcpy(pBuf, "n", 1);
  800. cnt++;
  801. rc = send(socket, pBuf, 8, 0);
  802. delete[]pBuf;
  803. close(socket);
  804. }
  805. break;
  806. case GdOpUpgradeRestart:
  807. {
  808. if (pInfo->dwParam1 == 6)//HealthManager call guardian to quit
  809. {
  810. LOG4VTM(INFO, "HealthManager call guardian to quit");
  811. close(socket);
  812. close(g_sListen);
  813. exit(0);//baoli?
  814. break;
  815. }
  816. if (pInfo->dwParam1 == 4)//just know framework is starting...
  817. {
  818. LOG4VTM(INFO, "framework is starting...");
  819. g_bFrameOnline = true;
  820. g_SpShellPID = GetSpshellProcID();
  821. LOG4VTM(INFO, "get spshell proc id" << g_SpShellPID);
  822. g_bAuthSuc = false;
  823. StartDoNetControlRVC();
  824. LOG4VTM(DEBUG, "to break upgrade...");
  825. close(socket);
  826. break;
  827. }
  828. if (pInfo->dwParam1 == 5)
  829. {
  830. LOG4VTM(INFO, "framework auth ok.");
  831. g_bInUpgrade = false;
  832. g_bAuthSuc = true;
  833. }
  834. if (!g_bFrameOnline)
  835. {
  836. g_bFrameOnline = true;
  837. g_SpShellPID = GetSpshellProcID();
  838. LOG4VTM(INFO, "get spshell proc id" << g_SpShellPID);
  839. StartDoNetControlRVC();
  840. }
  841. if (pInfo->dwParam1 == 1 || pInfo->dwParam1 == 3)
  842. g_dwTimeBegin = GetTickCountRVC();
  843. ServerReportEvent("upgrade restart");
  844. LOG4VTM(INFO, "upgrade restart " << pInfo->dwParam1);
  845. if (pInfo->dwParam1 == 1)//framework to restart after upgrade
  846. {
  847. g_bInUpgrade = true;
  848. WriteRunInfoContent("111");
  849. g_dwUpgradeRestartTimeBegin = GetTickCountRVC();
  850. }
  851. else if (pInfo->dwParam1 == 2)//need rollback after upgrade
  852. {
  853. LOG4VTM(INFO, "upgrade restart 222");
  854. WriteRunInfoContent("222");
  855. //rollback
  856. EnterCriticalSectionRVC(g_cs);
  857. g_needToRollBack = 0;
  858. LeaveCriticalSectionRVC(g_cs);
  859. LOG4VTM(INFO, "healthmanager said to rollback");
  860. FrameworkRollBack();
  861. }
  862. else if (pInfo->dwParam1 == 3)//upgrade succeeded
  863. {
  864. LOG4VTM(INFO, "upgrade restart ok");
  865. WriteRunInfoContent("333");
  866. EnterCriticalSectionRVC(g_cs);
  867. g_needToRollBack = 0;
  868. LeaveCriticalSectionRVC(g_cs);
  869. }
  870. //runinfo.close();
  871. close(socket);
  872. }
  873. break;
  874. case GdOpFrameQuit:
  875. if (!g_bFrameOnline)
  876. {
  877. g_bFrameOnline = true;
  878. g_SpShellPID = GetSpshellProcID();
  879. LOG4VTM(INFO, "get spshell proc id" << g_SpShellPID);
  880. StartDoNetControlRVC();
  881. }
  882. EnterCriticalSectionRVC(g_cs);
  883. g_bFrameQuit = true;
  884. LeaveCriticalSectionRVC(g_cs);
  885. close(socket);
  886. break;
  887. default:
  888. break;
  889. }
  890. LOG4VTM(DEBUG, "quit of DataProcessLinux");
  891. }
  892. #else
  893. void DataProcess(LPPER_HANDLE_DATA pPerHandleData,LPPER_IO_OPERATION_DATA pPerIoData)
  894. {
  895. GuardianInfo* pInfo = (GuardianInfo*)pPerIoData->Buffer;
  896. switch(pInfo->eType)
  897. {
  898. case GdOpShakeHand:
  899. {
  900. if (!g_bFrameOnline)
  901. {
  902. g_bFrameOnline = true;
  903. StartDoNetControlRVC();
  904. }
  905. int rc,err;
  906. EnterCriticalSectionRVC(g_cs);
  907. g_bFrameQuit = false;
  908. g_dwTimeBegin = GetTickCountRVC();
  909. LeaveCriticalSectionRVC(g_cs);
  910. char* pBuf = new char[8];
  911. memset(pBuf,0,8);
  912. //get guardian state
  913. //ex:u(update),g(guardian),r(reboot),b(rollback)
  914. if (cnt%2 == 0)
  915. memcpy(pBuf,"g",1);
  916. else
  917. memcpy(pBuf,"u",1);
  918. cnt++;
  919. rc = send(pPerHandleData->Socket,pBuf,8,0);
  920. delete []pBuf;
  921. closesocket(pPerHandleData->Socket);
  922. }
  923. break;
  924. case GdOpUpdateTask:
  925. {
  926. if (!g_bFrameOnline)
  927. {
  928. g_bFrameOnline = true;
  929. StartDoNetControlRVC();
  930. }
  931. }
  932. break;
  933. case GdOpQueryInstall:
  934. {
  935. if (!g_bFrameOnline)
  936. {
  937. g_bFrameOnline = true;
  938. StartDoNetControlRVC();
  939. }
  940. int rc,err;
  941. char* pBuf = new char[8];
  942. memset(pBuf,0,8);
  943. if (cnt%2 == 0)
  944. memcpy(pBuf,"y",1);
  945. else
  946. memcpy(pBuf,"n",1);
  947. cnt++;
  948. rc = send(pPerHandleData->Socket,pBuf,8,0);
  949. delete []pBuf;
  950. closesocket(pPerHandleData->Socket);
  951. }
  952. break;
  953. case GdOpUpgradeRestart:
  954. {
  955. if (pInfo->dwParam1 == 6)//need Upgrade guardian !!!Only!!!
  956. {
  957. g_needUpgradeGuardianOnly = true;
  958. }
  959. if (pInfo->dwParam1 == 4)//just know framework is starting...
  960. {
  961. LOG4VTM(INFO, "framework is starting...");
  962. //oilyang@20211208 add the following if receive framework is starting ,reset g_dwUpgradeRestartTimeBegin
  963. //in order to skip the cost time of "kill spshell"
  964. g_dwUpgradeRestartTimeBegin = GetTickCountRVC();
  965. g_bFrameOnline = true;
  966. g_bAuthSuc = false;
  967. StartDoNetControlRVC();
  968. break;
  969. }
  970. if (pInfo->dwParam1 == 5)
  971. {
  972. LOG4VTM(INFO, "framework auth ok.");
  973. g_bInUpgrade = false;
  974. g_bAuthSuc = true;
  975. }
  976. if (!g_bFrameOnline)
  977. {
  978. g_bFrameOnline = true;
  979. StartDoNetControlRVC();
  980. }
  981. if (pInfo->dwParam1 == 1 || pInfo->dwParam1 == 3)
  982. g_dwTimeBegin = GetTickCountRVC();
  983. ServerReportEvent("upgrade restart");
  984. LOG4VTM(INFO, "upgrade restart " << pInfo->dwParam1);
  985. if (pInfo->dwParam1 == 1)//framework to restart after upgrade
  986. {
  987. g_bInUpgrade = true;
  988. WriteRunInfoContent("111");
  989. g_dwUpgradeRestartTimeBegin = GetTickCountRVC();
  990. }
  991. else if (pInfo->dwParam1 == 2)//need rollback after upgrade
  992. {
  993. LOG4VTM(INFO, "upgrade restart 222");
  994. WriteRunInfoContent("222");
  995. //rollback
  996. EnterCriticalSectionRVC(g_cs);
  997. g_needToRollBack = 0;
  998. LeaveCriticalSectionRVC(g_cs);
  999. LOG4VTM(INFO, "healthmanager said to rollback");
  1000. FrameworkRollBack();
  1001. }else if (pInfo->dwParam1 == 3)//upgrade succeeded
  1002. {
  1003. LOG4VTM(INFO, "upgrade restart ok");
  1004. WriteRunInfoContent("333");
  1005. EnterCriticalSectionRVC(g_cs);
  1006. g_needToRollBack = 0;
  1007. LeaveCriticalSectionRVC(g_cs);
  1008. }
  1009. //runinfo.close();
  1010. closesocket(pPerHandleData->Socket);
  1011. }
  1012. break;
  1013. case GdOpFrameQuit:
  1014. if (!g_bFrameOnline)
  1015. {
  1016. g_bFrameOnline = true;
  1017. StartDoNetControlRVC();
  1018. }
  1019. EnterCriticalSectionRVC(g_cs);
  1020. g_bFrameQuit = true;
  1021. LeaveCriticalSectionRVC(g_cs);
  1022. closesocket(pPerHandleData->Socket);
  1023. break;
  1024. default:
  1025. break;
  1026. }
  1027. }
  1028. DWORD WINAPI ProcessIO(LPVOID lpParam)
  1029. {
  1030. HANDLE CompletionPort = (HANDLE)lpParam;
  1031. DWORD BytesTransferred;
  1032. LPPER_HANDLE_DATA PerHandleData;
  1033. LPPER_IO_OPERATION_DATA PerIoData;
  1034. while(true)
  1035. {
  1036. if(0 == GetQueuedCompletionStatus(CompletionPort, &BytesTransferred, (LPDWORD)&PerHandleData, (LPOVERLAPPED*)&PerIoData, INFINITE))
  1037. {
  1038. if( (GetLastError() == WAIT_TIMEOUT) || (GetLastError() == ERROR_NETNAME_DELETED) )
  1039. {
  1040. LOG4VTM(INFO, "closing socket(1) " << PerHandleData->Socket);
  1041. closesocket(PerHandleData->Socket);
  1042. delete PerIoData;
  1043. delete PerHandleData;
  1044. continue;
  1045. }
  1046. else
  1047. {
  1048. //OutErr("GetQueuedCompletionStatus failed!");
  1049. }
  1050. return 0;
  1051. }
  1052. // client quit
  1053. if(BytesTransferred == 0)
  1054. {
  1055. LOG4VTM(INFO, "closing socket(2) " <<PerHandleData->Socket);
  1056. closesocket(PerHandleData->Socket);
  1057. delete PerIoData;
  1058. delete PerHandleData;
  1059. continue;
  1060. }
  1061. // receiving data process
  1062. DataProcess(PerHandleData,PerIoData);
  1063. // socket WSARecv
  1064. DWORD Flags = 0;
  1065. DWORD dwRecv = 0;
  1066. ZeroMemory(PerIoData, sizeof(PER_IO_OPERATION_DATA));
  1067. PerIoData->DataBuf.buf = PerIoData->Buffer;
  1068. PerIoData->DataBuf.len = DATA_BUFSIZE;
  1069. WSARecv(PerHandleData->Socket, &PerIoData->DataBuf, 1, &dwRecv, &Flags, &PerIoData->Overlapped, NULL);
  1070. }
  1071. return 0;
  1072. }
  1073. DWORD WINAPI DoWork(void* pData)
  1074. {
  1075. LOG4VTM(INFO, "to wait.");
  1076. HANDLE hTimer;
  1077. LARGE_INTEGER li;
  1078. hTimer = CreateWaitableTimer(NULL,FALSE,NULL);
  1079. const int nTimerUnitsPerSecond = 10000000;
  1080. li.QuadPart = -(1*60*nTimerUnitsPerSecond);//oiltmp 1 minute
  1081. SetWaitableTimer(hTimer,&li,2*60*1000,NULL,NULL,FALSE);
  1082. while(1)
  1083. {
  1084. WaitForSingleObject(hTimer,INFINITE);
  1085. EnterCriticalSectionRVC(g_cs);
  1086. if (!g_bFrameQuit)
  1087. {
  1088. ULONGLONG dwTmpBegin = g_dwTimeBegin;
  1089. ULONGLONG dwUpgradeTmpBegin = g_dwUpgradeRestartTimeBegin;
  1090. LeaveCriticalSectionRVC(g_cs);
  1091. ULONGLONG dwTimeEnd = GetTickCountRVC();
  1092. //oilyang@20190828 add
  1093. //升级重启后,在10分钟内,只要离最后一次交互时间大于MAX_WAIT_TIME_TO_RESTART_UPGRADE,重启框架
  1094. if (g_bInUpgrade && ((dwTimeEnd - dwTmpBegin) < MAX_WAIT_TIME_TO_RESTART)
  1095. && (!g_bAuthSuc && ((dwTimeEnd - dwUpgradeTmpBegin) > MAX_WAIT_TIME_TO_RESTART_UPGRADE)))
  1096. {
  1097. LOG4VTM(WARN, "**in upgrade restart**,to restart framework.");
  1098. FrameworkShutdown(true,true);
  1099. }
  1100. if ((dwTimeEnd-dwTmpBegin) > MAX_WAIT_TIME_TO_RESTART)
  1101. {
  1102. LOG4VTM(ERROR, "framework maybe down.");
  1103. string strRunInfo;
  1104. if (ReadRuninfoContent(strRunInfo))
  1105. {
  1106. LOG4VTM(INFO, "to check if need rollback.");
  1107. LOG4VTM(INFO, "runinfo:" << strRunInfo);
  1108. if (strRunInfo.compare("111") == 0 && IsStartTimeFileExist())
  1109. {
  1110. EnterCriticalSectionRVC(g_cs);
  1111. g_needToRollBack = 1;
  1112. LeaveCriticalSectionRVC(g_cs);
  1113. }
  1114. }
  1115. else
  1116. LOG4VTM(WARN, "read run info failed.");
  1117. if (g_needToRollBack)
  1118. {
  1119. LOG4VTM(INFO, "after upgrade,time elapse,but can't wait the shake hands,so rollback.");
  1120. FrameworkRollBack();
  1121. }
  1122. else
  1123. {
  1124. //framework is down,to restart it! oilyang 20150413
  1125. //oilyang@20211221 if Upgrade guardian !!!Only!!! ,just reset dwTmpBegin
  1126. if (!g_needUpgradeGuardianOnly)
  1127. FrameworkShutdown();
  1128. else
  1129. dwTmpBegin = GetTickCountRVC();
  1130. }
  1131. }
  1132. }
  1133. else
  1134. LeaveCriticalSectionRVC(g_cs);
  1135. }
  1136. EndThreadRVC();
  1137. return 0;
  1138. }
  1139. DWORD WINAPI DoNetControl(LPVOID pData)
  1140. {
  1141. ServerReportEvent("DoNetControl start");
  1142. HANDLE hSnapshot;
  1143. //find spshell.exe
  1144. hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  1145. if (hSnapshot)
  1146. {
  1147. PROCESSENTRY32 pe;
  1148. pe.dwSize = sizeof(pe);
  1149. if (Process32First(hSnapshot, &pe))
  1150. {
  1151. do {
  1152. if (_stricmp(&pe.szExeFile[0], "spshell.exe") == 0)
  1153. {
  1154. //ServerReportEvent("find spshell.exe");
  1155. LOG4VTM(INFO, "find spshell.exe");
  1156. //DWORD dwExit = 0;
  1157. //do
  1158. //{
  1159. // GetExitCodeProcess(&pe.th32ProcessID,&dwExit);
  1160. // if (dwExit != STILL_ACTIVE)
  1161. // break;
  1162. //}while(1);
  1163. HANDLE hP = OpenProcess( PROCESS_ALL_ACCESS, FALSE, pe.th32ProcessID );
  1164. WaitForSingleObject(hP, INFINITE );
  1165. LOG4VTM(INFO, "spshell.exe quit");
  1166. //ServerReportEvent("spshell.exe quit");
  1167. NetControl();
  1168. break;
  1169. }
  1170. } while (Process32Next(hSnapshot, &pe));
  1171. }
  1172. CloseHandle(hSnapshot);
  1173. }
  1174. else
  1175. ServerReportEvent("create snapshot failed.");
  1176. EndThreadRVC();
  1177. return 0;
  1178. }
  1179. #endif //linux
  1180. int InitListenSocketRVC()
  1181. {
  1182. #ifdef linux
  1183. socklen_t clilen;
  1184. epfd = epoll_create(256);
  1185. struct sockaddr_in clientaddr;
  1186. struct sockaddr_in serveraddr;
  1187. g_sListen = socket(AF_INET, SOCK_STREAM, 0);
  1188. //setnonblocking(listenfd);
  1189. ev.data.fd = g_sListen;
  1190. ev.events = EPOLLIN | EPOLLET;
  1191. epoll_ctl(epfd, EPOLL_CTL_ADD, g_sListen, &ev);
  1192. memset(&serveraddr, 0, sizeof(serveraddr));
  1193. serveraddr.sin_family = AF_INET;
  1194. char* local_addr = "127.0.0.1";
  1195. inet_aton(local_addr, &(serveraddr.sin_addr));
  1196. serveraddr.sin_port = htons(default_port);
  1197. int tmpuse = 1;
  1198. if (setsockopt(g_sListen, SOL_SOCKET, SO_REUSEPORT, (char*)&tmpuse, sizeof(tmpuse)) < 0)
  1199. {
  1200. LOG4VTM(ERROR, "setsockopt failed. "<< errno);
  1201. LOG4VTM(ERROR, strerror(errno));
  1202. close(g_sListen);
  1203. return -1;
  1204. }
  1205. int ret = bind(g_sListen, (sockaddr*)& serveraddr, sizeof(serveraddr));
  1206. if (ret != 0)
  1207. {
  1208. LOG4VTM(ERROR, "bind failed: " << errno);
  1209. LOG4VTM(ERROR, strerror(errno));
  1210. close(g_sListen);
  1211. return -1;
  1212. }
  1213. ret= listen(g_sListen, LISTENQ);
  1214. if (ret != 0)
  1215. {
  1216. LOG4VTM(ERROR, "listen failed: " << errno);
  1217. LOG4VTM(ERROR, strerror(errno));
  1218. close(g_sListen);
  1219. return -1;
  1220. }
  1221. LOG4VTM(INFO, "(linux)listen ok: " << g_sListen);
  1222. cout << "listen on:" << g_sListen << endl;
  1223. return g_sListen;
  1224. #else
  1225. WSADATA wsaData;
  1226. int iResult;
  1227. struct addrinfo* result = NULL;
  1228. struct addrinfo hints;
  1229. int iSendResult;
  1230. char recvbuf[DEFAULT_BUFLEN];
  1231. int recvbuflen = DEFAULT_BUFLEN;
  1232. // Initialize Winsock
  1233. iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
  1234. if (iResult != 0) {
  1235. LOG4VTM(ERROR, "WSAStartup failed with error:" << iResult);
  1236. return 1;
  1237. }
  1238. ZeroMemory(&hints, sizeof(hints));
  1239. hints.ai_family = AF_INET;
  1240. hints.ai_socktype = SOCK_STREAM;
  1241. hints.ai_protocol = IPPROTO_TCP;
  1242. hints.ai_flags = AI_PASSIVE;
  1243. // Resolve the server address and port
  1244. iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
  1245. if (iResult != 0) {
  1246. LOG4VTM(ERROR, "getaddrinfo failed with error:" << iResult);
  1247. WSACleanup();
  1248. return 1;
  1249. }
  1250. // get system info to create work thread
  1251. SYSTEM_INFO SystemInfo;
  1252. GetSystemInfo(&SystemInfo);
  1253. // Create a SOCKET for connecting to server
  1254. g_sListen = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
  1255. if (g_sListen == INVALID_SOCKET) {
  1256. LOG4VTM(ERROR, "socket failed with error:" << WSAGetLastError());
  1257. freeaddrinfo(result);
  1258. WSACleanup();
  1259. return 1;
  1260. }
  1261. // Setup the TCP listening socket
  1262. struct sockaddr_in* sockaddr_ipv4 = (struct sockaddr_in*) result->ai_addr;
  1263. LOG4VTM(INFO, "ip:"<< inet_ntoa(sockaddr_ipv4->sin_addr));
  1264. iResult = bind(g_sListen, result->ai_addr, (int)result->ai_addrlen);
  1265. if (iResult == SOCKET_ERROR) {
  1266. LOG4VTM(ERROR, "bind failed with error:" << WSAGetLastError());
  1267. freeaddrinfo(result);
  1268. closesocket(g_sListen);
  1269. WSACleanup();
  1270. return 1;
  1271. }
  1272. freeaddrinfo(result);
  1273. LOG4VTM(INFO, "to listen.");
  1274. iResult = listen(g_sListen, SOMAXCONN);
  1275. if (iResult == SOCKET_ERROR) {
  1276. LOG4VTM(ERROR, "listen failed with error: " << WSAGetLastError());
  1277. closesocket(g_sListen);
  1278. WSACleanup();
  1279. return 1;
  1280. }
  1281. LOG4VTM(INFO, "listen ok.");
  1282. return g_sListen;
  1283. #endif //linux
  1284. }
  1285. void AcceptReqRVC()
  1286. {
  1287. #ifdef linux
  1288. StartDoWorkRVC();
  1289. LOG4VTM(DEBUG, "AcceptReqRVC:after StartDoWorkRVC");
  1290. int maxi, connfd, sockfd, nfds;
  1291. struct epoll_event events[20];
  1292. struct sockaddr_in clientaddr;
  1293. socklen_t clilen = sizeof(struct sockaddr);
  1294. ssize_t n;
  1295. maxi = 0;
  1296. char line[MAXLINE];
  1297. for (; ; ) {
  1298. //等待epoll事件的发生
  1299. nfds = epoll_wait(epfd, events, 20, 500);
  1300. //处理所发生的所有事件
  1301. for (int i = 0; i < nfds; ++i)
  1302. {
  1303. LOG4VTM(DEBUG, "nfds: " << nfds);
  1304. if (events[i].data.fd == g_sListen)//new connection
  1305. {
  1306. connfd = accept(g_sListen, (sockaddr*)& clientaddr, &clilen);
  1307. if (connfd < 0) {
  1308. LOG4VTM(ERROR, "connfd<0");
  1309. perror("connfd<0");
  1310. exit(1);
  1311. }
  1312. //setnonblocking(connfd);
  1313. char* str = inet_ntoa(clientaddr.sin_addr);
  1314. LOG4VTM(DEBUG, "accapt a connection from " << str);
  1315. ev.data.fd = connfd;
  1316. ev.events = EPOLLIN | EPOLLET;
  1317. //ev.events=EPOLLIN;
  1318. epoll_ctl(epfd, EPOLL_CTL_ADD, connfd, &ev);
  1319. }
  1320. else if (events[i].events & EPOLLIN)
  1321. {
  1322. LOG4VTM(DEBUG, "EPOLLIN,i:" << i << ",sock:" << events[i].data.fd);
  1323. if ((sockfd = events[i].data.fd) < 0)
  1324. continue;
  1325. if ((n = read(sockfd, line, MAXLINE)) < 0) {
  1326. if (errno == ECONNRESET) {
  1327. close(sockfd);
  1328. events[i].data.fd = -1;
  1329. }
  1330. else
  1331. LOG4VTM(ERROR, "readline error: " << strerror(errno));
  1332. }
  1333. else if (n == 0) {
  1334. close(sockfd);
  1335. events[i].data.fd = -1;
  1336. }
  1337. DataProcessLinux(sockfd,line);
  1338. line[n] = '\0';
  1339. ev.data.fd = sockfd;
  1340. ev.events = EPOLLOUT | EPOLLET;
  1341. epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev);
  1342. LOG4VTM(DEBUG, "out DataProcessLinux");
  1343. }
  1344. else if (events[i].events & EPOLLOUT)
  1345. {
  1346. LOG4VTM(DEBUG, "epoll out");
  1347. sockfd = events[i].data.fd;
  1348. write(sockfd, line, n);
  1349. ev.data.fd = sockfd;
  1350. ev.events = EPOLLIN | EPOLLET;
  1351. epoll_ctl(epfd, EPOLL_CTL_MOD, sockfd, &ev);
  1352. }
  1353. }
  1354. }
  1355. #else
  1356. HANDLE hCompletionPort;
  1357. hCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
  1358. // get system info to create work thread
  1359. SYSTEM_INFO SystemInfo;
  1360. GetSystemInfo(&SystemInfo);
  1361. for (int i = 0; i < SystemInfo.dwNumberOfProcessors * 2; i++)
  1362. {
  1363. HANDLE hProcessIO = CreateThread(NULL, 0, ProcessIO, hCompletionPort, 0, NULL);
  1364. if (hProcessIO)
  1365. CloseHandle(hProcessIO);
  1366. }
  1367. //waiting thread
  1368. StartDoWorkRVC();
  1369. SOCKET sClient;
  1370. LPPER_HANDLE_DATA PerHandleData;
  1371. LPPER_IO_OPERATION_DATA PerIoData;
  1372. while (true)
  1373. {
  1374. //sClient = WSAAccept(sListen, NULL, NULL, NULL, 0);
  1375. sClient = accept(g_sListen, NULL, NULL);
  1376. //cout << "Socket " << sClient << "connect" << endl;
  1377. PerHandleData = new PER_HANDLE_DATA();
  1378. PerHandleData->Socket = sClient;
  1379. // client completion port
  1380. CreateIoCompletionPort((HANDLE)sClient, hCompletionPort, (DWORD)PerHandleData, 0);
  1381. //
  1382. PerIoData = new PER_IO_OPERATION_DATA();
  1383. ZeroMemory(PerIoData, sizeof(PER_IO_OPERATION_DATA));
  1384. PerIoData->DataBuf.buf = PerIoData->Buffer;
  1385. PerIoData->DataBuf.len = DATA_BUFSIZE;
  1386. // WSARecv
  1387. DWORD Flags = 0;
  1388. DWORD dwRecv = 0;
  1389. WSARecv(sClient, &PerIoData->DataBuf, 1, &dwRecv, &Flags, &PerIoData->Overlapped, NULL);
  1390. LOG4VTM(DEBUG, "hold");
  1391. }
  1392. DWORD dwByteTrans;
  1393. PostQueuedCompletionStatus(hCompletionPort, dwByteTrans, 0, 0);
  1394. closesocket(g_sListen);
  1395. #endif //linux
  1396. }
  1397. #if linux
  1398. static void sig_handle(int signo)
  1399. {
  1400. switch (signo) {
  1401. case SIGSEGV:
  1402. {
  1403. LOG4VTM(INFO, "=========>>> capture signal SIGSEGV <<<=========");
  1404. break;
  1405. }
  1406. case SIGTERM:
  1407. LOG4VTM(INFO, "=========>>> capture signal SIGTERM <<<=========");
  1408. break;
  1409. case SIGCHLD:
  1410. {
  1411. LOG4VTM(INFO, "=========>>> capture signal SIGCHLD <<<=========");
  1412. if (signal(SIGCHLD, sig_handle) == SIG_ERR)
  1413. LOG4VTM(ERROR, "signal error.");
  1414. int status;
  1415. pid_t pid;
  1416. while ((pid = waitpid(0, &status, WNOHANG)) > 0) {
  1417. char szMsg[256] = { '\0' };
  1418. bool excep(false);
  1419. if (WIFEXITED(status)) {
  1420. sprintf(szMsg, "child process %d terminated normal with exit code: %d", pid, WEXITSTATUS(status));
  1421. } else {
  1422. const int signum = WTERMSIG(status);
  1423. sprintf(szMsg, "child process %d has been terminated unexpectly by signal %d", pid, signum);
  1424. //if(signum != SIGKILL)
  1425. excep = true;
  1426. }
  1427. LOG4VTM(INFO, szMsg);
  1428. if (g_SpShellPID != 0 && g_SpShellPID == pid) {
  1429. LOG4VTM(INFO, "Specified spshell process has exited!");
  1430. g_SpShellPID = 0;
  1431. if (excep) {
  1432. LOG4VTM(INFO, "Confirm other relate process has been terminated.");
  1433. int count = 60;
  1434. alive_process_info processes[60];
  1435. memset(processes, 0, sizeof(processes));
  1436. if (!osutil_detect_unique_app(relate_processes_ex, array_size(relate_processes_ex), &count, processes)) {
  1437. bool spshell_exist(false);
  1438. for (int i = 0; i < count; ++i) {
  1439. if (strcmp(processes[i].name, spshell_execute_name) == 0) {
  1440. spshell_exist = true;
  1441. break;
  1442. }
  1443. }
  1444. for (int i = 0; !spshell_exist && i < count; ++i) {
  1445. kill(processes[i].pid, SIGKILL);
  1446. LOG4VTM(INFO, "kill " << processes[i].name << ", pid: " << processes[i].pid << ", err: " <<errno);
  1447. }
  1448. }
  1449. }
  1450. }
  1451. }
  1452. break;
  1453. }
  1454. default:
  1455. char szMsg[256] = { '\0' };
  1456. sprintf(szMsg, "=========>>> capture signal %d <<<=========", signo);
  1457. LOG4VTM(INFO, szMsg);
  1458. break;
  1459. }
  1460. return;
  1461. }
  1462. #endif
  1463. int main(int argc, char* argv[])
  1464. {
  1465. //attach file descriptors 0,1,2 to /dev/null(for deamon app)
  1466. std::string terminalno;
  1467. int fd0, fd1, fd2;
  1468. g_bFrameOnline = true;
  1469. //MessageBox(NULL, NULL, NULL, 0);
  1470. if (argc > 1)
  1471. terminalno = argv[1];
  1472. #ifdef linux
  1473. fd0 = open("/dev/null", O_RDWR);
  1474. fd1 = dup(0);
  1475. fd2 = dup(0);
  1476. pthread_mutex_init(&g_cs_event,NULL);
  1477. pthread_mutex_init(&g_cs_log,NULL);
  1478. pthread_mutex_init(&g_cs,NULL);
  1479. #else
  1480. InitializeCriticalSectionAndSpinCount(&g_cs_event, 100);
  1481. InitializeCriticalSectionAndSpinCount(&g_cs_log, 100);
  1482. InitializeCriticalSectionAndSpinCount(&g_cs, 100);
  1483. ZeroMemory(currDirBuf, sizeof(currDirBuf));
  1484. ZeroMemory(chDisk, sizeof(chDisk));
  1485. GetCurrentDirectory(256, currDirBuf);
  1486. chDisk[0] = currDirBuf[0];
  1487. #endif
  1488. cmb::log_init_config config;
  1489. config.dev_name = "guardian";
  1490. config.terminalno = terminalno;
  1491. ///*TODO: 依赖上层提供环境变量来控制路径和开关,可以考虑厂商的方式 (80374374@1/4/2024)*/
  1492. #if defined(_MSC_VER)
  1493. config.log_dir = ("C:\\rvc\\dbg\\");
  1494. #else
  1495. config.log_dir = ("/opt/rvc/dbg/");
  1496. #endif //_MSC_VER
  1497. std::string str;
  1498. cmb::log4rvcother::init(config, str);
  1499. g_dwTimeBegin = GetTickCountRVC();
  1500. int i=1000;
  1501. LOG4VTM(INFO, "guardian version: " << GUARDIAN_VERSION_STR);
  1502. #if linux
  1503. g_SpShellPID = GetSpshellProcID();
  1504. LOG4VTM(INFO, ("get spshell proc id: ") << g_SpShellPID);
  1505. if (signal(SIGCHLD, sig_handle) == SIG_ERR) {
  1506. LOG4VTM(WARN, ("register for SIGCHLD failed: ") << errno);
  1507. } else {
  1508. LOG4VTM(DEBUG, ("register for SIGCHLD succ."));
  1509. }
  1510. #endif
  1511. StartDoNetControlRVC();
  1512. InitListenSocketRVC();
  1513. AcceptReqRVC();
  1514. }
  1515. void NetControl()
  1516. {
  1517. return;//oiltmp 20150724 for zl don't forbid net for now
  1518. #ifdef linux
  1519. //todo oiltestlinux
  1520. #else
  1521. HINSTANCE hmod = ::LoadLibrary(DLL_PATH);
  1522. if(hmod != NULL)
  1523. {
  1524. LOG4VTM(INFO, "NetControl start");
  1525. pWlanConnect WlanConnect = (pWlanConnect)GetProcAddress(hmod, "WlanConnect");
  1526. pDisableBluetooth BluetoothConnect = (pDisableBluetooth)GetProcAddress(hmod, "DisableBluetooth");
  1527. if (WlanConnect != NULL && BluetoothConnect != NULL)
  1528. {
  1529. DWORD dwRetWire,dwRetEther,dwRet3G,dwRet4G,dwRetBT;
  1530. dwRetWire = dwRetEther = dwRet3G = dwRet4G = dwRetBT = 0;
  1531. dwRetWire = WlanConnect(FALSE, NET_TYPE_WIRELESS);
  1532. LOG4VTM(DEBUG, "after wireless");
  1533. dwRetEther = WlanConnect(FALSE, NET_TYPE_ETHERNET);
  1534. LOG4VTM(DEBUG, "after ether");
  1535. dwRet3G = WlanConnect(FALSE, NET_TYPE_3G);
  1536. LOG4VTM(DEBUG, "after 3g");
  1537. dwRet4G = WlanConnect(FALSE, NET_TYPE_4G);
  1538. LOG4VTM(DEBUG, "after 4g");
  1539. dwRetBT = BluetoothConnect(TRUE);
  1540. LOG4VTM(DEBUG, "after bluetooth");
  1541. char buf[128];
  1542. ZeroMemory(buf,sizeof(buf));
  1543. sprintf(buf,"Wire Net open state:Wireless[%d],Ethernet[%d],3G[%d],4G[%d],Blue tooth[%d]",dwRetWire,dwRetEther,dwRet3G,dwRet4G,dwRetBT);
  1544. LOG4VTM(INFO, buf);
  1545. }
  1546. else
  1547. LOG4VTM(WARN, "Get function from CmbPadDll failed!");
  1548. }
  1549. else
  1550. LOG4VTM(WARN, "load CmbPadDll failed!");
  1551. #endif //linux
  1552. }