Fix server disk usage not being reported properly; closes pterodactyl/panel#2445
This commit is contained in:
parent
37e59e6928
commit
e29789114c
|
@ -75,6 +75,16 @@ func (fs *Filesystem) HasSpaceAvailable(allowStaleValue bool) bool {
|
||||||
return size <= fs.MaxDisk()
|
return size <= fs.MaxDisk()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Returns the cached value for the amount of disk space used by the filesystem. Do not rely on this
|
||||||
|
// function for critical logical checks. It should only be used in areas where the actual disk usage
|
||||||
|
// does not need to be perfect, e.g. API responses for server resource usage.
|
||||||
|
func (fs *Filesystem) CachedUsage() int64 {
|
||||||
|
fs.mu.RLock()
|
||||||
|
defer fs.mu.RUnlock()
|
||||||
|
|
||||||
|
return fs.diskUsed
|
||||||
|
}
|
||||||
|
|
||||||
// Internal helper function to allow other parts of the codebase to check the total used disk space
|
// Internal helper function to allow other parts of the codebase to check the total used disk space
|
||||||
// as needed without overly taxing the system. This will prioritize the value from the cache to avoid
|
// as needed without overly taxing the system. This will prioritize the value from the cache to avoid
|
||||||
// excessive IO usage. We will only walk the filesystem and determine the size of the directory if there
|
// excessive IO usage. We will only walk the filesystem and determine the size of the directory if there
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package server
|
package server
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"encoding/json"
|
||||||
"github.com/pterodactyl/wings/environment"
|
"github.com/pterodactyl/wings/environment"
|
||||||
"sync"
|
"sync"
|
||||||
)
|
)
|
||||||
|
@ -17,17 +18,34 @@ type ResourceUsage struct {
|
||||||
// The current server status.
|
// The current server status.
|
||||||
State string `json:"state" default:"offline"`
|
State string `json:"state" default:"offline"`
|
||||||
|
|
||||||
// The current disk space being used by the server. This is cached to prevent slow lookup
|
// The current disk space being used by the server. This value is not guaranteed to be accurate
|
||||||
// issues on frequent refreshes.
|
// at all times. It is "manually" set whenever server.Proc() is called. This is kind of just a
|
||||||
|
// hacky solution for now to avoid passing events all over the place.
|
||||||
Disk int64 `json:"disk_bytes"`
|
Disk int64 `json:"disk_bytes"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Alias the resource usage so that we don't infinitely recurse when marshaling the struct.
|
||||||
|
type IResourceUsage ResourceUsage
|
||||||
|
|
||||||
|
// Custom marshaler to ensure that the object is locked when we're converting it to JSON in
|
||||||
|
// order to avoid race conditions.
|
||||||
|
func (ru *ResourceUsage) MarshalJSON() ([]byte, error) {
|
||||||
|
ru.mu.Lock()
|
||||||
|
defer ru.mu.Unlock()
|
||||||
|
|
||||||
|
return json.Marshal(IResourceUsage(*ru))
|
||||||
|
}
|
||||||
|
|
||||||
// Returns the resource usage stats for the server instance. If the server is not running, only the
|
// Returns the resource usage stats for the server instance. If the server is not running, only the
|
||||||
// disk space currently used will be returned. When the server is running all of the other stats will
|
// disk space currently used will be returned. When the server is running all of the other stats will
|
||||||
// be returned.
|
// be returned.
|
||||||
//
|
//
|
||||||
// When a process is stopped all of the stats are zeroed out except for the disk.
|
// When a process is stopped all of the stats are zeroed out except for the disk.
|
||||||
func (s *Server) Proc() *ResourceUsage {
|
func (s *Server) Proc() *ResourceUsage {
|
||||||
|
s.resources.SetDisk(s.Filesystem().CachedUsage())
|
||||||
|
|
||||||
|
// Get a read lock on the resources at this point. Don't do this before setting
|
||||||
|
// the disk, otherwise you'll cause a deadlock.
|
||||||
s.resources.mu.RLock()
|
s.resources.mu.RLock()
|
||||||
defer s.resources.mu.RUnlock()
|
defer s.resources.mu.RUnlock()
|
||||||
|
|
||||||
|
@ -35,11 +53,9 @@ func (s *Server) Proc() *ResourceUsage {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *Server) emitProcUsage() {
|
func (s *Server) emitProcUsage() {
|
||||||
s.resources.mu.RLock()
|
if err := s.Events().PublishJson(StatsEvent, s.Proc()); err != nil {
|
||||||
if err := s.Events().PublishJson(StatsEvent, s.resources); err != nil {
|
|
||||||
s.Log().WithField("error", err).Warn("error while emitting server resource usage to listeners")
|
s.Log().WithField("error", err).Warn("error while emitting server resource usage to listeners")
|
||||||
}
|
}
|
||||||
s.resources.mu.RUnlock()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the servers current state.
|
// Returns the servers current state.
|
||||||
|
|
Loading…
Reference in New Issue
Block a user