mirror of
https://github.com/minio/minio.git
synced 2025-11-07 12:52:58 -05:00
allow service freeze/unfreeze on a setup (#13707)
an active running speedTest will reject all new S3 requests to the server, until speedTest is complete. this is to ensure that speedTest results are accurate and trusted. Co-authored-by: Klaus Post <klauspost@gmail.com>
This commit is contained in:
@@ -31,6 +31,8 @@ const (
|
||||
serviceRestart serviceSignal = iota // Restarts the server.
|
||||
serviceStop // Stops the server.
|
||||
serviceReloadDynamic // Reload dynamic config values.
|
||||
serviceFreeze // Freeze all S3 API calls.
|
||||
serviceUnFreeze // Un-Freeze previously frozen S3 API calls.
|
||||
// Add new service requests here.
|
||||
)
|
||||
|
||||
@@ -65,3 +67,57 @@ func restartProcess() error {
|
||||
// Re-uses the same pid. This preserves the pid over multiple server-respawns.
|
||||
return syscall.Exec(argv0, os.Args, os.Environ())
|
||||
}
|
||||
|
||||
// Keep track of number of freeze/unfreeze calls.
|
||||
const trackFreezeCount = true
|
||||
|
||||
// freezeServices will freeze all incoming S3 API calls.
|
||||
// For each call, unfreezeServices must be called once.
|
||||
func freezeServices() {
|
||||
// Use atomics for globalServiceFreeze, so we can read without locking.
|
||||
if trackFreezeCount {
|
||||
// We need a lock since we are need the 2 atomic values to remain in sync.
|
||||
globalServiceFreezeMu.Lock()
|
||||
// If multiple calls, first one creates channel.
|
||||
globalServiceFreezeCnt++
|
||||
if globalServiceFreezeCnt == 1 {
|
||||
globalServiceFreeze.Store(make(chan struct{}))
|
||||
}
|
||||
globalServiceFreezeMu.Unlock()
|
||||
} else {
|
||||
// If multiple calls, first one creates channel.
|
||||
globalServiceFreeze.CompareAndSwap(nil, make(chan struct{}))
|
||||
}
|
||||
}
|
||||
|
||||
// unfreezeServices will unfreeze all incoming S3 API calls.
|
||||
// For each call, unfreezeServices must be called once.
|
||||
func unfreezeServices() {
|
||||
if trackFreezeCount {
|
||||
// We need a lock since we need the 2 atomic values to remain in sync.
|
||||
globalServiceFreezeMu.Lock()
|
||||
// Close when we reach 0
|
||||
globalServiceFreezeCnt--
|
||||
if globalServiceFreezeCnt <= 0 {
|
||||
// Ensure we only close once.
|
||||
if val := globalServiceFreeze.Load(); val != nil {
|
||||
if ch, ok := val.(chan struct{}); ok {
|
||||
globalServiceFreeze.Store(nil)
|
||||
close(ch)
|
||||
}
|
||||
}
|
||||
globalServiceFreezeCnt = 0 // Don't risk going negative.
|
||||
}
|
||||
globalServiceFreezeMu.Unlock()
|
||||
} else {
|
||||
// If multiple calls, first one closes channel.
|
||||
if val := globalServiceFreeze.Load(); val != nil {
|
||||
if ch, ok := val.(chan struct{}); ok {
|
||||
// Ensure we only close once.
|
||||
if globalServiceFreeze.CompareAndSwap(val, nil) {
|
||||
close(ch)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user