|
|
1.1 ! root 1: .so ../ADM/mac ! 2: .XX netb 513 "A Look at the Ninth Edition Network File System" ! 3: .nr dP 2 ! 4: .nr dV 3p ! 5: .nr tP 1 ! 6: .nr tV 1p ! 7: .nr Hs 5 ! 8: .TL M10200 40125-100 ! 9: A Look at the Ninth Edition Network File System ! 10: .AU sar SF XT9112200 x6084 5-121 attunix!sar ! 11: Stephen Rago ! 12: .AI ! 13: .MH ! 14: .AB ! 15: The protocol used for the network file system in Research ! 16: .UX ! 17: has evolved since its original design and implementation. This paper describes the ! 18: current version of the protocol (NETB), including the semantics for both the client ! 19: and the server. ! 20: .AE ! 21: .2C ! 22: .NH 1 ! 23: Introduction ! 24: .PP ! 25: In Version 8 of the ! 26: .UX ! 27: operating system, Peter Weinberger* ! 28: .FS ! 29: .nf ! 30: * ! 31: .ps 6 ! 32: .ft H ! 33: .tr x. ! 34: .tr - ! 35: .cs H 5 ! 36: .vs 8u ! 37: -------------------xxxxxx-x--------------------- ! 38: -----------------xxxxxxxxxxxxx------------------ ! 39: ----------------xxxxxxx-xxxxxxxx---------------- ! 40: ---------------xx-xxxxxxx-xxxxxxxx-------------- ! 41: ---------------xxxx-xxxxxxxxx-x-xxx------------- ! 42: --------------x---------xxxxxxxxxxxxx----------- ! 43: --------------x----------xxxxxxxxxxxxxxxx------- ! 44: ---------------------------xxxxx-xxxxxx--------- ! 45: ------------xx-------------xxxxxxxxxxxxxxx------ ! 46: ---------------------------x-x-xxxxxxxxxxx------ ! 47: ----------xx---------------xxxxxxxxxxxxxxxxx---- ! 48: ---------xxx----------------xxxxxxxxxxx-x-xx---- ! 49: --------xx-------------------xxxxxxxxxxxxxxxx--- ! 50: --------xxx------------------xxxxxxxxxxxxxx-x--- ! 51: -------xxxx-------------------xxxxxxxxxxxxxxx--- ! 52: ------xxxx---------------------xxxxxxxxxxxxxx--- ! 53: ------xxxxx--------------------xxxxxxxxxxxxxx--- ! 54: -----xxxxx----x-x---------------xxxxxxxxxxxx---- ! 55: ----xxxxxxxxx-x-xxxxx-----xxxxxxx-xxxxxxxxxxx--- ! 56: ----xxxxxxx------xxxxx---xx--xxxxxxxxxxxxxxxx--- ! 57: ---xxxxxxxxx---xxxx-xxxxxxxxx--x-xxxxxxxxxxxx--- ! 58: ---xxxxxxxxx-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx--- ! 59: ---xxxxxxxxx-x-xx-x--x--xxxxxxxxxxxxxxxxxxxxx--- ! 60: ---xxxxxxx-x------x--x---xxxxxxxxxxxxxxxxxxx---- ! 61: ----xxxxxxx-----x--------x---x-xxxxxxxxxxxxx---- ! 62: ---xxxxxx-x---------x----xxx------xxxxxxxxxx---- ! 63: ------xx--x--------------xx-----xx-xxxxxxxx----- ! 64: ----x-xxx----------x------xx-------xxxxxx------- ! 65: -------xx------x-xx--------xxxxxxxxx-xxxx------- ! 66: --------x----x-x-x-------x-xx-x--x-xxxxx-------- ! 67: --------------------x-xxxxxxx-xxxxxxxxxx-------- ! 68: -------xx----------xxxxxxxx-x---xxx-xxx--------- ! 69: ------xxx------------xxxxxxx--x-x-xxxxx--------- ! 70: -------xx-----x-------xxxx-x-x-xxxx-xxxxxx------ ! 71: --------x----------------xxx-x-x-xxxxxxxx------- ! 72: -------xxx-----xxx-x-x-xxx-xxx-x-x--xxxxx------- ! 73: --------xx-----x-x-x-xxxxxxxxxxxxxxxxxxxx------- ! 74: ---------x----------------xxx--x-xxxxxxx-------- ! 75: ---------xx--------------xx-x-xxxx--xxx--------- ! 76: -------------x-----xxxxxxxx-x-xx-xx------------- ! 77: ---------------------xxxxxxxxxxxxxxxx----------- ! 78: --------------x------------x-x-xx-x------------- ! 79: -------------------------x-x-xxxxx-------------- ! 80: --------------x-----------xxxxxx-x-------------- ! 81: ----------------x--------x--x-xxxx-------------- ! 82: --------------x-x-xxx-xxxxxxxxx-x--------------- ! 83: ----------------x---xxxxxxxxx-xxxx-------------- ! 84: ---------------x-xxxx-x-x-xxxxxxxx-------------- ! 85: .tr -- ! 86: .tr xx ! 87: .fi ! 88: .vs ! 89: .ps ! 90: .ft ! 91: .FE ! 92: wrote a network file system that enabled files to be shared between machines ! 93: connected by a network. When I asked someone if there was a paper describing ! 94: it, they said, "yeah, but it's only an abstract." I thought they were speaking ! 95: figuratively. They were speaking literally |reference(weinberger neta). ! 96: Hence, as I began studying the ! 97: Version 9 network file system in preparation for porting it to UNIX System V Release 4.0, ! 98: it was suggested that I also document what it does. ! 99: This paper describes the inner workings of Weinberger's network file system. ! 100: .PP ! 101: The UNIX Version 8 network file system, known as NETA, provided remote file access ! 102: for the Computing Science Research Center. It has evolved over the years and ! 103: in its current form, runs on UNIX Version 9 and is now called NETB. ! 104: .NH 1 ! 105: Architecture ! 106: .PP ! 107: The client side is implemented in the kernel as a file system switch entry. The server ! 108: side is implemented as a user-level process. There is one server process ! 109: per client machine. ! 110: .PP ! 111: The server's name is ! 112: .I zarf . ! 113: (A zarf is an ornamental metal holder for a hot coffee cup.) ! 114: .PP ! 115: By convention, each machine ! 116: mounts other machines' file systems on mount points under ! 117: .CW /n . ! 118: .NH 1 ! 119: Client Startup ! 120: .PP ! 121: The client side of the network file system includes a command/daemon (\fIsetup\fP) ! 122: to set up ! 123: connections and a file system (NETB) to translate file system operations into ! 124: streams messages. \fISetup\fP makes a connection to the remote machine's server and ! 125: sends it information about the protocol version, client user ids, and client group ids. ! 126: Then it mounts the connection in the file system name space using NETB. ! 127: .PP ! 128: In the daemon mode, the command is started without any arguments. It reads the ! 129: file ! 130: .CW /usr/netb/friends ! 131: to decide which systems to mount. ! 132: Every 60 seconds the daemon checks the remotely mounted file systems to see if they are ! 133: still available. It also checks to see if the friends file has changed. If any friendly file ! 134: system is unavailable, then an attempt is made to mount it. ! 135: The format of the friends file is a list of entries containing a \fInetname\fP, ! 136: a \fIcall_arg\fP, a \fImount_point\fP, ! 137: a \fIprotocol\fP, a \fIunique_id\fP, a \fIdebug_flag\fP, and a \fIusername\fP, ! 138: separated by white space. ! 139: .PP ! 140: The \fInetname\fP is the network name (see ! 141: .I ipc (3)) ! 142: of the server machine. ! 143: The \fImount_point\fP is the location in the local file system where the remote file ! 144: system is to be mounted. ! 145: The \fIprotocol\fP indicates how the connection is to be placed. Protocol ! 146: .CW d ! 147: uses the ! 148: default network ! 149: .CW dk ! 150: (Datakit\(rg), expecting the service to be named ! 151: .CW fsb ! 152: and ignoring the ! 153: \fIcall_arg\fP. Protocol ! 154: .CW t ! 155: uses TCP, starting the service given by the ! 156: \fIcall_arg\fP using the ! 157: .I rsh ! 158: protocol. ! 159: The \fIunique_id\fP is an integer between 0 and 255 that distinguishes the connections ! 160: and must be unique among all active remote file systems. ! 161: The \fIdebug_flag\fP determines how much information gets written to the log files. ! 162: The \fIusername\fP is an optional field that provides the name of the calling process ! 163: making the mount. The default user name is ! 164: .CW daemon . ! 165: .PP ! 166: In command mode, the remote file system is mounted, but no daemon is created. ! 167: The arguments to the command are the same as the parameters in the friends file. ! 168: .NH 1 ! 169: Server Startup ! 170: .PP ! 171: The server expects to be started by the remote execution facility. ! 172: As such, file descriptor zero is attached to the network connection. ! 173: First, the server tries to identify the client. The method it uses depends ! 174: on the environment in which it is running. ! 175: On 4BSD systems, it does this by calling ! 176: .I getpeername (2). ! 177: On Version 9 (and System V) ! 178: systems, it does this ! 179: by checking the environment variables ! 180: .CW CSOURCE ! 181: and ! 182: .CW DKSOURCE .* ! 183: .FS ! 184: * CSOURCE is set by the remote execution facility when a service is invoked. ! 185: DKSOURCE is set by an older version of the remote execution facility. ! 186: .FE ! 187: The server then changes directory to ! 188: .CW /usr/netb . ! 189: If this fails, the server ! 190: changes directory to ! 191: .CW /tmp . ! 192: A log file, ! 193: .CW zarf.log , ! 194: is created. ! 195: .PP ! 196: The first network message read by the server is 16 bytes long. ! 197: The format is: ! 198: .KS ! 199: .ps -\n(tP ! 200: .vs -\n(tVu ! 201: .TS ! 202: center,box; ! 203: a | a . ! 204: byte use ! 205: = = ! 206: 0 maximum client message size ! 207: _ _ ! 208: 1 client device number ! 209: _ _ ! 210: 2 protocol type ! 211: _ _ ! 212: 3 debug flag ! 213: _ _ ! 214: 4-15 unused ! 215: .TE ! 216: .ps +\n(tP ! 217: .vs +\n(tVu ! 218: .KE ! 219: The maximum message size is currently set to 5K bytes. In the message, ! 220: the size is expressed in units of 1KB. The client can change the maximum ! 221: message size via an \fIioctl\fP (see \(sc5.1.2). ! 222: The device number is the major device number ! 223: of the client. ! 224: It is the same as the unique id obtained from the friends file. ! 225: The server creates device numbers using this major number. The minor number ! 226: is created on the fly and is unique among all device numbers the server has seen since ! 227: it started. ! 228: .PP ! 229: The protocol type is expressed as an ASCII character. ! 230: The currently supported protocols are ! 231: .CW t ! 232: (TCP byte streams) and ! 233: .CW d ! 234: (Datakit messages). ! 235: The debug flag determines the detail of the messages that get written to the log file. ! 236: .PP ! 237: The server responds to the first message with a one-byte response ! 238: containing the value 1. ! 239: .PP ! 240: The second network message read is \fImax_message_size\fP bytes long. ! 241: It contains the user ids from the client machine, ! 242: obtained from the client's password file. The entries are in ASCII, with the last entry ! 243: followed by a NULL. ! 244: The format of each entry in the message is: ! 245: .P1 ! 246: user_name user_id\n ! 247: .P2 ! 248: The server responds to this message with a one-byte response containing the value 2. ! 249: .PP ! 250: The user id message is parsed and a table is built mapping client user ids to server ! 251: user ids. Client and server hash lists map user ids to indices into the mapping table ! 252: to speed lookup operations. ! 253: .PP ! 254: The third network message read is also \fImax_message_size\fP bytes long. ! 255: It contains the group ids from the client machine, ! 256: obtained from the client's group file. The entries are in ASCII, with the last entry ! 257: followed by a NULL. ! 258: The format of each entry in the message is: ! 259: .P1 ! 260: group_name group_id\n ! 261: .P2 ! 262: The server responds to this message with a one-byte response containing the value 3. ! 263: .PP ! 264: The group id message is parsed and a table is built mapping client group ids to server ! 265: group ids. Client and server hash lists map group ids to indices into the mapping table ! 266: to speed lookup operations. ! 267: .PP ! 268: If there are too many user or group ids to fit in the message, the client does not ! 269: attempt to send the message to the server. Rather, the client closes the connection ! 270: and the server exits. ! 271: .PP ! 272: If everything is successful, the ! 273: server opens its root and creates an internal file entry mapping ! 274: its root to the client's mount point. The rest of the time is spent in a loop ! 275: servicing client requests. ! 276: .NH 1 ! 277: File System Operations ! 278: .PP ! 279: The file system operations in Version 9 are: ! 280: .nr xx \\n(PDu ! 281: .nr PD 0.1v ! 282: .IP \fBmount\fP 8 ! 283: mount and unmount the file system ! 284: .IP \fBput\fP ! 285: release an inode ! 286: .IP \fBget\fP ! 287: get an inode ! 288: .IP \fBfree\fP ! 289: free the disk space associated with the inode ! 290: .IP \fBupdat\fP ! 291: update the times on the inode ! 292: .IP \fBread\fP ! 293: read from the inode's file ! 294: .IP \fBwrite\fP ! 295: write to the inode's file ! 296: .IP \fBstat\fP ! 297: return the statistics on the inode's file ! 298: .IP \fBtrunc\fP ! 299: truncate the inode's file ! 300: .IP \fBnami\fP ! 301: parse a pathname ! 302: .IP \fBioctl\fP ! 303: file system-specific ioctls and device ioctls ! 304: .IP \fBopen\fP ! 305: open a device ! 306: .IP \fBdirread\fP ! 307: read a directory ! 308: .nr PD \\n(xxu ! 309: .PP ! 310: In the network file system, file system operations ! 311: consist of request/response messages. The client sends a message ! 312: to the server and blocks until the response comes back. ! 313: For historical reasons, the messages follow VAX-style byte ordering and ! 314: all network message structures are multiples of 8 bytes. ! 315: Messages sent from the client to the server are of the following format: ! 316: .KS ! 317: .ps -\n(tP ! 318: .vs -\n(tVu ! 319: .TS ! 320: center,box; ! 321: a . ! 322: message header ! 323: (struct sendb) ! 324: _ ! 325: optional ! 326: operation-specific ! 327: header ! 328: _ ! 329: optional ! 330: user data ! 331: .TE ! 332: .ps +\n(tP ! 333: .vs +\n(tVu ! 334: .KE ! 335: .PP ! 336: Throughout the rest of this paper, C structure definitions are used to describe ! 337: network messages. Elements of type \f(CWchar\fP are one byte long, elements of type ! 338: \f(CWshort\fP are two bytes long, and elements of type \f(CWlong\fP are four bytes long. ! 339: Fields are included to remove any ambiguity regarding structure padding. ! 340: .PP ! 341: The request message header is defined by a \f(CWstruct sendb\fP: ! 342: .P1 ! 343: struct sendb { ! 344: char version; ! 345: char cmd; ! 346: char flags; ! 347: char rsva; ! 348: long trannum; ! 349: long len; ! 350: long tag; ! 351: short uid; ! 352: short gid; ! 353: long rsvb; ! 354: } ! 355: .P2 ! 356: .PP ! 357: \f(CWversion\fP indicates which version of the protocol is in use. ! 358: \f(CWcmd\fP indicates the operation requested. ! 359: \f(CWrsva\fP and \f(CWrsvb\fP are pad fields. ! 360: \f(CWtrannum\fP is the transaction number for the message. ! 361: \f(CWlen\fP is the length of the message in bytes, including the headers and data. ! 362: \f(CWtag\fP is used to identify the file to which the operation pertains. ! 363: The tags are composed of the device number where the file lives shifted left 16 bits, ! 364: ORed with the inode number. ! 365: \f(CWuid\fP and \f(CWgid\fP are the user and group ids of the client generating the operation, ! 366: respectively. ! 367: .PP ! 368: Messages sent from the server to the client are of the following format: ! 369: .KS ! 370: .ps -\n(tP ! 371: .vs -\n(tVu ! 372: .TS ! 373: center,box; ! 374: a . ! 375: message header ! 376: (struct recvb) ! 377: _ ! 378: optional ! 379: operation-specific ! 380: header ! 381: _ ! 382: optional ! 383: user data ! 384: .TE ! 385: .ps +\n(tP ! 386: .vs +\n(tVu ! 387: .KE ! 388: .PP ! 389: The response message header is defined by a \f(CWstruct recvb\fP: ! 390: .P1 ! 391: struct recvb { ! 392: long trannum; ! 393: short errno; ! 394: char flags; ! 395: char rsvd; ! 396: long len; ! 397: long fsize; ! 398: } ! 399: .P2 ! 400: The server copies \f(CWtrannum\fP from the request message so the client can ! 401: match up responses with requests. ! 402: \f(CWerrno\fP is the error number if the operation failed, or 0 on success. ! 403: The \f(CWflags\fP field is used to indicate special conditions for certain operations. ! 404: \f(CWrsvd\fP is a pad field. \f(CWlen\fP is the ! 405: length of the message, including the headers and data. \f(CWfsize\fP is the file ! 406: size and is set only by the read, write, and dirread file system operations. ! 407: .PP ! 408: The following sections describe some details of the file system operations ! 409: for the network file system, including the content of messages exchanged between the client ! 410: and the server. There is no ! 411: .I nbopen () ! 412: entry point. ! 413: Instead, a stub (\fInullopen\fP) is used, which is provided by the system. ! 414: This is because \fIzarf\fP opens the file as part of parsing the pathname, so no extra ! 415: protocol is necessary. ! 416: \fIZarf\fP does not fully support access to devices. ! 417: .NH 2 ! 418: nbmount ! 419: .PP ! 420: When mounting the file system, the \fIflag\fP argument to ! 421: .I fmount (2) ! 422: contains the ! 423: device number for the remote file system. ! 424: The file descriptor passed to \fIfmount\fP is the client's end of the network ! 425: connection to the server. ! 426: The client side creates an inode for the root of the file system with this information. ! 427: .PP ! 428: When unmounting the file system, all active inodes on that file system ! 429: are converted to inodes in the error file system (errfs). This will cause all further ! 430: operations on them to fail, until the inodes are freed. ! 431: .NH 2 ! 432: nbget ! 433: .PP ! 434: The information ! 435: in the inode is filled in by \fInbget\fP, called from \fInami\fP. ! 436: For the root inode, it can be called from \fInbmount\fP, so it ! 437: constructs the information by hand. However, for all other inodes, it fills ! 438: in the information with the cached data obtained from the previous nami message. ! 439: The nami cache is one entry long. ! 440: .X "PARM CT 70 ! 441: .NH 2 ! 442: nbput ! 443: .PP ! 444: If the inode is marked ICHG, \fInbupdat\fP is called. ! 445: Then a NBPUT message is sent ! 446: to the server. The format of the message is: ! 447: .KS ! 448: .ps -\n(tP ! 449: .vs -\n(tVu ! 450: .TS ! 451: center,box; ! 452: c s ! 453: a | a . ! 454: NBPUT request ! 455: = ! 456: sendb value ! 457: _ _ ! 458: version 2 ! 459: cmd NBPUT ! 460: flags 0 ! 461: rsva unused ! 462: trannum transaction number ! 463: len sizeof(struct sendb) ! 464: (24 bytes) ! 465: tag tag of inode ! 466: uid uid of client ! 467: gid gid of client ! 468: rsvb unused ! 469: .TE ! 470: .ps +\n(tP ! 471: .vs +\n(tVu ! 472: .KE ! 473: .PP ! 474: For this operation, the server will search through its list of open files, matching on ! 475: \f(CWtag\fP. ! 476: If the file is found and it is not the root, then the server closes the file and invalidates ! 477: its entry in the list. The response sent back to the client is: ! 478: .KS ! 479: .ps -\n(tP ! 480: .vs -\n(tVu ! 481: .TS ! 482: center,box; ! 483: c s ! 484: a | a . ! 485: NBPUT response ! 486: = ! 487: recvb value ! 488: _ _ ! 489: trannum transaction number ! 490: errno error number or 0 ! 491: flags 0 ! 492: rsvd unused ! 493: len sizeof(struct recvb) ! 494: (16 bytes) ! 495: fsize 0 ! 496: .TE ! 497: .ps +\n(tP ! 498: .vs +\n(tVu ! 499: .KE ! 500: .X "PARM CT 50 ! 501: .NH 2 ! 502: nbfree ! 503: .PP ! 504: \fINbfree\fP is just a stub that doesn't do anything. Since the server removes ! 505: the disk space associated with a file during the nami NI_DEL and NI_RMDIR ! 506: operations, there is no need to do anything in \fInbfree\fP. ! 507: .NH 2 ! 508: nbupdat ! 509: .PP ! 510: This operation invalidates the nami cache. ! 511: The message sent to the server contains an operation-specific header in the form of ! 512: a \f(CW struct snbup\fP: ! 513: .P1 ! 514: struct snbup { ! 515: unsigned short mode; ! 516: short rdvdd; ! 517: long rsvd; ! 518: long ta; ! 519: long tm; ! 520: } ! 521: .P2 ! 522: The \f(CWmode\fP is the mode of the file from the inode. \f(CWrdvdd\fP is currently unused. ! 523: \f(CWrsvd\fP is a pad field. \f(CWta\fP ! 524: is the access time on the client machine and \f(CWtm\fP is ! 525: the modify time on the client machine. ! 526: If the inode is not marked IACC, \f(CWta\fP is set to 0. ! 527: If the inode is not marked IUPD, \f(CWtm\fP is set to 0. ! 528: The message sent to the server is as follows: ! 529: .KS ! 530: .ps -\n(tP ! 531: .vs -\n(tVu ! 532: .TS ! 533: center,box; ! 534: c s ! 535: a | a . ! 536: NBUPD request ! 537: = ! 538: sendb value ! 539: _ _ ! 540: version 2 ! 541: cmd NBUPD ! 542: flags 0 ! 543: rsva unused ! 544: trannum transaction number ! 545: len sizeof(struct sendb)+ ! 546: sizeof(struct snbup) ! 547: (40 bytes) ! 548: tag tag of inode ! 549: uid uid of client ! 550: gid gid of client ! 551: rsvb unused ! 552: _ _ ! 553: snbup value ! 554: _ _ ! 555: mode mode of inode ! 556: rdvdd unused ! 557: rsvd unused ! 558: ta access time or 0 ! 559: tm modify time or 0 ! 560: .TE ! 561: .ps +\n(tP ! 562: .vs +\n(tVu ! 563: .KE ! 564: .PP ! 565: If the times are zero in the client request message, the server obtains the times ! 566: from the cached ! 567: .I stat (2) ! 568: information for the file. Otherwise the times from the message ! 569: are adjusted with a time drift correction (see \(sc5.8). ! 570: The access and modify times are updated via ! 571: .I utime (2). ! 572: If the modes ! 573: are to be changed, and the client process owns the file, they are updated with either ! 574: .I fchmod (2) ! 575: or ! 576: .I chmod (2). ! 577: The server responds to the client with the following message: ! 578: .KS ! 579: .ps -\n(tP ! 580: .vs -\n(tVu ! 581: .TS ! 582: center,box; ! 583: c s ! 584: a | a . ! 585: NBUPD response ! 586: = ! 587: recvb value ! 588: _ _ ! 589: trannum transaction number ! 590: errno error number or 0 ! 591: flags 0 ! 592: rsvd unused ! 593: len sizeof(struct recvb) ! 594: (16 bytes) ! 595: fsize 0 ! 596: .TE ! 597: .ps +\n(tP ! 598: .vs +\n(tVu ! 599: .KE ! 600: ........ ! 601: .NH 2 ! 602: nbread ! 603: .PP ! 604: This operation invalidates the nami cache. ! 605: The client sends multiple messages to the server, reading at most \fImax_message_size\fP-16 ! 606: bytes at a time (currently 5104 bytes). ! 607: .PP ! 608: The message sent to the server includes an operation-specific \f(CWsnbread\fP structure: ! 609: .P1 ! 610: struct snbread { ! 611: long len; ! 612: long offset; ! 613: } ! 614: .P2 ! 615: \f(CWlen\fP is the number of bytes to be read and \f(CWoffset\fP is the offset in ! 616: the file at which the read should start. The message sent to the server is as follows: ! 617: .KS ! 618: .ps -\n(tP ! 619: .vs -\n(tVu ! 620: .TS ! 621: center,box; ! 622: c s ! 623: a | a . ! 624: NBREAD request ! 625: = ! 626: sendb value ! 627: _ _ ! 628: version 2 ! 629: cmd NBREAD ! 630: flags 0 ! 631: rsva unused ! 632: trannum transaction number ! 633: len sizeof(struct sendb)+ ! 634: sizeof(struct snbread) ! 635: (32 bytes) ! 636: tag tag of inode ! 637: uid uid of client ! 638: gid gid of client ! 639: rsvb unused ! 640: _ _ ! 641: snbread value ! 642: _ _ ! 643: len number of bytes to read ! 644: offset byte offset where to start ! 645: reading ! 646: .TE ! 647: .ps +\n(tP ! 648: .vs +\n(tVu ! 649: .KE ! 650: .PP ! 651: The server reads the data and sends it back to the client. When all of ! 652: the data is read, or ! 653: .I read (2) ! 654: returns less than the amount asked for, the \f(CWflags\fP ! 655: field is set to NBEND. ! 656: The message sent from the server to the client is: ! 657: .KS ! 658: .ps -\n(tP ! 659: .vs -\n(tVu ! 660: .TS ! 661: center,box; ! 662: c s ! 663: a | a . ! 664: NBREAD response ! 665: = ! 666: recvb value ! 667: _ _ ! 668: trannum transaction number ! 669: errno error number or 0 ! 670: flags 0 or NBEND ! 671: rsvd unused ! 672: len sizeof(struct recvb)+ ! 673: number of bytes read ! 674: fsize size of attempted read ! 675: _ _ ! 676: data read from file ! 677: .TE ! 678: .ps +\n(tP ! 679: .vs +\n(tVu ! 680: .KE ! 681: .NH 2 ! 682: nbwrite ! 683: .PP ! 684: This operation invalidates the nami cache. ! 685: The client sends multiple messages to the server, writing at most \fImax_message_size\fP-32 ! 686: bytes at a time (currently 5088 bytes). ! 687: The message sent to the server includes an operation-specific \f(CWsnbwrite\fP structure: ! 688: .P1 ! 689: struct snbwrite { ! 690: long len; ! 691: long offset; ! 692: } ! 693: .P2 ! 694: \f(CWlen\fP is the number of bytes to be written and \f(CWoffset\fP is the offset in ! 695: the file at which the write should start. The message sent to the server is as follows: ! 696: .KS ! 697: .ps -\n(tP ! 698: .vs -\n(tVu ! 699: .TS ! 700: center,box; ! 701: c s ! 702: a | a . ! 703: NBWRT request ! 704: = ! 705: sendb value ! 706: _ _ ! 707: version 2 ! 708: cmd NBWRT ! 709: flags 0 ! 710: rsva unused ! 711: trannum transaction number ! 712: len sizeof(struct sendb)+ ! 713: sizeof(struct snbwrite)+ ! 714: number of bytes to write ! 715: tag tag of inode ! 716: uid uid of client ! 717: gid gid of client ! 718: rsvb unused ! 719: _ _ ! 720: snbwrite value ! 721: _ _ ! 722: len number of bytes to write ! 723: offset byte offset where to ! 724: start writing ! 725: _ _ ! 726: data to be written ! 727: .TE ! 728: .ps +\n(tP ! 729: .vs +\n(tVu ! 730: .KE ! 731: The client marks the inode (IUPD|ICHG). After the write, the server seeks to ! 732: the end of the file and updates the size of the file. The message sent back to the client is: ! 733: .KS ! 734: .ps -\n(tP ! 735: .vs -\n(tVu ! 736: .TS ! 737: center,box; ! 738: c s ! 739: a | a . ! 740: NBWRT response ! 741: = ! 742: recvb value ! 743: _ _ ! 744: trannum transaction number ! 745: errno error number or 0 ! 746: flags 0 ! 747: rsvd unused ! 748: len sizeof(struct recvb) ! 749: (16 bytes) ! 750: fsize file size ! 751: .TE ! 752: .ps +\n(tP ! 753: .vs +\n(tVu ! 754: .KE ! 755: The client updates the size of the file in the inode with \f(CWfsize\fP. ! 756: .NH 2 ! 757: nbstat ! 758: .PP ! 759: The client maintains a one-entry cache from nami processing to avoid ! 760: sending a stat message to the server immediately after a nami operation. ! 761: If the client cache entry is valid, the ! 762: .I stat (2) ! 763: is satisfied from the ! 764: cached data. Otherwise a message is sent to the server. The operation-specific ! 765: part of the message contains a \f(CWsnbstat\fP structure: ! 766: .P1 ! 767: struct snbstat { ! 768: long ta; ! 769: long rsvd; ! 770: } ! 771: .P2 ! 772: \f(CWta\fP is the current time on the client and is used for synchronization. ! 773: \f(CWrsvd\fP is a pad field. The message sent from the client to the server is: ! 774: .KS ! 775: .ps -\n(tP ! 776: .vs -\n(tVu ! 777: .TS ! 778: center,box; ! 779: c s ! 780: a | a . ! 781: NBSTAT request ! 782: = ! 783: sendb value ! 784: _ _ ! 785: version 2 ! 786: cmd NBSTAT ! 787: flags 0 ! 788: rsva unused ! 789: trannum transaction number ! 790: len sizeof(struct sendb)+ ! 791: sizeof(struct snbstat) ! 792: (32 bytes) ! 793: tag tag of inode ! 794: uid uid of client ! 795: gid gid of client ! 796: rsvb unused ! 797: _ _ ! 798: snbstat value ! 799: _ _ ! 800: ta current time on client ! 801: rsvd unused ! 802: .TE ! 803: .ps +\n(tP ! 804: .vs +\n(tVu ! 805: .KE ! 806: .PP ! 807: After each of the first three stat messages, and ! 808: after every third stat message thereafter, the server recalculates the time drift between the ! 809: client machine and the server machine. The server uses ! 810: .I fstat (2) to obtain the ! 811: information about the given file. ! 812: The response message sent to the client has an operation-specific header ! 813: that contains a \f(CWrnbstat\fP structure: ! 814: .P1 ! 815: struct rnbstat { ! 816: long ino; ! 817: short dev; ! 818: short mode; ! 819: short nlink; ! 820: short uid, gid; ! 821: short rdev; ! 822: long size; ! 823: long ta; ! 824: long tm; ! 825: long tc; ! 826: }; ! 827: .P2 ! 828: The response message is as follows: ! 829: .KS ! 830: .ps -\n(tP ! 831: .vs -\n(tVu ! 832: .TS ! 833: center,box; ! 834: c s ! 835: a | a . ! 836: NBSTAT response ! 837: = ! 838: recvb value ! 839: _ _ ! 840: trannum transaction number ! 841: errno error number or 0 ! 842: flags 0 ! 843: rsvd unused ! 844: len sizeof(struct recvb)+ ! 845: sizeof(struct rnbstat) ! 846: (48 bytes) ! 847: fsize 0 ! 848: _ _ ! 849: rnbstat value ! 850: _ _ ! 851: ino inode number ! 852: dev device number ! 853: mode mode of file ! 854: nlink number of links to file ! 855: uid owner of file ! 856: gid group of file ! 857: rdev unused ! 858: size size of file ! 859: ta access time ! 860: tm modify time ! 861: tc change time ! 862: .TE ! 863: .ps +\n(tP ! 864: .vs +\n(tVu ! 865: .KE ! 866: .NH 2 ! 867: nbtrunc ! 868: .PP ! 869: \fINbtrunc\fP invalidates the nami cache. ! 870: The message sent to the server is as follows: ! 871: .KS ! 872: .ps -\n(tP ! 873: .vs -\n(tVu ! 874: .TS ! 875: center,box; ! 876: c s ! 877: a | a . ! 878: NBTRNC request ! 879: = ! 880: sendb value ! 881: _ _ ! 882: version 2 ! 883: cmd NBTRNC ! 884: flags 0 ! 885: rsva unused ! 886: trannum transaction number ! 887: len sizeof(struct sendb) ! 888: (24 bytes) ! 889: tag tag of inode ! 890: uid uid of client ! 891: gid gid of client ! 892: rsvb unused ! 893: .TE ! 894: .ps +\n(tP ! 895: .vs +\n(tVu ! 896: .KE ! 897: .PP ! 898: The client must own the file to be allowed to truncate it. The server uses ! 899: .I creat (2) ! 900: to truncate the file. Since ! 901: .I creat ! 902: also opens the file ! 903: for writing, the server immediately closes it. The message sent back to the ! 904: client is: ! 905: .KS ! 906: .ps -\n(tP ! 907: .vs -\n(tVu ! 908: .TS ! 909: center,box; ! 910: c s ! 911: a | a . ! 912: NBTRNC response ! 913: = ! 914: recvb value ! 915: _ _ ! 916: trannum transaction number ! 917: errno error number or 0 ! 918: flags nami flags ! 919: rsvd unused ! 920: len sizeof(struct recvb) ! 921: (16 bytes) ! 922: fsize 0 ! 923: .TE ! 924: .ps +\n(tP ! 925: .vs +\n(tVu ! 926: .KE ! 927: .NH 2 ! 928: nbnami ! 929: .PP ! 930: The file system-specific nami performs a number of operations. ! 931: It can parse a pathname, link a file, unlink a file, ! 932: make a directory, remove a directory, and create a file. ! 933: The message sent to the server contains an operation-specific header in the form ! 934: of a \f(CWsnbnami\fP structure: ! 935: .P1 ! 936: struct snbnami { ! 937: short mode; ! 938: short dev; ! 939: long ino; ! 940: } ! 941: .P2 ! 942: The message sent to the server is as follows: ! 943: .KS ! 944: .ps -\n(tP ! 945: .vs -\n(tVu ! 946: .TS ! 947: center,box; ! 948: c s ! 949: a | a . ! 950: NBNAMI request ! 951: = ! 952: sendb value ! 953: _ _ ! 954: version 2 ! 955: cmd NBNAMI ! 956: flags nami operation ! 957: rsva unused ! 958: trannum transaction number ! 959: len sizeof(struct sendb)+ ! 960: sizeof(struct snbnami)+ ! 961: number of bytes in the ! 962: pathname ! 963: tag tag of inode ! 964: uid uid of client ! 965: gid gid of client ! 966: rsvb unused ! 967: _ _ ! 968: snbnami value ! 969: _ _ ! 970: mode mode of inode for ! 971: NI_CREAT, NI_NXCREAT, ! 972: and NI_MKDIR ! 973: dev unused ! 974: ino inode number (tag) for ! 975: NI_LINK ! 976: _ _ ! 977: data full pathname ! 978: .TE ! 979: .ps +\n(tP ! 980: .vs +\n(tVu ! 981: .KE ! 982: The \f(CWflags\fP field determines what the server should do. ! 983: While parsing the pathname, if it goes out of the remote file system, the server ! 984: sets the \f(CWflags\fP field in the response message to NBROOT and sends the message ! 985: back to the client so the ! 986: client can continue with pathname evaluation. Each nami operation is described in the ! 987: following sections. ! 988: .X "PARM CT 60 ! 989: .PP ! 990: The response message sent back to the client contains a \f(CWrnbnami\fP structure: ! 991: .P1 ! 992: struct rnbnami { ! 993: long tag; ! 994: long ino; ! 995: short dev; ! 996: short mode; ! 997: long used; ! 998: short nlink; ! 999: short uid, gid; ! 1000: short rdev; ! 1001: long size; ! 1002: long ta; ! 1003: long tm; ! 1004: long tc; ! 1005: }; ! 1006: .P2 ! 1007: The message is as follows: ! 1008: .KS ! 1009: .ps -\n(tP ! 1010: .vs -\n(tVu ! 1011: .TS ! 1012: center,box; ! 1013: c s ! 1014: a | a . ! 1015: NBNAMI response ! 1016: = ! 1017: recvb value ! 1018: _ _ ! 1019: trannum transaction number ! 1020: errno error number or 0 ! 1021: flags 0 or NBROOT ! 1022: rsvd unused ! 1023: len sizeof(struct recvb)+ ! 1024: sizeof(struct rnbnami) ! 1025: (56 bytes) ! 1026: fsize 0 ! 1027: _ _ ! 1028: rnbnami value ! 1029: _ _ ! 1030: tag tag ! 1031: ino inode number ! 1032: dev device number ! 1033: mode mode of file ! 1034: used if NBROOT, number of bytes ! 1035: parsed in pathname ! 1036: nlink number of links to file ! 1037: uid owner of file ! 1038: gid group of file ! 1039: rdev unused ! 1040: size size of file ! 1041: ta access time ! 1042: tm modify time ! 1043: tc change time ! 1044: .TE ! 1045: .ps +\n(tP ! 1046: .vs +\n(tVu ! 1047: .KE ! 1048: .PP ! 1049: If the pathname evaluates to a file on the server's file system, then the server ! 1050: will perform different tasks based on the value of \f(CWflags\fP in the request message. ! 1051: .NH 3 ! 1052: NI_SEARCH ! 1053: .PP ! 1054: The server opens the file and sends the response message to the client. ! 1055: .NH 3 ! 1056: NI_DEL ! 1057: .PP ! 1058: If the client process has write permission in the directory containing the file, and if ! 1059: the file is a regular file, then the server attempts to ! 1060: .I unlink (2) ! 1061: it. ! 1062: If the file is a directory, the server tries to remove it with ! 1063: .I rmdir (2) ! 1064: instead. Other ! 1065: file types cannot be deleted. ! 1066: .NH 3 ! 1067: NI_CREAT ! 1068: .PP ! 1069: The server creates (and truncates) the file with ! 1070: .I creat (2). ! 1071: For ! 1072: new file creation, the server does not allow special files or symbolic links ! 1073: to be created. ! 1074: .NH 3 ! 1075: NI_NXCREAT ! 1076: .PP ! 1077: This does the same thing as NI_CREAT, but if the file already exists, it ! 1078: fails with EEXIST. ! 1079: .NH 3 ! 1080: NI_LINK ! 1081: .PP ! 1082: If the file already exists, the server fails the operation with EEXIST. ! 1083: Otherwise, the server uses ! 1084: .I link (2) ! 1085: to link the filename to the file ! 1086: represented by the client inode given by \f(CWino\fP. ! 1087: .NH 3 ! 1088: NI_MKDIR ! 1089: .PP ! 1090: If the file (directory) already exists, the server fails the operation with EEXIST. ! 1091: If the server has write permissions in the parent directory, then a new directory ! 1092: is created with ! 1093: .I mkdir (2). ! 1094: .NH 3 ! 1095: NI_RMDIR ! 1096: .PP ! 1097: This does the same thing as NI_DEL, but deals only with removing directories. ! 1098: .NH 2 ! 1099: nbdirread ! 1100: .PP ! 1101: This operation is used to read a directory and present the contents in a canonical form. ! 1102: The form is a NULL-terminated character string containing the i-number in decimal, a ! 1103: tab, and the filename. ! 1104: .PP ! 1105: The client sends one message to the server, reading at most \fImax_message_size\fP-24 ! 1106: bytes at a time (5096 bytes). ! 1107: The message sent to the server contains an operation-specific header in the form ! 1108: of a \f(CWsnbread\fP structure (see \(sc5.6). ! 1109: The message is as follows: ! 1110: .KS ! 1111: .ps -\n(tP ! 1112: .vs -\n(tVu ! 1113: .TS ! 1114: center,box; ! 1115: c s ! 1116: a | a . ! 1117: NBDIR request ! 1118: = ! 1119: sendb value ! 1120: _ _ ! 1121: version 2 ! 1122: cmd NBDIR ! 1123: flags 0 ! 1124: rsva unused ! 1125: trannum transaction number ! 1126: len sizeof(struct sendb)+ ! 1127: sizeof(struct snbread) ! 1128: (32 bytes) ! 1129: tag tag of inode ! 1130: uid uid of client ! 1131: gid gid of client ! 1132: rsvb unused ! 1133: _ _ ! 1134: snbread value ! 1135: _ _ ! 1136: len number of bytes to read ! 1137: offset byte offset where to ! 1138: start reading ! 1139: .TE ! 1140: .ps +\n(tP ! 1141: .vs +\n(tVu ! 1142: .KE ! 1143: .PP ! 1144: The server reads the directory and responds back with a message containing the directory ! 1145: contents and an operation-specific header in the form of a \f(CWrnbdir\fP structure: ! 1146: .P1 ! 1147: struct rnbdir { ! 1148: long used; ! 1149: long rsvd; ! 1150: }; ! 1151: .P2 ! 1152: The response message is as follows: ! 1153: .KS ! 1154: .ps -\n(tP ! 1155: .vs -\n(tVu ! 1156: .TS ! 1157: center,box; ! 1158: c s ! 1159: a | a . ! 1160: NBDIR response ! 1161: = ! 1162: recvb value ! 1163: _ _ ! 1164: trannum transaction number ! 1165: errno error number or 0 ! 1166: flags 0 ! 1167: rsvd unused ! 1168: len sizeof(struct recvb)+ ! 1169: sizeof(struct rnbdir) ! 1170: (24 bytes) ! 1171: fsize size of attempted read ! 1172: _ _ ! 1173: rnbdir value ! 1174: _ _ ! 1175: used bytes read ! 1176: rsvd unused ! 1177: _ _ ! 1178: data directory entries ! 1179: .TE ! 1180: .ps +\n(tP ! 1181: .vs +\n(tVu ! 1182: .KE ! 1183: .PP ! 1184: On success, \f(CWused\fP contains the number of bytes read. It is added to \f(CWu.u_offset\fP ! 1185: to get the new offset in the directory. ! 1186: .NH 2 ! 1187: nbioctl ! 1188: .PP ! 1189: The client side supports three ! 1190: .I ioctl (2) ! 1191: commands private to ! 1192: the file system type. NBIOCON turns debugging on, NBIOCOFF turns ! 1193: debugging off, and NBIOCBSZ changes the network message size. ! 1194: All other commands are sent to the server. It is assumed that all ! 1195: .I ioctl s ! 1196: contain a 64-byte buffer of data needed for the operation. ! 1197: Data are copied in from the buffer to send to the server and any resulting data ! 1198: are copied out to the buffer if the operation succeeds. ! 1199: The message sent to the server contains an operation-specific header in the form ! 1200: of a \f(CWsnbioc\fP structure: ! 1201: .P1 ! 1202: struct snbioc { ! 1203: long cmd; ! 1204: short flag; ! 1205: short rsvd; ! 1206: } ! 1207: .P2 ! 1208: The message sent to the server is: ! 1209: .KS ! 1210: .ps -\n(tP ! 1211: .vs -\n(tVu ! 1212: .TS ! 1213: center,box; ! 1214: c s ! 1215: a | a . ! 1216: NBIOCTL request ! 1217: = ! 1218: sendb value ! 1219: _ _ ! 1220: version 2 ! 1221: cmd NBIOCTL ! 1222: flags 0 ! 1223: rsva unused ! 1224: trannum transaction number ! 1225: len sizeof(struct sendb)+ ! 1226: sizeof(struct snbioc)+ ! 1227: 64 bytes of user data ! 1228: (96 bytes) ! 1229: tag tag of inode ! 1230: uid uid of client ! 1231: gid gid of client ! 1232: rsvb unused ! 1233: _ _ ! 1234: snbioc value ! 1235: _ _ ! 1236: cmd ioctl command ! 1237: flag file table flags ! 1238: rsvd unused ! 1239: _ _ ! 1240: data from user ioctl buffer ! 1241: .TE ! 1242: .ps +\n(tP ! 1243: .vs +\n(tVu ! 1244: .KE ! 1245: The response message sent from the server to the client is: ! 1246: .KS ! 1247: .ps -\n(tP ! 1248: .vs -\n(tVu ! 1249: .TS ! 1250: center,box; ! 1251: c s ! 1252: a | a . ! 1253: NBIOCTL response ! 1254: = ! 1255: recvb value ! 1256: _ _ ! 1257: trannum transaction number ! 1258: errno error number or 0 ! 1259: flags 0 ! 1260: rsvd unused ! 1261: len sizeof(struct recvb)+ ! 1262: 64 bytes of user data ! 1263: (80 bytes) ! 1264: fsize 0 ! 1265: _ _ ! 1266: data for user ioctl buffer ! 1267: .TE ! 1268: .ps +\n(tP ! 1269: .vs +\n(tVu ! 1270: .KE ! 1271: .PP ! 1272: Currently, \fIzarf\fP does not support \fIioctl\fP and returns ENOTTY for ! 1273: this operation. ! 1274: .X PARM CT 50 ! 1275: .NH 1 ! 1276: Permissions ! 1277: .PP ! 1278: The server determines permissions by matching passwd and group files. ! 1279: Exceptions to the default permissions can be found in ! 1280: .CW /usr/netb/except.local ! 1281: and ! 1282: .CW /usr/netb/except . ! 1283: The format of these files are comment lines begin with ! 1284: .CW # , ! 1285: blank lines are ignored, and lines may contain one of four valid directives. ! 1286: .PP ! 1287: The ! 1288: .CW client ! 1289: directive specifies the client to which the following lines apply: ! 1290: .P1 ! 1291: client \fICLIENT_NAME ! 1292: .P2 ! 1293: where \fICLIENT_NAME\fP is the name of the client machine, or ! 1294: .CW * ! 1295: for all clients that ! 1296: do not have an explicit entry. The client name is separated from the keyword ! 1297: by spaces or tabs. ! 1298: .PP ! 1299: The ! 1300: .CW uid ! 1301: directive specifies how to map a given user: ! 1302: .P1 ! 1303: uid \fICLIENT_USR_NAME\fP=\fISERVER_USR_NAME ! 1304: .P2 ! 1305: where \fICLIENT_USR_NAME\fP is the name of a user on the client machine and ! 1306: \fISERVER_USR_NAME\fP is the name of a user on the server machine to which the client ! 1307: is mapped. \fISERVER_USR_NAME\fP ! 1308: may be left out signifying the client is not to be mapped (i.e. disallowed access.) ! 1309: .PP ! 1310: The ! 1311: .CW gid ! 1312: directive specifies how to map a given group: ! 1313: .P1 ! 1314: gid \fICLIENT_GRP_NAME\fP=\fISERVER_GRP_NAME ! 1315: .P2 ! 1316: where \fICLIENT_GRP_NAME\fP is the name of a group on the client machine and ! 1317: \fISERVER_GRP_NAME\fP ! 1318: is the name of a group on the server machine to which the client is mapped. ! 1319: \fISERVER_GRP_NAME\fP ! 1320: may be left out signifying the client is not to be mapped (i.e. disallowed access.) ! 1321: .PP ! 1322: The ! 1323: .CW param ! 1324: directive conveys specific parameters to the server: ! 1325: .P1 ! 1326: param \fINAME\fP=\fIVALUE ! 1327: .P2 ! 1328: The following parameters ! 1329: .I NAME ) ( ! 1330: are supported: ! 1331: .IP \f(CWotherok\fP 10 ! 1332: this may take on a value of either 0 or 1. A value of 1 gives read ! 1333: permissions to client ids that are not mapped and a value of 0 denies access. In either ! 1334: case, client ids that are not mapped are denied write access. ! 1335: .IP \f(CWroot\fP ! 1336: the value for this parameter is the pathname of the root from ! 1337: which the server will execute. ! 1338: .NH 1 ! 1339: Acknowledgements ! 1340: .PP ! 1341: Peter Weinberger originally wrote the network file system. ! 1342: More recently, Norman ! 1343: Wilson has fixed bugs and rewritten \fIzarf\fP and \fIsetup\fP. ! 1344: He greatly improved the ! 1345: portability of \fIzarf\fP. Thanks to Peter Honeyman, Dennis Ritchie, and Norman ! 1346: Wilson for reviewing this paper. ! 1347: .NH 1 ! 1348: References ! 1349: .LP ! 1350: |reference_placement
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.