| 
									
										
										
										
											2021-04-19 03:41:13 +08:00
										 |  |  | // Copyright (c) 2015-2021 MinIO, Inc.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // This file is part of MinIO Object Storage stack
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // This program is free software: you can redistribute it and/or modify
 | 
					
						
							|  |  |  | // it under the terms of the GNU Affero General Public License as published by
 | 
					
						
							|  |  |  | // the Free Software Foundation, either version 3 of the License, or
 | 
					
						
							|  |  |  | // (at your option) any later version.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // This program is distributed in the hope that it will be useful
 | 
					
						
							|  |  |  | // but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
					
						
							|  |  |  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
					
						
							|  |  |  | // GNU Affero General Public License for more details.
 | 
					
						
							|  |  |  | //
 | 
					
						
							|  |  |  | // You should have received a copy of the GNU Affero General Public License
 | 
					
						
							|  |  |  | // along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
					
						
							| 
									
										
										
										
											2016-06-16 11:20:38 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2016-08-19 07:23:42 +08:00
										 |  |  | package cmd | 
					
						
							| 
									
										
										
										
											2016-06-16 11:20:38 +08:00
										 |  |  | 
 | 
					
						
							|  |  |  | import ( | 
					
						
							| 
									
										
										
										
											2018-03-16 04:27:16 +08:00
										 |  |  | 	"context" | 
					
						
							| 
									
										
										
										
											2020-09-12 14:02:32 +08:00
										 |  |  | 	"errors" | 
					
						
							|  |  |  | 	"net/http" | 
					
						
							| 
									
										
										
										
											2016-06-16 11:20:38 +08:00
										 |  |  | 	"os" | 
					
						
							| 
									
										
										
										
											2018-11-13 07:07:16 +08:00
										 |  |  | 	"strings" | 
					
						
							| 
									
										
										
										
											2024-08-14 06:26:05 +08:00
										 |  |  | 	"time" | 
					
						
							| 
									
										
										
										
											2018-04-06 06:04:40 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-05-02 14:15:08 +08:00
										 |  |  | 	"github.com/coreos/go-systemd/v22/daemon" | 
					
						
							| 
									
										
										
										
											2021-06-02 05:59:40 +08:00
										 |  |  | 	"github.com/minio/minio/internal/logger" | 
					
						
							| 
									
										
										
										
											2016-06-16 11:20:38 +08:00
										 |  |  | ) | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-08-14 06:26:05 +08:00
										 |  |  | func shutdownHealMRFWithTimeout() { | 
					
						
							|  |  |  | 	const shutdownTimeout = time.Minute | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	finished := make(chan struct{}) | 
					
						
							|  |  |  | 	go func() { | 
					
						
							|  |  |  | 		globalMRFState.shutdown() | 
					
						
							|  |  |  | 		close(finished) | 
					
						
							|  |  |  | 	}() | 
					
						
							|  |  |  | 	select { | 
					
						
							|  |  |  | 	case <-time.After(shutdownTimeout): | 
					
						
							|  |  |  | 	case <-finished: | 
					
						
							|  |  |  | 	} | 
					
						
							|  |  |  | } | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-13 07:33:21 +08:00
										 |  |  | func handleSignals() { | 
					
						
							|  |  |  | 	// Custom exit function
 | 
					
						
							| 
									
										
										
										
											2019-08-13 12:25:34 +08:00
										 |  |  | 	exit := func(success bool) { | 
					
						
							| 
									
										
										
										
											2024-05-02 01:57:52 +08:00
										 |  |  | 		if globalLoggerOutput != nil { | 
					
						
							|  |  |  | 			globalLoggerOutput.Close() | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-13 07:33:21 +08:00
										 |  |  | 		// If global profiler is set stop before we exit.
 | 
					
						
							| 
									
										
										
										
											2020-01-11 09:19:58 +08:00
										 |  |  | 		globalProfilerMu.Lock() | 
					
						
							|  |  |  | 		defer globalProfilerMu.Unlock() | 
					
						
							| 
									
										
										
										
											2020-01-22 07:49:25 +08:00
										 |  |  | 		for _, p := range globalProfiler { | 
					
						
							|  |  |  | 			p.Stop() | 
					
						
							| 
									
										
										
										
											2017-07-13 07:33:21 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-06-16 11:20:38 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-08-13 12:25:34 +08:00
										 |  |  | 		if success { | 
					
						
							| 
									
										
										
										
											2017-07-13 07:33:21 +08:00
										 |  |  | 			os.Exit(0) | 
					
						
							|  |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-06-16 11:20:38 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-13 07:33:21 +08:00
										 |  |  | 		os.Exit(1) | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-06-16 11:20:38 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2017-07-13 07:33:21 +08:00
										 |  |  | 	stopProcess := func() bool { | 
					
						
							| 
									
										
										
										
											2024-08-14 06:26:05 +08:00
										 |  |  | 		shutdownHealMRFWithTimeout() // this can take time sometimes, it needs to be executed
 | 
					
						
							|  |  |  | 		// before stopping s3 operations
 | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-09-09 00:10:55 +08:00
										 |  |  | 		// send signal to various go-routines that they need to quit.
 | 
					
						
							|  |  |  | 		cancelGlobalContext() | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2019-12-03 07:54:26 +08:00
										 |  |  | 		if httpServer := newHTTPServerFn(); httpServer != nil { | 
					
						
							| 
									
										
										
										
											2023-07-12 22:18:30 +08:00
										 |  |  | 			if err := httpServer.Shutdown(); err != nil && !errors.Is(err, http.ErrServerClosed) { | 
					
						
							| 
									
										
										
										
											2024-04-04 20:04:40 +08:00
										 |  |  | 				shutdownLogIf(context.Background(), err) | 
					
						
							| 
									
										
										
										
											2020-09-12 14:02:32 +08:00
										 |  |  | 			} | 
					
						
							| 
									
										
										
										
											2019-12-03 07:54:26 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-06-16 11:20:38 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2020-10-10 00:59:52 +08:00
										 |  |  | 		if objAPI := newObjectLayerFn(); objAPI != nil { | 
					
						
							| 
									
										
										
										
											2024-04-04 20:04:40 +08:00
										 |  |  | 			shutdownLogIf(context.Background(), objAPI.Shutdown(context.Background())) | 
					
						
							| 
									
										
										
										
											2017-07-13 07:33:21 +08:00
										 |  |  | 		} | 
					
						
							| 
									
										
										
										
											2016-06-16 11:20:38 +08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2024-09-05 01:02:39 +08:00
										 |  |  | 		if globalBrowserEnabled { | 
					
						
							|  |  |  | 			if srv := newConsoleServerFn(); srv != nil { | 
					
						
							|  |  |  | 				shutdownLogIf(context.Background(), srv.Shutdown()) | 
					
						
							|  |  |  | 			} | 
					
						
							| 
									
										
										
										
											2021-09-01 09:52:48 +08:00
										 |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-06-21 08:38:59 +08:00
										 |  |  | 		if globalEventNotifier != nil { | 
					
						
							|  |  |  | 			globalEventNotifier.RemoveAllBucketTargets() | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2023-07-12 22:18:30 +08:00
										 |  |  | 		return true | 
					
						
							| 
									
										
										
										
											2017-07-13 07:33:21 +08:00
										 |  |  | 	} | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | 	for { | 
					
						
							|  |  |  | 		select { | 
					
						
							| 
									
										
										
										
											2022-10-22 05:42:28 +08:00
										 |  |  | 		case err := <-globalHTTPServerErrorCh: | 
					
						
							| 
									
										
										
										
											2024-04-04 20:04:40 +08:00
										 |  |  | 			shutdownLogIf(context.Background(), err) | 
					
						
							| 
									
										
										
										
											2020-09-09 00:10:55 +08:00
										 |  |  | 			exit(stopProcess()) | 
					
						
							| 
									
										
										
										
											2017-07-13 07:33:21 +08:00
										 |  |  | 		case osSignal := <-globalOSSignalCh: | 
					
						
							| 
									
										
										
										
											2018-11-13 07:07:16 +08:00
										 |  |  | 			logger.Info("Exiting on signal: %s", strings.ToUpper(osSignal.String())) | 
					
						
							| 
									
										
										
										
											2023-05-02 14:15:08 +08:00
										 |  |  | 			daemon.SdNotify(false, daemon.SdNotifyStopping) | 
					
						
							| 
									
										
										
										
											2017-07-13 07:33:21 +08:00
										 |  |  | 			exit(stopProcess()) | 
					
						
							|  |  |  | 		case signal := <-globalServiceSignalCh: | 
					
						
							| 
									
										
										
										
											2019-08-29 06:04:43 +08:00
										 |  |  | 			switch signal { | 
					
						
							|  |  |  | 			case serviceRestart: | 
					
						
							| 
									
										
										
										
											2018-04-11 00:37:14 +08:00
										 |  |  | 				logger.Info("Restarting on service signal") | 
					
						
							| 
									
										
										
										
											2023-05-02 14:15:08 +08:00
										 |  |  | 				daemon.SdNotify(false, daemon.SdNotifyReloading) | 
					
						
							| 
									
										
										
										
											2018-06-01 03:30:15 +08:00
										 |  |  | 				stop := stopProcess() | 
					
						
							| 
									
										
										
										
											2017-07-13 07:33:21 +08:00
										 |  |  | 				rerr := restartProcess() | 
					
						
							| 
									
										
										
										
											2023-05-02 14:15:08 +08:00
										 |  |  | 				if rerr == nil { | 
					
						
							|  |  |  | 					daemon.SdNotify(false, daemon.SdNotifyReady) | 
					
						
							|  |  |  | 				} | 
					
						
							| 
									
										
										
										
											2024-04-04 20:04:40 +08:00
										 |  |  | 				shutdownLogIf(context.Background(), rerr) | 
					
						
							| 
									
										
										
										
											2018-06-01 03:30:15 +08:00
										 |  |  | 				exit(stop && rerr == nil) | 
					
						
							| 
									
										
										
										
											2019-08-29 06:04:43 +08:00
										 |  |  | 			case serviceStop: | 
					
						
							| 
									
										
										
										
											2018-04-11 00:37:14 +08:00
										 |  |  | 				logger.Info("Stopping on service signal") | 
					
						
							| 
									
										
										
										
											2023-05-02 14:15:08 +08:00
										 |  |  | 				daemon.SdNotify(false, daemon.SdNotifyStopping) | 
					
						
							| 
									
										
										
										
											2017-07-13 07:33:21 +08:00
										 |  |  | 				exit(stopProcess()) | 
					
						
							|  |  |  | 			} | 
					
						
							|  |  |  | 		} | 
					
						
							|  |  |  | 	} | 
					
						
							| 
									
										
										
										
											2016-06-16 11:20:38 +08:00
										 |  |  | } |