| // Copyright 2018 The Prometheus Authors |
| // 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 nfs |
| |
| import ( |
| "fmt" |
| ) |
| |
| func parseReplyCache(v []uint64) (ReplyCache, error) { |
| if len(v) != 3 { |
| return ReplyCache{}, fmt.Errorf("invalid ReplyCache line %q", v) |
| } |
| |
| return ReplyCache{ |
| Hits: v[0], |
| Misses: v[1], |
| NoCache: v[2], |
| }, nil |
| } |
| |
| func parseFileHandles(v []uint64) (FileHandles, error) { |
| if len(v) != 5 { |
| return FileHandles{}, fmt.Errorf("invalid FileHandles, line %q", v) |
| } |
| |
| return FileHandles{ |
| Stale: v[0], |
| TotalLookups: v[1], |
| AnonLookups: v[2], |
| DirNoCache: v[3], |
| NoDirNoCache: v[4], |
| }, nil |
| } |
| |
| func parseInputOutput(v []uint64) (InputOutput, error) { |
| if len(v) != 2 { |
| return InputOutput{}, fmt.Errorf("invalid InputOutput line %q", v) |
| } |
| |
| return InputOutput{ |
| Read: v[0], |
| Write: v[1], |
| }, nil |
| } |
| |
| func parseThreads(v []uint64) (Threads, error) { |
| if len(v) != 2 { |
| return Threads{}, fmt.Errorf("invalid Threads line %q", v) |
| } |
| |
| return Threads{ |
| Threads: v[0], |
| FullCnt: v[1], |
| }, nil |
| } |
| |
| func parseReadAheadCache(v []uint64) (ReadAheadCache, error) { |
| if len(v) != 12 { |
| return ReadAheadCache{}, fmt.Errorf("invalid ReadAheadCache line %q", v) |
| } |
| |
| return ReadAheadCache{ |
| CacheSize: v[0], |
| CacheHistogram: v[1:11], |
| NotFound: v[11], |
| }, nil |
| } |
| |
| func parseNetwork(v []uint64) (Network, error) { |
| if len(v) != 4 { |
| return Network{}, fmt.Errorf("invalid Network line %q", v) |
| } |
| |
| return Network{ |
| NetCount: v[0], |
| UDPCount: v[1], |
| TCPCount: v[2], |
| TCPConnect: v[3], |
| }, nil |
| } |
| |
| func parseServerRPC(v []uint64) (ServerRPC, error) { |
| if len(v) != 5 { |
| return ServerRPC{}, fmt.Errorf("invalid RPC line %q", v) |
| } |
| |
| return ServerRPC{ |
| RPCCount: v[0], |
| BadCnt: v[1], |
| BadFmt: v[2], |
| BadAuth: v[3], |
| BadcInt: v[4], |
| }, nil |
| } |
| |
| func parseClientRPC(v []uint64) (ClientRPC, error) { |
| if len(v) != 3 { |
| return ClientRPC{}, fmt.Errorf("invalid RPC line %q", v) |
| } |
| |
| return ClientRPC{ |
| RPCCount: v[0], |
| Retransmissions: v[1], |
| AuthRefreshes: v[2], |
| }, nil |
| } |
| |
| func parseV2Stats(v []uint64) (V2Stats, error) { |
| values := int(v[0]) |
| if len(v[1:]) != values || values != 18 { |
| return V2Stats{}, fmt.Errorf("invalid V2Stats line %q", v) |
| } |
| |
| return V2Stats{ |
| Null: v[1], |
| GetAttr: v[2], |
| SetAttr: v[3], |
| Root: v[4], |
| Lookup: v[5], |
| ReadLink: v[6], |
| Read: v[7], |
| WrCache: v[8], |
| Write: v[9], |
| Create: v[10], |
| Remove: v[11], |
| Rename: v[12], |
| Link: v[13], |
| SymLink: v[14], |
| MkDir: v[15], |
| RmDir: v[16], |
| ReadDir: v[17], |
| FsStat: v[18], |
| }, nil |
| } |
| |
| func parseV3Stats(v []uint64) (V3Stats, error) { |
| values := int(v[0]) |
| if len(v[1:]) != values || values != 22 { |
| return V3Stats{}, fmt.Errorf("invalid V3Stats line %q", v) |
| } |
| |
| return V3Stats{ |
| Null: v[1], |
| GetAttr: v[2], |
| SetAttr: v[3], |
| Lookup: v[4], |
| Access: v[5], |
| ReadLink: v[6], |
| Read: v[7], |
| Write: v[8], |
| Create: v[9], |
| MkDir: v[10], |
| SymLink: v[11], |
| MkNod: v[12], |
| Remove: v[13], |
| RmDir: v[14], |
| Rename: v[15], |
| Link: v[16], |
| ReadDir: v[17], |
| ReadDirPlus: v[18], |
| FsStat: v[19], |
| FsInfo: v[20], |
| PathConf: v[21], |
| Commit: v[22], |
| }, nil |
| } |
| |
| func parseClientV4Stats(v []uint64) (ClientV4Stats, error) { |
| values := int(v[0]) |
| if len(v[1:]) != values { |
| return ClientV4Stats{}, fmt.Errorf("invalid ClientV4Stats line %q", v) |
| } |
| |
| // This function currently supports mapping 59 NFS v4 client stats. Older |
| // kernels may emit fewer stats, so we must detect this and pad out the |
| // values to match the expected slice size. |
| if values < 59 { |
| newValues := make([]uint64, 60) |
| copy(newValues, v) |
| v = newValues |
| } |
| |
| return ClientV4Stats{ |
| Null: v[1], |
| Read: v[2], |
| Write: v[3], |
| Commit: v[4], |
| Open: v[5], |
| OpenConfirm: v[6], |
| OpenNoattr: v[7], |
| OpenDowngrade: v[8], |
| Close: v[9], |
| Setattr: v[10], |
| FsInfo: v[11], |
| Renew: v[12], |
| SetClientID: v[13], |
| SetClientIDConfirm: v[14], |
| Lock: v[15], |
| Lockt: v[16], |
| Locku: v[17], |
| Access: v[18], |
| Getattr: v[19], |
| Lookup: v[20], |
| LookupRoot: v[21], |
| Remove: v[22], |
| Rename: v[23], |
| Link: v[24], |
| Symlink: v[25], |
| Create: v[26], |
| Pathconf: v[27], |
| StatFs: v[28], |
| ReadLink: v[29], |
| ReadDir: v[30], |
| ServerCaps: v[31], |
| DelegReturn: v[32], |
| GetACL: v[33], |
| SetACL: v[34], |
| FsLocations: v[35], |
| ReleaseLockowner: v[36], |
| Secinfo: v[37], |
| FsidPresent: v[38], |
| ExchangeID: v[39], |
| CreateSession: v[40], |
| DestroySession: v[41], |
| Sequence: v[42], |
| GetLeaseTime: v[43], |
| ReclaimComplete: v[44], |
| LayoutGet: v[45], |
| GetDeviceInfo: v[46], |
| LayoutCommit: v[47], |
| LayoutReturn: v[48], |
| SecinfoNoName: v[49], |
| TestStateID: v[50], |
| FreeStateID: v[51], |
| GetDeviceList: v[52], |
| BindConnToSession: v[53], |
| DestroyClientID: v[54], |
| Seek: v[55], |
| Allocate: v[56], |
| DeAllocate: v[57], |
| LayoutStats: v[58], |
| Clone: v[59], |
| }, nil |
| } |
| |
| func parseServerV4Stats(v []uint64) (ServerV4Stats, error) { |
| values := int(v[0]) |
| if len(v[1:]) != values || values != 2 { |
| return ServerV4Stats{}, fmt.Errorf("invalid V4Stats line %q", v) |
| } |
| |
| return ServerV4Stats{ |
| Null: v[1], |
| Compound: v[2], |
| }, nil |
| } |
| |
| func parseV4Ops(v []uint64) (V4Ops, error) { |
| values := int(v[0]) |
| if len(v[1:]) != values || values < 39 { |
| return V4Ops{}, fmt.Errorf("invalid V4Ops line %q", v) |
| } |
| |
| stats := V4Ops{ |
| Op0Unused: v[1], |
| Op1Unused: v[2], |
| Op2Future: v[3], |
| Access: v[4], |
| Close: v[5], |
| Commit: v[6], |
| Create: v[7], |
| DelegPurge: v[8], |
| DelegReturn: v[9], |
| GetAttr: v[10], |
| GetFH: v[11], |
| Link: v[12], |
| Lock: v[13], |
| Lockt: v[14], |
| Locku: v[15], |
| Lookup: v[16], |
| LookupRoot: v[17], |
| Nverify: v[18], |
| Open: v[19], |
| OpenAttr: v[20], |
| OpenConfirm: v[21], |
| OpenDgrd: v[22], |
| PutFH: v[23], |
| PutPubFH: v[24], |
| PutRootFH: v[25], |
| Read: v[26], |
| ReadDir: v[27], |
| ReadLink: v[28], |
| Remove: v[29], |
| Rename: v[30], |
| Renew: v[31], |
| RestoreFH: v[32], |
| SaveFH: v[33], |
| SecInfo: v[34], |
| SetAttr: v[35], |
| Verify: v[36], |
| Write: v[37], |
| RelLockOwner: v[38], |
| } |
| |
| return stats, nil |
| } |