123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590 |
- // guardian.cpp : Defines the entry point for the console application.
- //
- #include "stdafx.h"
- #ifdef linux
- #include <sys/types.h>
- #include <sys/stat.h>
- #include <sys/socket.h>
- #include <sys/epoll.h>
- #include <netinet/in.h>
- #include <arpa/inet.h>
- #include <assert.h>
- #include <dirent.h>
- #include <fcntl.h>
- #include <unistd.h>
- #include <stdio.h>
- #include <errno.h>
- #include <string.h>
- #include <syslog.h>
- #include <signal.h>
- #include <pthread.h>
- #include <pwd.h>
- #include <signal.h>
- #include <sys/types.h>
- #include <sys/wait.h>
- #include "toolkit.h"
- #include "osutil.h"
- #include "memutil.h"
- #include <winpr/library.h>
- #include <winpr/synch.h>
- #include <winpr/sysinfo.h>
- #include <winpr/environment.h>
- int epfd;
- struct epoll_event ev;
- #define MAXLINE 128
- #define OPEN_MAX 100
- #define LISTENQ 20
- #define INFTIM 1000
- #else
- #undef UNICODE
- #pragma comment( linker, "/subsystem:\"windows\" /entry:\"mainCRTStartup\"" )
- #ifndef WIN32_LEAN_AND_MEAN
- #define WIN32_LEAN_AND_MEAN
- #endif
- #include <windows.h>
- #include <winsock2.h>
- #include <ws2tcpip.h>
- #include <TlHelp32.h>
- #include <direct.h>
- #include <ctime>
- #endif //linux
- #include <iostream>
- #include <fstream>
- #include <string>
- #include <vector>
- #include "GuardianBase.h"
- #include "guardian.h"
- #include "log4rvcother.h"
- #ifndef MAX_PATH
- #define MAX_PATH 260
- #endif
- #define GUARDIAN_VERSION_STR "0.0.2"
- #ifdef RVC_OS_WIN
- static char spshell_execute_name[] = "SpShell.exe";
- static char sphost_execute_name[] = "SpHost.exe";
- static char guardian_execute_name[] = "Guardian.exe";
- static char cefclient_execute_name[] = "cefclient.exe";
- #else
- static char spshell_execute_name[] = "spshell";
- static char sphost_execute_name[] = "sphost";
- static char guardian_execute_name[] = "guardian";
- static char cefclient_execute_name[] = "cefclient";
- #endif //_WIN32
- char* relate_processes[] = { spshell_execute_name };
- char* relate_processes_ex[] = { spshell_execute_name, sphost_execute_name, cefclient_execute_name };
- using namespace std;
- #ifdef linux
- int g_sListen;
- pthread_mutex_t g_cs, g_cs_event, g_cs_log;
- #define EnterCriticalSectionRVC(xType) pthread_mutex_lock(&xType)
- #define LeaveCriticalSectionRVC(xType) pthread_mutex_unlock(&xType)
- static int GetProcID()
- {
- return getpid();
- }
- #else
- SOCKET g_sListen = INVALID_SOCKET;
- DWORD WINAPI DoNetControl(void* pData);
- CRITICAL_SECTION g_cs, g_cs_event, g_cs_log;
- #define EnterCriticalSectionRVC(xType) EnterCriticalSection(&xType)
- #define LeaveCriticalSectionRVC(xType) LeaveCriticalSection(&xType)
- static int GetProcID()
- {
- return GetCurrentProcessId();
- }
- #endif //linux
- const int DEFAULT_BUFLEN = 512;
- const int SHAKEHAND_BUFZIE = 32;
- #define DEFAULT_PORT "30005"
- const int default_port = 30005;
- int g_needToRollBack = 0;
- bool g_needUpgradeGuardianOnly = false;
- bool g_bFrameQuit = false,g_bFrameOnline = false,g_bAuthSuc = false,g_bInUpgrade = false;
- ULONGLONG g_dwTimeBegin = 0;
- ULONGLONG g_dwUpgradeRestartTimeBegin = 0;
- int cnt = 0;
- char chDisk[2];
- char currDirBuf[256];
- const int MAX_WAIT_TIME_TO_RESTART = 600000;
- //oilyang@20211208 change value from 110000 to 180000
- const int MAX_WAIT_TIME_TO_RESTART_UPGRADE = 180000;
- static int g_SpShellPID = 0;
- #ifdef linux
- extern "C"
- {
- void* DoWorkLinux(void* arg);
- void* DoNetControlLinux(void* arg);
- }
- #define FUNCTION_STDCALL
- typedef unsigned short WORD;
- #else
- typedef struct
- {
- OVERLAPPED Overlapped;
- WSABUF DataBuf;
- CHAR Buffer[DATA_BUFSIZE];
- } PER_IO_OPERATION_DATA, * LPPER_IO_OPERATION_DATA;
- typedef struct
- {
- SOCKET Socket;
- } PER_HANDLE_DATA, * LPPER_HANDLE_DATA;
- DWORD WINAPI DoWork(void* pData);
- #define FUNCTION_STDCALL __stdcall
- #endif
- int BeginThreadRVC(void* (*pFuncLinux)(void*), LPTHREAD_START_ROUTINE pFuncWin)
- {
- #if defined(_MSC_VER)
- CreateThread(NULL, 0, pFuncWin, NULL, 0, NULL);
- return 0;
- #else
- pthread_t tidp;
- if ((pthread_create(&tidp, NULL, pFuncLinux, NULL) == -1)) {
- return 1;
- }
- cout << "after pthread_create of linux thread" << endl;
- return 0;
- #endif //_MSC_VER
- }
- void EndThreadRVC()
- {
- #ifdef linux
- pthread_exit(0);
- #endif //linux
- }
- void StartDoNetControlRVC()
- {
- #ifdef linux
- BeginThreadRVC(DoNetControlLinux, NULL);
- #else
- BeginThreadRVC(NULL, DoNetControl);
- #endif //linux
- }
- void StartDoWorkRVC()
- {
- #ifdef linux
- BeginThreadRVC(DoWorkLinux, NULL);
- #else
- BeginThreadRVC(NULL, DoWork);
- #endif //linux
- }
- void ServerReportEvent(const char* szFunction,const char* szName="guardian")
- {
- #ifdef linux
- return;//oiltest
- #else
- HANDLE hEventSource;
- LPCTSTR lpszStrings[2];
- char Buffer[1024] = {0};
- hEventSource = RegisterEventSource(NULL, szName);
- if( NULL != hEventSource )
- {
- strcpy_s(Buffer,1024,szFunction);
- lpszStrings[0] = szName;
- lpszStrings[1] = Buffer;
- ReportEvent(hEventSource, // event log handle
- EVENTLOG_ERROR_TYPE, // event type
- 0, // event category
- 0xe0000001, // event identifier
- NULL, // no security identifier
- 2, // size of lpszStrings array
- 0, // no binary data
- lpszStrings, // array of strings
- NULL); // no binary data
- DeregisterEventSource(hEventSource);
- }
- #endif //linux
- }
- bool VersionRollback()
- {
- const int VersionLenMax = 64;
- fstream verFile,verBak;//to confirm
- string strActiveTxtPath, strVersionDatPath;
- #ifdef linux
- char tmp[MAX_PATH];
- char* pos = NULL;
- GetModuleFileNameA(NULL, tmp, MAX_PATH);
- LOG4VTM(INFO, "rollback" << tmp);
- if ((pos = strstr(tmp, "/Run/")) != NULL) {
- pos[strlen("/Run/")] = '\0';
- strActiveTxtPath = string(tmp) + "version/active.txt";
- strVersionDatPath = string(tmp) + "runinfo/runcfg/version.dat";
- }
- else {
- strActiveTxtPath = "/opt/Run/version/active.txt";
- strVersionDatPath = "/opt/Run/runinfo/runcfg/version.dat";
- }
- #else
- string strDisk(chDisk);
- strActiveTxtPath = strDisk + ":\\Run\\version\\active.txt";
- strVersionDatPath = strDisk + ":\\Run\\runinfo\\runcfg\\version.dat";
- #endif //linux
-
- verFile.open(strActiveTxtPath,std::fstream::in|std::fstream::out|std::fstream::binary);
- verBak.open(strVersionDatPath,std::fstream::in|std::fstream::out|std::fstream::binary);
- if (!verFile.is_open() || !verBak.is_open())
- return false;
- char *pVerBak,*pNULL,*pCurrVer;
- pVerBak = new char[VersionLenMax];
- pNULL = new char[VersionLenMax];
- pCurrVer = new char[VersionLenMax];
- memset(pVerBak,0,VersionLenMax);
- memset(pNULL,0,VersionLenMax);
- memset(pCurrVer,0,VersionLenMax);
- verBak.seekg(0,verBak.end);
- int lenBak = verBak.tellg();
- verBak.seekg(0,verBak.beg);
- verBak.read(pVerBak,lenBak);
-
- //need to consider atomic op? oilyang
- verFile.seekg(0,verFile.end);
- int len = verFile.tellg();
- verFile.seekg(0,verFile.beg);
- verFile.read(pCurrVer,len);
- LOG4VTM(INFO, pVerBak);
- LOG4VTM(INFO, pCurrVer);
- LOG4VTM(INFO, pNULL);
- if (strcmp(pVerBak,pCurrVer) == 0)
- {
- ServerReportEvent(pVerBak);
- verFile.close();
- verBak.close();
- delete []pVerBak;
- delete []pNULL;
- return false;
- }
- //verBak.write(pNULL,len);
- //verFile.write(pNULL,len);
- //how foolish?
- verFile.close();
- verFile.open(strActiveTxtPath,std::fstream::in|std::fstream::out|std::fstream::binary|std::fstream::trunc);
- verFile.seekg(0,verFile.beg);
- verFile.write(pVerBak,lenBak);
- LOG4VTM(INFO, "terminal app version will rollback from " << pCurrVer << " to " << pVerBak);
- verFile.close();
- verBak.close();
- delete []pVerBak;
- delete []pNULL;
- return true;
- }
- #ifndef _WIN32
- static int GetSpshellProcID()
- {
- int result(0);
- char* spshell[] = { spshell_execute_name };
- alive_process_info processes[1];
- memset(processes, 0, sizeof(processes));
- int count = 1;
- if (!osutil_detect_unique_app(spshell, array_size(spshell), &count, processes)) {
- result = processes[0].pid;
- }
- return result;
- }
- static void ComfirmSpShellDead()
- {
- char* spshell[] = { spshell_execute_name };
- alive_process_info processes[1];
- memset(processes, 0, sizeof(processes));
- int count = 1;
- if (!osutil_detect_unique_app(spshell, array_size(spshell), &count, processes)) {
- if(g_SpShellPID == 0) g_SpShellPID = processes[0].pid;
- LOG4VTM(WARN, "has spshell process alive! and to kill it");
- assert(count > 0);
- if (kill(processes[0].pid, SIGTERM) != 0) {
- LOG4VTM(WARN, "kill with term for spshell failed, process id: " << processes[0].pid << ", err: " << errno);
- if (errno != 3 /**not exist */) {
- LOG4VTM(INFO, "to kill stronglely!");
- kill(processes[0].pid, SIGKILL);
- }
- } else {
- LOG4VTM(DEBUG, "kill with term for spshell succ. process id: " << processes[0].pid);
- }
- const int waitTimes = 100;
- const int eachTime = 300;
- int curTimes = 0;
- while (g_SpShellPID != 0 && curTimes < waitTimes) {
- if (osutil_detect_unique_app(spshell, array_size(spshell), NULL, NULL)) {
- g_SpShellPID = 0;
- break;
- }
- Sleep(eachTime);
- curTimes++;
- }
- if (g_SpShellPID == 0) {
- LOG4VTM(DEBUG, "spshell has gone!");
- }
- } else {
- LOG4VTM(INFO, "There are no any spshell process existed!");
- }
- //////////////////////////////////////////////////////////////////////////
- count = MAX_ALIVE_PROCESS_COUNT;
- alive_process_info processes2[MAX_ALIVE_PROCESS_COUNT];
- memset(processes2, 0, sizeof(processes2));
- if (!osutil_detect_unique_app(relate_processes_ex, array_size(relate_processes_ex), &count, processes2)) {
- for (int i = 0; i < count; ++i) {
- LOG4VTM(INFO, processes2[i].name << " " << processes2[i].path << " " << processes2[i].pid);
- }
- osutil_terminate_related_process(relate_processes_ex, array_size(relate_processes_ex), 0);
- Sleep(1000);
- }
- }
- inline static std::vector<std::string> Split(std::string str, char splitElem)
- {
- std::vector<std::string> strs;
- std::string::size_type pos1, pos2;
- pos2 = str.find(splitElem);
- pos1 = 0;
- while (std::string::npos != pos2) {
- strs.push_back(str.substr(pos1, pos2 - pos1));
- pos1 = pos2 + 1;
- pos2 = str.find(splitElem, pos1);
- }
- strs.push_back(str.substr(pos1));
- return strs;
- }
- static bool IsSpPathType(const std::string& value)
- {
- const int leastLength = strlen("Run/version/1.0.0.0/");
- std::string path(value.c_str());
- if (path.empty() || path.size() < leastLength) return false;
- const std::size_t sionPos = path.find("version");
- const std::size_t verPos = sionPos + strlen("version\\");
- if (sionPos == std::string::npos) return false;
- std::size_t suffixPos = std::string::npos, i;
- std::size_t dotCnt = 0;
- bool lastIsNum = false;
- for (i = verPos; i < path.size() && (path[i] >= '0' && path[i] <= '9' || path[i] == '.'); ++i) {
- lastIsNum = !(path[i] == '.');
- if (!lastIsNum) dotCnt++;
- }
- if (i >= path.size() || dotCnt != 3 || !lastIsNum)
- return false;
- return true;
- }
- /** 移除跟版本目录相关的环境变量信息*/
- static std::string CutSpPathFromPathValue(const char* value)
- {
- std::string path(value);
- std::string result("");
- std::vector<std::string> values = Split(path, ':');
- if (values.size() <= 0) {
- return path;
- }
- for (auto i = values.cbegin(); i != values.cend(); i++) {
- if (!IsSpPathType(*i)) {
- if (!result.empty()) result += ":";
- result += (*i);
- }
- }
- if (!result.empty() && path[path.size() - 1] == ':') {
- result += ":";
- }
- return result;
- }
- static void ResetEnviromentVars(const char* env)
- {
- DWORD size;
- char* buf;
- int len = 0;
- size = GetEnvironmentVariableA(env, NULL, 0);
- if (size == 0) {
- return;
- }
- len = size + MAX_PATH * 3;
- buf = (char*)malloc(len);
- memset(buf, 0, sizeof(buf));
- size = GetEnvironmentVariableA(env, buf, len);
- std::string newValue = CutSpPathFromPathValue(buf);
- if (newValue.empty()) {
- SetEnvironmentVariableA(env, NULL);
- } else if (newValue.size() < size) {
- strcpy(buf, newValue.c_str());
- SetEnvironmentVariableA(env, buf);
- }
- #if 1
- memset(buf, 0, sizeof(buf));
- size = GetEnvironmentVariableA(env, buf, len);
- LOG4VTM(INFO, buf << "env: " << env << " size: " << size);
- #endif
- FREE(buf);
- }
- static void ResetRelateEnviromentVars( const char* prefix)
- {
- LOG4VTM(INFO, prefix);
- ResetEnviromentVars("LD_LIBRARY_PATH");
- ResetEnviromentVars("PATH");
- }
- #endif //NOT _WIN32
- int FrameworkShutdown(bool bUpgrade=false,bool bRestart = true)
- {
- LOG4VTM(INFO, "in FrameworkShutdown,bUpgrade:" << bUpgrade << ",bRestart:" << bRestart);
- if (!bUpgrade)
- g_dwTimeBegin = GetTickCount64();
- #ifdef linux
- //todo oiltestlinux
- LOG4VTM(DEBUG, "to kill spshell");
- ServerReportEvent("FrameworkShutdown linux");
- ComfirmSpShellDead();
- char tmp[MAX_PATH];
- char* pos = NULL;
- GetModuleFileNameA(NULL, tmp, MAX_PATH);
- LOG4VTM(INFO, "FrameworkShutdown: " << tmp);
- if ((pos = strstr(tmp, "/version")) != NULL) {
- pos[strlen("/version")+1] = '\0';
- ResetRelateEnviromentVars(tmp);
-
- char path[MAX_PATH] = { '\0' };
- bool toResetCWD(false);
- LOG4VTM(DEBUG, "to get current directory...");
- GetCurrentDirectoryA(MAX_PATH, path);
- LOG4VTM(DEBUG, path);
- if (strlen(path) <= 0 || strcmp(path, tmp) != 0) {
- LOG4VTM(INFO, "to set current directory...");
- SetCurrentDirectoryA(tmp);
- toResetCWD = true;
- }
- strcat(tmp, "spexplorer.sh --restart");
- LOG4VTM(DEBUG, tmp);
- tk_process_t* process = NULL;
- tk_process_option_t option;
- option.exit_cb = NULL;
- option.file = NULL;
- option.flags = 0;
- option.params = tmp;
- if (0 == process_spawn(&option, &process)) {
- FREE(process);
- LOG4VTM(INFO, "run spexplorer.sh scripts succ.");
- Sleep(1000);
- g_SpShellPID = GetSpshellProcID();
- LOG4VTM(INFO, "get spshell proc id: " << g_SpShellPID);
- if (toResetCWD) {
- SetCurrentDirectoryA(path);
- }
- return 0;
- } else {
- FREE(process);
- LOG4VTM(ERROR, "run spexplorer.sh scripts failed!");
- if (toResetCWD) {
- SetCurrentDirectoryA(path);
- }
- return -1;
- }
- }
- LOG4VTM(WARN, "get regular version path failed!");
- return 0;
- #else
- STARTUPINFO si;
- PROCESS_INFORMATION pi;
- ZeroMemory( &si, sizeof(si) );
- si.cb = sizeof(si);
- ZeroMemory( &pi, sizeof(pi) );
- // Start the child process.
- std::string csRestart,csVerPath,csAll,csSep("\""),csBlank(" "),csScript("wscript.exe"),csReFlag("r");
- csRestart = "sprestart.exe ";
- csVerPath = chDisk;
- csVerPath = csVerPath + std::string(":\\Run\\version");
- csVerPath = csVerPath + std::string("\\VTM.exe");
- if (!bRestart)
- csReFlag = "n";
- csAll = csSep + csRestart + csSep + csBlank + csSep + csVerPath + csSep
- + csBlank + csSep + csReFlag + csSep;
- char* szCmdline = new char[csAll.length() + 1];
- memset(szCmdline, '\0', csAll.length() + 1);
- strcpy(szCmdline, csAll.c_str());
- if( !CreateProcess( NULL,szCmdline,NULL,NULL,FALSE,CREATE_NEW_CONSOLE,NULL,NULL,&si,&pi))
- {
- delete[] szCmdline;
- return -1;
- }
- DWORD dwErr = GetLastError();
- // Wait until child process exits.
- WaitForSingleObject( pi.hProcess, INFINITE );
- // Close process and thread handles.
- CloseHandle( pi.hProcess );
- CloseHandle( pi.hThread );
- delete[] szCmdline;
- return 0;
- #endif //linux
- }
- bool FrameworkRollBack()
- {
- bool bVerRollback = VersionRollback();
- LOG4VTM(INFO, "version rollback ");
- if (true)
- FrameworkShutdown();
- return true;
- }
- bool ReadRuninfoContent(string &strData)
- {
- fstream runinfo;
- string strGdRuninfoPath;
- #ifdef linux
- //todo oiltestlinux
- char tmp[MAX_PATH];
- char* pos = NULL;
- GetModuleFileNameA(NULL, tmp, MAX_PATH);
- if ((pos = strstr(tmp, "/Run/")) != NULL) {
- pos[strlen("/Run/")] = '\0';
- strGdRuninfoPath = string(tmp) + "runinfo/runcfg/gdruninfo";
- }
- else {
- strGdRuninfoPath = "/opt/Run/runinfo/runcfg/gdruninfo";
- }
- #else
- string strDisk(chDisk);
- strGdRuninfoPath = strDisk + ":\\Run\\runinfo\\runcfg\\gdruninfo";
- #endif //linux
- LOG4VTM(INFO, strGdRuninfoPath.c_str());
- runinfo.open(strGdRuninfoPath,std::fstream::in|std::fstream::out|std::fstream::binary);
- if (!runinfo.is_open())
- {
- LOG4VTM(INFO, "open gdruninfo(read) failed.");
- return false;
- }
- runinfo.seekg(0,ios::end);
- int size = runinfo.tellg();
- if (size <= 0)
- return false;
- char *pData = new char[size+1];
- memset(pData,0,size+1);
- runinfo.seekg(0,ios::beg);
- runinfo.read(pData,size);
- strData = string(pData);
- LOG4VTM(INFO, "read runinfo " << strData);
- return true;
- }
- bool WriteRunInfoContent(const char* pData)
- {
- ofstream runinfo;
- string strGdRuninfoPath;
- #ifdef linux
- //todo oiltestlinux
- char tmp[MAX_PATH];
- char* pos = NULL;
- GetModuleFileNameA(NULL, tmp, MAX_PATH);
- LOG4VTM(INFO, tmp);
- if ((pos = strstr(tmp, "/Run/")) != NULL) {
- pos[strlen("/Run/")] = '\0';
- strGdRuninfoPath = string(tmp) + "runinfo/runcfg/gdruninfo";
- }
- else {
- strGdRuninfoPath = "/opt/Run/runinfo/runcfg/gdruninfo";
- }
- LOG4VTM(INFO, strGdRuninfoPath.c_str());
- #else
- string strDisk(chDisk);
- strGdRuninfoPath = strDisk + ":\\Run\\runinfo\\runcfg\\gdruninfo";
- #endif //linux
- runinfo.open(strGdRuninfoPath,std::ofstream::in|std::ofstream::binary|std::ofstream::trunc);
- if (!runinfo.is_open())
- {
- LOG4VTM(INFO, "open gdruninfo(write) failed.");
- ServerReportEvent("open gdruninfo(write) failed.");
- return false;
- }
- runinfo.write(pData,strlen(pData));
- runinfo.close();
- LOG4VTM(INFO, "write " << strGdRuninfoPath << " done");
- return true;
- }
- bool IsStartTimeFileExist()
- {
- ofstream runinfo;
- string strStartTimePath;
- #ifdef linux
- //todo oiltestlinux
- char tmp[MAX_PATH];
- char* pos = NULL;
- GetModuleFileNameA(NULL, tmp, MAX_PATH);
- LOG4VTM(INFO, "IsStartTimeFileExist: " << tmp);
- if ((pos = strstr(tmp, "/Run/")) != NULL) {
- pos[strlen("/Run/")] = '\0';
- strStartTimePath = string(tmp) + "runinfo/runcfg/starttime.dat";
- }
- else {
- strStartTimePath = "/opt/Run/runinfo/runcfg/starttime.dat";
- }
- #else
- string strDisk(chDisk);
- strStartTimePath = strDisk + ":\\Run\\runinfo\\runcfg\\starttime.dat";
- #endif //linux
- runinfo.open(strStartTimePath, std::fstream::in | std::fstream::out | std::fstream::binary);
- if (!runinfo.is_open()) {
- LOG4VTM(ERROR, "open starttime.dat failed");
- return false;
- }
- else
- {
- runinfo.close();
- LOG4VTM(DEBUG, "open starttime.dat succ");
- return true;
- }
- }
- #ifdef linux
- void CheckDoWork(int sig)
- {
- cout << "CheckDoWork" << endl;
- if (SIGALRM == sig)
- {
- EnterCriticalSectionRVC(g_cs);
- if (!g_bFrameQuit)
- {
- ULONGLONG dwTmpBegin = g_dwTimeBegin;
- ULONGLONG dwUpgradeTmpBegin = g_dwUpgradeRestartTimeBegin;
- LeaveCriticalSectionRVC(g_cs);
- ULONGLONG dwTimeEnd = GetTickCount64();
- //oilyang@20190828 add
- //升级重启后,在10分钟内,只要离最后一次交互时间大于2分钟,重启框架
- if ((g_bInUpgrade && ((dwTimeEnd - dwUpgradeTmpBegin) < MAX_WAIT_TIME_TO_RESTART))
- && (!g_bAuthSuc && ((dwTimeEnd - dwTmpBegin) > MAX_WAIT_TIME_TO_RESTART_UPGRADE)))
- {
- LOG4VTM(WARN, "**in upgrade restart**,to restart framework(linux).");
- FrameworkShutdown(true, true);
- }
- if ((dwTimeEnd - dwTmpBegin) > MAX_WAIT_TIME_TO_RESTART)
- {
- LOG4VTM(ERROR, "framework maybe down.");
- string strRunInfo;
- if (ReadRuninfoContent(strRunInfo))
- {
- LOG4VTM(INFO, "to check if need rollback.");
- LOG4VTM(INFO, (char*)strRunInfo.c_str());
- if (strRunInfo.compare("111") == 0 && IsStartTimeFileExist())
- {
- EnterCriticalSectionRVC(g_cs);
- g_needToRollBack = 1;
- LeaveCriticalSectionRVC(g_cs);
- }
- }
- else
- LOG4VTM(WARN, "read run info failed.");
- if (g_needToRollBack)
- {
- LOG4VTM(INFO, "after upgrade,time elapse,but can't wait the shake hands,so rollback.");
- FrameworkRollBack();
- }
- else
- {
- //framework is down,to restart it! oilyang 20150413
- FrameworkShutdown();
- }
- }
- }
- else
- LeaveCriticalSectionRVC(g_cs);
- alarm(2 * 60); //we contimue set the timer
- }
- return;
- }
- void* DoWorkLinux(void* arg)
- {
- LOG4VTM(DEBUG, "DoWorkLinux");
- signal(SIGALRM, CheckDoWork); //relate the signal and function
- alarm(2 * 60); //trigger the timer
- EndThreadRVC();
- }
- void* DoNetControlLinux(void* arg)
- {
- LOG4VTM(DEBUG, "to end DoNetControlLinux");
- EndThreadRVC();
- LOG4VTM(DEBUG, "after end DoNetControlLinux");
- }
- void DataProcessLinux(int socket,const char*data)
- {
- GuardianInfo* pInfo = (GuardianInfo*)data;
- LOG4VTM(DEBUG, "eType:" << pInfo->eType << ",p1:" << pInfo->dwParam1 << ",p2:" << pInfo->dwParam2 << ",dwSize:" << pInfo->dwSize);
- switch (pInfo->eType)
- {
- case GdOpShakeHand:
- {
- if (!g_bFrameOnline)
- {
- g_bFrameOnline = true;
- g_SpShellPID = GetSpshellProcID();
- LOG4VTM(INFO, "get spshell proc id" << g_SpShellPID);
- StartDoNetControlRVC();
- }
- int rc, err;
- EnterCriticalSectionRVC(g_cs);
- g_bFrameQuit = false;
- g_dwTimeBegin = GetTickCount64();
- LeaveCriticalSectionRVC(g_cs);
- char* pBuf = new char[8];
- memset(pBuf, 0, 8);
- //get guardian state
- //ex:u(update),g(guardian),r(reboot),b(rollback)
- if (cnt % 2 == 0)
- memcpy(pBuf, "g", 1);
- else
- memcpy(pBuf, "u", 1);
- cnt++;
- rc = send(socket, pBuf, 8, 0);
- delete[]pBuf;
- close(socket);
- }
- break;
- case GdOpUpdateTask:
- {
- if (!g_bFrameOnline)
- {
- g_bFrameOnline = true;
- g_SpShellPID = GetSpshellProcID();
- LOG4VTM(INFO, "get spshell proc id" << g_SpShellPID);
- StartDoNetControlRVC();
- }
- }
- break;
- case GdOpQueryInstall:
- {
- if (!g_bFrameOnline)
- {
- g_bFrameOnline = true;
- g_SpShellPID = GetSpshellProcID();
- LOG4VTM(INFO, "get spshell proc id" << g_SpShellPID);
- StartDoNetControlRVC();
- }
- int rc, err;
- char* pBuf = new char[8];
- memset(pBuf, 0, 8);
- if (cnt % 2 == 0)
- memcpy(pBuf, "y", 1);
- else
- memcpy(pBuf, "n", 1);
- cnt++;
- rc = send(socket, pBuf, 8, 0);
- delete[]pBuf;
- close(socket);
- }
- break;
- case GdOpUpgradeRestart:
- {
- if (pInfo->dwParam1 == 6)//HealthManager call guardian to quit
- {
- LOG4VTM(INFO, "HealthManager call guardian to quit");
- close(socket);
- close(g_sListen);
- exit(0);//baoli?
- break;
- }
- if (pInfo->dwParam1 == 4)//just know framework is starting...
- {
- LOG4VTM(INFO, "framework is starting...");
- g_bFrameOnline = true;
- g_SpShellPID = GetSpshellProcID();
- LOG4VTM(INFO, "get spshell proc id" << g_SpShellPID);
- g_bAuthSuc = false;
- StartDoNetControlRVC();
- LOG4VTM(DEBUG, "to break upgrade...");
- close(socket);
- break;
- }
- if (pInfo->dwParam1 == 5)
- {
- LOG4VTM(INFO, "framework auth ok.");
- g_bInUpgrade = false;
- g_bAuthSuc = true;
- }
- if (!g_bFrameOnline)
- {
- g_bFrameOnline = true;
- g_SpShellPID = GetSpshellProcID();
- LOG4VTM(INFO, "get spshell proc id" << g_SpShellPID);
- StartDoNetControlRVC();
- }
- if (pInfo->dwParam1 == 1 || pInfo->dwParam1 == 3)
- g_dwTimeBegin = GetTickCount64();
- ServerReportEvent("upgrade restart");
- LOG4VTM(INFO, "upgrade restart " << pInfo->dwParam1);
- if (pInfo->dwParam1 == 1)//framework to restart after upgrade
- {
- g_bInUpgrade = true;
- WriteRunInfoContent("111");
- g_dwUpgradeRestartTimeBegin = GetTickCount64();
- }
- else if (pInfo->dwParam1 == 2)//need rollback after upgrade
- {
- LOG4VTM(INFO, "upgrade restart 222");
- WriteRunInfoContent("222");
- //rollback
- EnterCriticalSectionRVC(g_cs);
- g_needToRollBack = 0;
- LeaveCriticalSectionRVC(g_cs);
- LOG4VTM(INFO, "healthmanager said to rollback");
- FrameworkRollBack();
- }
- else if (pInfo->dwParam1 == 3)//upgrade succeeded
- {
- LOG4VTM(INFO, "upgrade restart ok");
- WriteRunInfoContent("333");
- EnterCriticalSectionRVC(g_cs);
- g_needToRollBack = 0;
- LeaveCriticalSectionRVC(g_cs);
- }
- //runinfo.close();
- close(socket);
- }
- break;
- case GdOpFrameQuit:
- if (!g_bFrameOnline)
- {
- g_bFrameOnline = true;
- g_SpShellPID = GetSpshellProcID();
- LOG4VTM(INFO, "get spshell proc id" << g_SpShellPID);
- StartDoNetControlRVC();
- }
- EnterCriticalSectionRVC(g_cs);
- g_bFrameQuit = true;
- LeaveCriticalSectionRVC(g_cs);
- close(socket);
- break;
- default:
- break;
- }
- LOG4VTM(DEBUG, "quit of DataProcessLinux");
- }
- #else
- void DataProcess(LPPER_HANDLE_DATA pPerHandleData,LPPER_IO_OPERATION_DATA pPerIoData)
- {
- GuardianInfo* pInfo = (GuardianInfo*)pPerIoData->Buffer;
- switch(pInfo->eType)
- {
- case GdOpShakeHand:
- {
- if (!g_bFrameOnline)
- {
- g_bFrameOnline = true;
- StartDoNetControlRVC();
- }
- int rc,err;
- EnterCriticalSectionRVC(g_cs);
- g_bFrameQuit = false;
- g_dwTimeBegin = GetTickCount64();
- LeaveCriticalSectionRVC(g_cs);
- char* pBuf = new char[8];
- memset(pBuf,0,8);
- //get guardian state
- //ex:u(update),g(guardian),r(reboot),b(rollback)
- if (cnt%2 == 0)
- memcpy(pBuf,"g",1);
- else
- memcpy(pBuf,"u",1);
- cnt++;
- rc = send(pPerHandleData->Socket,pBuf,8,0);
- delete []pBuf;
- closesocket(pPerHandleData->Socket);
- }
- break;
- case GdOpUpdateTask:
- {
- if (!g_bFrameOnline)
- {
- g_bFrameOnline = true;
- StartDoNetControlRVC();
- }
- }
- break;
- case GdOpQueryInstall:
- {
- if (!g_bFrameOnline)
- {
- g_bFrameOnline = true;
- StartDoNetControlRVC();
- }
- int rc,err;
- char* pBuf = new char[8];
- memset(pBuf,0,8);
- if (cnt%2 == 0)
- memcpy(pBuf,"y",1);
- else
- memcpy(pBuf,"n",1);
- cnt++;
- rc = send(pPerHandleData->Socket,pBuf,8,0);
- delete []pBuf;
- closesocket(pPerHandleData->Socket);
- }
- break;
- case GdOpUpgradeRestart:
- {
- if (pInfo->dwParam1 == 6)//need Upgrade guardian !!!Only!!!
- {
- g_needUpgradeGuardianOnly = true;
- }
- if (pInfo->dwParam1 == 4)//just know framework is starting...
- {
- LOG4VTM(INFO, "framework is starting...");
- //oilyang@20211208 add the following if receive framework is starting ,reset g_dwUpgradeRestartTimeBegin
- //in order to skip the cost time of "kill spshell"
- g_dwUpgradeRestartTimeBegin = GetTickCount64();
- g_bFrameOnline = true;
- g_bAuthSuc = false;
- StartDoNetControlRVC();
- break;
- }
- if (pInfo->dwParam1 == 5)
- {
- LOG4VTM(INFO, "framework auth ok.");
- g_bInUpgrade = false;
- g_bAuthSuc = true;
- }
- if (!g_bFrameOnline)
- {
- g_bFrameOnline = true;
- StartDoNetControlRVC();
- }
- if (pInfo->dwParam1 == 1 || pInfo->dwParam1 == 3)
- g_dwTimeBegin = GetTickCount64();
- ServerReportEvent("upgrade restart");
- LOG4VTM(INFO, "upgrade restart " << pInfo->dwParam1);
- if (pInfo->dwParam1 == 1)//framework to restart after upgrade
- {
- g_bInUpgrade = true;
- WriteRunInfoContent("111");
- g_dwUpgradeRestartTimeBegin = GetTickCount64();
- }
- else if (pInfo->dwParam1 == 2)//need rollback after upgrade
- {
- LOG4VTM(INFO, "upgrade restart 222");
- WriteRunInfoContent("222");
- //rollback
- EnterCriticalSectionRVC(g_cs);
- g_needToRollBack = 0;
- LeaveCriticalSectionRVC(g_cs);
- LOG4VTM(INFO, "healthmanager said to rollback");
- FrameworkRollBack();
- }else if (pInfo->dwParam1 == 3)//upgrade succeeded
- {
- LOG4VTM(INFO, "upgrade restart ok");
- WriteRunInfoContent("333");
- EnterCriticalSectionRVC(g_cs);
- g_needToRollBack = 0;
- LeaveCriticalSectionRVC(g_cs);
- }
- //runinfo.close();
- closesocket(pPerHandleData->Socket);
- }
- break;
- case GdOpFrameQuit:
- if (!g_bFrameOnline)
- {
- g_bFrameOnline = true;
- StartDoNetControlRVC();
- }
- EnterCriticalSectionRVC(g_cs);
- g_bFrameQuit = true;
- LeaveCriticalSectionRVC(g_cs);
- closesocket(pPerHandleData->Socket);
- break;
- default:
- break;
- }
- }
- DWORD WINAPI ProcessIO(LPVOID lpParam)
- {
- HANDLE CompletionPort = (HANDLE)lpParam;
- DWORD BytesTransferred;
- LPPER_HANDLE_DATA PerHandleData;
- LPPER_IO_OPERATION_DATA PerIoData;
- while(true)
- {
- if(0 == GetQueuedCompletionStatus(CompletionPort, &BytesTransferred, (LPDWORD)&PerHandleData, (LPOVERLAPPED*)&PerIoData, INFINITE))
- {
- if( (GetLastError() == WAIT_TIMEOUT) || (GetLastError() == ERROR_NETNAME_DELETED) )
- {
- LOG4VTM(INFO, "closing socket(1) " << PerHandleData->Socket);
- closesocket(PerHandleData->Socket);
- delete PerIoData;
- delete PerHandleData;
- continue;
- }
- else
- {
- //OutErr("GetQueuedCompletionStatus failed!");
- }
- return 0;
- }
- // client quit
- if(BytesTransferred == 0)
- {
- LOG4VTM(INFO, "closing socket(2) " <<PerHandleData->Socket);
- closesocket(PerHandleData->Socket);
- delete PerIoData;
- delete PerHandleData;
- continue;
- }
- // receiving data process
- DataProcess(PerHandleData,PerIoData);
-
- // socket WSARecv
- DWORD Flags = 0;
- DWORD dwRecv = 0;
- ZeroMemory(PerIoData, sizeof(PER_IO_OPERATION_DATA));
- PerIoData->DataBuf.buf = PerIoData->Buffer;
- PerIoData->DataBuf.len = DATA_BUFSIZE;
- WSARecv(PerHandleData->Socket, &PerIoData->DataBuf, 1, &dwRecv, &Flags, &PerIoData->Overlapped, NULL);
- }
- return 0;
- }
- DWORD WINAPI DoWork(void* pData)
- {
- LOG4VTM(INFO, "to wait.");
- HANDLE hTimer;
- LARGE_INTEGER li;
- hTimer = CreateWaitableTimer(NULL,FALSE,NULL);
- const int nTimerUnitsPerSecond = 10000000;
- li.QuadPart = -(1*60*nTimerUnitsPerSecond);//oiltmp 1 minute
- SetWaitableTimer(hTimer,&li,2*60*1000,NULL,NULL,FALSE);
- while(1)
- {
- WaitForSingleObject(hTimer,INFINITE);
- EnterCriticalSectionRVC(g_cs);
- if (!g_bFrameQuit)
- {
- ULONGLONG dwTmpBegin = g_dwTimeBegin;
- ULONGLONG dwUpgradeTmpBegin = g_dwUpgradeRestartTimeBegin;
- LeaveCriticalSectionRVC(g_cs);
- ULONGLONG dwTimeEnd = GetTickCount64();
- //oilyang@20190828 add
- //升级重启后,在10分钟内,只要离最后一次交互时间大于MAX_WAIT_TIME_TO_RESTART_UPGRADE,重启框架
- if (g_bInUpgrade && ((dwTimeEnd - dwTmpBegin) < MAX_WAIT_TIME_TO_RESTART)
- && (!g_bAuthSuc && ((dwTimeEnd - dwUpgradeTmpBegin) > MAX_WAIT_TIME_TO_RESTART_UPGRADE)))
- {
- LOG4VTM(WARN, "**in upgrade restart**,to restart framework.");
- FrameworkShutdown(true,true);
- }
- if ((dwTimeEnd-dwTmpBegin) > MAX_WAIT_TIME_TO_RESTART)
- {
- LOG4VTM(ERROR, "framework maybe down.");
- string strRunInfo;
- if (ReadRuninfoContent(strRunInfo))
- {
- LOG4VTM(INFO, "to check if need rollback.");
- LOG4VTM(INFO, "runinfo:" << strRunInfo);
- if (strRunInfo.compare("111") == 0 && IsStartTimeFileExist())
- {
- EnterCriticalSectionRVC(g_cs);
- g_needToRollBack = 1;
- LeaveCriticalSectionRVC(g_cs);
- }
- }
- else
- LOG4VTM(WARN, "read run info failed.");
- if (g_needToRollBack)
- {
- LOG4VTM(INFO, "after upgrade,time elapse,but can't wait the shake hands,so rollback.");
- FrameworkRollBack();
- }
- else
- {
- //framework is down,to restart it! oilyang 20150413
- //oilyang@20211221 if Upgrade guardian !!!Only!!! ,just reset dwTmpBegin
- if (!g_needUpgradeGuardianOnly)
- FrameworkShutdown();
- else
- dwTmpBegin = GetTickCount64();
- }
- }
- }
- else
- LeaveCriticalSectionRVC(g_cs);
- }
-
- EndThreadRVC();
- return 0;
- }
- DWORD WINAPI DoNetControl(LPVOID pData)
- {
- ServerReportEvent("DoNetControl start");
- HANDLE hSnapshot;
- //find spshell.exe
- hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
- if (hSnapshot)
- {
- PROCESSENTRY32 pe;
- pe.dwSize = sizeof(pe);
- if (Process32First(hSnapshot, &pe))
- {
- do {
- if (_stricmp(&pe.szExeFile[0], "spshell.exe") == 0)
- {
- //ServerReportEvent("find spshell.exe");
- LOG4VTM(INFO, "find spshell.exe");
- //DWORD dwExit = 0;
- //do
- //{
- // GetExitCodeProcess(&pe.th32ProcessID,&dwExit);
- // if (dwExit != STILL_ACTIVE)
- // break;
- //}while(1);
- HANDLE hP = OpenProcess( PROCESS_ALL_ACCESS, FALSE, pe.th32ProcessID );
- WaitForSingleObject(hP, INFINITE );
- LOG4VTM(INFO, "spshell.exe quit");
- break;
- }
- } while (Process32Next(hSnapshot, &pe));
- }
- CloseHandle(hSnapshot);
- }
- else
- ServerReportEvent("create snapshot failed.");
- EndThreadRVC();
- return 0;
- }
- #endif //linux
- int InitListenSocketRVC()
- {
- #ifdef linux
- socklen_t clilen;
- epfd = epoll_create(256);
- struct sockaddr_in clientaddr;
- struct sockaddr_in serveraddr;
- g_sListen = socket(AF_INET, SOCK_STREAM, 0);
- //setnonblocking(listenfd);
- ev.data.fd = g_sListen;
- ev.events = EPOLLIN | EPOLLET;
- epoll_ctl(epfd, EPOLL_CTL_ADD, g_sListen, &ev);
- memset(&serveraddr, 0, sizeof(serveraddr));
- serveraddr.sin_family = AF_INET;
- char* local_addr = "127.0.0.1";
- inet_aton(local_addr, &(serveraddr.sin_addr));
- serveraddr.sin_port = htons(default_port);
- int tmpuse = 1;
- if (setsockopt(g_sListen, SOL_SOCKET, SO_REUSEPORT, (char*)&tmpuse, sizeof(tmpuse)) < 0)
- {
- LOG4VTM(ERROR, "setsockopt failed. "<< errno);
- LOG4VTM(ERROR, strerror(errno));
- close(g_sListen);
- return -1;
- }
- int ret = bind(g_sListen, (sockaddr*)& serveraddr, sizeof(serveraddr));
- if (ret != 0)
- {
- LOG4VTM(ERROR, "bind failed: " << errno);
- LOG4VTM(ERROR, strerror(errno));
- close(g_sListen);
- return -1;
- }
- ret= listen(g_sListen, LISTENQ);
- if (ret != 0)
- {
- LOG4VTM(ERROR, "listen failed: " << errno);
- LOG4VTM(ERROR, strerror(errno));
- close(g_sListen);
- return -1;
- }
- LOG4VTM(INFO, "(linux)listen ok: " << g_sListen);
- cout << "listen on:" << g_sListen << endl;
- return g_sListen;
- #else
- WSADATA wsaData;
- int iResult;
- struct addrinfo* result = NULL;
- struct addrinfo hints;
- int iSendResult;
- char recvbuf[DEFAULT_BUFLEN];
- int recvbuflen = DEFAULT_BUFLEN;
- // Initialize Winsock
- iResult = WSAStartup(MAKEWORD(2, 2), &wsaData);
- if (iResult != 0) {
- LOG4VTM(ERROR, "WSAStartup failed with error:" << iResult);
- return 1;
- }
- ZeroMemory(&hints, sizeof(hints));
- hints.ai_family = AF_INET;
- hints.ai_socktype = SOCK_STREAM;
- hints.ai_protocol = IPPROTO_TCP;
- hints.ai_flags = AI_PASSIVE;
- // Resolve the server address and port
- iResult = getaddrinfo(NULL, DEFAULT_PORT, &hints, &result);
- if (iResult != 0) {
- LOG4VTM(ERROR, "getaddrinfo failed with error:" << iResult);
- WSACleanup();
- return 1;
- }
- // get system info to create work thread
- SYSTEM_INFO SystemInfo;
- GetSystemInfo(&SystemInfo);
- // Create a SOCKET for connecting to server
- g_sListen = socket(result->ai_family, result->ai_socktype, result->ai_protocol);
- if (g_sListen == INVALID_SOCKET) {
- LOG4VTM(ERROR, "socket failed with error:" << WSAGetLastError());
- freeaddrinfo(result);
- WSACleanup();
- return 1;
- }
- // Setup the TCP listening socket
- struct sockaddr_in* sockaddr_ipv4 = (struct sockaddr_in*) result->ai_addr;
- LOG4VTM(INFO, "ip:"<< inet_ntoa(sockaddr_ipv4->sin_addr));
- iResult = bind(g_sListen, result->ai_addr, (int)result->ai_addrlen);
- if (iResult == SOCKET_ERROR) {
- LOG4VTM(ERROR, "bind failed with error:" << WSAGetLastError());
- freeaddrinfo(result);
- closesocket(g_sListen);
- WSACleanup();
- return 1;
- }
- freeaddrinfo(result);
- LOG4VTM(INFO, "to listen.");
- iResult = listen(g_sListen, SOMAXCONN);
- if (iResult == SOCKET_ERROR) {
- LOG4VTM(ERROR, "listen failed with error: " << WSAGetLastError());
- closesocket(g_sListen);
- WSACleanup();
- return 1;
- }
- LOG4VTM(INFO, "listen ok.");
- return g_sListen;
- #endif //linux
- }
- void AcceptReqRVC()
- {
- #ifdef linux
- StartDoWorkRVC();
- LOG4VTM(DEBUG, "AcceptReqRVC:after StartDoWorkRVC");
- int maxi, connfd, sockfd, nfds;
- struct epoll_event events[20];
- struct sockaddr_in clientaddr;
- socklen_t clilen = sizeof(struct sockaddr);
- ssize_t n;
- maxi = 0;
- char line[MAXLINE];
- for (; ; ) {
- //等待epoll事件的发生
- nfds = epoll_wait(epfd, events, 20, 500);
- //处理所发生的所有事件
- for (int i = 0; i < nfds; ++i)
- {
- LOG4VTM(DEBUG, "nfds: " << nfds);
- if (events[i].data.fd == g_sListen)//new connection
- {
- connfd = accept(g_sListen, (sockaddr*)& clientaddr, &clilen);
- if (connfd < 0) {
- LOG4VTM(ERROR, "connfd<0");
- perror("connfd<0");
- exit(1);
- }
- //setnonblocking(connfd);
- char* str = inet_ntoa(clientaddr.sin_addr);
- LOG4VTM(DEBUG, "accapt a connection from " << str);
- ev.data.fd = connfd;
- ev.events = EPOLLIN | EPOLLET;
- //ev.events=EPOLLIN;
- epoll_ctl(epfd, EPOLL_CTL_ADD, connfd, &ev);
- }
- else if (events[i].events & EPOLLIN)
- {
- LOG4VTM(DEBUG, "EPOLLIN,i:" << i << ",sock:" << events[i].data.fd);
- if ((sockfd = events[i].data.fd) < 0)
- continue;
- if ((n = read(sockfd, line, MAXLINE)) < 0) {
- if (errno == ECONNRESET) {
- close(sockfd);
- events[i].data.fd = -1;
- }
- else
- LOG4VTM(ERROR, "readline error: " << strerror(errno));
- }
- else if (n == 0) {
- close(sockfd);
- events[i].data.fd = -1;
- }
- DataProcessLinux(sockfd,line);
- line[n] = '\0';
- ev.data.fd = sockfd;
- ev.events = EPOLLOUT | EPOLLET;
- epoll_ctl(epfd,EPOLL_CTL_MOD,sockfd,&ev);
- LOG4VTM(DEBUG, "out DataProcessLinux");
- }
- else if (events[i].events & EPOLLOUT)
- {
- LOG4VTM(DEBUG, "epoll out");
- sockfd = events[i].data.fd;
- write(sockfd, line, n);
- ev.data.fd = sockfd;
- ev.events = EPOLLIN | EPOLLET;
- epoll_ctl(epfd, EPOLL_CTL_MOD, sockfd, &ev);
- }
- }
- }
- #else
- HANDLE hCompletionPort;
- hCompletionPort = CreateIoCompletionPort(INVALID_HANDLE_VALUE, NULL, 0, 0);
- // get system info to create work thread
- SYSTEM_INFO SystemInfo;
- GetSystemInfo(&SystemInfo);
- for (int i = 0; i < SystemInfo.dwNumberOfProcessors * 2; i++)
- {
- HANDLE hProcessIO = CreateThread(NULL, 0, ProcessIO, hCompletionPort, 0, NULL);
- if (hProcessIO)
- CloseHandle(hProcessIO);
- }
- //waiting thread
- StartDoWorkRVC();
- SOCKET sClient;
- LPPER_HANDLE_DATA PerHandleData;
- LPPER_IO_OPERATION_DATA PerIoData;
- while (true)
- {
- //sClient = WSAAccept(sListen, NULL, NULL, NULL, 0);
- sClient = accept(g_sListen, NULL, NULL);
- //cout << "Socket " << sClient << "connect" << endl;
- PerHandleData = new PER_HANDLE_DATA();
- PerHandleData->Socket = sClient;
- // client completion port
- CreateIoCompletionPort((HANDLE)sClient, hCompletionPort, (DWORD)PerHandleData, 0);
- //
- PerIoData = new PER_IO_OPERATION_DATA();
- ZeroMemory(PerIoData, sizeof(PER_IO_OPERATION_DATA));
- PerIoData->DataBuf.buf = PerIoData->Buffer;
- PerIoData->DataBuf.len = DATA_BUFSIZE;
- // WSARecv
- DWORD Flags = 0;
- DWORD dwRecv = 0;
- WSARecv(sClient, &PerIoData->DataBuf, 1, &dwRecv, &Flags, &PerIoData->Overlapped, NULL);
- LOG4VTM(DEBUG, "hold");
- }
- DWORD dwByteTrans;
- PostQueuedCompletionStatus(hCompletionPort, dwByteTrans, 0, 0);
- closesocket(g_sListen);
- #endif //linux
- }
- #if linux
- static void sig_handle(int signo)
- {
- switch (signo) {
- case SIGSEGV:
- {
- LOG4VTM(INFO, "=========>>> capture signal SIGSEGV <<<=========");
- break;
- }
- case SIGTERM:
- LOG4VTM(INFO, "=========>>> capture signal SIGTERM <<<=========");
- break;
- case SIGCHLD:
- {
- LOG4VTM(INFO, "=========>>> capture signal SIGCHLD <<<=========");
-
- if (signal(SIGCHLD, sig_handle) == SIG_ERR)
- LOG4VTM(ERROR, "signal error.");
- int status;
- pid_t pid;
- while ((pid = waitpid(0, &status, WNOHANG)) > 0) {
- char szMsg[256] = { '\0' };
- bool excep(false);
- if (WIFEXITED(status)) {
- sprintf(szMsg, "child process %d terminated normal with exit code: %d", pid, WEXITSTATUS(status));
- } else {
- const int signum = WTERMSIG(status);
- sprintf(szMsg, "child process %d has been terminated unexpectly by signal %d", pid, signum);
- //if(signum != SIGKILL)
- excep = true;
- }
- LOG4VTM(INFO, szMsg);
- if (g_SpShellPID != 0 && g_SpShellPID == pid) {
- LOG4VTM(INFO, "Specified spshell process has exited!");
- g_SpShellPID = 0;
- if (excep) {
- LOG4VTM(INFO, "Confirm other relate process has been terminated.");
- int count = 60;
- alive_process_info processes[60];
- memset(processes, 0, sizeof(processes));
- if (!osutil_detect_unique_app(relate_processes_ex, array_size(relate_processes_ex), &count, processes)) {
- bool spshell_exist(false);
- for (int i = 0; i < count; ++i) {
- if (strcmp(processes[i].name, spshell_execute_name) == 0) {
- spshell_exist = true;
- break;
- }
- }
- for (int i = 0; !spshell_exist && i < count; ++i) {
- kill(processes[i].pid, SIGKILL);
- LOG4VTM(INFO, "kill " << processes[i].name << ", pid: " << processes[i].pid << ", err: " <<errno);
- }
- }
- }
- }
- }
- break;
- }
- default:
- char szMsg[256] = { '\0' };
- sprintf(szMsg, "=========>>> capture signal %d <<<=========", signo);
- LOG4VTM(INFO, szMsg);
- break;
- }
- return;
- }
- #endif
- int main(int argc, char* argv[])
- {
- //attach file descriptors 0,1,2 to /dev/null(for deamon app)
- std::string terminalno;
- int fd0, fd1, fd2;
- g_bFrameOnline = true;
- //MessageBox(NULL, NULL, NULL, 0);
- if (argc > 1)
- terminalno = argv[1];
- #ifdef linux
- fd0 = open("/dev/null", O_RDWR);
- fd1 = dup(0);
- fd2 = dup(0);
- pthread_mutex_init(&g_cs_event,NULL);
- pthread_mutex_init(&g_cs_log,NULL);
- pthread_mutex_init(&g_cs,NULL);
- #else
- InitializeCriticalSectionAndSpinCount(&g_cs_event, 100);
- InitializeCriticalSectionAndSpinCount(&g_cs_log, 100);
- InitializeCriticalSectionAndSpinCount(&g_cs, 100);
- ZeroMemory(currDirBuf, sizeof(currDirBuf));
- ZeroMemory(chDisk, sizeof(chDisk));
- GetCurrentDirectory(256, currDirBuf);
- chDisk[0] = currDirBuf[0];
- #endif
- cmb::log_init_config config;
- config.dev_name = "guardian";
- config.terminalno = terminalno;
- ///*TODO: 依赖上层提供环境变量来控制路径和开关,可以考虑厂商的方式 (80374374@1/4/2024)*/
- #if defined(_MSC_VER)
- config.log_dir = ("C:\\rvc\\dbg\\");
- #else
- config.log_dir = ("/opt/rvc/dbg/");
- #endif //_MSC_VER
- std::string str;
- cmb::log4rvcother::init(config, str);
- g_dwTimeBegin = GetTickCount64();
- int i=1000;
- LOG4VTM(INFO, "guardian version: " << GUARDIAN_VERSION_STR);
- #if linux
- g_SpShellPID = GetSpshellProcID();
- LOG4VTM(INFO, ("get spshell proc id: ") << g_SpShellPID);
- if (signal(SIGCHLD, sig_handle) == SIG_ERR) {
- LOG4VTM(WARN, ("register for SIGCHLD failed: ") << errno);
- } else {
- LOG4VTM(DEBUG, ("register for SIGCHLD succ."));
- }
- #endif
- StartDoNetControlRVC();
- InitListenSocketRVC();
- AcceptReqRVC();
- }
|