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