12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682 |
- // 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/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;
- #define NET_TYPE_WIRELESS 1
- #define NET_TYPE_ETHERNET 2
- #define NET_TYPE_3G 3
- #define NET_TYPE_4G 4
- #define NET_TYPE_BLUETOOTH 5
- #define DLL_PATH "C:\\RVC\\SystemInit\\CmbPadDll.dll"
- typedef DWORD(*pWlanConnect)(BOOL bConnect, int nType);
- typedef DWORD (*pDisableBluetooth)(BOOL bDisable);
- #ifdef linux
- int g_sListen;
- pthread_mutex_t g_cs, g_cs_event, g_cs_log;
- #define EnterCriticalSectionRVC(xType) pthread_mutex_lock(&xType)
- #define LeaveCriticalSectionRVC(xType) pthread_mutex_unlock(&xType)
- 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];
- void NetControl();
- 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
- unsigned long long GetTickCountRVC() {
- #ifdef linux
- struct timespec ts;
- clock_gettime(CLOCK_MONOTONIC, &ts);
- return (ts.tv_sec * 1000 + ts.tv_nsec / 1000000);
- #else
- return GetTickCount64();
- #endif //RVC_OS_WIN
- }
- void GetLocalTimeRVC(SYSTEMTIME& stTime)
- {
- #ifdef linux
- time_t ct = 0;
- struct tm* ltm = NULL;
- WORD wMilliseconds = 0;
- DWORD ticks = 0;
- struct timespec ts;
- ct = time(NULL);
- ltm = localtime(&ct);
- if (!clock_gettime(CLOCK_MONOTONIC_RAW, &ts)) {
- ticks = (ts.tv_sec * 1000) + (ts.tv_nsec / 1000000);
- wMilliseconds = (WORD)(ticks % 1000);
- }
- memset(&stTime, 0, sizeof(SYSTEMTIME));
- if (ltm) {
- stTime.wYear = (WORD)(ltm->tm_year + 1900);
- stTime.wMonth = (WORD)(ltm->tm_mon + 1);
- stTime.wDayOfWeek = (WORD)ltm->tm_wday;
- stTime.wDay = (WORD)ltm->tm_mday;
- stTime.wHour = (WORD)ltm->tm_hour;
- stTime.wMinute = (WORD)ltm->tm_min;
- stTime.wSecond = (WORD)ltm->tm_sec;
- stTime.wMilliseconds = wMilliseconds;
- }
- #else
- GetLocalTime(&stTime);
- #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 = GetTickCountRVC();
- NetControl();
- #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 = GetTickCountRVC();
- //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 = GetTickCountRVC();
- 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 = GetTickCountRVC();
- 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 = GetTickCountRVC();
- }
- 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 = GetTickCountRVC();
- 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 = GetTickCountRVC();
- 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 = GetTickCountRVC();
- 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 = GetTickCountRVC();
- }
- 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 = GetTickCountRVC();
- //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 = GetTickCountRVC();
- }
- }
- }
- 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");
- //ServerReportEvent("spshell.exe quit");
- NetControl();
- 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 = GetTickCountRVC();
- 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();
- }
- void NetControl()
- {
- return;//oiltmp 20150724 for zl don't forbid net for now
- #ifdef linux
- //todo oiltestlinux
- #else
- HINSTANCE hmod = ::LoadLibrary(DLL_PATH);
- if(hmod != NULL)
- {
- LOG4VTM(INFO, "NetControl start");
- pWlanConnect WlanConnect = (pWlanConnect)GetProcAddress(hmod, "WlanConnect");
- pDisableBluetooth BluetoothConnect = (pDisableBluetooth)GetProcAddress(hmod, "DisableBluetooth");
- if (WlanConnect != NULL && BluetoothConnect != NULL)
- {
- DWORD dwRetWire,dwRetEther,dwRet3G,dwRet4G,dwRetBT;
- dwRetWire = dwRetEther = dwRet3G = dwRet4G = dwRetBT = 0;
- dwRetWire = WlanConnect(FALSE, NET_TYPE_WIRELESS);
- LOG4VTM(DEBUG, "after wireless");
- dwRetEther = WlanConnect(FALSE, NET_TYPE_ETHERNET);
- LOG4VTM(DEBUG, "after ether");
- dwRet3G = WlanConnect(FALSE, NET_TYPE_3G);
- LOG4VTM(DEBUG, "after 3g");
- dwRet4G = WlanConnect(FALSE, NET_TYPE_4G);
- LOG4VTM(DEBUG, "after 4g");
- dwRetBT = BluetoothConnect(TRUE);
- LOG4VTM(DEBUG, "after bluetooth");
- char buf[128];
- ZeroMemory(buf,sizeof(buf));
- sprintf(buf,"Wire Net open state:Wireless[%d],Ethernet[%d],3G[%d],4G[%d],Blue tooth[%d]",dwRetWire,dwRetEther,dwRet3G,dwRet4G,dwRetBT);
- LOG4VTM(INFO, buf);
- }
- else
- LOG4VTM(WARN, "Get function from CmbPadDll failed!");
- }
- else
- LOG4VTM(WARN, "load CmbPadDll failed!");
- #endif //linux
- }
|