• No se han encontrado resultados

The original version of 3DFS was implemented by modifying the func- tion that maps names to i-nodes in the kernel. It proved too hard to maintain this version, since it relied on specic UNIX kernel implemen- tations. To avoid this, n-DFS is now implemented as a user-level library that contains versions of many of the UNIX system calls. This library can either be merged with libc, or kept separately. Systems that do not have dynamic shared libraries require that programs be relinked to get the n-DFS extensions.

With the n-DFS library installed, each system call that n-DFS needs to know is intercepted and interpreted. As necessary, zero or more system calls are made by n-DFS to carry out a given action.

Because n-DFS runs in the user address space, it is not possible to guarantee that it will not aect an application that uses it. If the appli- cation writes into a random location that happens to lie in its address space, it could overwrite data that is critical to one or more n-DFS ser- vices. However, n-DFS was designed to be as unobtrusive as possible so that it could be used with existing programs. For example, since the vi

editor uses the sbrk call to obtain heap memory and expects consecutive calls to sbrk to return contiguous memory, we could not usemallocto get

Libraries and File System Architecture 85

heap memory needed for n-DFS. Instead, n-DFS maintains a static data area along with a 4K buer to handle dynamic information. This space is more than adequate to handle the compact per-process information.

The mount system call is used to communicate with n-DFS itself. We chose to extend the mount call rather than adding another call so that any program that needs to use n-DFS services directly will not have an unsatised external reference when run without the n-DFS library. The arguments to mount are chosen so that the real mount returns an error code if n-DFS is not involved.

Each process using n-DFS requires tables of information relating to each of its dimensions, and this table needs to be inherited by each child process. With 3DFS, the execve system call inserts an environment vari- able named \ " to the front of the environment list to pass down these tables. The rst system call intercepted by 3DFS reads the environment, extracts this information, and then deletes this environment entry. This creates two problems. First, it is possible for a user program to modify the environment before making any system calls, so the correct information may not be present. Second, programs that are close to the

ARG MAX

limit of the size of the argument list plus environment are pushed over this limit with the additional 3DFS data. To circumvent this problem, n-DFS passes down this information in an open le. Since n-DFS inter- cepts the close system call, there is no way that the user program can delete or modify this information before it is read by n-DFS. To save the time of creating and unlinking a le, n-DFS uses a UNIX pipe whenever the amount of information that is necessary is less then the

PIPE MAX

, the number of bytes that can safely be written on a pipe without blocking. A second optimization is done when a process that has not made any mount calls executes an exec call; the n-DFS table that was passed to this process can be reused to pass to the child process.

n-DFS uses libcs to implement external servers as explained earlier in Section 2.2.7.

2.5.2.1 Shell Interface

At the shell level, the vpath command controls the n-DFS namespace.

86 Fowler, Korn, and Rao

example,cdandumask),vpathis a shell built-in.vpathuses the mount(2)

system call, intercepted by n-DFS, to specify relationships between pairs of pathnames:

$ vpath path1 path2

If path1 and path2 are directories, any reference to the directory hierarchy under path1 will be mapped to the ordered union of the path1 and path2 hierarchies, where les under path1 take precedence over les under path2. path2of the form /#* controls the n-DFS internal state. For this case, a path1 of \{" can serve as a placeholder to preserve the vpath argument

pairs. For example,

$ vpath { /#option/debug=5

sets the n-DFS debug trace output level to 5.

$ vpath { /#option/trace

prints the intercepted n-DFS systems calls on standard error for all child processes.

Replication is specied by rst dening the replication service

$ vpath /dev/tcp/share/rpl/user

/#fs/rpl/monitor/regular/write/call=open,close,write/ack=write

where /dev/tcp/share/rpl/user is the pathname of a per-user repli-

cation server that is shared among all hosts in the local network.

/dev/tcp/host/rplnames a specic server running on host. /#fs denes

a new le system service. The replication service is a le service that has the name rpl (usage described below), with the following attributes:

monitor: Intercepted calls are run locally but also passed on to the

service.

regular: Monitors regular les (no directories, special devices, and so

forth).

write: Monitors only les open for write. call=... : Monitors only these intercepted calls.

ack=... : Blocks for server acknowledgment for these calls.

Replication hierarchies are then specied by mounting directories on the replication service:

Libraries and File System Architecture 87

$ vpath dir1 /#rpl dir2 /#rpl

where rpl is the name from the /#fs mount above. The service can be switched o by

$ vpath { /#fs/rpl/o

and on by

$ vpath { /#fs/rpl/on

without breaking the service connection.

Finally, the commandvpathwith one argument prints out the physical

path associated with the input logical path. vpath without arguments

lists a complete conguration mapping. This can be saved into a le and used to restore an n-DFS conguration sometime in the future.

Documento similar