1// Copyright 2018 The Prometheus Authors
2// Licensed under the Apache License, Version 2.0 (the "License");
3// you may not use this file except in compliance with the License.
4// You may obtain a copy of the License at
5//
6// http://www.apache.org/licenses/LICENSE-2.0
7//
8// Unless required by applicable law or agreed to in writing, software
9// distributed under the License is distributed on an "AS IS" BASIS,
10// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11// See the License for the specific language governing permissions and
12// limitations under the License.
13
14// Package nfs implements parsing of /proc/net/rpc/nfsd.
15// Fields are documented in https://www.svennd.be/nfsd-stats-explained-procnetrpcnfsd/
16package nfs
17
18import (
19	"os"
20	"strings"
21
22	"github.com/prometheus/procfs/internal/fs"
23)
24
25// ReplyCache models the "rc" line.
26type ReplyCache struct {
27	Hits    uint64
28	Misses  uint64
29	NoCache uint64
30}
31
32// FileHandles models the "fh" line.
33type FileHandles struct {
34	Stale        uint64
35	TotalLookups uint64
36	AnonLookups  uint64
37	DirNoCache   uint64
38	NoDirNoCache uint64
39}
40
41// InputOutput models the "io" line.
42type InputOutput struct {
43	Read  uint64
44	Write uint64
45}
46
47// Threads models the "th" line.
48type Threads struct {
49	Threads uint64
50	FullCnt uint64
51}
52
53// ReadAheadCache models the "ra" line.
54type ReadAheadCache struct {
55	CacheSize      uint64
56	CacheHistogram []uint64
57	NotFound       uint64
58}
59
60// Network models the "net" line.
61type Network struct {
62	NetCount   uint64
63	UDPCount   uint64
64	TCPCount   uint64
65	TCPConnect uint64
66}
67
68// ClientRPC models the nfs "rpc" line.
69type ClientRPC struct {
70	RPCCount        uint64
71	Retransmissions uint64
72	AuthRefreshes   uint64
73}
74
75// ServerRPC models the nfsd "rpc" line.
76type ServerRPC struct {
77	RPCCount uint64
78	BadCnt   uint64
79	BadFmt   uint64
80	BadAuth  uint64
81	BadcInt  uint64
82}
83
84// V2Stats models the "proc2" line.
85type V2Stats struct {
86	Null     uint64
87	GetAttr  uint64
88	SetAttr  uint64
89	Root     uint64
90	Lookup   uint64
91	ReadLink uint64
92	Read     uint64
93	WrCache  uint64
94	Write    uint64
95	Create   uint64
96	Remove   uint64
97	Rename   uint64
98	Link     uint64
99	SymLink  uint64
100	MkDir    uint64
101	RmDir    uint64
102	ReadDir  uint64
103	FsStat   uint64
104}
105
106// V3Stats models the "proc3" line.
107type V3Stats struct {
108	Null        uint64
109	GetAttr     uint64
110	SetAttr     uint64
111	Lookup      uint64
112	Access      uint64
113	ReadLink    uint64
114	Read        uint64
115	Write       uint64
116	Create      uint64
117	MkDir       uint64
118	SymLink     uint64
119	MkNod       uint64
120	Remove      uint64
121	RmDir       uint64
122	Rename      uint64
123	Link        uint64
124	ReadDir     uint64
125	ReadDirPlus uint64
126	FsStat      uint64
127	FsInfo      uint64
128	PathConf    uint64
129	Commit      uint64
130}
131
132// ClientV4Stats models the nfs "proc4" line.
133type ClientV4Stats struct {
134	Null               uint64
135	Read               uint64
136	Write              uint64
137	Commit             uint64
138	Open               uint64
139	OpenConfirm        uint64
140	OpenNoattr         uint64
141	OpenDowngrade      uint64
142	Close              uint64
143	Setattr            uint64
144	FsInfo             uint64
145	Renew              uint64
146	SetClientID        uint64
147	SetClientIDConfirm uint64
148	Lock               uint64
149	Lockt              uint64
150	Locku              uint64
151	Access             uint64
152	Getattr            uint64
153	Lookup             uint64
154	LookupRoot         uint64
155	Remove             uint64
156	Rename             uint64
157	Link               uint64
158	Symlink            uint64
159	Create             uint64
160	Pathconf           uint64
161	StatFs             uint64
162	ReadLink           uint64
163	ReadDir            uint64
164	ServerCaps         uint64
165	DelegReturn        uint64
166	GetACL             uint64
167	SetACL             uint64
168	FsLocations        uint64
169	ReleaseLockowner   uint64
170	Secinfo            uint64
171	FsidPresent        uint64
172	ExchangeID         uint64
173	CreateSession      uint64
174	DestroySession     uint64
175	Sequence           uint64
176	GetLeaseTime       uint64
177	ReclaimComplete    uint64
178	LayoutGet          uint64
179	GetDeviceInfo      uint64
180	LayoutCommit       uint64
181	LayoutReturn       uint64
182	SecinfoNoName      uint64
183	TestStateID        uint64
184	FreeStateID        uint64
185	GetDeviceList      uint64
186	BindConnToSession  uint64
187	DestroyClientID    uint64
188	Seek               uint64
189	Allocate           uint64
190	DeAllocate         uint64
191	LayoutStats        uint64
192	Clone              uint64
193}
194
195// ServerV4Stats models the nfsd "proc4" line.
196type ServerV4Stats struct {
197	Null     uint64
198	Compound uint64
199}
200
201// V4Ops models the "proc4ops" line: NFSv4 operations
202// Variable list, see:
203// v4.0 https://tools.ietf.org/html/rfc3010 (38 operations)
204// v4.1 https://tools.ietf.org/html/rfc5661 (58 operations)
205// v4.2 https://tools.ietf.org/html/draft-ietf-nfsv4-minorversion2-41 (71 operations)
206type V4Ops struct {
207	//Values       uint64 // Variable depending on v4.x sub-version. TODO: Will this always at least include the fields in this struct?
208	Op0Unused    uint64
209	Op1Unused    uint64
210	Op2Future    uint64
211	Access       uint64
212	Close        uint64
213	Commit       uint64
214	Create       uint64
215	DelegPurge   uint64
216	DelegReturn  uint64
217	GetAttr      uint64
218	GetFH        uint64
219	Link         uint64
220	Lock         uint64
221	Lockt        uint64
222	Locku        uint64
223	Lookup       uint64
224	LookupRoot   uint64
225	Nverify      uint64
226	Open         uint64
227	OpenAttr     uint64
228	OpenConfirm  uint64
229	OpenDgrd     uint64
230	PutFH        uint64
231	PutPubFH     uint64
232	PutRootFH    uint64
233	Read         uint64
234	ReadDir      uint64
235	ReadLink     uint64
236	Remove       uint64
237	Rename       uint64
238	Renew        uint64
239	RestoreFH    uint64
240	SaveFH       uint64
241	SecInfo      uint64
242	SetAttr      uint64
243	Verify       uint64
244	Write        uint64
245	RelLockOwner uint64
246}
247
248// ClientRPCStats models all stats from /proc/net/rpc/nfs.
249type ClientRPCStats struct {
250	Network       Network
251	ClientRPC     ClientRPC
252	V2Stats       V2Stats
253	V3Stats       V3Stats
254	ClientV4Stats ClientV4Stats
255}
256
257// ServerRPCStats models all stats from /proc/net/rpc/nfsd.
258type ServerRPCStats struct {
259	ReplyCache     ReplyCache
260	FileHandles    FileHandles
261	InputOutput    InputOutput
262	Threads        Threads
263	ReadAheadCache ReadAheadCache
264	Network        Network
265	ServerRPC      ServerRPC
266	V2Stats        V2Stats
267	V3Stats        V3Stats
268	ServerV4Stats  ServerV4Stats
269	V4Ops          V4Ops
270}
271
272// FS represents the pseudo-filesystem proc, which provides an interface to
273// kernel data structures.
274type FS struct {
275	proc *fs.FS
276}
277
278// NewDefaultFS returns a new FS mounted under the default mountPoint. It will error
279// if the mount point can't be read.
280func NewDefaultFS() (FS, error) {
281	return NewFS(fs.DefaultProcMountPoint)
282}
283
284// NewFS returns a new FS mounted under the given mountPoint. It will error
285// if the mount point can't be read.
286func NewFS(mountPoint string) (FS, error) {
287	if strings.TrimSpace(mountPoint) == "" {
288		mountPoint = fs.DefaultProcMountPoint
289	}
290	fs, err := fs.NewFS(mountPoint)
291	if err != nil {
292		return FS{}, err
293	}
294	return FS{&fs}, nil
295}
296
297// ClientRPCStats retrieves NFS client RPC statistics
298// from proc/net/rpc/nfs.
299func (fs FS) ClientRPCStats() (*ClientRPCStats, error) {
300	f, err := os.Open(fs.proc.Path("net/rpc/nfs"))
301	if err != nil {
302		return nil, err
303	}
304	defer f.Close()
305
306	return ParseClientRPCStats(f)
307}
308
309// ServerRPCStats retrieves NFS daemon RPC statistics
310// from proc/net/rpc/nfsd.
311func (fs FS) ServerRPCStats() (*ServerRPCStats, error) {
312	f, err := os.Open(fs.proc.Path("net/rpc/nfsd"))
313	if err != nil {
314		return nil, err
315	}
316	defer f.Close()
317
318	return ParseServerRPCStats(f)
319}
320