diff --git a/cli/cmd/const.go b/cli/cmd/const.go index 01c62ca0d..75b82732f 100644 --- a/cli/cmd/const.go +++ b/cli/cmd/const.go @@ -144,6 +144,8 @@ const ( CliFlagDecommissionDpLimit = "decommissionDpLimit" CliFlagDecommissionDiskLimit = "decommissionDiskLimit" CliFlagTrashInterval = "trashInterval" + CliFlagAccessTimeValidInterval = "accessTimeValidInterval" + CliFlagEnablePersistAccessTime = "enablePersistAccessTime" // CliFlagSetDataPartitionCount = "count" use dp-count instead // Shorthand format of resource name diff --git a/cli/cmd/fmt.go b/cli/cmd/fmt.go index 6aaa31aee..b64583540 100644 --- a/cli/cmd/fmt.go +++ b/cli/cmd/fmt.go @@ -182,7 +182,7 @@ func formatSimpleVolView(svv *proto.SimpleVolView) string { sb.WriteString(fmt.Sprintf(" DpRepairBlockSize : %v\n", strutil.FormatSize(svv.DpRepairBlockSize))) sb.WriteString(fmt.Sprintf(" EnableAutoDpMetaRepair : %v\n", svv.EnableAutoDpMetaRepair)) sb.WriteString(fmt.Sprintf(" Quota : %v\n", formatEnabledDisabled(svv.EnableQuota))) - sb.WriteString(fmt.Sprintf(" AccessTimeInterval : %v\n", time.Duration(svv.AccessTimeInterval)*time.Second)) + sb.WriteString(fmt.Sprintf(" AccessTimeValidInterval : %v\n", time.Duration(svv.AccessTimeInterval)*time.Second)) sb.WriteString(fmt.Sprintf(" EnablePersistAccessTime : %v\n", svv.EnablePersistAccessTime)) if svv.Forbidden && svv.Status == 1 { sb.WriteString(fmt.Sprintf(" DeleteDelayTime : %v\n", time.Until(svv.DeleteExecTime))) diff --git a/cli/cmd/vol.go b/cli/cmd/vol.go index 04836d7bd..a8d97331d 100644 --- a/cli/cmd/vol.go +++ b/cli/cmd/vol.go @@ -294,6 +294,8 @@ func newVolUpdateCmd(client *master.MasterClient) *cobra.Command { var optEnableQuota string var optEnableDpAutoMetaRepair string var optTrashInterval int64 + var optAccessTimeValidInterval int64 + var optEnablePersistAccessTime string var confirmString = strings.Builder{} var vv *proto.SimpleVolView cmd := &cobra.Command{ @@ -590,13 +592,51 @@ func newVolUpdateCmd(client *master.MasterClient) *cobra.Command { if optTrashInterval >= 0 { if optTrashInterval != vv.TrashInterval { isChange = true - confirmString.WriteString(fmt.Sprintf(" TrashInterval : %v h -> %v h\n", vv.TrashInterval, optTrashInterval)) + confirmString.WriteString(fmt.Sprintf(" TrashInterval : %v s -> %v s\n", vv.TrashInterval, optTrashInterval)) vv.TrashInterval = optTrashInterval } else { - confirmString.WriteString(fmt.Sprintf(" TrashInterval : %v h\n", vv.TrashInterval)) + confirmString.WriteString(fmt.Sprintf(" TrashInterval : %v s\n", vv.TrashInterval)) } } else { - confirmString.WriteString(fmt.Sprintf(" TrashInterval : %v h\n", vv.TrashInterval)) + confirmString.WriteString(fmt.Sprintf(" TrashInterval : %v s\n", vv.TrashInterval)) + } + if optAccessTimeValidInterval >= 0 { + if optAccessTimeValidInterval < 1800 { + err = fmt.Errorf("AccessTimeValidInterval must greater than or equal to 1800\n") + return + } + if optAccessTimeValidInterval != vv.AccessTimeInterval { + isChange = true + confirmString.WriteString(fmt.Sprintf(" AccessTimeValidInterval : %v s -> %v h\n", vv.AccessTimeInterval, optAccessTimeValidInterval)) + vv.AccessTimeInterval = optAccessTimeValidInterval + } else { + confirmString.WriteString(fmt.Sprintf(" AccessTimeValidInterval : %v s\n", vv.AccessTimeInterval)) + } + } else { + confirmString.WriteString(fmt.Sprintf(" AccessTimeValidInterval : %v s\n", vv.AccessTimeInterval)) + } + + if optEnablePersistAccessTime != "" { + enablePersistAccessTime := false + if optEnablePersistAccessTime == "false" { + if vv.EnablePersistAccessTime { + isChange = true + } + } + if optEnablePersistAccessTime == "true" { + if !vv.EnablePersistAccessTime { + isChange = true + } + enablePersistAccessTime = true + } + if isChange { + confirmString.WriteString(fmt.Sprintf(" EnablePersistAccessTime : %v -> %v \n", vv.EnablePersistAccessTime, enablePersistAccessTime)) + vv.EnablePersistAccessTime = enablePersistAccessTime + } else { + confirmString.WriteString(fmt.Sprintf(" EnablePersistAccessTime : %v \n", vv.EnablePersistAccessTime)) + } + } else { + confirmString.WriteString(fmt.Sprintf(" EnablePersistAccessTime : %v \n", vv.EnablePersistAccessTime)) } if optEnableDpAutoMetaRepair != "" { enable := false @@ -675,6 +715,9 @@ func newVolUpdateCmd(client *master.MasterClient) *cobra.Command { cmd.Flags().StringVar(&optEnableDpAutoMetaRepair, CliFlagAutoDpMetaRepair, "", "Enable or disable dp auto meta repair") cmd.Flags().Int64Var(&optTrashInterval, CliFlagTrashInterval, -1, "The retention period for files in trash") + cmd.Flags().Int64Var(&optAccessTimeValidInterval, CliFlagAccessTimeValidInterval, -1, "Effective time interval for accesstime, at least 1800 [Unit: second]") + cmd.Flags().StringVar(&optEnablePersistAccessTime, CliFlagEnablePersistAccessTime, "", "true/false to enable/disable persisting access time") + return cmd } diff --git a/master/api_args_parse.go b/master/api_args_parse.go index 153c18478..7968b0947 100644 --- a/master/api_args_parse.go +++ b/master/api_args_parse.go @@ -399,6 +399,8 @@ type updateVolReq struct { crossZone bool trashInterval int64 enableAutoDpMetaRepair bool + accessTimeValidInterval int64 + enablePersistAccessTime bool } func parseColdVolUpdateArgs(r *http.Request, vol *Vol) (args *coldVolArgs, err error) { @@ -534,7 +536,13 @@ func parseVolUpdateReq(r *http.Request, vol *Vol, req *updateVolReq) (err error) return } - if req.trashInterval, err = extractInt64WithDefault(r, intervalKey, 0); err != nil { + if req.trashInterval, err = extractInt64WithDefault(r, trashIntervalKey, vol.TrashInterval); err != nil { + return + } + if req.accessTimeValidInterval, err = extractInt64WithDefault(r, accessTimeIntervalKey, vol.AccessTimeValidInterval); err != nil { + return + } + if req.enablePersistAccessTime, err = extractBoolWithDefault(r, enablePersistAccessTimeKey, vol.EnablePersistAccessTime); err != nil { return } if req.enableAutoDpMetaRepair, err = extractBoolWithDefault(r, autoDpMetaRepairKey, vol.EnableAutoMetaRepair.Load()); err != nil { @@ -651,7 +659,7 @@ type coldVolArgs struct { cacheLowWater int cacheLRUInterval int cacheRule string - accessTimeInterval int64 + accessTimeValidInterval int64 trashInterval int64 enablePersistAccessTime bool } @@ -682,6 +690,9 @@ type createVolReq struct { txConflictRetryInterval int64 qosLimitArgs *qosArgs clientReqPeriod, clientHitTriggerCnt uint32 + trashInterval int64 + accessTimeValidInterval int64 + enablePersistAccessTime bool // cold vol args coldArgs coldVolArgs } @@ -852,6 +863,15 @@ func parseRequestToCreateVol(r *http.Request, req *createVolReq) (err error) { return } + if req.trashInterval, err = extractInt64WithDefault(r, trashIntervalKey, 0); err != nil { + return + } + if req.accessTimeValidInterval, err = extractInt64WithDefault(r, accessTimeIntervalKey, proto.DefaultAccessTimeValidInterval); err != nil { + return + } + if req.enablePersistAccessTime, err = extractBoolWithDefault(r, enablePersistAccessTimeKey, false); err != nil { + return + } return } @@ -1047,6 +1067,18 @@ func extractStatus(r *http.Request) (status bool, err error) { return } +func extractPersistStatus(r *http.Request) (status bool, err error) { + var value string + if value = r.FormValue(enablePersistAccessTimeKey); value == "" { + err = keyNotFound(enablePersistAccessTimeKey) + return + } + if status, err = strconv.ParseBool(value); err != nil { + return + } + return +} + func extractForbidden(r *http.Request) (forbidden bool, err error) { var value string if value = r.FormValue(forbiddenKey); value == "" { @@ -1953,7 +1985,7 @@ func extractInodeId(r *http.Request) (inode uint64, err error) { return strconv.ParseUint(value, 10, 64) } -func parseRequestToSetInterval(r *http.Request) (name, authKey string, interval int64, err error) { +func parseRequestToSetTrashInterval(r *http.Request) (name, authKey string, interval int64, err error) { if err = r.ParseForm(); err != nil { return } @@ -1964,12 +1996,13 @@ func parseRequestToSetInterval(r *http.Request) (name, authKey string, interval if authKey, err = extractAuthKey(r); err != nil { return } - if interval, err = extractInt64WithDefault(r, intervalKey, 0); err != nil { + if interval, err = extractInt64WithDefault(r, trashIntervalKey, 0); err != nil { return } return } -func parseRequestToSetPersist(r *http.Request) (name, authKey string, enable bool, err error) { + +func parseRequestToSetAccessTimeInterval(r *http.Request) (name, authKey string, interval int64, err error) { if err = r.ParseForm(); err != nil { return } @@ -1980,7 +2013,24 @@ func parseRequestToSetPersist(r *http.Request) (name, authKey string, enable boo if authKey, err = extractAuthKey(r); err != nil { return } - if enable, err = extractStatus(r); err != nil { + if interval, err = extractInt64WithDefault(r, accessTimeIntervalKey, 0); err != nil { + return + } + return +} + +func parseRequestToSetPersistAccessTime(r *http.Request) (name, authKey string, enable bool, err error) { + if err = r.ParseForm(); err != nil { + return + } + + if name, err = extractName(r); err != nil { + return + } + if authKey, err = extractAuthKey(r); err != nil { + return + } + if enable, err = extractPersistStatus(r); err != nil { return } return diff --git a/master/api_service.go b/master/api_service.go index 49e9a1ee7..c869fbf07 100644 --- a/master/api_service.go +++ b/master/api_service.go @@ -2333,6 +2333,8 @@ func (m *Server) updateVol(w http.ResponseWriter, r *http.Request) { newArgs.txOpLimit = req.txOpLimit newArgs.enableQuota = req.enableQuota newArgs.trashInterval = req.trashInterval + newArgs.accessTimeValidInterval = req.accessTimeValidInterval + newArgs.enablePersistAccessTime = req.enablePersistAccessTime if req.coldArgs != nil { newArgs.coldArgs = req.coldArgs } @@ -2537,6 +2539,9 @@ func (m *Server) checkCreateReq(req *createVolReq) (err error) { return fmt.Errorf("dp replicaNum %d can't be large than dataNodeCnt %d", req.dpReplicaNum, m.cluster.dataNodeCount()) } + if req.accessTimeValidInterval < proto.MinAccessTimeValidInterval { + return fmt.Errorf("accessTimeValidInterval must greater than or equal to 1800") + } req.coldArgs = args return nil } @@ -2726,7 +2731,7 @@ func newSimpleView(vol *Vol) (view *proto.SimpleVolView) { DeleteExecTime: vol.DeleteExecTime, DpRepairBlockSize: vol.dpRepairBlockSize, EnableAutoDpMetaRepair: vol.EnableAutoMetaRepair.Load(), - AccessTimeInterval: vol.AccessTimeInterval, + AccessTimeInterval: vol.AccessTimeValidInterval, EnablePersistAccessTime: vol.EnablePersistAccessTime, } diff --git a/master/cluster.go b/master/cluster.go index 29c08cf45..e8e5ea050 100644 --- a/master/cluster.go +++ b/master/cluster.go @@ -3367,8 +3367,11 @@ func (c *Cluster) doCreateVol(req *createVolReq) (vol *Vol, err error) { FlowRlimit: req.qosLimitArgs.flowRVal, FlowWlimit: req.qosLimitArgs.flowWVal, - DpReadOnlyWhenVolFull: req.DpReadOnlyWhenVolFull, - EnableAutoMetaRepair: false, + DpReadOnlyWhenVolFull: req.DpReadOnlyWhenVolFull, + EnableAutoMetaRepair: false, + TrashInterval: req.trashInterval, + AccessTimeInterval: req.accessTimeValidInterval, + EnablePersistAccessTime: req.enablePersistAccessTime, } log.LogInfof("[doCreateVol] volView, %v", vv) diff --git a/master/const.go b/master/const.go index 1fcdb10bb..aa8d4637f 100644 --- a/master/const.go +++ b/master/const.go @@ -147,6 +147,9 @@ const ( dpTimeoutKey = "dpTimeout" ShowAll = "showAll" intervalKey = "interval" + trashIntervalKey = "trashInterval" + accessTimeIntervalKey = "accessTimeValidInterval" + enablePersistAccessTimeKey = "enablePersistAccessTime" ) const ( diff --git a/master/metadata_fsm_op.go b/master/metadata_fsm_op.go index c06052d3d..1782bf8b4 100644 --- a/master/metadata_fsm_op.go +++ b/master/metadata_fsm_op.go @@ -397,7 +397,7 @@ func newVolValue(vol *Vol) (vv *volValue) { User: vol.user, DpRepairBlockSize: vol.dpRepairBlockSize, EnableAutoMetaRepair: vol.EnableAutoMetaRepair.Load(), - AccessTimeInterval: vol.AccessTimeInterval, + AccessTimeInterval: vol.AccessTimeValidInterval, EnablePersistAccessTime: vol.EnablePersistAccessTime, } diff --git a/master/vol.go b/master/vol.go index e7e6327db..20e91cd08 100644 --- a/master/vol.go +++ b/master/vol.go @@ -55,6 +55,7 @@ type VolVarargs struct { crossZone bool accessTimeInterval int64 enableAutoDpMetaRepair bool + accessTimeValidInterval int64 enablePersistAccessTime bool } @@ -138,6 +139,7 @@ type Vol struct { ReadOnlyForVolFull bool // only if the switch DpReadOnlyWhenVolFull is on, mark vol is readonly when is full AccessTimeInterval int64 EnablePersistAccessTime bool + AccessTimeValidInterval int64 EnableAutoMetaRepair atomicutil.Bool TopoSubItem @@ -221,6 +223,10 @@ func newVol(vv volValue) (vol *Vol) { vol.preloadCapacity = math.MaxUint64 // mark as special value to trigger calculate vol.dpRepairBlockSize = proto.DefaultDpRepairBlockSize vol.EnableAutoMetaRepair.Store(defaultEnableDpMetaRepair) + vol.preloadCapacity = math.MaxUint64 //mark as special value to trigger calculate + vol.TrashInterval = vv.TrashInterval + vol.AccessTimeValidInterval = vv.AccessTimeInterval + vol.EnablePersistAccessTime = vv.EnablePersistAccessTime return } @@ -253,7 +259,10 @@ func newVolFromVolValue(vv *volValue) (vol *Vol) { } vol.EnableAutoMetaRepair.Store(vv.EnableAutoMetaRepair) vol.EnablePersistAccessTime = vv.EnablePersistAccessTime - vol.AccessTimeInterval = vv.AccessTimeInterval + vol.AccessTimeValidInterval = vv.AccessTimeInterval + if vol.AccessTimeValidInterval == 0 { + vol.AccessTimeValidInterval = proto.DefaultAccessTimeValidInterval + } return vol } @@ -1604,6 +1613,7 @@ func setVolFromArgs(args *VolVarargs, vol *Vol) { vol.dpSelectorName = args.dpSelectorName vol.dpSelectorParm = args.dpSelectorParm vol.TrashInterval = args.trashInterval + vol.AccessTimeValidInterval = args.accessTimeValidInterval vol.AccessTimeInterval = args.accessTimeInterval vol.EnableAutoMetaRepair.Store(args.enableAutoDpMetaRepair) vol.EnablePersistAccessTime = args.enablePersistAccessTime @@ -1620,7 +1630,7 @@ func getVolVarargs(vol *Vol) *VolVarargs { cacheLowWater: vol.CacheLowWater, cacheLRUInterval: vol.CacheLRUInterval, cacheRule: vol.CacheRule, - accessTimeInterval: vol.AccessTimeInterval, + accessTimeValidInterval: vol.AccessTimeValidInterval, trashInterval: vol.TrashInterval, enablePersistAccessTime: vol.EnablePersistAccessTime, } @@ -1645,7 +1655,7 @@ func getVolVarargs(vol *Vol) *VolVarargs { txOpLimit: vol.txOpLimit, coldArgs: args, dpReadOnlyWhenVolFull: vol.DpReadOnlyWhenVolFull, - accessTimeInterval: vol.AccessTimeInterval, + accessTimeValidInterval: vol.AccessTimeValidInterval, trashInterval: vol.TrashInterval, enablePersistAccessTime: vol.EnablePersistAccessTime, enableAutoDpMetaRepair: vol.EnableAutoMetaRepair.Load(), diff --git a/metanode/api_handler.go b/metanode/api_handler.go index 9d6d61fbe..b52cd9dae 100644 --- a/metanode/api_handler.go +++ b/metanode/api_handler.go @@ -355,7 +355,7 @@ func (m *MetaNode) getInodeHandler(w http.ResponseWriter, r *http.Request) { } finalResp := &proto.InodeGetWithPersistAccessTimeResponse{} finalResp.Info = inodeResp.Info - finalResp.PersistAccessTime = persistAtResp.Info.AccessTime + finalResp.Info.PersistAccessTime = persistAtResp.Info.AccessTime resp.Data = finalResp return } diff --git a/metanode/partition.go b/metanode/partition.go index b9dbf67a2..dc7d953f1 100644 --- a/metanode/partition.go +++ b/metanode/partition.go @@ -1735,7 +1735,7 @@ func (mp *metaPartition) GetVolName() (volName string) { func (mp *metaPartition) GetAccessTimeValidInterval() time.Duration { interval := atomic.LoadUint64(&mp.accessTimeValidInterval) if interval == 0 { - return 0 + return proto.DefaultAccessTimeValidInterval } return time.Duration(interval) } diff --git a/metanode/partition_free_list.go b/metanode/partition_free_list.go index 81c4ae864..0a66d29ab 100644 --- a/metanode/partition_free_list.go +++ b/metanode/partition_free_list.go @@ -89,6 +89,9 @@ func (mp *metaPartition) UpdateVolumeView(dataView *proto.DataPartitionsView, vo mp.vol.UpdatePartitions(convert(dataView)) mp.vol.volDeleteLockTime = volumeView.DeleteLockTime mp.enablePersistAccessTime = volumeView.EnablePersistAccessTime + if volumeView.AccessTimeInterval <= proto.MinAccessTimeValidInterval { + volumeView.AccessTimeInterval = proto.MinAccessTimeValidInterval + } atomic.StoreUint64(&mp.accessTimeValidInterval, uint64(volumeView.AccessTimeInterval)) } diff --git a/metanode/partition_op_extent.go b/metanode/partition_op_extent.go index 2f7b1f0bc..fac1687a2 100644 --- a/metanode/partition_op_extent.go +++ b/metanode/partition_op_extent.go @@ -645,9 +645,10 @@ func (mp *metaPartition) persistInodeAccessTime(inode uint64, p *Packet) { } ino := item.(*Inode) ctime := Now.GetCurrentTimeUnix() - if !(ctime > ino.AccessTime && time.Now().Sub(time.Unix(ino.AccessTime, 0)) > mp.GetAccessTimeValidInterval()*time.Second) { + at := time.Unix(ino.AccessTime, 0) + if !(ctime > ino.AccessTime && time.Now().Sub(at) > mp.GetAccessTimeValidInterval()*time.Second) { log.LogDebugf("%v %v %v", ctime > ino.AccessTime, - time.Now().Sub(time.Unix(ino.AccessTime, 0)) > mp.GetAccessTimeValidInterval(), mp.accessTimeValidInterval) + time.Now().Sub(at) > mp.GetAccessTimeValidInterval(), mp.GetAccessTimeValidInterval()) return } var ( @@ -658,7 +659,7 @@ func (mp *metaPartition) persistInodeAccessTime(inode uint64, p *Packet) { ) // always update local AccessTime ino.AccessTime = ctime - log.LogDebugf("persistInodeAccessTime ino(%v) persist at to %v", ino.Inode, time.Unix(ino.AccessTime, 0)) + log.LogDebugf("persistInodeAccessTime ino(%v) persist at to %v", ino.Inode, at) if leaderAddr, ok := mp.IsLeader(); ok { // sync AccessTime to followers val, err = ino.Marshal() @@ -682,12 +683,13 @@ func (mp *metaPartition) persistInodeAccessTime(inode uint64, p *Packet) { m.connPool.PutConnect(mConn, ForceClosedConnect) return } - if err = p.WriteToConn(mConn); err != nil { + packetCopy := p.GetCopy() + if err = packetCopy.WriteToConn(mConn); err != nil { log.LogWarnf("persistInodeAccessTime ino(%v) write to connect failed %v", ino.Inode, err) m.connPool.PutConnect(mConn, ForceClosedConnect) return } - if err = p.ReadFromConn(mConn, proto.NoReadDeadlineTime); err != nil { + if err = packetCopy.ReadFromConn(mConn, proto.NoReadDeadlineTime); err != nil { log.LogWarnf("persistInodeAccessTime ino(%v) read from connect failed %v", ino.Inode, err) m.connPool.PutConnect(mConn, ForceClosedConnect) return diff --git a/proto/fs_proto.go b/proto/fs_proto.go index 50a162aa3..1536ce755 100644 --- a/proto/fs_proto.go +++ b/proto/fs_proto.go @@ -80,20 +80,21 @@ func IsAncestor(parent, child string) bool { // InodeInfo defines the inode struct. type InodeInfo struct { - Inode uint64 `json:"ino"` - Mode uint32 `json:"mode"` - Nlink uint32 `json:"nlink"` - Size uint64 `json:"sz"` - Uid uint32 `json:"uid"` - Gid uint32 `json:"gid"` - Generation uint64 `json:"gen"` - ModifyTime time.Time `json:"mt"` - CreateTime time.Time `json:"ct"` - AccessTime time.Time `json:"at"` - Target []byte `json:"tgt"` - QuotaInfos map[uint32]*MetaQuotaInfo `json:"qifs"` - VerSeq uint64 `json:"seq"` - expiration int64 + Inode uint64 `json:"ino"` + Mode uint32 `json:"mode"` + Nlink uint32 `json:"nlink"` + Size uint64 `json:"sz"` + Uid uint32 `json:"uid"` + Gid uint32 `json:"gid"` + Generation uint64 `json:"gen"` + ModifyTime time.Time `json:"mt"` + CreateTime time.Time `json:"ct"` + AccessTime time.Time `json:"at"` + Target []byte `json:"tgt"` + QuotaInfos map[uint32]*MetaQuotaInfo `json:"qifs"` + VerSeq uint64 `json:"seq"` + expiration int64 + PersistAccessTime time.Time `json:"pat"` } type SimpleExtInfo struct { diff --git a/proto/transaction.go b/proto/transaction.go index d2be7f52f..f7092559a 100755 --- a/proto/transaction.go +++ b/proto/transaction.go @@ -38,6 +38,8 @@ const ( MinTxConflictRetryInterval = 10 // ms DefaultTxDeleteTime = 120 ClearOrphanTxTime = 3600 + DefaultAccessTimeValidInterval = 3600 * 24 + MinAccessTimeValidInterval = 3600 * 12 MaxBufferSize = 1024 * 1024 * 1024 // 1GB ) diff --git a/sdk/master/api_admin.go b/sdk/master/api_admin.go index 8980b9eaf..a5ad55d4a 100644 --- a/sdk/master/api_admin.go +++ b/sdk/master/api_admin.go @@ -18,6 +18,7 @@ import ( "encoding/json" "fmt" "net/http" + "os" "strconv" "time" @@ -295,6 +296,9 @@ func (api *AdminAPI) UpdateVolume( request.addParam("autoDpMetaRepair", strconv.FormatBool(vv.EnableAutoDpMetaRepair)) request.addParam("clientIDKey", clientIDKey) request.addParam("interval", strconv.FormatInt(vv.TrashInterval, 10)) + request.addParam("trashInterval", strconv.FormatInt(vv.TrashInterval, 10)) + request.addParam("accessTimeValidInterval", strconv.FormatInt(vv.AccessTimeInterval, 10)) + request.addParam("enablePersistAccessTime", strconv.FormatBool(vv.EnablePersistAccessTime)) if txMask != "" { request.addParam("enableTxMask", txMask) @@ -316,6 +320,10 @@ func (api *AdminAPI) UpdateVolume( return } +func stdout(format string, a ...interface{}) { + _, _ = fmt.Fprintf(os.Stdout, format, a...) +} + func (api *AdminAPI) PutDataPartitions(volName string, dpsView []byte) (err error) { return api.mc.request(newRequest(post, proto.AdminPutDataPartitions). Header(api.h).addParam("name", volName).Body(dpsView))