smart.go_disabled 4.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. package smart
  2. /*
  3. DISK SMART Service Listener
  4. Original author: alanyeung
  5. Rewritten by tobychui in Oct 2020 for system arch upgrade
  6. This module is not the core part of aroz online system.
  7. If you want to remove disk smart handler (e.g. running in VM?)
  8. remove the corrisponding code in disk.go
  9. */
  10. import (
  11. "encoding/json"
  12. "log"
  13. "net/http"
  14. "os/exec"
  15. "runtime"
  16. "errors"
  17. "time"
  18. )
  19. // SMART was used for storing all Devices data
  20. type SMART struct {
  21. Port string `json:"Port"`
  22. DriveSmart *DeviceSMART `json:"SMART"`
  23. }
  24. type SMARTListener struct{
  25. SystemSmartExecutable string
  26. LastScanTime int64
  27. SMARTInformation []*SMART
  28. ReadingInProgress bool
  29. }
  30. // DiskSmartInit Desktop script initiation
  31. func NewSmartListener() (*SMARTListener, error){
  32. var SystemSmartExecutable string = ""
  33. log.Println("Starting SMART mointoring")
  34. if !(fileExists("system/disk/smart/win/smartctl.exe") || fileExists("system/disk/smart/linux/smartctl_arm") || fileExists("system/disk/smart/linux/smartctl_arm64") || fileExists("system/disk/smart/linux/smartctl_i386")) {
  35. return &SMARTListener{}, errors.New("Smartctl.exe not found")
  36. }
  37. if runtime.GOOS == "windows" {
  38. SystemSmartExecutable = "./system/disk/smart/win/smartctl.exe"
  39. } else if runtime.GOOS == "linux" {
  40. if runtime.GOARCH == "arm" {
  41. SystemSmartExecutable = "./system/disk/smart/linux/smartctl_armv6"
  42. }
  43. if runtime.GOARCH == "arm64" {
  44. SystemSmartExecutable = "./system/disk/smart/linux/smartctl_armv6"
  45. }
  46. if runtime.GOARCH == "386" {
  47. SystemSmartExecutable = "./system/disk/smart/linux/smartctl_i386"
  48. }
  49. if runtime.GOARCH == "amd64" {
  50. SystemSmartExecutable = "./system/disk/smart/linux/smartctl_i386"
  51. }
  52. } else {
  53. return &SMARTListener{}, errors.New("Not supported platform")
  54. }
  55. return &SMARTListener{
  56. SystemSmartExecutable: SystemSmartExecutable,
  57. LastScanTime: 0,
  58. SMARTInformation: []*SMART{},
  59. ReadingInProgress: false,
  60. },nil
  61. }
  62. // ReadSMART xxx
  63. func (s *SMARTListener)ReadSMART() []*SMART {
  64. if time.Now().Unix()-s.LastScanTime > 30 {
  65. if (s.ReadingInProgress == false){
  66. //Set reading flag to true
  67. s.ReadingInProgress = true;
  68. s.SMARTInformation = []*SMART{}
  69. //Scan disk
  70. cmd := exec.Command(s.SystemSmartExecutable, "--scan", "--json=c")
  71. out, _ := cmd.CombinedOutput()
  72. Devices := new(DevicesList)
  73. DevicesOutput := string(out)
  74. json.Unmarshal([]byte(DevicesOutput), &Devices)
  75. for _, element := range Devices.Devices {
  76. //Load SMART for each drive
  77. cmd := exec.Command(s.SystemSmartExecutable, "-i", element.Name, "-a", "--json=c")
  78. out, err := cmd.CombinedOutput()
  79. if err != nil{
  80. //log.Println(string(out), err);
  81. }
  82. InvSMARTInformation := new(DeviceSMART)
  83. SMARTOutput := string(out)
  84. json.Unmarshal([]byte(SMARTOutput), &InvSMARTInformation)
  85. if len(InvSMARTInformation.Smartctl.Messages) > 0 {
  86. if InvSMARTInformation.Smartctl.Messages[0].Severity == "error" {
  87. log.Println("[SMART Mointoring] Disk " + element.Name + " cannot be readed")
  88. } else {
  89. //putting everything into that struct array
  90. n := SMART{Port: element.Name, DriveSmart: InvSMARTInformation}
  91. s.SMARTInformation = append(s.SMARTInformation, &n)
  92. }
  93. } else {
  94. //putting everything into that struct array
  95. n := SMART{Port: element.Name, DriveSmart: InvSMARTInformation}
  96. s.SMARTInformation = append(s.SMARTInformation, &n)
  97. }
  98. }
  99. s.LastScanTime = time.Now().Unix()
  100. //Set reading flag to false
  101. s.ReadingInProgress = false;
  102. }
  103. }
  104. return s.SMARTInformation
  105. }
  106. func (s *SMARTListener)GetSMART(w http.ResponseWriter, r *http.Request) {
  107. jsonText, _ := json.Marshal(s.ReadSMART())
  108. sendJSONResponse(w, string(jsonText))
  109. }
  110. func (s *SMARTListener)CheckDiskTable(w http.ResponseWriter, r *http.Request) {
  111. disks, ok := r.URL.Query()["disk"]
  112. if !ok || len(disks[0]) < 1 {
  113. log.Println("Parameter DISK not found.")
  114. return
  115. }
  116. DiskStatus := new(DeviceSMART)
  117. for _, info := range s.ReadSMART() {
  118. if info.Port == disks[0] {
  119. DiskStatus = info.DriveSmart
  120. }
  121. }
  122. JSONStr, _ := json.Marshal(DiskStatus.AtaSmartAttributes.Table)
  123. //send!
  124. sendJSONResponse(w, string(JSONStr))
  125. }
  126. func (s *SMARTListener)CheckDiskTestStatus(w http.ResponseWriter, r *http.Request) {
  127. disks, ok := r.URL.Query()["disk"]
  128. if !ok || len(disks[0]) < 1 {
  129. log.Println("Parameter DISK not found.")
  130. return
  131. }
  132. DiskTestStatus := new(DeviceSMART)
  133. for _, info := range s.ReadSMART() {
  134. if info.Port == disks[0] {
  135. DiskTestStatus = info.DriveSmart
  136. }
  137. }
  138. JSONStr, _ := json.Marshal(DiskTestStatus.AtaSmartData.SelfTest.Status)
  139. //send!
  140. sendJSONResponse(w, string(JSONStr))
  141. }