1 #
2 # CDDL HEADER START
3 #
4 # The contents of this file are subject to the terms of the
5 # Common Development and Distribution License (the "License").
6 # You may not use this file except in compliance with the License.
7 #
8 # You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 # or http://www.opensolaris.org/os/licensing.
10 # See the License for the specific language governing permissions
11 # and limitations under the License.
12 #
13 # When distributing Covered Code, include this CDDL HEADER in each
14 # file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 # If applicable, add the following below this CDDL HEADER, with the
16 # fields enclosed by brackets "[]" replaced with your own identifying
17 # information: Portions Copyright [yyyy] [name of copyright owner]
18 #
19 # CDDL HEADER END
20 #
21
22 #
23 # Copyright 2006 Sun Microsystems, Inc. All rights reserved.
24 # Use is subject to license terms.
25 #
26
27 NFS Version 4 Test Client
28 =========================
29
30 The "nfsh" program provides a Tcl environment extended with the
31 following commands:
32
33
34 connect
35
36 [ -p port ] [ -t transport] [-s security mechanisms] <hostname>
37 -> (null)
38
39 Creates an RPC client handle to the named server.
40 By default the connection is established over a
41 TCP connection to port 2049 with AUTH_SYS.
42
43 The -p and -t options can be used to modify the port
44 number or to provide an alternative transport: currently
45 "udp" or "tcp".
46
47 The -s option is used to specify the security mechanisms:
48 currently "sys", "krb5", "krb5i" or "krb5p". The "nfsh"
49 needs to enable the "KRB5=_RPCGSS" flag in the Makefile.master
50 before compilation; and requires RPCSEC_GSS library.
51
52 The connection persists until the script completes, or
53 the "disconnect" command is used, or a new connection
54 is created with "connect".
55
56 disconnect
57
58 (null) -> (null)
59
60 Disconnects a connection established by the "connect"
61 command. If the connection is over TCP, the client
62 will actively drop the TCP connection.
63
64 exit
65 Exit the nfsv4shell.
66
67 compound
68 { op ; op ; ... } -> { {result} {result} ...}
69
70 The compound command accepts a list of compound
71 operations and returns a list of results. The
72 operations are listed below, each with their result.
73 On completion of the compound operation, the Tcl
74 variable "status" is set to the overall status
75 value for the v4 operation - normally "OK".
76 The compound command sets the compound "tag" string
77 to the contents of the Tcl "tag" variable.
78
79 Each op uses the same naming convention as the
80 operation, but with the first character capitalized.
81
82 Currently, the following compound ops are implemented:
83
84 Access
85 { rlmtdxi } -> { supported access }
86
87 The argument is any of the "r,l,m,t,d,x" character,
88 representing the following:
89 r -> ACCESS4_READ
90 l -> ACCESS4_LOOKUP
91 m -> ACCESS4_MODIFY
92 t -> ACCESS4_EXTEND
93 d -> ACCESS4_DELETE
94 x -> ACCESS4_EXECUTE
95 i -> 0x00000100 (illegal access bit)
96
97 The result prints out the supported and the access
98 value returned by the server.
99
100 Close
101 { seqid stateid{seqid other} } -> { stateid{seqid other} }
102
103 This operation requires 2 arguments, the seqid and
104 stateid where stateid is a two fields argument consists
105 of {seqid other} returning by Open op, closes the file
106 with <cfh> and prints out the stateid.
107
108 Commit
109 { offset count } -> { writeverf }
110
111 This operation requires 2 arguments, the offset and
112 the count, which the data to be flushed out.
113
114 The result prints out the write verifier.
115
116 Create
117 { objname {{name val} ...} {s | f | d | l linkdata |
118 b specd1 specd2 | c specd1 specd2}
119 -> { {atomic before after} { {name val} {name val} ... }
120
121 This operation requires 2 arguments. First argument
122 is the objname. The second argument is a single
123 character from the following list:
124 l -> of type NF4LNK
125 b -> of type NF4BLK
126 c -> of type NF4CHR
127 s -> of type NF4SOCK
128 f -> of type NF4FIFO
129 d -> of type NF4DIR
130
131 Some type from the above list need more arguments.
132 Thus, the usage for each type looks like:
133 l -> Create objname l linkdata
134 b -> Create object b specd1 specd2
135 c -> Create object c specd1 specd2
136 s -> Create object
137 f -> Create object
138 d -> Create object
139
140 The result prints out true/false of atomic,
141 before and after ids. The before and after
142 ids are 64-bit values represented as decimal
143 numbers. It also returns the attribute list.
144
145 Delegpurge
146 { clientid } -> (null)
147
148 This operation takes the clientid argument, purges
149 all of the delegations awaiting recovery for a
150 given client.
151
152 The status of the operation will be printed.
153
154 Delegreturn
155 { stateid{seqid other} } -> (null)
156
157 This operation takes the stateid (which is a two
158 fields) argument, returns the delegation represented
159 by the given stateid.
160
161 The status of the operation will be printed.
162
163 Getattr
164 { name name ... } -> { {name val} {name val} ...}
165
166 The argument is a list of attribute names that
167 are to be retrieved. The names are converted
168 to a protocol bitmap.
169
170 The result is a list of attributes, each as a
171 name/value pair. Each name/value pair is presented
172 as a sublist, e.g. "{ type dir }". More complex
173 attribute values are presented as sublists, e.g.
174 "{ time_modify { 1288560 0 }}"
175 Attribute names are string values derived from
176 the protocol spec.
177
178 Getfh
179 (null) -> filehandle
180
181 Returns the value of the current filehandle.
182 Most commonly follows an Lookup.
183 The filehandle value is presented as a
184 hexadecimal string.
185
186 Link
187 { newname } -> { atomic before after }
188
189 The argument is the new name to be created.
190
191 The results prints out true/false of atomic,
192 before and after ids. The before and after
193 ids are 64-bit values represented as decimal
194 numbers.
195
196 Lock
197 { ltype reclaim(T|F) offset length newlock(T|F)
198 stateid{seqid other} lseqid {oseqid clientid owner} }
199 -> { stateid access }
200
201 This operation requires 8 arguments, including
202 the locktype in numeric, with the following:
203 1 - READ_LT
204 2 - WRITE_LT
205 3 - READW_LT ( blocking read )
206 4 - WRITEW_LT ( blocking write)
207
208 the reclaim, which would be a single letter of 'T'
209 (true) or 'F' (false); the offset and length in the
210 file from <cfh> to be locked; the stateid with 2 fields
211 {seqid other}, the lock_seqid; If this is new lock,
212 the open_seqid, clientid and owner are also required.
213
214 If the operation is successful, the stateid will
215 be printed. If the lock is denied, the owner,
216 offset and length of conflicted lock on file.
217
218 Lockt
219 { type clientid owner_val offset length } -> { owner }
220
221 Similar to Lock operation, it takes the following
222 locktype as the first argument:
223 1 - READ_LT
224 2 - WRITE_LT
225 3 - READW_LT ( blocking read )
226 4 - WRITEW_LT ( blocking write)
227
228 the other arguments includes clientid, the owner
229 name and the offset and length of the lock to be
230 tested.
231
232 If the operation is successful, the stateid will
233 be printed. If the lock is denied, the owner,
234 offset and length of conflicted lock on file.
235
236 Locku
237 { type seqid stateid{seqid other} offset length }
238 -> { stateid }
239
240 Similar to Lockt operation, it takes the following
241 locktype as the first argument:
242 1 - READ_LT
243 2 - WRITE_LT
244 3 - READW_LT ( blocking read )
245 4 - WRITEW_LT ( blocking write)
246
247 the other arguments includes lock_seqid, stateid with
248 2 fields {seqid other}, the offset and length in the
249 file to be unlocked.
250
251 If the operation is successful, the stateid will
252 be printed. If the lock is denied, the stateid
253 will be printed.
254
255 Lookup
256 { name } -> (null)
257
258 Accepts the component name to be looked and sets the
259 current filehandle to it. The result status will be
260 returned.
261
262 Lookupp
263 (null) -> (null)
264
265 Returns the result status.
266
267 Nverify
268 { {name val} {name {v1 v2}} ... } -> (null)
269
270 Accepts a list of attributes in the form of
271 {name val} pairs. Returns the result status.
272
273 Open
274 { seqid access deny {clientid owner}
275 {opentype createmode {{name val} {name val}...} | createverf}
276 {claim {filename | delegate_type | delegate_stateid filename}}
277 }
278 -> { stateid{seqid other} cinfo rflags {{name val} ...}
279 delegation }
280
281 This operation takes 6 arguments with some
282 arguments have different fields. Basically
283 it needs:
284 the open_seqid
285 and the share_access (1-READ, 2-WRITE, 3-ACCESS_BOTH)
286 and the share_deny (0-DENY_NONE, 1-DENY_READ,
287 2-DENY_WRITE, and 3-DENY_BOTH)
288 and { clientid owner } (the owner pair)
289 and one of the following open_type(s):
290 { 0 junkfield1 junkfield2 } (NOCREATE)
291 { 1
292 { 0 { {name val} {name val} ... } } (CREATE/UNCHECKED)
293 { 1 { {name val} {name val} ... } } (CREATE/GARDED)
294 { 2 createverf } } (CREATE/EXCLUSIVE)
295 } (CREATE)
296 and one of the following claim_type(s):
297 { 0 filename } (CLAIM_NULL)
298 { 1 delegate_type } (CLAIM_PREVIOUS)
299 { 2 {filename delegate_stateid } } (CLAIM_DELEGATE_CUR)
300 { 3 filename } (CLAIM_DELEGATE_PREV)
301 arguments.
302
303 The results returned from server will be printed
304 based on the argument, including status, stateid
305 {seqid other}, change_info, rflags, attributes and the
306 delegation_type.
307
308 See "Examples" section for the compound sample of Open call.
309
310 Openattr
311 { createdir } -> (null)
312
313 It takes an argument of createdir, "T" (true) or "F"
314 (false) value; sets the current filehandle of the named
315 attribute directory associated with the current filehandle.
316
317 Open_confirm
318 { open_stateid{seqid other} seqid } -> { stateid }
319
320 This operation takes the open_stateid and the sequence id
321 confirms the stateid and owner.
322
323 If it is successful, the stateid will be printed.
324
325 Open_downgrade
326 { stateid{seqid other} seqid access deny }
327 -> { stateid{seqid other} }
328
329 This operation takes the stateid, sequence id
330 access and deny, 4 arguments; and to reduce
331 the Open file access.
332
333 If it is successful, the stateid will be printed.
334
335 Putfh
336 { filehandle } -> (null)
337
338 Accepts a hexadecimal encoded filehandle as
339 and argument and sets the current filehandle.
340
341 Putpubfh
342 (null) -> (null)
343
344 Sets the current filehandle to the public
345 filehandle.
346
347 Putrootfh
348 (null) -> (null)
349
350 Sets the current filehandle to the root
351 filehandle.
352
353 Read
354 { stateid{seqid other}, offset, count } -> { eof len data }
355
356 It takes 3 arguments, the open_stateid (with 2 fields,
357 seqid and other), the offset and the length to read.
358
359 The result prints out the true/false value of eof,
360 the len and the data. Right now the data is printed
361 as binary string.
362
363 Readdir
364 { cookie verifier dircount maxcount { name name ...} }
365 -> { verifier { { cookie name
366 { {name val} {name val} ...} } ... } }
367
368 One of the more complex compound ops. Readdir op
369 takes 5 arguments. The cookie and verifier values
370 are given as hexadecimal strings. On the first
371 call a cookie of "0" is used. The final argument
372 is a list of attributes to be returned for
373 each directory entry.
374
375 The result begins with a verifier, followed by
376 a list of entries. Each entry begins with the
377 entry cookie followed by the entry name. The
378 third element of each entry is a list of attribute
379 names and values - as would be returned by Getattr.
380 The final value returned is a boolean eof value.
381 if eof is set to "true" then the end of the
382 directory has been reached. The readdir.tcl
383 script shows an example of readdir use.
384
385 Readlink
386 (null) -> { linkdata }
387
388 Reads the linkdata pointed by the <cfh>;
389 Returns the result status and linkdata.
390
391 Release_lockowner
392 { clientid lock_owner } -> { null }
393
394 It takes the clientid and lock_owner value to
395 the server to release the state related to this
396 lockowner. The result status will be printed.
397
398 Remove
399 { target } -> (null)
400
401 Accepts the target name to be removed.
402 Returns the result status.
403
404 Rename
405 { oldname newname } ->
406 { source { atomic before after }
407 target { atomic before after }}
408
409 This operation requires 2 arguments as string,
410 oldname and newname, which the oldname will be
411 renamed to the newname.
412
413 The results prints out true/false of atomic,
414 before and after ids. The before and after
415 ids are 64-bit values represented as decimal
416 numbers.
417
418 Renew
419 { clientid } -> (null)
420
421 This operation takes the clientid to renew the
422 leased holds at the server.
423
424 Restorefh
425 (null) -> (null)
426
427 Restore the saved filehandle to the current
428 filehandle.
429
430 Savefh
431 (null) -> (null)
432
433 Save the current filehandle.
434
435 Secinfo
436 { name } -> { sec_favor_info }
437
438 Given the filename, this operation returns the
439 security mechanisms information based on the
440 favor. If the favor is RPCSEC_GSS, the security
441 triple of the rpc_gss_svc will be printed out.
442
443 Setattr
444 { stateid{seqid other} { {name val} {name {v1 v2}} ... } }
445 -> { attr_name attr_name }
446
447 This operation sends the request to server
448 to set the attributes listed in the {name val}
449 pairs. It requires 2 arguments. The first
450 argument is the stateid with 2 fields (seqid other).
451 The second argument is the sublist of {name val}
452 pairs of the attributes to be set. The "name" must
453 be all lower case and the same names as defined in
454 the spec. If the "val" portion has two values,
455 e.g. the seconds and nseconds in nfstime4
456 structures for time attribute, the { } must be
457 used. An example of the Setattr command can be:
458 Setattr 0 { {mode 0666} {owner v4user}
459 {time_modify_set {sec nsec}} }
460
461 You may use the "clock seconds" TCL command
462 to get the current time second value.
463
464 The result prints the names of the bits
465 that are set by the server.
466
467 Setclientid
468 { verifier id_string {cb_prog netid addr} }
469 -> { clientid setclientid_confirm }
470
471 Given the verifier and client id_string pair,
472 this operation sets the client id.
473
474 Note: the callback function for delegation
475 has not yet been implemented. The callback
476 cb_program is currently set to 0, and same
477 as the callback_ident.
478
479 Setclientid_confirm
480 { clientid setclientid_confirm } -> (null)
481
482 Given the clientid and the setclientid_confirm
483 verifier returned by the server from the
484 Setclientid call as the argument, this operation
485 confirms the clientid.
486
487 Verify
488 { {name val} {name {v1 v2}} ... } -> (null)
489
490 Accepts a list of attributes in the form of
491 {name val} pairs. Returns the result status.
492
493 Write
494 { stateid{seqid other} offset stable_how datatype data }
495 -> { count committed verifier }
496
497 Accepts regular list of 5 arguments, where the
498 "stable_how" is asking for one character with
499 the following representation:
500 u -> UNSTABLE
501 d -> DATA_SYNC
502 f -> FILE_SYNC
503 e.g. "Write {0 0} 2 f a {data to write}" means to
504 write (to cfh) the data starting at offset=2,
505 and stateid={0 0} and file_sync the 'ascii' data.
506
507 Currently it takes only ascii string for the data.
508 Hex string will be supported in the future.
509
510 The result prints out the count, committed level
511 and the verifier returned from the server.
512
513 Note: the writing of hex (UTF8) characters has not
514 yet been implemented. Currently it only works for
515 ASCII characters.
516 -----------------------------------------
517
518 Other commands
519 --------------
520
521 If the "tclprocs" TCL procedures scripts is included
522 in the currently directory, all procedures/commands
523 can be freely used in 'nfsh'. Please see the tclprocs
524 script for the available procedures.
525
526 -----------------------------------------
527
528 Examples
529 --------
530
531 There are tcl scripts under 'scripts' directory which
532 show how the tool is used in batch mode, including:
533
534 tclprocs - commonly used TCL procedures
535 attributes - prints the attributes of a file/dir
536 ckerrors - checks server error responses of ops
537 lock_neg - test some irregular conditions of Lock/Open/Close
538 opensimple - simple test for open ops
539 pathhandles - evaluates a path and prints FH
540 readdir - reads a directory
541 setattr - set attributes on a file
542 tcopy - local-to-remote or remote-to-local file copy
543 test - a test for some basic ops
544 trylock - test Open/Lock/Locku/Lockt/Close operations
545 walk - walks down a directory
546
547 For example:
548
549 - Output of the "trylock" script:
550 $./trylock wnfspc /export/test
551
552 Setclientid 103129416501010 16746 ...
553 Res: {Setclientid OK {3d77d559000000e2 0000000000000000}}
554
555 Setclientid_confirm 3d77d559000000e2 0000000000000000 ...
556 Res: {Setclientid_confirm OK}
557
558 Open to create tfile.16746 ...
559 Open 1 3 0 {3d77d559000000e2 16746} {1 0 {{mode 0664} {size 88}}} {0 tfile.16746}
560 Res: {Putfh OK} {Open OK {0 3D77D559000000E800000000} {{atomic false} {before 3d784b4514a46c80} {after 3d784bda1f426160}} 6 {size mode} NONE} {Getfh OK 01D8000700000002000A0000000004EF2A51238A000A00000000000C0012BEA20000000000000000} {Getattr OK {{size 88} {mode 664}}}
561
562 Lock 2 F 0 1024 T (0 3D77D559000000E800000000) 1 (2 3d77d559000000e2 16746)
563 Res: {Putfh OK} {Lock OK {1 3D77D559400000E800000080}}
564
565 first LOCKT with owner(3d77d559000000e2 fake_owner) of region 0-1024
566 Res: {Putfh OK} {Lockt DENIED {0 1024 2} {3d77d559000000e2 16746}}
567
568 second LOCKT with owner(3d77d559000000e2 fake_owner) of region 1025-2048
569 Res: {Putfh OK} {Lockt OK}
570
571 third LOCKT with owner(3d77d559000000e2 16746) of region 0-1024
572 Res: {Putfh OK} {Lockt OK}
573
574 Locku 2 2 (1 3D77D559400000E800000080) 0 1024
575 Res: {Putfh OK} {Locku OK {2 3D77D559400000E800000080}}
576
577 forth LOCKT with owner(3d77d559000000e2 fake_owner) of region 0-1024
578 Res: {Putfh OK} {Lockt OK}
579
580 Final Close 2 (0 3D77D559000000E800000000) ...
581 Res: {Putfh OK} {Close OK {1 3D77D559000000E800000000}}
582
583 Open with/non-CREATE tfile.16746 ...
584 Open 2 3 0 {3d77d559000000e2 16746} {0 0 {{mode 0664} {size 88}}} {0 tfile.16746}
585 Res: {Putfh OK} {Open OK {0 3D77D559000000E900000000} {{atomic true} {before 3d784bda1f6f7470} {after 3d784bda1f6f7470}} 6 {} NONE} {Getfh OK 01D8000700000002000A0000000004EF2A51238A000A00000000000C0012BEA20000000000000000}
586
587 Final Close 2 (0 3D77D559000000E900000000) ...
588 Res: {Putfh OK} {Close OK {1 3D77D559000000E900000000}}
589
590 Remove tfile.16746 ...
591 Res: {Putfh OK} {Remove OK {{atomic false} {before 3d784bda1f426160} {after 3d784bda26ec0128}}}
592
593
594 - Try another script "setattr":
595 $ setattr javanfs2 /export/test
596 Attributes Before Setattr (at Fri Jan 18 12:01:37 PST 2002):
597 File size = 0
598 Mode bits = 640
599 Owner = tuser1@eng.sun.com
600 Group = staff@eng.sun.com
601 Access time = 1011383961 230000000 - Fri Jan 18 11:59:21 PST 2002
602 Modified time = 1011383961 230000000 - Fri Jan 18 11:59:21 PST 2002
603 Now sleep for 30 seconds ...
604 New attributes after Setattr (at Fri Jan 18 12:02:08 PST 2002):
605 File size = 8888
606 Mode bits = 765
607 Owner = tuser1@eng.sun.com
608 Group = staff@eng.sun.com
609 Access time = 1011383910 0 - Fri Jan 18 11:58:30 PST 2002
610 Modified time = 1011383991 309992000 - Fri Jan 18 11:59:51 PST 2002
611 $
612
613
614
615 The tool can also be used interactively from command line.
616 For example:
617
618 $ nfsh
619 % connect krbsec3
620 % compound {Putrootfh; Lookup {export v4}; Getattr {type}}
621 {Putrootfh OK} {Lookup OK} {Getattr OK {{type dir}}}
622 %
623 % set fh [ get_fh {export v4 dir1} ]
624 0080000700000002000A000000005900099ACD63000A0000000016406A35C71700000000
625 %
626 % set res [ compound {Putfh $fh; Readdir 0 0 1024 1024 {type size}} ]
627 {Putfh OK} {Readdir OK 0000000000000000 {{0000000000000028 file1
628 {{type reg} {size 30}}} {0000000000000038 dir2 {{type dir} {size 512}}}
629 {000000000000004C file.empty {{type reg} {size 0}}} {0000000000000060
630 file_noperm {{type reg} {size 30}}} {0000000000000200 file.bin
631 {{type reg} {size 18204}}}} true}
632 %
633 % prn_dirlist [ lindex [lindex $res 1] 3 ]
634 file1
635 File type = file
636 File size = 30
637 dir2
638 File type = dir
639 File size = 512
640 file.empty
641 File type = file
642 File size = 0
643 file_noperm
644 File type = file
645 File size = 30
646 file.bin
647 File type = file
648 File size = 18204
649 %
650 % disconnect
651 % exit
652
653
654 Results can also be verified and formatted with TCL
655 commands using the scripts.
656
657
658 Here is a simple example for the Open call to create
659 a file called "file.2" with mode=0644 under the sun-8 directory:
660
661 $ nfsh
662 % connect -t udp wnfspc
663 % compound {Setclientid 188888 aowner {0 0 0}}
664 {Setclientid OK {3d77d559000000e3 0000000000000000}}
665 % compound {Setclientid_confirm 3d77d559000000e3 0000000000000000}
666 {Setclientid_confirm OK}
667 % set dfh [get_fh {export test}]
668 01D8000700000002000A00000000000C0012BEA2000A00000000000C0012BEA20000000000000000
669 % set res [compound {Putfh $dfh; Open 1 3 0 {3d77d559000000e3 aowner} {1 0 {{mode 0644}}} {0 file.2}; Getfh}]
670 {Putfh OK} {Open OK {0 3D77D559000000EA00000000} {{atomic false} {before 3d784bda26ec0128} {after 3d784d1405223968}} 6 {mode} NONE} {Getfh OK 01D8000700000002000A00000000091A3143D7C6000A00000000000C0012BEA20000000000000000}
671 % set stateid [lindex [lindex $res 1] 2]
672 0 3D77D559000000EA00000000
673 % set fh [lindex [lindex $res 2] 2]
674 01D8000700000002000A00000000091A3143D7C6000A00000000000C0012BEA20000000000000000
675 % compound {Putfh $fh; Open_confirm $stateid 2}
676 {Putfh OK} {Open_confirm OK {0 3D77D559000000EA00000000}}
677 %
678
679
680 Note - we can use variables inside NFS operation's parameters. Actually, this
681 shell support all normal TCL substitutions (backslash, variable and command).
682
683 -----------------------------------------
684 Variables
685 ---------
686
687 The client uses sets some Tcl variables:
688
689 nfsh_version
690 The current version of nfsv4shell
691 tool. If "Unknown" is returned,
692 the NFSH_VERS is not set at compile
693 time.
694
695 status
696 The status value returned by a
697 compound operation. It will be
698 "OK" if the compound op completed
699 successfully. Otherwise, it will
700 be the error code. The error code
701 is the same as the protocol spec
702 with the "NFS4ERR_" prefix removed,
703 e.g. "STALE".
704 tag
705 If set, the tag string will be used
706 as the compound tag. The variable
707 is set to the returned tag (in case
708 the server changed it).
709
710 opcount
711 A count of the number of compound
712 ops that were successfully executed
713 by the server.
714
715
716