[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Re: partman review



On Sun, Feb 29, 2004 at 02:41:46PM +0100, Sven Luther wrote:
> 
> Hope you can do something with that, and i waited a bit more than a
> minute.

I expected much longer log file.  On your machine partman has fallen
from the beginning in some infinite loop.  This happens before any use
of libparted.  It may be something with the synchronisation between
the server and the clients.  Does your architecture use some different
version of libc?

Here is how the connections between parted_server and the clients are
organised in partman.  partman_server runs in background, holds all
necessary structures of libparted and accepts commands from shell
scripts.  The clients write to a FIFO named infifo and read from
outfifo.  parted_server reads from infifo and writes to infifo.

This is the scenario:

1. The server opens infifo for reading.  This stops it until some
   client opens infifo for writting.

2. A client opens infifo for writting (it will be stopped if the
   server has not yet opened infifo for reading).

3. The server reads a command from infifo (it waits until the client
   supplies such a command).

4. The client writes a command to infifo.  Then it opens outifo for
   reading -- this stops it until the server reads the command.

5. The server reads the command and opens outfifo for writting.

6. The server writes some responce to outfifo.

7. If this is not the final of the dialogue then the server will be
   waiting for a data from the client (supplied via infifo).  The
   client writes the necessary data to infifo.  If this is also not
   the final of the dialogue then the client will be waiting for a
   data from the server (supplied via outfifo).  The server writes the
   necessary data to outfifo.  This repeates as many times as
   necessary.  All writes are flushed.

8. When the server or the client writes the last data to outfifo (or
   to infifo) then it closes infifo and outfifo.  When the client (the
   server) receives the last data from outfifo (from infifo) then it
   also closes infifo and outfifo.

Now the interesting part comes.  The closing of the FIFOs could
happend in any order.  In order to synchronise the client and the
server open the FIFOs in the opposite direction.

9. The server opens outfifo for reading.  Notice that it is possible
   that the server has written to outfifo some data that the client
   has not had the time to read yet.  Nevertheless on i386 and libc6
   the server will be stopped waiting for the client to be ready.

10. The same happens with the client.  It opens outfifo for writting.
    This stops it until the server manages to open outfifo for
    reading.  At this time both processes are synchronised.

11. The client closes the oufifo without supplying any data in it.
    The server reads everything until EOF from outfifo and then closes
    it.  (This reading is protection against bugs -- there might be
    some unread data in outfifo.)

12. Do the same for infifo.  The client opens infifo for reading and
    the server for writting (at that moment again both processes will
    be synchronised).

13. The server closes infifo and continues goes to 1.

14. The client reads the data from infifo and closes it.  It may go to
    2. at any time.


Attached to this mail you will find a small script `client' and a
small C-program server.c.  Compile the server and then start the
client.  The client should print infininte number of strings 'How do
you do'.  If it doesn't do this on your machine I will be happy as
this means that you have to debug two very short programs.  Acording
to the log file you send the server has finished 8. from the scenario
only once and then never reaches again 1.  The client waits for it.
This means that the problem is somewhere between 9. and 13.

Anton Zinoviev
#!/bin/sh

[ ! -f infifo ] || rm infifo
[ ! -f outfifo ] || rm outfifo

mknod infifo p
mknod outfifo p

./server &

while true; do
    exec 6>infifo
    echo Hello world >&6
    exec 7<outfifo
    read responce <&7
    echo $responce
    exec 7<&-
    exec 6>&-
    # open the fifos in oposite direction in order to synchronise
    exec 7>outfifo
    exec 7>&-
    exec 6<infifo
    cat <&6 >/dev/null
    exec 6<&-
done

#include <stdlib.h>
#include <stdio.h>

int
main ()
{
  char *str;
  char c;
  FILE *infifo, *outfifo;
  for (;;)
    {
      infifo = fopen ("infifo", "r");
      if (infifo == NULL)
	return 1;
      fscanf (infifo, "%as", &str);
      free (str);
      outfifo = fopen ("outfifo", "w");
      fprintf (outfifo, "How do you do?\n");
      fflush (outfifo);
      fclose (infifo);
      fclose (outfifo);
      /* open the fifos in oposite direction in order to synchronise */
      outfifo = fopen ("outfifo", "r");
      if (outfifo == NULL)
	return 1;
      while (EOF != (c = fgetc (outfifo)))
	{
	}
      fclose (outfifo);
      infifo = fopen ("infifo", "w");
      if (infifo == NULL)
	return 1;
      fclose (infifo);
    }
  return 0;
}

Reply to: