Fourth FAQ

for

Project 4 -- IPC

[Note that this first question is refering back to question 4 from the previous FAQ.]

Q. thanks for your help,but you said in the project description that any one the same computer can access my server(part1 page:3 ), then how it will be possible if i dont give excecute permissions to others..?? thanks for helping

A. There are different kinds of access between which we, as computer scientists, should be able to differentiate.

Several kinds of access are possible for the primeatschoold executable file itself. These include read, write, and execute permissions. As I said in the previous FAQ, there is no need to give anyone on the system besides the owner permission to execute primeatschoold. This is because only the owner of the server needs to be able to run it. For this reason, and because it is generally a good policy from a security standpoint to limit permissions to those for which there is a legitimate need, I further indicated that you should not give execute permissions for primeatschoold to anyone other than its owner.

Similarly, you do not need to give anyone on the system besides the owner permission to read or write the primeatschoold executable file. Further, again for security reasons, you should not give anyone else on the system read or write permissions for the primeatschoold executable file.

However, we need to understand that the permissions that relate to the executable file itself are not the only access kinds we need to consider on the system. We also need to consider ways in which we could access the process that results when we run the executable file. In particular, we need to consider how we can communicate with that process. Communication with the server is what the assignment description is very explicitly talking about when it says, "... anyone on the same computer can start up a client and connect it to your server and get numbers back."

We cannot begin to understand the client/server model if we fail to understand that someone can be given the ability to connect to a server even if that user cannot run the server's executable file. In fact, one of the most common uses of a server (including ftp servers and www servers, among many others) is to give people access to files or data in places where they do not have permission to run processes. Someone else runs the server process and the person who wants the file or data runs a client process that connects to the server and asks for the file or data.

In your project, then, you must give others permission to connect to (that is, to communicate with) your primeatschoold server but not permission to exectute it.

Everything above holds true for primeathomed as well.


Q. For some reason, after every 40-50 numbers a client processes on turing (it's at ~user1234/primeserv), the client returns a "Broken Pipe" error and exits out. I'm not sure even where to begin debugging this, and can't find a good, generalized definition of what "broken pipe" entails.

A. A "Broken pipe" error happens when a process tries to write to a pipe that is not open for reading by any process. (See page 335 of Haviland, et al.)

You can easily generate such an error to see it happen by doing the following:

  1. Create a pipe with a reader and writer by typing "cat <largefile> | more" (where <largefile> is some large file you can read).
  2. Send a SIGTERM signal to more to kill it off.

Since cat will still be writing the file to the pipe, cat will generate a "Broken pipe" error.

As a first guess for debugging this, I'd say look at your server. If it opens and closes the server FIFO for every message it reads, then there is a good chance that at some point the server will close its FIFO while the client is already trying to write to it and the client will generate a Broken pipe error. That is to say, if the server had already closed the FIFO before the client tried to write to it, then the client would simply block and wait for the server to reopen the FIFO. It is only if the server closes the FIFO after the client has blocked in its read that there is a Broken pipe error. (The reason you don't get this message with every write from the client is that the server will most often have the FIFO open for reading and will be blocked waiting for a write. It will only be every so often that the server will close its FIFO while the client is blocked trying to write to it.)

If this is the problem, the remedy is simple: Have the server open its FIFO once on startup and leave it open until the server shuts down.

By the way, Jim Summers, our system administrator, has asked us not to run these processes on turing.cs.ou.edu because it is the file server for the department and we can degrade performance of the overall system by making it too busy. We should, therefore, stick to the gpel machines for this class.


Q. Say I have a FIFO open, and am reading a command out of it, just one, then closing it. If another process throws a command into the FIFO while I'm reading the one other command out, while that command be lost when I close the FIFO? (Pretty much asking: Is the FIFO cleared after every close?)

A. First, recall that reading from and writing to a FIFO are both atomic operations (unless you are dealing with a single message larger than the total size of the FIFO). Therefore, one process cannot write a message into the FIFO at the same time that another one is reading from that FIFO -- whichever operation starts first will complete before the other one is allowed to begin.

As for the clearing of a FIFO, this isn't done on every close. It is done, however, if the last process that has the FIFO open calls close on that FIFO. Here are two examples to consider that differ in closes.

    Example 1:
  1. Process 1 opens the FIFO for writing,
  2. Process 1 tries to write but blocks because no process has the FIFO open for reading,
  3. Process 2 opens the FIFO for reading,
  4. Process 2 tries to read one byte but blocks because the FIFO is empty,
  5. Process 1 writes 2 bytes to the FIFO (it is no longer blocked because process 2 has the FIFO open for reading),
  6. Process 2 reads one byte from the FIFO (it is no longer blocked because the FIFO is no longer empty),
  7. Process 2 closes the FIFO,
  8. Process 2 opens the FIFO for reading,
  9. Process 2 reads one byte from the FIFO.
  10. ...

Note that, despite the fact that process 2 closed the FIFO, the second byte that process 1 had written to the FIFO is still available because process 1 had the FIFO open the whole time.

    Example 2:
  1. Process 1 opens the FIFO for writing,
  2. Process 1 tries to write but blocks because no process has the FIFO open for reading,
  3. Process 2 opens the FIFO for reading,
  4. Process 2 tries to read one byte but blocks because the FIFO is empty,
  5. Process 1 writes 2 bytes to the FIFO (it is no longer blocked because process 2 has the FIFO open for reading),
  6. Process 1 closes the FIFO,
  7. Process 2 reads one byte from the FIFO (it is no longer blocked because the FIFO is no longer empty),
  8. Process 2 closes the FIFO,
  9. Process 2 opens the FIFO for reading,
  10. Process 2 tries to read one byte but blocks because the FIFO is empty.
  11. ...

Note that, in this case, the second byte that process 1 had written to the FIFO is gone because both processes had closed the FIFO before process 2 tried to reopen it.


Q. Right now I have the server holding the missed numbers in memory, and then it writes them out to the schoolmissedprimes file when it shuts down. Is this kosher, or do I actually need to be writing them as they are passed around? I know the project spec says the later of the two, so if I'm asking a RTFM question, just slap me.

A. You will need to have the file updated while the server is running, as per the assignment. While your method would work fine if the server always shuts down properly, we should plan to have our server recover with very little or no loss if it shuts down improperly (if it crashes, there is a power failure, etc.). Note that most servers are intended to stay up for months or years at a time, until there is a hardware upgrade or similar system maintanance that requires the system to be shut down. For this reason, improper shutdowns of servers due to things like power failures are almost as common as proper shutdowns. By keeping the file up to date, we can ensure that there is very little data lost by an improper server shutdown.

(By the way, the file should be named primeatschoolfile.)


Q. We have gotten some very odd behavior from UNIX regarding project 4. In one case, the system would make one read, but then would not make a second read from a while loop, but would read if we took it out of the while loop. (This iseven if the while loop was foolproof (while(1)).

Another case involves the system not writing newline characters correctly. It would treat the newline as two bytes no matter what we did to maniputlate it (ascii int cast as character, etc.). The exact same code, replacing the newlinewith a comma, worked perfectly.

A. The behavior you describe is indeed very odd. So odd, in fact, that my guess is that there is something else that is being overlooked. I'd need to see the reading/looping code to find the problem there but on the newline problem, I can take a guess as to what the problem is. In C, '\n' is a single byte representing the newline character. However, "\n" is a string of two bytes -- the first is newline character, the second is the string termination character '\0'. If you used "\n" where you should have used '\n', you could easily have seen the behavior you described.