mirror of
https://github.com/minio/minio.git
synced 2024-12-24 06:05:55 -05:00
Fix possible race in shutdown callbacks process and simplify shuttting down profiler (#2684)
This commit is contained in:
parent
51e337228e
commit
f82f535509
71
cmd/utils.go
71
cmd/utils.go
@ -117,16 +117,30 @@ type shutdownCallbacks struct {
|
|||||||
// globalShutdownCBs stores regular and object storages callbacks
|
// globalShutdownCBs stores regular and object storages callbacks
|
||||||
var globalShutdownCBs *shutdownCallbacks
|
var globalShutdownCBs *shutdownCallbacks
|
||||||
|
|
||||||
func (s shutdownCallbacks) GetObjectLayerCBs() []cleanupOnExitFunc {
|
func (s *shutdownCallbacks) RunObjectLayerCBs() errCode {
|
||||||
s.RLock()
|
s.RLock()
|
||||||
defer s.RUnlock()
|
defer s.RUnlock()
|
||||||
return s.objectLayerCallbacks
|
exitCode := exitSuccess
|
||||||
|
for _, callback := range s.objectLayerCallbacks {
|
||||||
|
exitCode = callback()
|
||||||
|
if exitCode != exitSuccess {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return exitCode
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s shutdownCallbacks) GetGenericCBs() []cleanupOnExitFunc {
|
func (s *shutdownCallbacks) RunGenericCBs() errCode {
|
||||||
s.RLock()
|
s.RLock()
|
||||||
defer s.RUnlock()
|
defer s.RUnlock()
|
||||||
return s.genericCallbacks
|
exitCode := exitSuccess
|
||||||
|
for _, callback := range s.genericCallbacks {
|
||||||
|
exitCode = callback()
|
||||||
|
if exitCode != exitSuccess {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return exitCode
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *shutdownCallbacks) AddObjectLayerCB(callback cleanupOnExitFunc) error {
|
func (s *shutdownCallbacks) AddObjectLayerCB(callback cleanupOnExitFunc) error {
|
||||||
@ -203,6 +217,16 @@ func startMonitorShutdownSignal(onExitFn onExitFunc) error {
|
|||||||
return errInvalidArgument
|
return errInvalidArgument
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Custom exit function
|
||||||
|
runExitFn := func(exitCode errCode) {
|
||||||
|
// If global profiler is set stop before we exit.
|
||||||
|
if globalProfiler != nil {
|
||||||
|
globalProfiler.Stop()
|
||||||
|
}
|
||||||
|
// Call user supplied user exit function
|
||||||
|
onExitFn(int(exitCode))
|
||||||
|
}
|
||||||
|
|
||||||
// Start listening on shutdown signal.
|
// Start listening on shutdown signal.
|
||||||
go func() {
|
go func() {
|
||||||
defer close(globalShutdownSignalCh)
|
defer close(globalShutdownSignalCh)
|
||||||
@ -216,27 +240,14 @@ func startMonitorShutdownSignal(onExitFn onExitFunc) error {
|
|||||||
globalShutdownSignalCh <- shutdownHalt
|
globalShutdownSignalCh <- shutdownHalt
|
||||||
case signal := <-globalShutdownSignalCh:
|
case signal := <-globalShutdownSignalCh:
|
||||||
// Call all object storage shutdown callbacks and exit for emergency
|
// Call all object storage shutdown callbacks and exit for emergency
|
||||||
for _, callback := range globalShutdownCBs.GetObjectLayerCBs() {
|
exitCode := globalShutdownCBs.RunObjectLayerCBs()
|
||||||
exitCode := callback()
|
if exitCode != exitSuccess {
|
||||||
if exitCode != exitSuccess {
|
runExitFn(exitCode)
|
||||||
// If global profiler is set stop before we exit.
|
|
||||||
if globalProfiler != nil {
|
|
||||||
globalProfiler.Stop()
|
|
||||||
}
|
|
||||||
onExitFn(int(exitCode))
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
// Call all callbacks and exit for emergency
|
exitCode = globalShutdownCBs.RunGenericCBs()
|
||||||
for _, callback := range globalShutdownCBs.GetGenericCBs() {
|
if exitCode != exitSuccess {
|
||||||
exitCode := callback()
|
runExitFn(exitCode)
|
||||||
if exitCode != exitSuccess {
|
|
||||||
// If global profiler is set stop before we exit.
|
|
||||||
if globalProfiler != nil {
|
|
||||||
globalProfiler.Stop()
|
|
||||||
}
|
|
||||||
onExitFn(int(exitCode))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
// All shutdown callbacks ensure that the server is safely terminated
|
// All shutdown callbacks ensure that the server is safely terminated
|
||||||
// and any concurrent process could be started again
|
// and any concurrent process could be started again
|
||||||
@ -252,22 +263,12 @@ func startMonitorShutdownSignal(onExitFn onExitFunc) error {
|
|||||||
errorIf(errors.New("Unable to reboot."), err.Error())
|
errorIf(errors.New("Unable to reboot."), err.Error())
|
||||||
}
|
}
|
||||||
|
|
||||||
// If global profiler is set stop before we exit.
|
|
||||||
if globalProfiler != nil {
|
|
||||||
globalProfiler.Stop()
|
|
||||||
}
|
|
||||||
|
|
||||||
// Successfully forked.
|
// Successfully forked.
|
||||||
onExitFn(int(exitSuccess))
|
runExitFn(exitSuccess)
|
||||||
}
|
|
||||||
|
|
||||||
// If global profiler is set stop before we exit.
|
|
||||||
if globalProfiler != nil {
|
|
||||||
globalProfiler.Stop()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exit as success if no errors.
|
// Exit as success if no errors.
|
||||||
onExitFn(int(exitSuccess))
|
runExitFn(exitSuccess)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
Loading…
Reference in New Issue
Block a user