storj.io/minio@v0.0.0-20230509071714-0cbc90f649b1/pkg/madmin/top-commands.go (about) 1 /* 2 * MinIO Cloud Storage, (C) 2019 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 18 package madmin 19 20 import ( 21 "context" 22 "encoding/json" 23 "io/ioutil" 24 "net/http" 25 "net/url" 26 "strconv" 27 "strings" 28 "time" 29 ) 30 31 // LockEntry holds information about client requesting the lock, 32 // servers holding the lock, source on the client machine, 33 // ID, type(read or write) and time stamp. 34 type LockEntry struct { 35 Timestamp time.Time `json:"time"` // When the lock was first granted 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 }