guardian.cpp 44 KB

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