2018-01-09 06:30:55 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								/ *  
						 
					
						
							
								
									
										
										
										
											2019-04-10 02:39:42 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								 *  MinIO  Cloud  Storage ,  ( C )  2017  MinIO ,  Inc . 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-09 06:30:55 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Licensed  under  the  Apache  License ,  Version  2.0  ( the  "License" ) ; 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  you  may  not  use  this  file  except  in  compliance  with  the  License . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  You  may  obtain  a  copy  of  the  License  at 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *      http : //www.apache.org/licenses/LICENSE-2.0
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  Unless  required  by  applicable  law  or  agreed  to  in  writing ,  software 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  distributed  under  the  License  is  distributed  on  an  "AS IS"  BASIS , 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  WITHOUT  WARRANTIES  OR  CONDITIONS  OF  ANY  KIND ,  either  express  or  implied . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  See  the  License  for  the  specific  language  governing  permissions  and 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 *  limitations  under  the  License . 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								 * / 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								package  cmd  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								import  (  
						 
					
						
							
								
									
										
										
										
											2018-04-06 06:04:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"context" 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-09 06:30:55 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"fmt" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"io" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									"os" 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-01 05:17:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"path" 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-09 06:30:55 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"time" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-10-05 01:35:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/minio/minio/cmd/config" 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-10 02:13:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									"github.com/minio/minio/cmd/logger" 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-09 06:30:55 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									"github.com/minio/minio/pkg/lock" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// FS format version strings.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								const  (  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									formatBackendFS    =  "fs" 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									formatFSVersionV1  =  "1" 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-01 05:17:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									formatFSVersionV2  =  "2" 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-09 06:30:55 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								)  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// formatFSV1 - structure holds format version '1'.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  formatFSV1  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									formatMetaV1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									FS  struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Version  string  ` json:"version" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  ` json:"fs" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-02-01 05:17:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// formatFSV2 - structure is same as formatFSV1. But the multipart backend
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// structure is flat instead of hierarchy now.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// In .minio.sys/multipart we have:
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// sha256(bucket/object)/uploadID/[fs.json, 1.etag, 2.etag ....]
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  formatFSV2  =  formatFSV1  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-01-09 06:30:55 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// Used to detect the version of "fs" format.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  formatFSVersionDetect  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									FS  struct  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										Version  string  ` json:"version" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									}  ` json:"fs" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-07-19 11:17:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Generic structure to manage both v1 and v2 structures
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								type  formatFS  struct  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									formatMetaV1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									FS  interface { }  ` json:"fs" ` 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-02-01 05:17:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Returns the latest "fs" format V1
  
						 
					
						
							
								
									
										
										
										
											2018-01-09 06:30:55 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								func  newFormatFSV1 ( )  ( format  * formatFSV1 )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									f  :=  & formatFSV1 { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									f . Version  =  formatMetaVersionV1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									f . Format  =  formatBackendFS 
							 
						 
					
						
							
								
									
										
										
										
											2018-07-19 11:17:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									f . ID  =  mustGetUUID ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-09 06:30:55 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									f . FS . Version  =  formatFSVersionV1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  f 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Returns the field formatMetaV1.Format i.e the string "fs" which is never likely to change.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// We do not use this function in XL to get the format as the file is not fcntl-locked on XL.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  formatMetaGetFormatBackendFS ( r  io . ReadSeeker )  ( string ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									format  :=  & formatMetaV1 { } 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-07 07:37:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  :=  jsonLoad ( r ,  format ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-09 06:30:55 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  "" ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  format . Version  ==  formatMetaVersionV1  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  format . Format ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  "" ,  fmt . Errorf ( ` format.Version expected: %s, got: %s ` ,  formatMetaVersionV1 ,  format . Version ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Returns formatFS.FS.Version
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  formatFSGetVersion ( r  io . ReadSeeker )  ( string ,  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									format  :=  & formatFSVersionDetect { } 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-07 07:37:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  :=  jsonLoad ( r ,  format ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-09 06:30:55 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  "" ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  format . FS . Version ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-02-01 05:17:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								// Migrate from V1 to V2. V2 implements new backend format for multipart
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// uploads. Delete the previous multipart directory.
  
						 
					
						
							
								
									
										
										
										
											2018-04-06 06:04:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  formatFSMigrateV1ToV2 ( ctx  context . Context ,  wlk  * lock . LockedFile ,  fsPath  string )  error  {  
						 
					
						
							
								
									
										
										
										
											2018-02-01 05:17:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									version ,  err  :=  formatFSGetVersion ( wlk ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  version  !=  formatFSVersionV1  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  fmt . Errorf ( ` format.json version expected %s, found %s ` ,  formatFSVersionV1 ,  version ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-04-06 06:04:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  =  fsRemoveAll ( ctx ,  path . Join ( fsPath ,  minioMetaMultipartBucket ) ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-01 05:17:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  =  os . MkdirAll ( path . Join ( fsPath ,  minioMetaMultipartBucket ) ,  0755 ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-07-19 11:17:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									formatV1  :=  formatFSV1 { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  =  jsonLoad ( wlk ,  & formatV1 ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									formatV2  :=  formatFSV2 { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									formatV2 . formatMetaV1  =  formatV1 . formatMetaV1 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									formatV2 . FS . Version  =  formatFSVersionV2 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  jsonSave ( wlk . File ,  formatV2 ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-01 05:17:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-01-09 06:30:55 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								// Migrate the "fs" backend.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Migration should happen when formatFSV1.FS.Version changes. This version
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// can change when there is a change to the struct formatFSV1.FS or if there
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// is any change in the backend file system tree structure.
  
						 
					
						
							
								
									
										
										
										
											2018-04-06 06:04:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  formatFSMigrate ( ctx  context . Context ,  wlk  * lock . LockedFile ,  fsPath  string )  error  {  
						 
					
						
							
								
									
										
										
										
											2018-01-09 06:30:55 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// Add any migration code here in case we bump format.FS.Version
 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-01 05:17:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									version ,  err  :=  formatFSGetVersion ( wlk ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									switch  version  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  formatFSVersionV1 : 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-06 06:04:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  err  =  formatFSMigrateV1ToV2 ( ctx ,  wlk ,  fsPath ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-01 05:17:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										fallthrough 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									case  formatFSVersionV2 : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// We are at the latest version.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-09 06:30:55 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Make sure that the version is what we expect after the migration.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-01 05:17:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									version ,  err  =  formatFSGetVersion ( wlk ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-09 06:30:55 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-01 05:17:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  version  !=  formatFSVersionV2  { 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-05 01:35:33 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  config . ErrUnexpectedBackendVersion ( fmt . Errorf ( ` %s file: expected FS version: %s, found FS version: %s ` ,  formatConfigFile ,  formatFSVersionV2 ,  version ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-09 06:30:55 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Creates a new format.json if unformatted.
  
						 
					
						
							
								
									
										
										
										
											2019-10-16 09:35:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  createFormatFS ( fsFormatPath  string )  error  {  
						 
					
						
							
								
									
										
										
										
											2018-01-09 06:30:55 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// Attempt a write lock on formatConfigFile `format.json`
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// file stored in minioMetaBucket(.minio.sys) directory.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									lk ,  err  :=  lock . TryLockedOpenFile ( fsFormatPath ,  os . O_RDWR | os . O_CREATE ,  0600 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-06 06:04:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-09 06:30:55 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Close the locked file upon return.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  lk . Close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									fi ,  err  :=  lk . Stat ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-06 06:04:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-09 06:30:55 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  fi . Size ( )  !=  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// format.json already got created because of another minio process's createFormatFS()
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-02-07 07:37:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									return  jsonSave ( lk . File ,  newFormatFSV1 ( ) ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-09 06:30:55 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// This function returns a read-locked format.json reference to the caller.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// The file descriptor should be kept open throughout the life
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// of the process so that another minio process does not try to
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// migrate the backend when we are actively working on the backend.
  
						 
					
						
							
								
									
										
										
										
											2018-04-06 06:04:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								func  initFormatFS ( ctx  context . Context ,  fsPath  string )  ( rlk  * lock . RLockedFile ,  err  error )  {  
						 
					
						
							
								
									
										
										
										
											2018-01-09 06:30:55 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									fsFormatPath  :=  pathJoin ( fsPath ,  minioMetaBucket ,  formatConfigFile ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-07-19 11:17:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Add a deployment ID, if it does not exist.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  :=  formatFSFixDeploymentID ( fsFormatPath ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2018-01-09 06:30:55 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
									// Any read on format.json should be done with read-lock.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Any write on format.json should be done with write-lock.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										isEmpty  :=  false 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rlk ,  err  :=  lock . RLockedOpenFile ( fsFormatPath ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// format.json can be empty in a rare condition when another
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// minio process just created the file but could not hold lock
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// and write to it.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											var  fi  os . FileInfo 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											fi ,  err  =  rlk . Stat ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-06 06:04:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  nil ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-09 06:30:55 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											isEmpty  =  fi . Size ( )  ==  0 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  os . IsNotExist ( err )  ||  isEmpty  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												rlk . Close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Fresh disk - create format.json
 
							 
						 
					
						
							
								
									
										
										
										
											2019-10-16 09:35:41 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											err  =  createFormatFS ( fsFormatPath ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-09 06:30:55 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											if  err  ==  lock . ErrAlreadyLocked  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// Lock already present, sleep and attempt again.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// Can happen in a rare situation when a parallel minio process
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// holds the lock and creates format.json
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												time . Sleep ( 100  *  time . Millisecond ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-06 06:04:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
												return  nil ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-09 06:30:55 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// After successfully creating format.json try to hold a read-lock on
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// the file.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-06 06:04:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  nil ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-09 06:30:55 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										formatBackend ,  err  :=  formatMetaGetFormatBackendFS ( rlk ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-06 06:04:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											return  nil ,  err 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-09 06:30:55 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  formatBackend  !=  formatBackendFS  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  fmt . Errorf ( ` %s file: expected format-type: %s, found: %s ` ,  formatConfigFile ,  formatBackendFS ,  formatBackend ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										version ,  err  :=  formatFSGetVersion ( rlk ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2018-02-01 05:17:24 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										if  version  !=  formatFSVersionV2  { 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-09 06:30:55 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											// Format needs migration
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rlk . Close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Hold write lock during migration so that we do not disturb any
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// minio processes running in parallel.
 
							 
						 
					
						
							
								
									
										
										
										
											2018-07-19 11:17:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											var  wlk  * lock . LockedFile 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											wlk ,  err  =  lock . TryLockedOpenFile ( fsFormatPath ,  os . O_RDWR ,  0 ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-09 06:30:55 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											if  err  ==  lock . ErrAlreadyLocked  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// Lock already present, sleep and attempt again.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												time . Sleep ( 100  *  time . Millisecond ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
									
										
										
										
											2018-04-06 06:04:40 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
											err  =  formatFSMigrate ( ctx ,  wlk ,  fsPath ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-09 06:30:55 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
											wlk . Close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// Migration failed, bail out so that the user can observe what happened.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											// Successfully migrated, now try to hold a read-lock on format.json
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2018-07-19 11:17:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										var  id  string 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  id ,  err  =  formatFSGetDeploymentID ( rlk ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rlk . Close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2018-11-20 06:47:03 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										globalDeploymentID  =  id 
							 
						 
					
						
							
								
									
										
										
										
											2018-01-09 06:30:55 +08:00 
										
									 
								 
							 
							
								
							 
							
								 
							
							
										return  rlk ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
									
										
										
										
											2018-07-19 11:17:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  formatFSGetDeploymentID ( rlk  * lock . RLockedFile )  ( id  string ,  err  error )  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									format  :=  & formatFS { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  :=  jsonLoad ( rlk ,  format ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  "" ,  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  format . ID ,  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								}  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								// Generate a deployment ID if one does not exist already.
  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								func  formatFSFixDeploymentID ( fsFormatPath  string )  error  {  
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rlk ,  err  :=  lock . RLockedOpenFile ( fsFormatPath ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  ==  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// format.json can be empty in a rare condition when another
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// minio process just created the file but could not hold lock
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										// and write to it.
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										var  fi  os . FileInfo 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										fi ,  err  =  rlk . Stat ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rlk . Close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										if  fi . Size ( )  ==  0  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											rlk . Close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  os . IsNotExist ( err )  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									formatBackend ,  err  :=  formatMetaGetFormatBackendFS ( rlk ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rlk . Close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  formatBackend  !=  formatBackendFS  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										rlk . Close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  fmt . Errorf ( ` %s file: expected format-type: %s, found: %s ` ,  formatConfigFile ,  formatBackendFS ,  formatBackend ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									format  :=  & formatFS { } 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									err  =  jsonLoad ( rlk ,  format ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									rlk . Close ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Check if it needs to be updated
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  format . ID  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-01-10 02:13:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									formatStartTime  :=  time . Now ( ) . Round ( time . Second ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									getElapsedTime  :=  func ( )  string  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  time . Now ( ) . Round ( time . Second ) . Sub ( formatStartTime ) . String ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									doneCh  :=  make ( chan  struct { } ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									defer  close ( doneCh ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-02-13 20:59:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									var  wlk  * lock . LockedFile 
							 
						 
					
						
							
								
									
										
										
										
											2019-12-25 05:49:48 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									retryCh  :=  newRetryTimerSimple ( doneCh ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									var  stop  bool 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									for  ! stop  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										select  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  <- retryCh : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											wlk ,  err  =  lock . TryLockedOpenFile ( fsFormatPath ,  os . O_RDWR ,  0 ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  ==  lock . ErrAlreadyLocked  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												// Lock already present, sleep and attempt again
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												logger . Info ( "Another minio process(es) might be holding a lock to the file %s. Please kill that minio process(es) (elapsed %s)\n" ,  fsFormatPath ,  getElapsedTime ( ) ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												continue 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											if  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
												return  err 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											} 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											stop  =  true 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										case  <- globalOSSignalCh : 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
											return  fmt . Errorf ( "Initializing FS format stopped gracefully" ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-13 20:59:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
										} 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-14 04:18:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2018-07-19 11:17:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-14 04:18:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									defer  wlk . Close ( ) 
							 
						 
					
						
							
								
									
										
										
										
											2019-01-10 02:13:04 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
									
										
										
										
											2019-11-14 04:18:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									if  err  =  jsonLoad ( wlk ,  format ) ;  err  !=  nil  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  err 
							 
						 
					
						
							
								
									
										
										
										
											2018-07-19 11:17:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-14 04:18:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Check if format needs to be updated
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									if  format . ID  !=  ""  { 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
										return  nil 
							 
						 
					
						
							
								
									
										
										
										
											2019-02-13 20:59:36 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
									} 
							 
						 
					
						
							
								
									
										
										
										
											2019-11-14 04:18:23 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									// Set new UUID to the format and save it
 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									format . ID  =  mustGetUUID ( ) 
							 
						 
					
						
							
								
							 
							
								
							 
							
								 
							
							
									return  jsonSave ( wlk ,  format ) 
							 
						 
					
						
							
								
									
										
										
										
											2018-07-19 11:17:35 +08:00 
										
									 
								 
							 
							
								
									
										 
								
							 
							
								 
							
							
								}