github.com/minio/madmin-go@v1.7.5/top-commands.go (about) 1 // 2 // MinIO Object Storage (c) 2021 MinIO, Inc. 3 // 4 // Licensed under the Apache License, Version 2.0 (the "License"); 5 // you may not use this file except in compliance with the License. 6 // You may obtain a copy of the License at 7 // 8 // http://www.apache.org/licenses/LICENSE-2.0 9 // 10 // Unless required by applicable law or agreed to in writing, software 11 // distributed under the License is distributed on an "AS IS" BASIS, 12 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 // See the License for the specific language governing permissions and 14 // limitations under the License. 15 // 16 17 package madmin 18 19 import ( 20 "context" 21 "encoding/json" 22 "io/ioutil" 23 "net/http" 24 "net/url" 25 "strconv" 26 "strings" 27 "time" 28 ) 29 30 // LockEntry holds information about client requesting the lock, 31 // servers holding the lock, source on the client machine, 32 // ID, type(read or write) and time stamp. 33 type LockEntry struct { 34 Timestamp time.Time `json:"time"` // When the lock was first granted 35 Elapsed time.Duration `json:"elapsed"` // Duration for which lock has been held 36 Resource string `json:"resource"` // Resource contains info like bucket+object 37 Type string `json:"type"` // Type indicates if 'Write' or 'Read' lock 38 Source string `json:"source"` // Source at which lock was granted 39 ServerList []string `json:"serverlist"` // List of servers participating in the lock. 40 Owner string `json:"owner"` // Owner UUID indicates server owns the lock. 41 ID string `json:"id"` // UID to uniquely identify request of client. 42 // Represents quorum number of servers required to hold this lock, used to look for stale locks. 43 Quorum int `json:"quorum"` 44 } 45 46 // LockEntries - To sort the locks 47 type LockEntries []LockEntry 48 49 func (l LockEntries) Len() int { 50 return len(l) 51 } 52 53 func (l LockEntries) Less(i, j int) bool { 54 return l[i].Timestamp.Before(l[j].Timestamp) 55 } 56 57 func (l LockEntries) Swap(i, j int) { 58 l[i], l[j] = l[j], l[i] 59 } 60 61 // TopLockOpts top lock options 62 type TopLockOpts struct { 63 Count int 64 Stale bool 65 } 66 67 // ForceUnlock force unlocks input paths... 68 func (adm *AdminClient) ForceUnlock(ctx context.Context, paths ...string) error { 69 // Execute POST on /minio/admin/v3/force-unlock 70 queryVals := make(url.Values) 71 queryVals.Set("paths", strings.Join(paths, ",")) 72 resp, err := adm.executeMethod(ctx, 73 http.MethodPost, 74 requestData{ 75 relPath: adminAPIPrefix + "/force-unlock", 76 queryValues: queryVals, 77 }, 78 ) 79 defer closeResponse(resp) 80 if err != nil { 81 return err 82 } 83 84 if resp.StatusCode != http.StatusOK { 85 return httpRespToErrorResponse(resp) 86 } 87 88 return nil 89 } 90 91 // TopLocksWithOpts - returns the count number of oldest locks currently active on the server. 92 // additionally we can also enable `stale` to get stale locks currently present on server. 93 func (adm *AdminClient) TopLocksWithOpts(ctx context.Context, opts TopLockOpts) (LockEntries, error) { 94 // Execute GET on /minio/admin/v3/top/locks?count=10 95 // to get the 'count' number of oldest locks currently 96 // active on the server. 97 queryVals := make(url.Values) 98 queryVals.Set("count", strconv.Itoa(opts.Count)) 99 queryVals.Set("stale", strconv.FormatBool(opts.Stale)) 100 resp, err := adm.executeMethod(ctx, 101 http.MethodGet, 102 requestData{ 103 relPath: adminAPIPrefix + "/top/locks", 104 queryValues: queryVals, 105 }, 106 ) 107 defer closeResponse(resp) 108 if err != nil { 109 return nil, err 110 } 111 112 if resp.StatusCode != http.StatusOK { 113 return nil, httpRespToErrorResponse(resp) 114 } 115 116 response, err := ioutil.ReadAll(resp.Body) 117 if err != nil { 118 return LockEntries{}, err 119 } 120 121 var lockEntries LockEntries 122 err = json.Unmarshal(response, &lockEntries) 123 return lockEntries, err 124 } 125 126 // TopLocks - returns top '10' oldest locks currently active on the server. 127 func (adm *AdminClient) TopLocks(ctx context.Context) (LockEntries, error) { 128 return adm.TopLocksWithOpts(ctx, TopLockOpts{Count: 10}) 129 }