You can not select more than 25 topics
			Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
		
		
		
		
		
			
		
			
				
					
					
						
							103 lines
						
					
					
						
							3.1 KiB
						
					
					
				
			
		
		
		
			
			
			
		
		
	
	
							103 lines
						
					
					
						
							3.1 KiB
						
					
					
				
								package volume_info
							 | 
						|
								
							 | 
						|
								import (
							 | 
						|
									"fmt"
							 | 
						|
									jsonpb "google.golang.org/protobuf/encoding/protojson"
							 | 
						|
									"os"
							 | 
						|
								
							 | 
						|
									"github.com/seaweedfs/seaweedfs/weed/glog"
							 | 
						|
									"github.com/seaweedfs/seaweedfs/weed/pb/volume_server_pb"
							 | 
						|
									_ "github.com/seaweedfs/seaweedfs/weed/storage/backend/rclone_backend"
							 | 
						|
									_ "github.com/seaweedfs/seaweedfs/weed/storage/backend/s3_backend"
							 | 
						|
									"github.com/seaweedfs/seaweedfs/weed/util"
							 | 
						|
								)
							 | 
						|
								
							 | 
						|
								// MaybeLoadVolumeInfo load the file data as *volume_server_pb.VolumeInfo, the returned volumeInfo will not be nil
							 | 
						|
								func MaybeLoadVolumeInfo(fileName string) (volumeInfo *volume_server_pb.VolumeInfo, hasRemoteFile bool, hasVolumeInfoFile bool, err error) {
							 | 
						|
								
							 | 
						|
									volumeInfo = &volume_server_pb.VolumeInfo{}
							 | 
						|
								
							 | 
						|
									glog.V(1).Infof("maybeLoadVolumeInfo checks %s", fileName)
							 | 
						|
									if exists, canRead, _, _, _ := util.CheckFile(fileName); !exists || !canRead {
							 | 
						|
										if !exists {
							 | 
						|
											return
							 | 
						|
										}
							 | 
						|
										hasVolumeInfoFile = true
							 | 
						|
										if !canRead {
							 | 
						|
											glog.Warningf("can not read %s", fileName)
							 | 
						|
											err = fmt.Errorf("can not read %s", fileName)
							 | 
						|
											return
							 | 
						|
										}
							 | 
						|
										return
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									hasVolumeInfoFile = true
							 | 
						|
								
							 | 
						|
									glog.V(1).Infof("maybeLoadVolumeInfo reads %s", fileName)
							 | 
						|
									fileData, readErr := os.ReadFile(fileName)
							 | 
						|
									if readErr != nil {
							 | 
						|
										glog.Warningf("fail to read %s : %v", fileName, readErr)
							 | 
						|
										err = fmt.Errorf("fail to read %s : %v", fileName, readErr)
							 | 
						|
										return
							 | 
						|
								
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									glog.V(1).Infof("maybeLoadVolumeInfo Unmarshal volume info %v", fileName)
							 | 
						|
									if err = jsonpb.Unmarshal(fileData, volumeInfo); err != nil {
							 | 
						|
										if oldVersionErr := tryOldVersionVolumeInfo(fileData, volumeInfo); oldVersionErr != nil {
							 | 
						|
											glog.Warningf("unmarshal error: %v oldFormat: %v", err, oldVersionErr)
							 | 
						|
											err = fmt.Errorf("unmarshal error: %w oldFormat: %v", err, oldVersionErr)
							 | 
						|
											return
							 | 
						|
										} else {
							 | 
						|
											err = nil
							 | 
						|
										}
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									if len(volumeInfo.GetFiles()) == 0 {
							 | 
						|
										return
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									hasRemoteFile = true
							 | 
						|
								
							 | 
						|
									return
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								func SaveVolumeInfo(fileName string, volumeInfo *volume_server_pb.VolumeInfo) error {
							 | 
						|
								
							 | 
						|
									if exists, _, canWrite, _, _ := util.CheckFile(fileName); exists && !canWrite {
							 | 
						|
										return fmt.Errorf("failed to check %s not writable", fileName)
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									m := jsonpb.MarshalOptions{
							 | 
						|
										AllowPartial:    true,
							 | 
						|
										EmitUnpopulated: true,
							 | 
						|
										Indent:          "  ",
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									text, marshalErr := m.Marshal(volumeInfo)
							 | 
						|
									if marshalErr != nil {
							 | 
						|
										return fmt.Errorf("failed to marshal %s: %v", fileName, marshalErr)
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									if err := util.WriteFile(fileName, text, 0644); err != nil {
							 | 
						|
										return fmt.Errorf("failed to write %s: %v", fileName, err)
							 | 
						|
									}
							 | 
						|
								
							 | 
						|
									return nil
							 | 
						|
								}
							 | 
						|
								
							 | 
						|
								func tryOldVersionVolumeInfo(data []byte, volumeInfo *volume_server_pb.VolumeInfo) error {
							 | 
						|
									oldVersionVolumeInfo := &volume_server_pb.OldVersionVolumeInfo{}
							 | 
						|
									if err := jsonpb.Unmarshal(data, oldVersionVolumeInfo); err != nil {
							 | 
						|
										return fmt.Errorf("failed to unmarshal old version volume info: %w", err)
							 | 
						|
									}
							 | 
						|
									volumeInfo.Files = oldVersionVolumeInfo.Files
							 | 
						|
									volumeInfo.Version = oldVersionVolumeInfo.Version
							 | 
						|
									volumeInfo.Replication = oldVersionVolumeInfo.Replication
							 | 
						|
									volumeInfo.BytesOffset = oldVersionVolumeInfo.BytesOffset
							 | 
						|
									volumeInfo.DatFileSize = oldVersionVolumeInfo.DatFileSize
							 | 
						|
									volumeInfo.ExpireAtSec = oldVersionVolumeInfo.DestroyTime
							 | 
						|
									volumeInfo.ReadOnly = oldVersionVolumeInfo.ReadOnly
							 | 
						|
								
							 | 
						|
									return nil
							 | 
						|
								}
							 |