On 5/25/20 2:03 PM, Kenneth D'souza wrote: > Add new option --file to process specific states file, > provided the info file resides in the same directory as > states file. If the info file is not valid or present the > fields would be marked as "N/A". > > --verbose option will be helpful for debugging purpose. > > Signed-off-by: Kenneth D'souza <kdsouza@xxxxxxxxxx> > Signed-off-by: Achilles Gaikwad <agaikwad@xxxxxxxxxx> Committed... (tag: nfs-utils-2-4-4-rc6) steved. > --- > tools/nfsdclnts/nfsdclnts.man | 26 +++++++++++++++++++++++++- > tools/nfsdclnts/nfsdclnts.py | 32 +++++++++++++++++++++++++++----- > 2 files changed, 52 insertions(+), 6 deletions(-) > > diff --git a/tools/nfsdclnts/nfsdclnts.man b/tools/nfsdclnts/nfsdclnts.man > index 3701de9a..c7efbd70 100644 > --- a/tools/nfsdclnts/nfsdclnts.man > +++ b/tools/nfsdclnts/nfsdclnts.man > @@ -63,6 +63,18 @@ Print hostname of nfs\-client instead of ip-address. > Hide the header information. > .RE > .sp > +\fB\-v, \-\-verbose\fP > +.RS 4 > +Verbose operation, show debug messages. > +.RE > +.sp > +\fB\-f, \-\-file\fP > +.RS 4 > +Instead of processing all client directories under /proc/fs/nfsd/clients, one can provide a specific > +states file to process. One should make sure that info file resides in the same directory as states file. > +If the info file is not valid or present the fields would be marked as "N/A". > +.RE > +.sp > \fB\-h, \-\-help\fP > .RS 4 > Print help explaining the command line options. > @@ -118,7 +130,19 @@ Inode number | Type | Access | Deny | ip address | Client ID > .fi > .if n .RE > .sp > -\fBnfsdclnts.py \-\-quiet \-\-hostname\fP > +\fBnfsdclnts \-\-file /proc/fs/nfsd/clients/3/states -t open\fP > +.RS 4 > +Process specific states file. > +.RE > +.sp > +.if n .RS 4 > +.nf > +Inode number | Type | Access | Deny | ip address | Client ID | vers | Filename > +33823232 | open | r\- | \-\- | [::1]:757 | 0xc79a009f5eb65e84 | 4.2 | testfile > +.fi > +.if n .RE > +.sp > +\fBnfsdclnts \-\-quiet \-\-hostname\fP > .RS 4 > Hide the header information. > .RE > diff --git a/tools/nfsdclnts/nfsdclnts.py b/tools/nfsdclnts/nfsdclnts.py > index 7370fede..e5f636a2 100755 > --- a/tools/nfsdclnts/nfsdclnts.py > +++ b/tools/nfsdclnts/nfsdclnts.py > @@ -54,10 +54,16 @@ def file_to_dict(path): > client_info[key] = val.strip() > # FIXME: There has to be a better way of converting the info file to a dictionary. > except ValueError as reason: > - print('%s' % reason) > + if verbose: > + print('Exception occured, %s' % reason) > + > + if len(client_info) == 0 and verbose: > + print("Provided %s file is not valid" %path) > return client_info > + > except OSError as reason: > - print('%s' % reason) > + if verbose: > + print('%s' % reason) > > # this function gets the paths from /proc/fs/nfsd/clients/ > # returns a list of paths for each client which has nfs-share mounted. > @@ -159,10 +165,12 @@ def opener(path): > data.append(clientinfo) > return data > except: > - print("Exception occurred, Please make sure %s is a YAML file" %path) > + if verbose: > + print("Exception occurred, Please make sure %s is a YAML file" %path) > > except OSError as reason: > - print('%s' % reason) > + if verbose: > + print('%s' % reason) > > def print_cols(argument): > title_inode = 'Inode number' > @@ -204,11 +212,25 @@ def nfsd4_show(): > help = 'output clients information, --hostname is implied.') > parser.add_argument('--hostname', action = 'store_true', > help = 'print hostname of client instead of its ip address. Longer hostnames are truncated.') > + parser.add_argument('-v', '--verbose', action = 'store_true', > + help = 'Verbose operation, show debug messages.') > + parser.add_argument('-f', '--file', nargs='+', type = str, metavar='', > + help = 'pass client states file, provided that info file resides in the same directory.') > parser.add_argument('-q', '--quiet', action = 'store_true', > help = 'don\'t print the header information') > > args = parser.parse_args() > - paths = getpaths() > + > + global verbose > + verbose = False > + if args.verbose: > + verbose = True > + > + if args.file: > + paths = args.file > + else: > + paths = getpaths() > + > p = mp.Pool(mp.cpu_count(), init_worker) > try: > result = p.map(opener, paths) >