|
@@ -1,904 +0,0 @@
|
|
-#include <stdio.h>
|
|
|
|
-#include <unistd.h>
|
|
|
|
-#include <string.h>
|
|
|
|
-#include <string>
|
|
|
|
-#include <vector>
|
|
|
|
-#include <map>
|
|
|
|
-#include <ext/stdio_filebuf.h>
|
|
|
|
-#include <iostream>
|
|
|
|
-#include <fstream>
|
|
|
|
-#include <signal.h>
|
|
|
|
-#include <sys/statvfs.h>
|
|
|
|
-#include <sys/statfs.h>
|
|
|
|
-#include <sys/types.h>
|
|
|
|
-#include <fcntl.h>
|
|
|
|
-#include <unistd.h>
|
|
|
|
-#include <limits.h>
|
|
|
|
-#include <libudev.h>
|
|
|
|
-#include <poll.h>
|
|
|
|
-#include <errno.h>
|
|
|
|
-#include <getopt.h>
|
|
|
|
-#include <gfa/gfasitarautils.h>
|
|
|
|
-#include <gfa/gfaipc.h>
|
|
|
|
-#include "stgdevinfo.h"
|
|
|
|
-#include "mysqlinfo.h"
|
|
|
|
-#include "spiinfo.h"
|
|
|
|
-
|
|
|
|
-/////////////////////////////////////////////////////////////////////////////
|
|
|
|
-
|
|
|
|
-#ifdef _DEBUG
|
|
|
|
-#define TRACE(...) fprintf(stdout, __VA_ARGS__), fflush(stdout)
|
|
|
|
-#else // _DEBUG
|
|
|
|
-#define TRACE(...)
|
|
|
|
-#endif // _DEBUG
|
|
|
|
-
|
|
|
|
-#define UNUSED(v) (void)v
|
|
|
|
-#define _countof(a) (sizeof(a) / sizeof(*a))
|
|
|
|
-
|
|
|
|
-/////////////////////////////////////////////////////////////////////////////
|
|
|
|
-
|
|
|
|
-#define _APPID GFA_APPCTRL_APPID_SYSINFO
|
|
|
|
-#define _APPNAME "SysInfo"
|
|
|
|
-#define _CYCLE_INTV 500
|
|
|
|
-
|
|
|
|
-/////////////////////////////////////////////////////////////////////////////
|
|
|
|
-
|
|
|
|
-static volatile bool g_fRun = false;
|
|
|
|
-static volatile bool g_fPause = false;
|
|
|
|
-static volatile bool g_fZombie = false;
|
|
|
|
-static sigset_t g_set;
|
|
|
|
-
|
|
|
|
-/////////////////////////////////////////////////////////////////////////////
|
|
|
|
-
|
|
|
|
-#ifdef _DEBUG
|
|
|
|
-static const char *g_pszStateNames[] =
|
|
|
|
-{
|
|
|
|
- "Not running",
|
|
|
|
- "Initializing",
|
|
|
|
- "Running",
|
|
|
|
- "Paused",
|
|
|
|
- "Hanging",
|
|
|
|
- "Terminating",
|
|
|
|
- "Invalid"
|
|
|
|
-};
|
|
|
|
-#endif // _DEBUG
|
|
|
|
-
|
|
|
|
-/////////////////////////////////////////////////////////////////////////////
|
|
|
|
-#if 0
|
|
|
|
-static long long _NumberFromString(const char *pszString, int base = 10, bool *pbErr = NULL);
|
|
|
|
-static const char* _ReadDevPropertyValue(struct udev_device* dev, const char *pszKey, char *pszValue, size_t nCChValue, bool bTruncate = false);
|
|
|
|
-static long long _ReadDevPropertyValue(struct udev_device* dev, const char *pszKey, int base = 10, bool *pbErr = NULL);
|
|
|
|
-
|
|
|
|
-/////////////////////////////////////////////////////////////////////////////
|
|
|
|
-/////////////////////////////////////////////////////////////////////////////
|
|
|
|
-/////////////////////////////////////////////////////////////////////////////
|
|
|
|
-
|
|
|
|
-static int _LookupPartition(const GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm, const char *pszDevNode)
|
|
|
|
-{
|
|
|
|
- int nIndex = -1;
|
|
|
|
-
|
|
|
|
- if(pszDevNode && *pszDevNode)
|
|
|
|
- {
|
|
|
|
- for(size_t i = 0; i < _countof(sdm.parts); ++i)
|
|
|
|
- {
|
|
|
|
- if(sdm.parts[i].valid && !strcmp(sdm.parts[i].szDevNode, pszDevNode))
|
|
|
|
- {
|
|
|
|
- nIndex = i; // found partition
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return nIndex;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static int _AddPartition(GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm, const GFA_SYSINFO_PARTITION &part, bool &bChange)
|
|
|
|
-{
|
|
|
|
- int nIndex = -1;
|
|
|
|
- bChange = false;
|
|
|
|
-
|
|
|
|
- if((nIndex = _LookupPartition(sdm, part.szDevNode)) >= 0)
|
|
|
|
- return nIndex; // partition already exists
|
|
|
|
-
|
|
|
|
- for(size_t i = 0; i < _countof(sdm.parts); ++i)
|
|
|
|
- {
|
|
|
|
- if(!sdm.parts[i].valid)
|
|
|
|
- {
|
|
|
|
- memcpy(&sdm.parts[i], &part, sizeof(GFA_SYSINFO_PARTITION));
|
|
|
|
- sdm.parts[i].valid = true;
|
|
|
|
- bChange = true;
|
|
|
|
- nIndex = i;
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return nIndex;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static int _RemovePartition(GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm, int nIndex, bool &bChange)
|
|
|
|
-{
|
|
|
|
- bChange = false;
|
|
|
|
-
|
|
|
|
- if(nIndex >= 0 && nIndex < (int)_countof(sdm.parts))
|
|
|
|
- {
|
|
|
|
- bChange = sdm.parts[nIndex].valid;
|
|
|
|
- sdm.parts[nIndex].valid = false;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return nIndex;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static bool _PartitionSetDisk(GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm, int nPartIdx, int nDiskIdx, bool &bChange)
|
|
|
|
-{
|
|
|
|
- bChange = false;
|
|
|
|
-
|
|
|
|
- if( (nPartIdx >= 0) && (nPartIdx < (int)_countof(sdm.parts)) &&
|
|
|
|
- (nDiskIdx >= 0) && (nDiskIdx < (int)_countof(sdm.disks)))
|
|
|
|
- {
|
|
|
|
- if(sdm.parts[nPartIdx].nDiskIdx != nDiskIdx)
|
|
|
|
- {
|
|
|
|
- sdm.parts[nPartIdx].nDiskIdx = nDiskIdx;
|
|
|
|
- bChange = true;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return false;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static int _PartitionGetDisk(GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm, int nPartIdx)
|
|
|
|
-{
|
|
|
|
- if((nPartIdx >= 0) && (nPartIdx < (int)_countof(sdm.parts)))
|
|
|
|
- return sdm.parts[nPartIdx].nDiskIdx;
|
|
|
|
- return -1;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static void _ClearMapChanges(GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm)
|
|
|
|
-{
|
|
|
|
- sdm.nPartChangeMask = 0;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static bool _DeviceMapChanged(const GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm)
|
|
|
|
-{
|
|
|
|
- return !!sdm.nPartChangeMask;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static unsigned int _SetPartitionChange(GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm, int nPartIdx)
|
|
|
|
-{
|
|
|
|
- if((nPartIdx >= 0) && (nPartIdx < (int)_countof(sdm.parts)))
|
|
|
|
- {
|
|
|
|
- unsigned int nChanged = (0x01 << nPartIdx);
|
|
|
|
- sdm.nPartChangeMask |= nChanged;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return sdm.nPartChangeMask;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/////////////////////////////////////////////////////////////////////////////
|
|
|
|
-
|
|
|
|
-static int _LookupDisk(const GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm, const char *pszDevNode)
|
|
|
|
-{
|
|
|
|
- int nIndex = -1;
|
|
|
|
-
|
|
|
|
- if(pszDevNode && *pszDevNode)
|
|
|
|
- {
|
|
|
|
- for(size_t i = 0; i < _countof(sdm.disks); ++i)
|
|
|
|
- {
|
|
|
|
- if(sdm.disks[i].valid && !strcmp(sdm.disks[i].szDevNode, pszDevNode))
|
|
|
|
- {
|
|
|
|
- nIndex = i; // found partition
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return nIndex;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static int _AddDisk(GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm, const GFA_SYSINFO_DISK &disk, bool &bChange)
|
|
|
|
-{
|
|
|
|
- int nIndex = -1;
|
|
|
|
- bChange = false;
|
|
|
|
-
|
|
|
|
- if((nIndex = _LookupDisk(sdm, disk.szDevNode)) >= 0)
|
|
|
|
- return nIndex; // partition already exists
|
|
|
|
-
|
|
|
|
- for(size_t i = 0; i < _countof(sdm.disks); ++i)
|
|
|
|
- {
|
|
|
|
- if(!sdm.disks[i].valid)
|
|
|
|
- {
|
|
|
|
- memcpy(&sdm.disks[i], &disk, sizeof(GFA_SYSINFO_DISK));
|
|
|
|
- sdm.disks[i].valid = true;
|
|
|
|
- bChange = true;
|
|
|
|
- nIndex = i;
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return nIndex;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static int _RemoveDisk(GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm, int nIndex, bool &bChange)
|
|
|
|
-{
|
|
|
|
- bChange = false;
|
|
|
|
-
|
|
|
|
- if(nIndex >= 0 && nIndex < (int)_countof(sdm.disks))
|
|
|
|
- {
|
|
|
|
- bChange = sdm.disks[nIndex].valid;
|
|
|
|
- sdm.disks[nIndex].valid = false;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return nIndex;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static unsigned int _DiskAddPartition(GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm, int nDiskIdx, int nPartIdx, bool &bChange)
|
|
|
|
-{
|
|
|
|
- bChange = false;
|
|
|
|
-
|
|
|
|
- if( (nPartIdx >= 0) && (nPartIdx < (int)_countof(sdm.parts)) &&
|
|
|
|
- (nDiskIdx >= 0) && (nDiskIdx < (int)_countof(sdm.disks)))
|
|
|
|
- {
|
|
|
|
- GFA_SYSINFO_DISK &disk = sdm.disks[nDiskIdx];
|
|
|
|
-
|
|
|
|
- for(unsigned int i = 0; i < disk.nPartCount; ++i)
|
|
|
|
- {
|
|
|
|
- if(disk.aPartIdx[i] == nPartIdx)
|
|
|
|
- return disk.nPartCount;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if(disk.nPartCount < _countof(disk.aPartIdx))
|
|
|
|
- {
|
|
|
|
- disk.aPartIdx[disk.nPartCount++] = nPartIdx;
|
|
|
|
- bChange = true;
|
|
|
|
- return disk.nPartCount;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return 0;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static unsigned int _DiskRemovePartition(GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm, int nDiskIdx, int nPartIdx, bool &bChange)
|
|
|
|
-{
|
|
|
|
- bChange = false;
|
|
|
|
-
|
|
|
|
- if( (nPartIdx >= 0) && (nPartIdx < (int)_countof(sdm.parts)) &&
|
|
|
|
- (nDiskIdx >= 0) && (nDiskIdx < (int)_countof(sdm.disks)))
|
|
|
|
- {
|
|
|
|
- unsigned int i, j;
|
|
|
|
- GFA_SYSINFO_DISK &disk = sdm.disks[nDiskIdx];
|
|
|
|
-
|
|
|
|
- for(i = 0; i < disk.nPartCount; ++i)
|
|
|
|
- {
|
|
|
|
- if(disk.aPartIdx[i] == nPartIdx)
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if(i < disk.nPartCount)
|
|
|
|
- {
|
|
|
|
- for(j = i + 1; j < disk.nPartCount; ++i, ++j)
|
|
|
|
- {
|
|
|
|
- disk.aPartIdx[i] = disk.aPartIdx[j];
|
|
|
|
- }
|
|
|
|
- bChange = true;
|
|
|
|
- return --disk.nPartCount;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return disk.nPartCount;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return 0;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/////////////////////////////////////////////////////////////////////////////
|
|
|
|
-/////////////////////////////////////////////////////////////////////////////
|
|
|
|
-/////////////////////////////////////////////////////////////////////////////
|
|
|
|
-
|
|
|
|
-static bool _LookupMountPoint(MountMap &mm, const char *pszNode, char *pszMntPoint, size_t nCChMntPoint)
|
|
|
|
-{
|
|
|
|
- MountMap::const_iterator it = mm.find(pszNode);
|
|
|
|
- if(it == mm.end())
|
|
|
|
- return false;
|
|
|
|
- const std::string &s = it->second;
|
|
|
|
-
|
|
|
|
- if(s.length() < nCChMntPoint)
|
|
|
|
- {
|
|
|
|
- strcpy(pszMntPoint, s.c_str());
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return false;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static bool _UpdatePartitionFsInfo(MountMap &mm, GFA_SYSINFO_PARTITION &part)
|
|
|
|
-{
|
|
|
|
- if(_LookupMountPoint(mm, part.szDevNode, part.szMntPoint, sizeof(part.szMntPoint)))
|
|
|
|
- {
|
|
|
|
- struct statvfs stvs;
|
|
|
|
-
|
|
|
|
- if(!statvfs(part.szMntPoint, &stvs))
|
|
|
|
- {
|
|
|
|
- part.nKiBSize = stvs.f_bsize * stvs.f_blocks / 1024;
|
|
|
|
- part.nKiBFree = stvs.f_bsize * stvs.f_bfree / 1024;
|
|
|
|
- part.nKiBUsed = part.nKiBSize - part.nKiBFree;
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- TRACE("statvfs failed on \"%s\": %s\n", part.szMntPoint, strerror(errno));
|
|
|
|
- memset(part.szMntPoint, 0, sizeof(part.szMntPoint));
|
|
|
|
- part.nKiBSize = 0;
|
|
|
|
- part.nKiBFree = 0;
|
|
|
|
- part.nKiBUsed = 0;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return true;
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- memset(part.szMntPoint, 0, sizeof(part.szMntPoint));
|
|
|
|
- part.nKiBSize = 0;
|
|
|
|
- part.nKiBFree = 0;
|
|
|
|
- part.nKiBUsed = 0;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return false;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/////////////////////////////////////////////////////////////////////////////
|
|
|
|
-
|
|
|
|
-static std::string _StrReplace(std::string &s, const char *pszFind, const char *pszRepl)
|
|
|
|
-{
|
|
|
|
- std::string r = s;
|
|
|
|
-
|
|
|
|
- if(pszFind && *pszFind && pszRepl)
|
|
|
|
- {
|
|
|
|
- size_t nFind, nLen = strlen(pszFind);
|
|
|
|
-
|
|
|
|
- while((nFind = r.find(pszFind)) != std::string::npos)
|
|
|
|
- {
|
|
|
|
- r = r.replace(nFind, nLen, pszRepl);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return r;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static std::string _UnescapeMountpointString(std::string &s)
|
|
|
|
-{
|
|
|
|
- std::string r = s;
|
|
|
|
- r = _StrReplace(r, "\\040", " ");
|
|
|
|
- r = _StrReplace(r, "\\011", "\t");
|
|
|
|
- r = _StrReplace(r, "\\012", "\n");
|
|
|
|
- r = _StrReplace(r, "\\134", "\\");
|
|
|
|
- return r;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static void _UpdateMountMap(MountMap &mm)
|
|
|
|
-{
|
|
|
|
- char szLine[512], szNode[512], szMount[512];
|
|
|
|
- std::ifstream mounts(_MOUNTS_FILE);
|
|
|
|
- mm.clear();
|
|
|
|
-
|
|
|
|
- while(mounts.getline(szLine, sizeof(szLine)).good())
|
|
|
|
- {
|
|
|
|
- if((sscanf(szLine, "%s %s", szNode, szMount) == 2))
|
|
|
|
- {
|
|
|
|
- std::string key(szNode);
|
|
|
|
- key = _UnescapeMountpointString(key);
|
|
|
|
- std::string val(szMount);
|
|
|
|
- val = _UnescapeMountpointString(val);
|
|
|
|
- mm.emplace(key, val);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/////////////////////////////////////////////////////////////////////////////
|
|
|
|
-
|
|
|
|
-static bool _ProcessMounts(GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm, MountMap &mm)
|
|
|
|
-{
|
|
|
|
- bool bChange = false;
|
|
|
|
- char szMntPoint[_countof(GFA_SYSINFO_PARTITION::szMntPoint)];
|
|
|
|
-
|
|
|
|
- for(size_t i = 0; i < _countof(sdm.parts); ++i)
|
|
|
|
- {
|
|
|
|
- GFA_SYSINFO_PARTITION &part = sdm.parts[i];
|
|
|
|
-
|
|
|
|
- if(part.valid)
|
|
|
|
- {
|
|
|
|
- bool bMountedOld = !!*part.szMntPoint;
|
|
|
|
- bool bMountedNew = _LookupMountPoint(mm, part.szDevNode, szMntPoint, sizeof(szMntPoint));
|
|
|
|
-
|
|
|
|
- if(!bMountedOld && bMountedNew)
|
|
|
|
- {
|
|
|
|
- memcpy(part.szMntPoint, szMntPoint, sizeof(part.szMntPoint));
|
|
|
|
- _UpdatePartitionFsInfo(mm, part);
|
|
|
|
- _SetPartitionChange(sdm, i);
|
|
|
|
- bChange = true;
|
|
|
|
- }
|
|
|
|
- else if(bMountedOld && !bMountedNew)
|
|
|
|
- {
|
|
|
|
- memset(part.szMntPoint, 0, sizeof(part.szMntPoint));
|
|
|
|
- _UpdatePartitionFsInfo(mm, part);
|
|
|
|
- _SetPartitionChange(sdm, i);
|
|
|
|
- bChange = true;
|
|
|
|
- }
|
|
|
|
- else if(bMountedOld && bMountedNew)
|
|
|
|
- {
|
|
|
|
- if(strcmp(part.szMntPoint, szMntPoint))
|
|
|
|
- {
|
|
|
|
- memcpy(part.szMntPoint, szMntPoint, sizeof(part.szMntPoint));
|
|
|
|
- _UpdatePartitionFsInfo(mm, part);
|
|
|
|
- _SetPartitionChange(sdm, i);
|
|
|
|
- bChange = true;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return bChange;
|
|
|
|
-}
|
|
|
|
-#endif
|
|
|
|
-
|
|
|
|
-/////////////////////////////////////////////////////////////////////////////
|
|
|
|
-
|
|
|
|
-static void _ProcessCtrlMessages(HAPPCTRL hAC, HAPPINFO hAI, bool &bStateTransition)
|
|
|
|
-{
|
|
|
|
- ctrlmsg_t nCtrlMsg;
|
|
|
|
-
|
|
|
|
- while(g_fRun && (nCtrlMsg = ::GfaIpcAppCtrlGetNextCtrlMsg(hAI)))
|
|
|
|
- {
|
|
|
|
- switch(nCtrlMsg)
|
|
|
|
- {
|
|
|
|
- case GFA_APPCTRL_CTRLMSG_STOP:
|
|
|
|
- bStateTransition = g_fRun;
|
|
|
|
- g_fRun = false;
|
|
|
|
- TRACE("Received Message: STOP!\n");
|
|
|
|
- break;
|
|
|
|
- case GFA_APPCTRL_CTRLMSG_PAUSE:
|
|
|
|
- if(!g_fPause)
|
|
|
|
- {
|
|
|
|
- bStateTransition = true;
|
|
|
|
- g_fPause = true;
|
|
|
|
- ::GfaIpcAppCtrlSetState(hAC, GIAS_Paused);
|
|
|
|
- TRACE("%-8s: State: %s\n", "Me", g_pszStateNames[GIAS_Paused]);
|
|
|
|
- }
|
|
|
|
- break;
|
|
|
|
- case GFA_APPCTRL_CTRLMSG_RESUME:
|
|
|
|
- if(g_fPause)
|
|
|
|
- {
|
|
|
|
- bStateTransition = true;
|
|
|
|
- g_fPause = false;
|
|
|
|
- ::GfaIpcAppCtrlSetState(hAC, GIAS_Running);
|
|
|
|
- TRACE("%-8s: State: %s\n", "Me", g_pszStateNames[GIAS_Running]);
|
|
|
|
- }
|
|
|
|
- break;
|
|
|
|
- default:
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-#if 0
|
|
|
|
-static const char* _GetFileSpec(const char *pszPathname)
|
|
|
|
-{
|
|
|
|
- if(pszPathname && *pszPathname)
|
|
|
|
- {
|
|
|
|
- const char *pSlash = strrchr(pszPathname, '/');
|
|
|
|
- if(pSlash)
|
|
|
|
- return ++pSlash;
|
|
|
|
- else
|
|
|
|
- return pszPathname;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return NULL;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static bool _IsInternalEmmc(const char *pszDevNode)
|
|
|
|
-{
|
|
|
|
- if(pszDevNode)
|
|
|
|
- {
|
|
|
|
- const char *pszDevName = _GetFileSpec(pszDevNode);
|
|
|
|
- return _STR_EQUALS(pszDevName, _INTERNAL_EMMC_PART2) || _STR_EQUALS(pszDevName, _INTERNAL_EMMC_PART1);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return false;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static long long _NumberFromString(const char *pszString, int base, bool *pbErr)
|
|
|
|
-{
|
|
|
|
- if(!pszString || !*pszString)
|
|
|
|
- {
|
|
|
|
- if(pbErr)
|
|
|
|
- *pbErr = true;
|
|
|
|
- return 0;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- char *endptr;
|
|
|
|
- long long nRet = strtoll(pszString, &endptr, base);
|
|
|
|
-
|
|
|
|
- if( (((nRet == LLONG_MAX) || (nRet == LLONG_MIN)) && (errno == ERANGE)) ||
|
|
|
|
- ((nRet == 0) && (errno == EINVAL)) ||
|
|
|
|
- (!!*endptr))
|
|
|
|
- {
|
|
|
|
- if(pbErr)
|
|
|
|
- *pbErr = true;
|
|
|
|
- return 0;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if(pbErr)
|
|
|
|
- *pbErr = false;
|
|
|
|
- return nRet;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static long long _ReadDevPropertyValue(struct udev_device* dev, const char *pszKey, int base, bool *pbErr)
|
|
|
|
-{
|
|
|
|
- char szNum[64];
|
|
|
|
- return _NumberFromString(_ReadDevPropertyValue(dev, pszKey, szNum, sizeof(szNum), false), base, pbErr);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static const char* _ReadDevPropertyValue(struct udev_device* dev, const char *pszKey, char *pszValue, size_t nCChValue, bool bTruncate)
|
|
|
|
-{
|
|
|
|
- if(!pszValue || !nCChValue)
|
|
|
|
- return NULL;
|
|
|
|
- memset(pszValue, 0, nCChValue);
|
|
|
|
-
|
|
|
|
- const char *pszVal = ::udev_device_get_property_value(dev, pszKey);
|
|
|
|
-
|
|
|
|
- if(pszVal)
|
|
|
|
- {
|
|
|
|
- size_t nLen = strlen(pszVal);
|
|
|
|
-
|
|
|
|
- if(nLen < nCChValue)
|
|
|
|
- {
|
|
|
|
- strcpy(pszValue, pszVal);
|
|
|
|
- return pszValue;
|
|
|
|
- }
|
|
|
|
- else if(bTruncate)
|
|
|
|
- {
|
|
|
|
- memcpy(pszValue, pszVal, nCChValue);
|
|
|
|
- pszValue[nCChValue - 1] = '\0';
|
|
|
|
- return pszValue;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return NULL;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static void _ProcessPartition(GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm, MountMap &mm, struct udev_device* dev)
|
|
|
|
-{
|
|
|
|
- if(dev)
|
|
|
|
- {
|
|
|
|
- bool bChange;
|
|
|
|
- GFA_SYSINFO_PARTITION part;
|
|
|
|
- memset(&part, 0, sizeof(part));
|
|
|
|
- part.nDiskIdx = -1;
|
|
|
|
- int nPartIdx = -1;
|
|
|
|
- int nDiskIdx = -1;
|
|
|
|
-
|
|
|
|
- const char *pszDevNode = ::udev_device_get_devnode(dev);
|
|
|
|
-
|
|
|
|
- if(!pszDevNode)
|
|
|
|
- return;
|
|
|
|
-// if(_IsInternalEmmc(pszDevNode))
|
|
|
|
-// return; // skip internal emmc
|
|
|
|
- bool bInternalEmmc = _IsInternalEmmc(pszDevNode);
|
|
|
|
- strncpy(part.szDevNode, pszDevNode, sizeof(part.szDevNode) - 1);
|
|
|
|
-
|
|
|
|
- const char *pszAction = ::udev_device_get_action(dev);
|
|
|
|
- bool bAdd = _STR_EQUALS(pszAction, "add");
|
|
|
|
- bool bRem = _STR_EQUALS(pszAction, "remove");
|
|
|
|
- bool bEnum = !pszAction;
|
|
|
|
-
|
|
|
|
- if(bAdd || bEnum)
|
|
|
|
- {
|
|
|
|
- if(_LookupPartition(sdm, part.szDevNode) >= 0)
|
|
|
|
- return;
|
|
|
|
-
|
|
|
|
- part.internal = bInternalEmmc;
|
|
|
|
- _ReadDevPropertyValue(dev, "ID_FS_LABEL", part.szFsLabel, sizeof(part.szFsLabel), true);
|
|
|
|
- _ReadDevPropertyValue(dev, "ID_FS_TYPE", part.szFsType, sizeof(part.szFsType), true);
|
|
|
|
- _ReadDevPropertyValue(dev, "ID_FS_VERSION", part.szFsVersion, sizeof(part.szFsVersion), true);
|
|
|
|
- part.nKiBPartSize = _ReadDevPropertyValue(dev, "ID_PART_ENTRY_SIZE") / 2;
|
|
|
|
- _UpdatePartitionFsInfo(mm, part);
|
|
|
|
-
|
|
|
|
- struct udev_device* cur = dev;
|
|
|
|
-
|
|
|
|
- while((cur = ::udev_device_get_parent(cur)))
|
|
|
|
- {
|
|
|
|
- const char *pszSs = ::udev_device_get_subsystem(cur);
|
|
|
|
- const char *pszDt = ::udev_device_get_devtype(cur);
|
|
|
|
- const char *pszDn = ::udev_device_get_devnode(cur);
|
|
|
|
-
|
|
|
|
- if(!pszDn)
|
|
|
|
- break;
|
|
|
|
-
|
|
|
|
- if(_STR_EQUALS(pszSs, "usb") || _STR_EQUALS(pszSs, "block"))
|
|
|
|
- {
|
|
|
|
- if(_STR_EQUALS(pszDt, "disk"))
|
|
|
|
- {
|
|
|
|
- GFA_SYSINFO_DISK disk;
|
|
|
|
- memset(&disk, 0, sizeof(disk));
|
|
|
|
- strncpy(disk.szDevNode, pszDn, sizeof(disk.szDevNode) - 1);
|
|
|
|
-
|
|
|
|
- disk.internal = bInternalEmmc;
|
|
|
|
- if(!_ReadDevPropertyValue(cur, "ID_NAME", disk.szName, sizeof(disk.szName), true))
|
|
|
|
- _ReadDevPropertyValue(cur, "ID_MODEL", disk.szName, sizeof(disk.szName), true);
|
|
|
|
- _ReadDevPropertyValue(cur, "ID_VENDOR", disk.szVendor, sizeof(disk.szVendor), true);
|
|
|
|
- _ReadDevPropertyValue(cur, "ID_BUS", disk.szBus, sizeof(disk.szBus), true);
|
|
|
|
-
|
|
|
|
- disk.nVendorID = _ReadDevPropertyValue(cur, "ID_VENDOR_ID", 16);
|
|
|
|
- disk.nProductID = _ReadDevPropertyValue(cur, "ID_MODEL_ID", 16);
|
|
|
|
-
|
|
|
|
- if((nDiskIdx = _AddDisk(sdm, disk, bChange)) >= 0)
|
|
|
|
- {
|
|
|
|
- if((nPartIdx = _AddPartition(sdm, part, bChange)) < 0)
|
|
|
|
- {
|
|
|
|
- if(sdm.disks[nDiskIdx].nPartCount == 0)
|
|
|
|
- _RemoveDisk(sdm, nDiskIdx, bChange);
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- _DiskAddPartition(sdm, nDiskIdx, nPartIdx, bChange);
|
|
|
|
- _PartitionSetDisk(sdm, nPartIdx, nDiskIdx, bChange);
|
|
|
|
- _SetPartitionChange(sdm, nPartIdx);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- else if(bRem)
|
|
|
|
- {
|
|
|
|
- if((nPartIdx = _LookupPartition(sdm, pszDevNode)) >= 0)
|
|
|
|
- {
|
|
|
|
- _RemovePartition(sdm, nPartIdx, bChange);
|
|
|
|
- _SetPartitionChange(sdm, nPartIdx);
|
|
|
|
-
|
|
|
|
- if((nDiskIdx = _PartitionGetDisk(sdm, nPartIdx)) >= 0)
|
|
|
|
- {
|
|
|
|
- if(!_DiskRemovePartition(sdm, nDiskIdx, nPartIdx, bChange))
|
|
|
|
- {
|
|
|
|
- _RemoveDisk(sdm, nDiskIdx, bChange);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static void _EnumStorageDevices(GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm, MountMap &mm, struct udev *pUdev)
|
|
|
|
-{
|
|
|
|
- struct udev_enumerate *pEnum = ::udev_enumerate_new(pUdev);
|
|
|
|
- ::udev_enumerate_add_match_subsystem(pEnum, "block");
|
|
|
|
- ::udev_enumerate_add_match_property(pEnum, "DEVTYPE", "partition");
|
|
|
|
- ::udev_enumerate_scan_devices(pEnum);
|
|
|
|
-
|
|
|
|
- struct udev_list_entry *devices = ::udev_enumerate_get_list_entry(pEnum);
|
|
|
|
- struct udev_list_entry *entry;
|
|
|
|
-
|
|
|
|
- udev_list_entry_foreach(entry, devices)
|
|
|
|
- {
|
|
|
|
- const char *pszPath = ::udev_list_entry_get_name(entry);
|
|
|
|
- struct udev_device* dev = ::udev_device_new_from_syspath(pUdev, pszPath);
|
|
|
|
-
|
|
|
|
- _ProcessPartition(sdm, mm, dev);
|
|
|
|
- ::udev_device_unref(dev);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- ::udev_enumerate_unref(pEnum);
|
|
|
|
-}
|
|
|
|
-#endif
|
|
|
|
-
|
|
|
|
-/////////////////////////////////////////////////////////////////////////////
|
|
|
|
-
|
|
|
|
-static void _LockSHM(HSHM hShm)
|
|
|
|
-{
|
|
|
|
- ::GfaIpcLockSHMAndSigBlock(hShm, &g_set);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static void _UnlockSHM(HSHM hShm)
|
|
|
|
-{
|
|
|
|
- ::GfaIpcUnlockSHMAndSigUnblock(hShm, &g_set);
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-static void _SigHandler(int sig)
|
|
|
|
-{
|
|
|
|
- UNUSED(sig);
|
|
|
|
- g_fPause = false;
|
|
|
|
- g_fRun = false;
|
|
|
|
- g_fZombie = false;
|
|
|
|
-}
|
|
|
|
-
|
|
|
|
-/////////////////////////////////////////////////////////////////////////////
|
|
|
|
-/////////////////////////////////////////////////////////////////////////////
|
|
|
|
-/////////////////////////////////////////////////////////////////////////////
|
|
|
|
-
|
|
|
|
-int main(int argc, char *argv[])
|
|
|
|
-{
|
|
|
|
- int c;
|
|
|
|
- HAPPCTRL hAC = NULL;
|
|
|
|
- HAPPINFO hAI;
|
|
|
|
- CCycleTimer ct(_CYCLE_INTV), perfCnt(0U);
|
|
|
|
- cy_time_t wStart, wEnd, wCur = 0;
|
|
|
|
- std::string sDbUser, sDbPass;
|
|
|
|
- CMySqlInfo mySqlInfo;
|
|
|
|
- CStgDevInfo stgDevInfo;
|
|
|
|
- CSpiInfo spiInfo;
|
|
|
|
- bool bStateTransition;
|
|
|
|
-
|
|
|
|
- /////////////////////////////////////////////////////////////////////////
|
|
|
|
- // parse command line options
|
|
|
|
-
|
|
|
|
- while((c = getopt(argc, argv, "p:u:")) != -1)
|
|
|
|
- {
|
|
|
|
- switch(c)
|
|
|
|
- {
|
|
|
|
- case 'p':
|
|
|
|
- sDbPass = optarg;
|
|
|
|
- break;
|
|
|
|
- case 'u':
|
|
|
|
- sDbUser = optarg;
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /////////////////////////////////////////////////////////////////////////
|
|
|
|
- // signal handling
|
|
|
|
-
|
|
|
|
- struct sigaction sa;
|
|
|
|
- memset(&sa, 0, sizeof(sa));
|
|
|
|
- ::sigfillset(&g_set);
|
|
|
|
- ::sigdelset(&g_set, SIGSEGV);
|
|
|
|
-
|
|
|
|
- sa.sa_handler = _SigHandler;
|
|
|
|
- sigaction(SIGHUP, &sa, NULL); // handles user's terminal disconnect
|
|
|
|
- sigaction(SIGQUIT, &sa, NULL); // handles Ctrl + '\'
|
|
|
|
- sigaction(SIGTERM, &sa, NULL); // handles normal termination
|
|
|
|
- sigaction(SIGABRT, &sa, NULL); // handles abnormal termination (i.e. abort())
|
|
|
|
- sigaction(SIGINT, &sa, NULL); // handles Ctrl + 'C'
|
|
|
|
-
|
|
|
|
- // ignore signals
|
|
|
|
- sa.sa_handler = SIG_IGN;
|
|
|
|
- sigaction(SIGTSTP, &sa, NULL); // ignores Ctrl + 'Z'
|
|
|
|
- sigaction(SIGCHLD, &sa, NULL); // ignores child process termination
|
|
|
|
- sigaction(0, &sa, NULL); // ignores shell termination
|
|
|
|
-
|
|
|
|
- /////////////////////////////////////////////////////////////////////////
|
|
|
|
- // initialize
|
|
|
|
-
|
|
|
|
- CMySqlInfo::EXEC_PARAMS myep;
|
|
|
|
- CStgDevInfo::EXEC_PARAMS step;
|
|
|
|
- CSpiInfo::EXEC_PARAMS spep;
|
|
|
|
-
|
|
|
|
- do
|
|
|
|
- {
|
|
|
|
- g_fZombie = true;
|
|
|
|
-
|
|
|
|
- if(!(hAC = ::GfaIpcAppCtrlAcquire(_APPID, _APPNAME, _CYCLE_INTV * 1000, _CYCLE_INTV * 3000)))
|
|
|
|
- {
|
|
|
|
- TRACE("GfaIpcAppCtrlAcquire failed\n");
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- ::GfaIpcAppCtrlSetLockUnlockFunctions(hAC, _LockSHM, _UnlockSHM);
|
|
|
|
- ::GfaIpcAppCtrlSetState(hAC, GIAS_Initializing);
|
|
|
|
-
|
|
|
|
- if(!::GfaIpcAppCtrlCreateSysInfo(hAC))
|
|
|
|
- {
|
|
|
|
- TRACE("GfaIpcAppCtrlCreateSysInfo failed\n");
|
|
|
|
- break;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- ::GfaIpcDumpSHMROT();
|
|
|
|
-
|
|
|
|
- TRACE("My Name: %s\n", _APPNAME);
|
|
|
|
- TRACE("My AppID: %llu\n", _APPID);
|
|
|
|
- TRACE("My PID: %d\n", getpid());
|
|
|
|
- TRACE("My Cycle: %d\n", _CYCLE_INTV);
|
|
|
|
-
|
|
|
|
- myep = {hAC, sDbUser, sDbPass};
|
|
|
|
- mySqlInfo.Create(&myep);
|
|
|
|
-
|
|
|
|
- step = {hAC};
|
|
|
|
- stgDevInfo.Create(&step);
|
|
|
|
-
|
|
|
|
- spep = {hAC};
|
|
|
|
- spiInfo.Create(&spep);
|
|
|
|
-
|
|
|
|
- g_fZombie = false;
|
|
|
|
- g_fRun = true;
|
|
|
|
- ::GfaIpcAppCtrlSetState(hAC, GIAS_Running);
|
|
|
|
- mySqlInfo.Signal(CMySqlInfo::S_UpdateAll);
|
|
|
|
- stgDevInfo.Signal(CStgDevInfo::S_Init);
|
|
|
|
- spiInfo.Signal(CSpiInfo::S_Init);
|
|
|
|
- }
|
|
|
|
- while(false);
|
|
|
|
-
|
|
|
|
- /////////////////////////////////////////////////////////////////////////
|
|
|
|
- /////////////////////////////////////////////////////////////////////////
|
|
|
|
- // run
|
|
|
|
-
|
|
|
|
- while(g_fRun)
|
|
|
|
- {
|
|
|
|
- bStateTransition = false;
|
|
|
|
-
|
|
|
|
- /////////////////////////////////////////////////////////////////////
|
|
|
|
- // trigger cycle timer
|
|
|
|
-
|
|
|
|
- ct.Trigger();
|
|
|
|
-
|
|
|
|
- /////////////////////////////////////////////////////////////////////
|
|
|
|
- // update app control info
|
|
|
|
-
|
|
|
|
- if((hAI = ::GfaIpcAppCtrlInfoUpdate(hAC, wCur)))
|
|
|
|
- {
|
|
|
|
- _ProcessCtrlMessages(hAC, hAI, bStateTransition);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /////////////////////////////////////////////////////////////////////
|
|
|
|
- // if not paused, do work
|
|
|
|
-
|
|
|
|
- if(g_fRun)
|
|
|
|
- {
|
|
|
|
- if(bStateTransition)
|
|
|
|
- {
|
|
|
|
- if(g_fPause)
|
|
|
|
- {
|
|
|
|
- mySqlInfo.Signal(CMySqlInfo::S_Pause);
|
|
|
|
- stgDevInfo.Signal(CStgDevInfo::S_Pause);
|
|
|
|
- spiInfo.Signal(CSpiInfo::S_Pause);
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- mySqlInfo.Signal(CMySqlInfo::S_Resume);
|
|
|
|
- stgDevInfo.Signal(CStgDevInfo::S_Resume);
|
|
|
|
- spiInfo.Signal(CSpiInfo::S_Resume);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if(!g_fPause)
|
|
|
|
- {
|
|
|
|
- wStart = ct.GetMicroTick();
|
|
|
|
- ::GfaIpcAppCtrlUpdateSysInfo(hAC);
|
|
|
|
- wEnd = ct.GetMicroTick();
|
|
|
|
- wCur = wEnd - wStart;
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- ct.Sleep1();
|
|
|
|
- }
|
|
|
|
- else
|
|
|
|
- {
|
|
|
|
- ::GfaIpcAppCtrlSetState(hAC, GIAS_Terminating);
|
|
|
|
- }
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- /////////////////////////////////////////////////////////////////////////
|
|
|
|
- /////////////////////////////////////////////////////////////////////////
|
|
|
|
- // terminate
|
|
|
|
-
|
|
|
|
- mySqlInfo.Signal(CMySqlInfo::S_Terminate);
|
|
|
|
- stgDevInfo.Signal(CStgDevInfo::S_Terminate);
|
|
|
|
- spiInfo.Signal(CSpiInfo::S_Terminate);
|
|
|
|
-
|
|
|
|
- mySqlInfo.Join(NULL);
|
|
|
|
- stgDevInfo.Join(NULL);
|
|
|
|
- spiInfo.Join(NULL);
|
|
|
|
-
|
|
|
|
- if(g_fZombie)
|
|
|
|
- {
|
|
|
|
- if(hAC)
|
|
|
|
- ::GfaIpcAppCtrlSetState(hAC, GIAS_Zombie);
|
|
|
|
- TRACE("%-8s: State: %s\n", "Me", ::GfaIpcAppCtrlGetStateText(GIAS_Zombie));
|
|
|
|
- pause();
|
|
|
|
- if(hAC)
|
|
|
|
- ::GfaIpcAppCtrlSetState(hAC, GIAS_Terminating);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- if(hAC)
|
|
|
|
- {
|
|
|
|
- ::GfaIpcAppCtrlReleaseSysInfo(hAC);
|
|
|
|
- ::GfaIpcAppCtrlRelease(hAC);
|
|
|
|
- }
|
|
|
|
-
|
|
|
|
- return 0;
|
|
|
|
-}
|
|
|