github.com/Cloud-Foundations/Dominator@v0.3.4/sub/rpcd/poll.go (about) 1 package rpcd 2 3 import ( 4 "fmt" 5 "os" 6 "syscall" 7 "time" 8 9 "github.com/Cloud-Foundations/Dominator/lib/srpc" 10 "github.com/Cloud-Foundations/Dominator/proto/sub" 11 ) 12 13 var ( 14 filename string = "/proc/uptime" 15 startTime time.Time = time.Now() 16 ) 17 18 func (t *rpcType) Poll(conn *srpc.Conn) error { 19 defer conn.Flush() 20 var request sub.PollRequest 21 var response sub.PollResponse 22 if err := conn.Decode(&request); err != nil { 23 _, err = conn.WriteString(err.Error() + "\n") 24 return err 25 } 26 if !request.ShortPollOnly && !conn.GetAuthInformation().HaveMethodAccess { 27 _, e := conn.WriteString(srpc.ErrorAccessToMethodDenied.Error() + "\n") 28 return e 29 } 30 if _, err := conn.WriteString("\n"); err != nil { 31 return err 32 } 33 response.NetworkSpeed = t.params.NetworkReaderContext.MaximumSpeed() 34 response.CurrentConfiguration = t.getConfiguration() 35 t.rwLock.RLock() 36 response.FetchInProgress = t.fetchInProgress 37 response.UpdateInProgress = t.updateInProgress 38 if t.lastFetchError != nil { 39 response.LastFetchError = t.lastFetchError.Error() 40 } 41 if !t.updateInProgress { 42 if t.lastUpdateError != nil { 43 response.LastUpdateError = t.lastUpdateError.Error() 44 } 45 response.LastUpdateHadTriggerFailures = t.lastUpdateHadTriggerFailures 46 } 47 response.InitialImageName = t.initialImageName 48 response.LastSuccessfulImageName = t.lastSuccessfulImageName 49 response.LastNote = t.lastNote 50 response.LastWriteError = t.lastWriteError 51 response.LockedByAnotherClient = 52 t.getClientLock(conn, request.LockFor) != nil 53 response.LockedUntil = t.lockedUntil 54 response.FreeSpace = t.getFreeSpace() 55 response.DisruptionState = t.disruptionState 56 t.rwLock.RUnlock() 57 response.StartTime = startTime 58 response.PollTime = time.Now() 59 response.ScanCount = t.params.FileSystemHistory.ScanCount() 60 response.DurationOfLastScan = 61 t.params.FileSystemHistory.DurationOfLastScan() 62 response.GenerationCount = t.params.FileSystemHistory.GenerationCount() 63 response.SystemUptime = t.getSystemUptime() 64 fs := t.params.FileSystemHistory.FileSystem() 65 if fs != nil && 66 !request.ShortPollOnly && 67 request.HaveGeneration != t.params.FileSystemHistory.GenerationCount() { 68 response.FileSystemFollows = true 69 } 70 if err := conn.Encode(response); err != nil { 71 return err 72 } 73 if response.FileSystemFollows { 74 if err := fs.FileSystem.Encode(conn); err != nil { 75 return err 76 } 77 if err := fs.ObjectCache.Encode(conn); err != nil { 78 return err 79 } 80 } 81 return nil 82 } 83 84 func (t *rpcType) getFreeSpace() *uint64 { 85 rootDir := t.config.RootDirectoryName 86 if fd, err := syscall.Open(rootDir, syscall.O_RDONLY, 0); err != nil { 87 t.params.Logger.Printf("error opening: %s: %s", rootDir, err) 88 return nil 89 } else { 90 defer syscall.Close(fd) 91 var statbuf syscall.Statfs_t 92 if err := syscall.Fstatfs(fd, &statbuf); err != nil { 93 t.params.Logger.Printf("error getting file-system stats: %s\n", err) 94 return nil 95 } 96 retval := uint64(statbuf.Bfree * uint64(statbuf.Bsize)) 97 return &retval 98 } 99 } 100 101 func (t *rpcType) getSystemUptime() *time.Duration { 102 if uptime, err := getSystemUptime(); err != nil { 103 t.params.Logger.Printf("error getting system uptime: %s\n", err) 104 return nil 105 } else { 106 return &uptime 107 } 108 } 109 110 func getSystemUptime() (time.Duration, error) { 111 file, err := os.Open(filename) 112 if err != nil { 113 return 0, err 114 } 115 defer file.Close() 116 var idleTime, upTime float64 117 nScanned, err := fmt.Fscanf(file, "%f %f", &upTime, &idleTime) 118 if err != nil { 119 return 0, err 120 } 121 if nScanned < 2 { 122 return 0, fmt.Errorf("only read %d values from %s", nScanned, filename) 123 } 124 return time.Duration(upTime * float64(time.Second)), nil 125 }