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

[Nbd] Keep idle, but not dead, clients always ready



/*
Background:

This is an attempt to work around a design flaw in the nbd-client
nbd-server system where the server terminates a connection presuming
an idle client has instead, died.  The server, during a -a <xxx> timeout
shutdown does not ping the idle client or otherwise have a little exchange on
its socket, it just kills it.

In a partial respose, the client side implemented a --persist option.  Trying
to make a new connection when it finds the severed connection by the server.
If there doesn't happen to be a request on
/dev/nbdxxx
between when the server times out and when the client with --persist
reconnects, then all seems well.  However, should a swap or other request
happen then, it is a disaster.  Especially in a 'swap' environment.

When there are enough clients the odds of hitting this problem multiply
until a crash it is a question of when, not if.

Also, there are these annoying notices on the console on the clients
side every time the --persist option catches a server shutdown and
remakes its connection.  This causes the nbd process to just work,
all the time, silently, as follows:

This little program generates a bit of traffic from the client
to the server every 4 hours.  This resets the nbd-server shutdown
clock, while keeping the safegaurd on the server side of allowing
really dead server connections to end themselves.  I suggest a
server setting for -a of about 9 hours.

The compiled version of this program is meant to be run in
   the /etc/nd-client setup file:
...
NBD_TYPE[0]=s
...
/etc/nbdping&
...

I imagine that the ndb-xxx developers will replace the need for this
sooner or later by an internal means of having the -a server shutdown
option check to ensure the client is not simply idle.  Till, then, this
works well!

No warranties, Licensed under the GPL, for all three or four months until
the developers make it unecessary, I hope!

Harry Coin
Bettendorf, Iowa

*/


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

#define our_temp_file "/tmp/nbdping.tmp"
int main()
{
        int i; FILE *f;  //char buf[1024]; // struct stat stat_buf;
        //First, make sure we are the only copy of this running.
        i = system("pgrep -c nbdping > " our_temp_file);
        if (!i) { //the system command worked, now check the result.
                f= fopen(our_temp_file,"r");
                if (f!=NULL) {
                        fscanf(f,"%d",&i);
                        fclose(f);
                }
        } else i = 0;
        unlink(our_temp_file);
        if (i>1) exit(0); //only one of us, and it isn't us.
        //now, on to business.
while(!system("dd if=/dev/nbd0 of=/dev/null bs=1024 count=2 iflag=direct &> /dev/null\n")) {
                sleep(4*60*60); //4 hours
        }
        return (0);
}




Reply to: