main.cpp 21 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869
  1. #include <stdio.h>
  2. #include <unistd.h>
  3. #include <string.h>
  4. #include <string>
  5. #include <vector>
  6. #include <map>
  7. #include <ext/stdio_filebuf.h>
  8. #include <iostream>
  9. #include <fstream>
  10. #include <signal.h>
  11. #include <sys/statvfs.h>
  12. #include <sys/statfs.h>
  13. #include <sys/types.h>
  14. #include <fcntl.h>
  15. #include <unistd.h>
  16. #include <limits.h>
  17. #include <libudev.h>
  18. #include <poll.h>
  19. #include <errno.h>
  20. #include <getopt.h>
  21. #include <gfa/gfasitarautils.h>
  22. #include <gfa/gfaipc.h>
  23. #include "stgdevinfo.h"
  24. #include "mysqlinfo.h"
  25. /////////////////////////////////////////////////////////////////////////////
  26. #ifdef _DEBUG
  27. #define TRACE(...) fprintf(stdout, __VA_ARGS__), fflush(stdout)
  28. #else // _DEBUG
  29. #define TRACE(...)
  30. #endif // _DEBUG
  31. #define UNUSED(v) (void)v
  32. #define _countof(a) (sizeof(a) / sizeof(*a))
  33. /////////////////////////////////////////////////////////////////////////////
  34. #define _APPID GFA_APPCTRL_APPID_SYSINFO
  35. #define _APPNAME "SysInfo"
  36. #define _CYCLE_INTV 500
  37. /////////////////////////////////////////////////////////////////////////////
  38. static volatile bool g_fRun = false;
  39. static volatile bool g_fPause = false;
  40. static volatile bool g_fZombie = false;
  41. /////////////////////////////////////////////////////////////////////////////
  42. static const char *g_pszStateNames[] =
  43. {
  44. "Not running",
  45. "Initializing",
  46. "Running",
  47. "Paused",
  48. "Hanging",
  49. "Terminating",
  50. "Invalid"
  51. };
  52. /////////////////////////////////////////////////////////////////////////////
  53. #if 0
  54. static long long _NumberFromString(const char *pszString, int base = 10, bool *pbErr = NULL);
  55. static const char* _ReadDevPropertyValue(struct udev_device* dev, const char *pszKey, char *pszValue, size_t nCChValue, bool bTruncate = false);
  56. static long long _ReadDevPropertyValue(struct udev_device* dev, const char *pszKey, int base = 10, bool *pbErr = NULL);
  57. /////////////////////////////////////////////////////////////////////////////
  58. /////////////////////////////////////////////////////////////////////////////
  59. /////////////////////////////////////////////////////////////////////////////
  60. static int _LookupPartition(const GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm, const char *pszDevNode)
  61. {
  62. int nIndex = -1;
  63. if(pszDevNode && *pszDevNode)
  64. {
  65. for(size_t i = 0; i < _countof(sdm.parts); ++i)
  66. {
  67. if(sdm.parts[i].valid && !strcmp(sdm.parts[i].szDevNode, pszDevNode))
  68. {
  69. nIndex = i; // found partition
  70. break;
  71. }
  72. }
  73. }
  74. return nIndex;
  75. }
  76. static int _AddPartition(GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm, const GFA_SYSINFO_PARTITION &part, bool &bChange)
  77. {
  78. int nIndex = -1;
  79. bChange = false;
  80. if((nIndex = _LookupPartition(sdm, part.szDevNode)) >= 0)
  81. return nIndex; // partition already exists
  82. for(size_t i = 0; i < _countof(sdm.parts); ++i)
  83. {
  84. if(!sdm.parts[i].valid)
  85. {
  86. memcpy(&sdm.parts[i], &part, sizeof(GFA_SYSINFO_PARTITION));
  87. sdm.parts[i].valid = true;
  88. bChange = true;
  89. nIndex = i;
  90. break;
  91. }
  92. }
  93. return nIndex;
  94. }
  95. static int _RemovePartition(GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm, int nIndex, bool &bChange)
  96. {
  97. bChange = false;
  98. if(nIndex >= 0 && nIndex < (int)_countof(sdm.parts))
  99. {
  100. bChange = sdm.parts[nIndex].valid;
  101. sdm.parts[nIndex].valid = false;
  102. }
  103. return nIndex;
  104. }
  105. static bool _PartitionSetDisk(GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm, int nPartIdx, int nDiskIdx, bool &bChange)
  106. {
  107. bChange = false;
  108. if( (nPartIdx >= 0) && (nPartIdx < (int)_countof(sdm.parts)) &&
  109. (nDiskIdx >= 0) && (nDiskIdx < (int)_countof(sdm.disks)))
  110. {
  111. if(sdm.parts[nPartIdx].nDiskIdx != nDiskIdx)
  112. {
  113. sdm.parts[nPartIdx].nDiskIdx = nDiskIdx;
  114. bChange = true;
  115. }
  116. return true;
  117. }
  118. return false;
  119. }
  120. static int _PartitionGetDisk(GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm, int nPartIdx)
  121. {
  122. if((nPartIdx >= 0) && (nPartIdx < (int)_countof(sdm.parts)))
  123. return sdm.parts[nPartIdx].nDiskIdx;
  124. return -1;
  125. }
  126. static void _ClearMapChanges(GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm)
  127. {
  128. sdm.nPartChangeMask = 0;
  129. }
  130. static bool _DeviceMapChanged(const GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm)
  131. {
  132. return !!sdm.nPartChangeMask;
  133. }
  134. static unsigned int _SetPartitionChange(GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm, int nPartIdx)
  135. {
  136. if((nPartIdx >= 0) && (nPartIdx < (int)_countof(sdm.parts)))
  137. {
  138. unsigned int nChanged = (0x01 << nPartIdx);
  139. sdm.nPartChangeMask |= nChanged;
  140. }
  141. return sdm.nPartChangeMask;
  142. }
  143. /////////////////////////////////////////////////////////////////////////////
  144. static int _LookupDisk(const GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm, const char *pszDevNode)
  145. {
  146. int nIndex = -1;
  147. if(pszDevNode && *pszDevNode)
  148. {
  149. for(size_t i = 0; i < _countof(sdm.disks); ++i)
  150. {
  151. if(sdm.disks[i].valid && !strcmp(sdm.disks[i].szDevNode, pszDevNode))
  152. {
  153. nIndex = i; // found partition
  154. break;
  155. }
  156. }
  157. }
  158. return nIndex;
  159. }
  160. static int _AddDisk(GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm, const GFA_SYSINFO_DISK &disk, bool &bChange)
  161. {
  162. int nIndex = -1;
  163. bChange = false;
  164. if((nIndex = _LookupDisk(sdm, disk.szDevNode)) >= 0)
  165. return nIndex; // partition already exists
  166. for(size_t i = 0; i < _countof(sdm.disks); ++i)
  167. {
  168. if(!sdm.disks[i].valid)
  169. {
  170. memcpy(&sdm.disks[i], &disk, sizeof(GFA_SYSINFO_DISK));
  171. sdm.disks[i].valid = true;
  172. bChange = true;
  173. nIndex = i;
  174. break;
  175. }
  176. }
  177. return nIndex;
  178. }
  179. static int _RemoveDisk(GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm, int nIndex, bool &bChange)
  180. {
  181. bChange = false;
  182. if(nIndex >= 0 && nIndex < (int)_countof(sdm.disks))
  183. {
  184. bChange = sdm.disks[nIndex].valid;
  185. sdm.disks[nIndex].valid = false;
  186. }
  187. return nIndex;
  188. }
  189. static unsigned int _DiskAddPartition(GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm, int nDiskIdx, int nPartIdx, bool &bChange)
  190. {
  191. bChange = false;
  192. if( (nPartIdx >= 0) && (nPartIdx < (int)_countof(sdm.parts)) &&
  193. (nDiskIdx >= 0) && (nDiskIdx < (int)_countof(sdm.disks)))
  194. {
  195. GFA_SYSINFO_DISK &disk = sdm.disks[nDiskIdx];
  196. for(unsigned int i = 0; i < disk.nPartCount; ++i)
  197. {
  198. if(disk.aPartIdx[i] == nPartIdx)
  199. return disk.nPartCount;
  200. }
  201. if(disk.nPartCount < _countof(disk.aPartIdx))
  202. {
  203. disk.aPartIdx[disk.nPartCount++] = nPartIdx;
  204. bChange = true;
  205. return disk.nPartCount;
  206. }
  207. }
  208. return 0;
  209. }
  210. static unsigned int _DiskRemovePartition(GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm, int nDiskIdx, int nPartIdx, bool &bChange)
  211. {
  212. bChange = false;
  213. if( (nPartIdx >= 0) && (nPartIdx < (int)_countof(sdm.parts)) &&
  214. (nDiskIdx >= 0) && (nDiskIdx < (int)_countof(sdm.disks)))
  215. {
  216. unsigned int i, j;
  217. GFA_SYSINFO_DISK &disk = sdm.disks[nDiskIdx];
  218. for(i = 0; i < disk.nPartCount; ++i)
  219. {
  220. if(disk.aPartIdx[i] == nPartIdx)
  221. break;
  222. }
  223. if(i < disk.nPartCount)
  224. {
  225. for(j = i + 1; j < disk.nPartCount; ++i, ++j)
  226. {
  227. disk.aPartIdx[i] = disk.aPartIdx[j];
  228. }
  229. bChange = true;
  230. return --disk.nPartCount;
  231. }
  232. return disk.nPartCount;
  233. }
  234. return 0;
  235. }
  236. /////////////////////////////////////////////////////////////////////////////
  237. /////////////////////////////////////////////////////////////////////////////
  238. /////////////////////////////////////////////////////////////////////////////
  239. static bool _LookupMountPoint(MountMap &mm, const char *pszNode, char *pszMntPoint, size_t nCChMntPoint)
  240. {
  241. MountMap::const_iterator it = mm.find(pszNode);
  242. if(it == mm.end())
  243. return false;
  244. const std::string &s = it->second;
  245. if(s.length() < nCChMntPoint)
  246. {
  247. strcpy(pszMntPoint, s.c_str());
  248. return true;
  249. }
  250. return false;
  251. }
  252. static bool _UpdatePartitionFsInfo(MountMap &mm, GFA_SYSINFO_PARTITION &part)
  253. {
  254. if(_LookupMountPoint(mm, part.szDevNode, part.szMntPoint, sizeof(part.szMntPoint)))
  255. {
  256. struct statvfs stvs;
  257. if(!statvfs(part.szMntPoint, &stvs))
  258. {
  259. part.nKiBSize = stvs.f_bsize * stvs.f_blocks / 1024;
  260. part.nKiBFree = stvs.f_bsize * stvs.f_bfree / 1024;
  261. part.nKiBUsed = part.nKiBSize - part.nKiBFree;
  262. }
  263. else
  264. {
  265. TRACE("statvfs failed on \"%s\": %s\n", part.szMntPoint, strerror(errno));
  266. memset(part.szMntPoint, 0, sizeof(part.szMntPoint));
  267. part.nKiBSize = 0;
  268. part.nKiBFree = 0;
  269. part.nKiBUsed = 0;
  270. }
  271. return true;
  272. }
  273. else
  274. {
  275. memset(part.szMntPoint, 0, sizeof(part.szMntPoint));
  276. part.nKiBSize = 0;
  277. part.nKiBFree = 0;
  278. part.nKiBUsed = 0;
  279. }
  280. return false;
  281. }
  282. /////////////////////////////////////////////////////////////////////////////
  283. static std::string _StrReplace(std::string &s, const char *pszFind, const char *pszRepl)
  284. {
  285. std::string r = s;
  286. if(pszFind && *pszFind && pszRepl)
  287. {
  288. size_t nFind, nLen = strlen(pszFind);
  289. while((nFind = r.find(pszFind)) != std::string::npos)
  290. {
  291. r = r.replace(nFind, nLen, pszRepl);
  292. }
  293. }
  294. return r;
  295. }
  296. static std::string _UnescapeMountpointString(std::string &s)
  297. {
  298. std::string r = s;
  299. r = _StrReplace(r, "\\040", " ");
  300. r = _StrReplace(r, "\\011", "\t");
  301. r = _StrReplace(r, "\\012", "\n");
  302. r = _StrReplace(r, "\\134", "\\");
  303. return r;
  304. }
  305. static void _UpdateMountMap(MountMap &mm)
  306. {
  307. char szLine[512], szNode[512], szMount[512];
  308. std::ifstream mounts(_MOUNTS_FILE);
  309. mm.clear();
  310. while(mounts.getline(szLine, sizeof(szLine)).good())
  311. {
  312. if((sscanf(szLine, "%s %s", szNode, szMount) == 2))
  313. {
  314. std::string key(szNode);
  315. key = _UnescapeMountpointString(key);
  316. std::string val(szMount);
  317. val = _UnescapeMountpointString(val);
  318. mm.emplace(key, val);
  319. }
  320. }
  321. }
  322. /////////////////////////////////////////////////////////////////////////////
  323. static bool _ProcessMounts(GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm, MountMap &mm)
  324. {
  325. bool bChange = false;
  326. char szMntPoint[_countof(GFA_SYSINFO_PARTITION::szMntPoint)];
  327. for(size_t i = 0; i < _countof(sdm.parts); ++i)
  328. {
  329. GFA_SYSINFO_PARTITION &part = sdm.parts[i];
  330. if(part.valid)
  331. {
  332. bool bMountedOld = !!*part.szMntPoint;
  333. bool bMountedNew = _LookupMountPoint(mm, part.szDevNode, szMntPoint, sizeof(szMntPoint));
  334. if(!bMountedOld && bMountedNew)
  335. {
  336. memcpy(part.szMntPoint, szMntPoint, sizeof(part.szMntPoint));
  337. _UpdatePartitionFsInfo(mm, part);
  338. _SetPartitionChange(sdm, i);
  339. bChange = true;
  340. }
  341. else if(bMountedOld && !bMountedNew)
  342. {
  343. memset(part.szMntPoint, 0, sizeof(part.szMntPoint));
  344. _UpdatePartitionFsInfo(mm, part);
  345. _SetPartitionChange(sdm, i);
  346. bChange = true;
  347. }
  348. else if(bMountedOld && bMountedNew)
  349. {
  350. if(strcmp(part.szMntPoint, szMntPoint))
  351. {
  352. memcpy(part.szMntPoint, szMntPoint, sizeof(part.szMntPoint));
  353. _UpdatePartitionFsInfo(mm, part);
  354. _SetPartitionChange(sdm, i);
  355. bChange = true;
  356. }
  357. }
  358. }
  359. }
  360. return bChange;
  361. }
  362. #endif
  363. /////////////////////////////////////////////////////////////////////////////
  364. static void _ProcessCtrlMessages(HAPPCTRL hAC, HAPPINFO hAI, bool &bStateTransition)
  365. {
  366. ctrlmsg_t nCtrlMsg;
  367. while(g_fRun && (nCtrlMsg = ::GfaIpcAppCtrlGetNextCtrlMsg(hAI)))
  368. {
  369. switch(nCtrlMsg)
  370. {
  371. case GFA_APPCTRL_CTRLMSG_STOP:
  372. bStateTransition = g_fRun;
  373. g_fRun = false;
  374. TRACE("Received Message: STOP!\n");
  375. break;
  376. case GFA_APPCTRL_CTRLMSG_PAUSE:
  377. if(!g_fPause)
  378. {
  379. bStateTransition = true;
  380. g_fPause = true;
  381. ::GfaIpcAppCtrlSetState(hAC, GIAS_Paused);
  382. TRACE("%-8s: State: %s\n", "Me", g_pszStateNames[GIAS_Paused]);
  383. }
  384. break;
  385. case GFA_APPCTRL_CTRLMSG_RESUME:
  386. if(g_fPause)
  387. {
  388. bStateTransition = true;
  389. g_fPause = false;
  390. ::GfaIpcAppCtrlSetState(hAC, GIAS_Running);
  391. TRACE("%-8s: State: %s\n", "Me", g_pszStateNames[GIAS_Running]);
  392. }
  393. break;
  394. default:
  395. break;
  396. }
  397. }
  398. }
  399. #if 0
  400. static const char* _GetFileSpec(const char *pszPathname)
  401. {
  402. if(pszPathname && *pszPathname)
  403. {
  404. const char *pSlash = strrchr(pszPathname, '/');
  405. if(pSlash)
  406. return ++pSlash;
  407. else
  408. return pszPathname;
  409. }
  410. return NULL;
  411. }
  412. static bool _IsInternalEmmc(const char *pszDevNode)
  413. {
  414. if(pszDevNode)
  415. {
  416. const char *pszDevName = _GetFileSpec(pszDevNode);
  417. return _STR_EQUALS(pszDevName, _INTERNAL_EMMC_PART2) || _STR_EQUALS(pszDevName, _INTERNAL_EMMC_PART1);
  418. }
  419. return false;
  420. }
  421. static long long _NumberFromString(const char *pszString, int base, bool *pbErr)
  422. {
  423. if(!pszString || !*pszString)
  424. {
  425. if(pbErr)
  426. *pbErr = true;
  427. return 0;
  428. }
  429. char *endptr;
  430. long long nRet = strtoll(pszString, &endptr, base);
  431. if( (((nRet == LLONG_MAX) || (nRet == LLONG_MIN)) && (errno == ERANGE)) ||
  432. ((nRet == 0) && (errno == EINVAL)) ||
  433. (!!*endptr))
  434. {
  435. if(pbErr)
  436. *pbErr = true;
  437. return 0;
  438. }
  439. if(pbErr)
  440. *pbErr = false;
  441. return nRet;
  442. }
  443. static long long _ReadDevPropertyValue(struct udev_device* dev, const char *pszKey, int base, bool *pbErr)
  444. {
  445. char szNum[64];
  446. return _NumberFromString(_ReadDevPropertyValue(dev, pszKey, szNum, sizeof(szNum), false), base, pbErr);
  447. }
  448. static const char* _ReadDevPropertyValue(struct udev_device* dev, const char *pszKey, char *pszValue, size_t nCChValue, bool bTruncate)
  449. {
  450. if(!pszValue || !nCChValue)
  451. return NULL;
  452. memset(pszValue, 0, nCChValue);
  453. const char *pszVal = ::udev_device_get_property_value(dev, pszKey);
  454. if(pszVal)
  455. {
  456. size_t nLen = strlen(pszVal);
  457. if(nLen < nCChValue)
  458. {
  459. strcpy(pszValue, pszVal);
  460. return pszValue;
  461. }
  462. else if(bTruncate)
  463. {
  464. memcpy(pszValue, pszVal, nCChValue);
  465. pszValue[nCChValue - 1] = '\0';
  466. return pszValue;
  467. }
  468. }
  469. return NULL;
  470. }
  471. static void _ProcessPartition(GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm, MountMap &mm, struct udev_device* dev)
  472. {
  473. if(dev)
  474. {
  475. bool bChange;
  476. GFA_SYSINFO_PARTITION part;
  477. memset(&part, 0, sizeof(part));
  478. part.nDiskIdx = -1;
  479. int nPartIdx = -1;
  480. int nDiskIdx = -1;
  481. const char *pszDevNode = ::udev_device_get_devnode(dev);
  482. if(!pszDevNode)
  483. return;
  484. // if(_IsInternalEmmc(pszDevNode))
  485. // return; // skip internal emmc
  486. bool bInternalEmmc = _IsInternalEmmc(pszDevNode);
  487. strncpy(part.szDevNode, pszDevNode, sizeof(part.szDevNode) - 1);
  488. const char *pszAction = ::udev_device_get_action(dev);
  489. bool bAdd = _STR_EQUALS(pszAction, "add");
  490. bool bRem = _STR_EQUALS(pszAction, "remove");
  491. bool bEnum = !pszAction;
  492. if(bAdd || bEnum)
  493. {
  494. if(_LookupPartition(sdm, part.szDevNode) >= 0)
  495. return;
  496. part.internal = bInternalEmmc;
  497. _ReadDevPropertyValue(dev, "ID_FS_LABEL", part.szFsLabel, sizeof(part.szFsLabel), true);
  498. _ReadDevPropertyValue(dev, "ID_FS_TYPE", part.szFsType, sizeof(part.szFsType), true);
  499. _ReadDevPropertyValue(dev, "ID_FS_VERSION", part.szFsVersion, sizeof(part.szFsVersion), true);
  500. part.nKiBPartSize = _ReadDevPropertyValue(dev, "ID_PART_ENTRY_SIZE") / 2;
  501. _UpdatePartitionFsInfo(mm, part);
  502. struct udev_device* cur = dev;
  503. while((cur = ::udev_device_get_parent(cur)))
  504. {
  505. const char *pszSs = ::udev_device_get_subsystem(cur);
  506. const char *pszDt = ::udev_device_get_devtype(cur);
  507. const char *pszDn = ::udev_device_get_devnode(cur);
  508. if(!pszDn)
  509. break;
  510. if(_STR_EQUALS(pszSs, "usb") || _STR_EQUALS(pszSs, "block"))
  511. {
  512. if(_STR_EQUALS(pszDt, "disk"))
  513. {
  514. GFA_SYSINFO_DISK disk;
  515. memset(&disk, 0, sizeof(disk));
  516. strncpy(disk.szDevNode, pszDn, sizeof(disk.szDevNode) - 1);
  517. disk.internal = bInternalEmmc;
  518. if(!_ReadDevPropertyValue(cur, "ID_NAME", disk.szName, sizeof(disk.szName), true))
  519. _ReadDevPropertyValue(cur, "ID_MODEL", disk.szName, sizeof(disk.szName), true);
  520. _ReadDevPropertyValue(cur, "ID_VENDOR", disk.szVendor, sizeof(disk.szVendor), true);
  521. _ReadDevPropertyValue(cur, "ID_BUS", disk.szBus, sizeof(disk.szBus), true);
  522. disk.nVendorID = _ReadDevPropertyValue(cur, "ID_VENDOR_ID", 16);
  523. disk.nProductID = _ReadDevPropertyValue(cur, "ID_MODEL_ID", 16);
  524. if((nDiskIdx = _AddDisk(sdm, disk, bChange)) >= 0)
  525. {
  526. if((nPartIdx = _AddPartition(sdm, part, bChange)) < 0)
  527. {
  528. if(sdm.disks[nDiskIdx].nPartCount == 0)
  529. _RemoveDisk(sdm, nDiskIdx, bChange);
  530. break;
  531. }
  532. _DiskAddPartition(sdm, nDiskIdx, nPartIdx, bChange);
  533. _PartitionSetDisk(sdm, nPartIdx, nDiskIdx, bChange);
  534. _SetPartitionChange(sdm, nPartIdx);
  535. }
  536. break;
  537. }
  538. }
  539. }
  540. }
  541. else if(bRem)
  542. {
  543. if((nPartIdx = _LookupPartition(sdm, pszDevNode)) >= 0)
  544. {
  545. _RemovePartition(sdm, nPartIdx, bChange);
  546. _SetPartitionChange(sdm, nPartIdx);
  547. if((nDiskIdx = _PartitionGetDisk(sdm, nPartIdx)) >= 0)
  548. {
  549. if(!_DiskRemovePartition(sdm, nDiskIdx, nPartIdx, bChange))
  550. {
  551. _RemoveDisk(sdm, nDiskIdx, bChange);
  552. }
  553. }
  554. }
  555. }
  556. }
  557. }
  558. static void _EnumStorageDevices(GFA_SYSINFO_STORAGE_DEVICE_MAP &sdm, MountMap &mm, struct udev *pUdev)
  559. {
  560. struct udev_enumerate *pEnum = ::udev_enumerate_new(pUdev);
  561. ::udev_enumerate_add_match_subsystem(pEnum, "block");
  562. ::udev_enumerate_add_match_property(pEnum, "DEVTYPE", "partition");
  563. ::udev_enumerate_scan_devices(pEnum);
  564. struct udev_list_entry *devices = ::udev_enumerate_get_list_entry(pEnum);
  565. struct udev_list_entry *entry;
  566. udev_list_entry_foreach(entry, devices)
  567. {
  568. const char *pszPath = ::udev_list_entry_get_name(entry);
  569. struct udev_device* dev = ::udev_device_new_from_syspath(pUdev, pszPath);
  570. _ProcessPartition(sdm, mm, dev);
  571. ::udev_device_unref(dev);
  572. }
  573. ::udev_enumerate_unref(pEnum);
  574. }
  575. #endif
  576. /////////////////////////////////////////////////////////////////////////////
  577. static void _SigHandler(int sig)
  578. {
  579. UNUSED(sig);
  580. g_fPause = false;
  581. g_fRun = false;
  582. g_fZombie = false;
  583. }
  584. /////////////////////////////////////////////////////////////////////////////
  585. /////////////////////////////////////////////////////////////////////////////
  586. /////////////////////////////////////////////////////////////////////////////
  587. int main(int argc, char *argv[])
  588. {
  589. int c;
  590. HAPPCTRL hAC = NULL;
  591. HAPPINFO hAI;
  592. CCycleTimer ct(_CYCLE_INTV), perfCnt(0U);
  593. cy_time_t wStart, wEnd, wCur = 0;
  594. std::string sDbUser, sDbPass;
  595. CMySqlInfo mySqlInfo;
  596. CStgDevInfo stgDevInfo;
  597. bool bStateTransition;
  598. /////////////////////////////////////////////////////////////////////////
  599. // parse command line options
  600. while((c = getopt(argc, argv, "p:u:")) != -1)
  601. {
  602. switch(c)
  603. {
  604. case 'p':
  605. sDbPass = optarg;
  606. break;
  607. case 'u':
  608. sDbUser = optarg;
  609. break;
  610. }
  611. }
  612. /////////////////////////////////////////////////////////////////////////
  613. // signal handling
  614. struct sigaction sa;
  615. memset(&sa, 0, sizeof(sa));
  616. sa.sa_handler = _SigHandler;
  617. sigaction(SIGHUP, &sa, NULL); // handles user's terminal disconnect
  618. sigaction(SIGQUIT, &sa, NULL); // handles Ctrl + '\'
  619. sigaction(SIGTERM, &sa, NULL); // handles normal termination
  620. sigaction(SIGABRT, &sa, NULL); // handles abnormal termination (i.e. abort())
  621. sigaction(SIGINT, &sa, NULL); // handles Ctrl + 'C'
  622. // ignore signals
  623. sa.sa_handler = SIG_IGN;
  624. sigaction(SIGTSTP, &sa, NULL); // ignores Ctrl + 'Z'
  625. sigaction(SIGCHLD, &sa, NULL); // ignores child process termination
  626. sigaction(0, &sa, NULL); // ignores shell termination
  627. /////////////////////////////////////////////////////////////////////////
  628. // initialize
  629. do
  630. {
  631. g_fZombie = true;
  632. if(!(hAC = ::GfaIpcAppCtrlAcquire(_APPID, _APPNAME, _CYCLE_INTV * 1000, _CYCLE_INTV * 3000)))
  633. {
  634. TRACE("GfaIpcAppCtrlAcquire failed\n");
  635. break;
  636. }
  637. ::GfaIpcAppCtrlSetState(hAC, GIAS_Initializing);
  638. if(!::GfaIpcAppCtrlCreateSysInfo(hAC))
  639. {
  640. TRACE("GfaIpcAppCtrlCreateSysInfo failed\n");
  641. break;
  642. }
  643. ::GfaIpcDumpSHMROT();
  644. TRACE("My Name: %s\n", _APPNAME);
  645. TRACE("My AppID: %llu\n", _APPID);
  646. TRACE("My PID: %d\n", getpid());
  647. TRACE("My Cycle: %d\n", _CYCLE_INTV);
  648. CMySqlInfo::EXEC_PARAMS myep = {hAC, sDbUser, sDbPass};
  649. mySqlInfo.Create(&myep);
  650. CStgDevInfo::EXEC_PARAMS step = {hAC};
  651. stgDevInfo.Create(&step);
  652. g_fZombie = false;
  653. g_fRun = true;
  654. ::GfaIpcAppCtrlSetState(hAC, GIAS_Running);
  655. mySqlInfo.Signal(CMySqlInfo::S_UpdateAll);
  656. stgDevInfo.Signal(CStgDevInfo::S_Init);
  657. }
  658. while(false);
  659. /////////////////////////////////////////////////////////////////////////
  660. /////////////////////////////////////////////////////////////////////////
  661. // run
  662. while(g_fRun)
  663. {
  664. bStateTransition = false;
  665. /////////////////////////////////////////////////////////////////////
  666. // trigger cycle timer
  667. ct.Trigger();
  668. /////////////////////////////////////////////////////////////////////
  669. // update app control info
  670. if((hAI = ::GfaIpcAppCtrlInfoUpdate(hAC, wCur)))
  671. {
  672. _ProcessCtrlMessages(hAC, hAI, bStateTransition);
  673. }
  674. /////////////////////////////////////////////////////////////////////
  675. // if not paused, do work
  676. if(g_fRun)
  677. {
  678. if(bStateTransition)
  679. {
  680. if(g_fPause)
  681. {
  682. mySqlInfo.Signal(CMySqlInfo::S_Pause);
  683. stgDevInfo.Signal(CStgDevInfo::S_Pause);
  684. }
  685. else
  686. {
  687. mySqlInfo.Signal(CMySqlInfo::S_Resume);
  688. stgDevInfo.Signal(CStgDevInfo::S_Resume);
  689. }
  690. }
  691. if(!g_fPause)
  692. {
  693. wStart = ct.GetMicroTick();
  694. ::GfaIpcAppCtrlUpdateSysInfo(hAC);
  695. wEnd = ct.GetMicroTick();
  696. wCur = wEnd - wStart;
  697. }
  698. ct.Sleep1();
  699. }
  700. }
  701. /////////////////////////////////////////////////////////////////////////
  702. /////////////////////////////////////////////////////////////////////////
  703. // terminate
  704. mySqlInfo.Signal(CMySqlInfo::S_Terminate);
  705. stgDevInfo.Signal(CStgDevInfo::S_Terminate);
  706. mySqlInfo.Join(NULL);
  707. stgDevInfo.Join(NULL);
  708. if(g_fZombie)
  709. {
  710. if(hAC)
  711. ::GfaIpcAppCtrlSetState(hAC, GIAS_Zombie);
  712. TRACE("%-8s: State: %s\n", "Me", ::GfaIpcAppCtrlGetStateText(GIAS_Zombie));
  713. pause();
  714. }
  715. if(hAC)
  716. {
  717. ::GfaIpcAppCtrlSetState(hAC, GIAS_Terminating);
  718. ::GfaIpcAppCtrlReleaseSysInfo(hAC);
  719. ::GfaIpcAppCtrlRelease(hAC);
  720. }
  721. return 0;
  722. }