Solution for OS2000 Exam3

Question 1. Directories and IPC. (20 pts.)

When a person goes to load a file into a user application, it is often nice to have the application display a list of all the files in the present working directory. There are two ways to get this information from the system -- by using system calls and by using a shell command.

A. Give appropriate system calls for doing this and explain how you would use them.

The appropriate system calls for this are opendir, readdir, and closedir. I would simply call opendir on the present working directory using opendir("."), call readdir in a loop until it returns a null pointer, display the name field of the returned structure on each iteration through the loop, and call closedir when done with the loop.

Alternately, I could save the name field on each iteration through the loop, then do some processing on the whole list (such as sorting it), before displaying the whole list.

B. Give an appropriate shell command for doing this and explain how you would use it. In particular, be sure to say what form of IPC you would use to get the information from the command and why.

An appropriate shell command for this would be ls. If the format of the output produced by ls would be sufficient, I could simply exec ls (along with appropriate flags -- on most systems just "-a" -- to ensure that all files are displayed) and let it display the list of files to the user. In this case, no IPC would be needed.

If I wanted to display the list in another format, I would use a pipe to retrieve the list. The simplest way to do this would be to use popen with the read option ("r") specified. Once the list was retrieved through the pipe, I could format it as desired, then display it.


Question 2. Client-Server Model. (30 pts.)

When we have a server process with one or more clients implemented using FIFOs, we can have the server read from a common FIFO that all the clients can write to, but we generally have a separate FIFO for each client to read from, rather than a single common FIFO that they can all read from.

A. List and explain two reasons for having multiple client FIFOs.

  1. Coordination. If more than one client is reading from the same FIFO, then we need to have some way to tell each one whose turn it is to read next. Otherwise, a message meant for one client could be accidentally read by another.
  2. Privacy. If the FIFO is publicly accessible, e.g., world readable, then clients might get access to information that they are not supposed to have. In this case, a message meant for one client could be intentionally read by another.

[There are other reasons that you could list as well, such as the first-in-first-out nature of FIFOs, which means that one client must finish its read from the common FIFO before the next can begin, which can hurt our throughput or even cause all processes to stop if one is stuck (e.g., in an infinite loop).]

B. Would it be possible to have a single client FIFO for multiple clients? If not, explain why not. If so, explain how you could overcome the reasons you gave above.

We could partially overcome the coordination problem by using signals, semaphores, or another similar IPC type. Using signals, for instance, the server could signal a client that it was that client's turn to read from the FIFO, wait for the client to signal that it had finished reading, then signal the next client that it was that client's turn, etc.

The privacy problem is harder to overcome. If the FIFO needs to be readable by just some trusted users on the system, we could have a group made for those users and set the permissions on the FIFO so that it is readable by that group, rather than by everyone on the system. However, if we must have the FIFO readable by all users (so that arbitrary users can communicate with the server), then the privacy problem will persist. Only if we have access control lists (ACLs) can we specify FIFO (or file) access on a per-user basis. If we do have ACLs, however, then the server can change the FIFOs ACL, so that only the current client has permission to read from it.

[Your answer here must match your answer to part A.]

C. Is there another IPC method that would make it easier to overcome the disadvantages of a single client message area that you listed in part A? If so, name the IPC type and explain how it could make this job easier. If not, explain why all IPC types are the same in this respect.

Message Queues can make the coordination much easier, as each client could have a client number assigned to it and only read a message if it has a tag that corresponds to the client's number. However, the privacy problem will actually get worse with any other IPC, because only FIFOs have file-type permissions associated with them.

[Your answer here must match your answer to part A.]


Question 3. IPC. (30 pts.)

A. Which IPC method would be best for implementing a web server? Explain your answer.

Sockets. Of all the IPC methods we have discussed, only sockets and STREAMS allow for communication across the machines, which is vital to almost all web servers. Sockets have the advantage over STREAMS that they are generally better known and more widely available.

[You could also have chosen STREAMS and made the argument that they benefit from code reuse, as they come out of a modular device driver interface effort.]

B. Is there another IPC method that could also be used? If so, say which one and explain how it could be used. If not, explain why not.

STREAMS. The use is the same, only the system calls need to be replaced.

[Or: Sockets. The use is the same, only the system calls need to be replaced.]

C. For requesting and sending ordinary web pages, would you use TCP or UDP? Explain your answer.

I'd use UDP. UDP is intended for connectionless communications and this is what most web page requests and responses are. The client sends a request for a single page and the server sends that page. That is the end of the communication, unless the client sends a new request. In contrast, TCP is intended for connection-oriented communications.


Question 4. Threads. (20 pts.)

A. If you were asked to implement JAVA threads on an OS that doesn't support threads, what implementation model would you use? Explain your answer.

If the OS doesn't support threads, the only implementation possible is user-level threads. You can only use kernel-level thread (or a combination approach) with OS support. Therefore, I would use user-level threads.

B. If you were asked to implement JAVA threads on an OS that has kernel threads, what implementation model would you use? Explain your answer.

If the threads supported by the OS are compatible with JAVA threads, I would choose to use kernel-level threads, because I wouldn't have to spend my effort duplicating existing code, because they would be more efficient in terms of space since they are already built into the kernel, because they can be blocked individually resulting in better throughput, and because they can be multiprocessed if this is a multiprocessor machine.

If, however, the threads supported by the OS are only partially compatible with JAVA threads, I would choose to use combined user-level and kernel-level threads, with the thread library providing compatibility as needed. The more I can build on the existing threads supported by the OS, the more I can carry over the advantages of using kernel-level threads mentioned above.