process_status.go 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331
  1. package linux
  2. import (
  3. "io/ioutil"
  4. "strconv"
  5. "strings"
  6. )
  7. // Provides much of the information from ProcessStatm and ProcessStat
  8. type ProcessStatus struct {
  9. Name string
  10. State string
  11. Tgid uint64
  12. Pid uint64
  13. PPid int64
  14. TracerPid uint64
  15. RealUid uint64
  16. EffectiveUid uint64
  17. SavedSetUid uint64
  18. FilesystemUid uint64
  19. RealGid uint64
  20. EffectiveGid uint64
  21. SavedSetGid uint64
  22. FilesystemGid uint64
  23. FDSize uint64
  24. Groups []int64
  25. VmPeak uint64
  26. VmSize uint64
  27. VmLck uint64
  28. VmHWM uint64
  29. VmRSS uint64
  30. VmData uint64
  31. VmStk uint64
  32. VmExe uint64
  33. VmLib uint64
  34. VmPTE uint64
  35. VmSwap uint64
  36. Threads uint64
  37. SigQLength uint64
  38. SigQLimit uint64
  39. SigPnd uint64
  40. ShdPnd uint64
  41. SigBlk uint64
  42. SigIgn uint64
  43. SigCgt uint64
  44. CapInh uint64
  45. CapPrm uint64
  46. CapEff uint64
  47. CapBnd uint64
  48. Seccomp uint8
  49. CpusAllowed []uint32
  50. MemsAllowed []uint32
  51. VoluntaryCtxtSwitches uint64
  52. NonvoluntaryCtxtSwitches uint64
  53. }
  54. func ReadProcessStatus(path string) (*ProcessStatus, error) {
  55. b, err := ioutil.ReadFile(path)
  56. if err != nil {
  57. return nil, err
  58. }
  59. status := ProcessStatus{}
  60. lines := strings.Split(string(b), "\n")
  61. for _, line := range lines {
  62. if strings.Index(line, ":") == -1 {
  63. continue
  64. }
  65. l := strings.Split(line, ":")
  66. k := strings.TrimSpace(l[0])
  67. v := strings.TrimSpace(l[1])
  68. switch k {
  69. case "Name":
  70. status.Name = v
  71. case "State":
  72. status.State = v
  73. case "Tgid":
  74. if status.Tgid, err = strconv.ParseUint(v, 10, 64); err != nil {
  75. return nil, err
  76. }
  77. case "Pid":
  78. if status.Pid, err = strconv.ParseUint(v, 10, 64); err != nil {
  79. return nil, err
  80. }
  81. case "PPid":
  82. if status.PPid, err = strconv.ParseInt(v, 10, 64); err != nil {
  83. return nil, err
  84. }
  85. case "TracerPid":
  86. if status.TracerPid, err = strconv.ParseUint(v, 10, 64); err != nil {
  87. return nil, err
  88. }
  89. case "Uid":
  90. if f := strings.Fields(v); len(f) == 4 {
  91. if status.RealUid, err = strconv.ParseUint(f[0], 10, 64); err != nil {
  92. return nil, err
  93. }
  94. if status.EffectiveUid, err = strconv.ParseUint(f[1], 10, 64); err != nil {
  95. return nil, err
  96. }
  97. if status.SavedSetUid, err = strconv.ParseUint(f[2], 10, 64); err != nil {
  98. return nil, err
  99. }
  100. if status.FilesystemUid, err = strconv.ParseUint(f[3], 10, 64); err != nil {
  101. return nil, err
  102. }
  103. }
  104. case "Gid":
  105. if f := strings.Fields(v); len(f) == 4 {
  106. if status.RealGid, err = strconv.ParseUint(f[0], 10, 64); err != nil {
  107. return nil, err
  108. }
  109. if status.EffectiveGid, err = strconv.ParseUint(f[1], 10, 64); err != nil {
  110. return nil, err
  111. }
  112. if status.SavedSetGid, err = strconv.ParseUint(f[2], 10, 64); err != nil {
  113. return nil, err
  114. }
  115. if status.FilesystemGid, err = strconv.ParseUint(f[3], 10, 64); err != nil {
  116. return nil, err
  117. }
  118. }
  119. case "FDSize":
  120. if status.FDSize, err = strconv.ParseUint(v, 10, 64); err != nil {
  121. return nil, err
  122. }
  123. case "Groups":
  124. {
  125. f := strings.Fields(v)
  126. status.Groups = make([]int64, len(f))
  127. for i := range status.Groups {
  128. if status.Groups[i], err = strconv.ParseInt(f[i], 10, 64); err != nil {
  129. return nil, err
  130. }
  131. }
  132. }
  133. case "VmPeak":
  134. {
  135. f := strings.Fields(v)
  136. if status.VmPeak, err = strconv.ParseUint(f[0], 10, 64); err != nil {
  137. return nil, err
  138. }
  139. }
  140. case "VmSize":
  141. {
  142. f := strings.Fields(v)
  143. if status.VmSize, err = strconv.ParseUint(f[0], 10, 64); err != nil {
  144. return nil, err
  145. }
  146. }
  147. case "VmLck":
  148. {
  149. f := strings.Fields(v)
  150. if status.VmLck, err = strconv.ParseUint(f[0], 10, 64); err != nil {
  151. return nil, err
  152. }
  153. }
  154. case "VmHWM":
  155. {
  156. f := strings.Fields(v)
  157. if status.VmHWM, err = strconv.ParseUint(f[0], 10, 64); err != nil {
  158. return nil, err
  159. }
  160. }
  161. case "VmRSS":
  162. {
  163. f := strings.Fields(v)
  164. if status.VmRSS, err = strconv.ParseUint(f[0], 10, 64); err != nil {
  165. return nil, err
  166. }
  167. }
  168. case "VmData":
  169. {
  170. f := strings.Fields(v)
  171. if status.VmData, err = strconv.ParseUint(f[0], 10, 64); err != nil {
  172. return nil, err
  173. }
  174. }
  175. case "VmStk":
  176. {
  177. f := strings.Fields(v)
  178. if status.VmStk, err = strconv.ParseUint(f[0], 10, 64); err != nil {
  179. return nil, err
  180. }
  181. }
  182. case "VmExe":
  183. {
  184. f := strings.Fields(v)
  185. if status.VmExe, err = strconv.ParseUint(f[0], 10, 64); err != nil {
  186. return nil, err
  187. }
  188. }
  189. case "VmLib":
  190. {
  191. f := strings.Fields(v)
  192. if status.VmLib, err = strconv.ParseUint(f[0], 10, 64); err != nil {
  193. return nil, err
  194. }
  195. }
  196. case "VmPTE":
  197. {
  198. f := strings.Fields(v)
  199. if status.VmPTE, err = strconv.ParseUint(f[0], 10, 64); err != nil {
  200. return nil, err
  201. }
  202. }
  203. case "VmSwap":
  204. {
  205. f := strings.Fields(v)
  206. if status.VmSwap, err = strconv.ParseUint(f[0], 10, 64); err != nil {
  207. return nil, err
  208. }
  209. }
  210. case "Threads":
  211. if status.Threads, err = strconv.ParseUint(v, 10, 64); err != nil {
  212. return nil, err
  213. }
  214. case "SigQ":
  215. {
  216. if f := strings.Split(v, "/"); len(f) == 2 {
  217. if status.SigQLength, err = strconv.ParseUint(f[0], 10, 64); err != nil {
  218. return nil, err
  219. }
  220. if status.SigQLimit, err = strconv.ParseUint(f[1], 10, 64); err != nil {
  221. return nil, err
  222. }
  223. }
  224. }
  225. case "SigPnd":
  226. if status.SigPnd, err = strconv.ParseUint(v, 16, 64); err != nil {
  227. return nil, err
  228. }
  229. case "ShdPnd":
  230. if status.ShdPnd, err = strconv.ParseUint(v, 16, 64); err != nil {
  231. return nil, err
  232. }
  233. case "SigBlk":
  234. if status.SigBlk, err = strconv.ParseUint(v, 16, 64); err != nil {
  235. return nil, err
  236. }
  237. case "SigIgn":
  238. if status.SigIgn, err = strconv.ParseUint(v, 16, 64); err != nil {
  239. return nil, err
  240. }
  241. case "SigCgt":
  242. if status.SigCgt, err = strconv.ParseUint(v, 16, 64); err != nil {
  243. return nil, err
  244. }
  245. case "CapInh":
  246. if status.CapInh, err = strconv.ParseUint(v, 16, 64); err != nil {
  247. return nil, err
  248. }
  249. case "CapPrm":
  250. if status.CapPrm, err = strconv.ParseUint(v, 16, 64); err != nil {
  251. return nil, err
  252. }
  253. case "CapEff":
  254. if status.CapEff, err = strconv.ParseUint(v, 16, 64); err != nil {
  255. return nil, err
  256. }
  257. case "CapBnd":
  258. if status.CapBnd, err = strconv.ParseUint(v, 16, 64); err != nil {
  259. return nil, err
  260. }
  261. case "Seccomp":
  262. {
  263. var n uint64
  264. if n, err = strconv.ParseUint(v, 10, 8); err != nil {
  265. return nil, err
  266. }
  267. status.Seccomp = uint8(n)
  268. }
  269. case "Cpus_allowed":
  270. {
  271. var n uint64
  272. f := strings.Split(v, ",")
  273. status.CpusAllowed = make([]uint32, len(f))
  274. for i := range status.CpusAllowed {
  275. if n, err = strconv.ParseUint(f[i], 16, 32); err != nil {
  276. return nil, err
  277. }
  278. status.CpusAllowed[i] = uint32(n)
  279. }
  280. }
  281. case "Mems_allowed":
  282. {
  283. var n uint64
  284. f := strings.Split(v, ",")
  285. status.MemsAllowed = make([]uint32, len(f))
  286. for i := range status.MemsAllowed {
  287. if n, err = strconv.ParseUint(f[i], 16, 32); err != nil {
  288. return nil, err
  289. }
  290. status.MemsAllowed[i] = uint32(n)
  291. }
  292. }
  293. case "voluntary_ctxt_switches":
  294. if status.VoluntaryCtxtSwitches, err = strconv.ParseUint(v, 10, 64); err != nil {
  295. return nil, err
  296. }
  297. case "nonvoluntary_ctxt_switches":
  298. if status.NonvoluntaryCtxtSwitches, err = strconv.ParseUint(v, 10, 64); err != nil {
  299. return nil, err
  300. }
  301. }
  302. }
  303. return &status, nil
  304. }