Re: [Nbd] [PATCH 2/2] NBD: allow hung network I/O to be cancelled
- To: "Wouter Verhelst" <w@...112...>
- Cc: nbd-general@lists.sourceforge.net, Paul Clements <paul.clements@...124...>, Andrew Morton <akpm@...133...>, david@...134..., Corey Minyard <cminyard@...84...>
- Subject: Re: [Nbd] [PATCH 2/2] NBD: allow hung network I/O to be cancelled
- From: "Mike Snitzer" <snitzer@...17...>
- Date: Fri, 24 Aug 2007 17:25:26 -0400
- Message-id: <170fa0d20708241425j4ac505c7s9a82c0747dda4ff5@...18...>
- In-reply-to: <46CF2CDD.5000802@...124...>
- References: <46CF101F.4050603@...124...> <46CF1826.9050101@...124...> <170fa0d20708241113y31d2ba95xf30c83c7c4c98cd2@...18...> <46CF2CDD.5000802@...124...>
On 8/24/07, Paul Clements <paul.clements@...124...> wrote:
> Mike Snitzer wrote:
> > On 8/24/07, Paul Clements <paul.clements@...124...> wrote:
> >> This patch allows NBD I/O to be cancelled when a network outage occurs.
> >> Previously, I/O would just hang, and if enough I/O was hung in nbd, the
> >> system (at least user-level) would completely hang until a TCP timeout
> >> (default, 15 minutes) occurred.
> >>
> >> The patch introduces a new ioctl NBD_SET_TIMEOUT that allows a transmit
> >> timeout value (in seconds) to be specified. Any network send that
> >> exceeds the timeout will be cancelled and the nbd connection will be
> >> shut down. I've tested with various timeout values and 6 seconds seems
> >> to be a good choice for the timeout. If the NBD_SET_TIMEOUT ioctl is not
> >> called, you get the old (I/O hang) behavior.
> >
> > Hi Paul,
> >
> > Thanks for implementing this! Do you happen to have an associated
> > nbd-client patch for userspace? If not I'd be happy to coordinate
> > with you and Wouter on a patch.
>
> No, I don't. I just basically hardcoded my nbd-client to do a 6 second
> timeout by default, but Wouter will probably want to do something a
> little less hackish for the official nbd-client.
I trimmed LKML to avoid spamming so many others with userspace changes...
Wouter,
The attached patch adds nbd-client timeout support; this applies to
the tip of the svn trunk.
Please feel free to change as you see fit. I'm not sure if it would
be wise to default to a timeout (e.g. Paul's suggestion of 6) rather
than my current default of not specifying a timeout (to maintain
compatibility).
thanks,
Mike
Index: nbd-client.c
===================================================================
--- ./nbd-client.c (revision 278)
+++ ./nbd-client.c (working copy)
@@ -140,6 +140,16 @@
err("Unable to set read-only attribute for device");
}
+void set_timeout(int nbd, int timeout) {
+#ifdef NBD_SET_TIMEOUT
+ if (timeout) {
+ if (ioctl(nbd, NBD_SET_TIMEOUT, timeout) < 0)
+ err("Ioctl NBD_SET_TIMEOUT failed: %m\n");
+ fprintf(stderr, "timeout=%d\n", timeout);
+ }
+#endif
+}
+
void finish_sock(int sock, int nbd, int swap) {
if (ioctl(nbd, NBD_SET_SOCK, sock) < 0)
err("Ioctl NBD_SET_SOCK failed: %m\n");
@@ -160,6 +170,7 @@
char *hostname, *nbddev;
int swap=0;
int cont=0;
+ int timeout=0;
u64 size64;
u32 flags;
@@ -168,7 +179,7 @@
if (argc < 3) {
errmsg:
fprintf(stderr, "nbd-client version %s\n", PACKAGE_VERSION);
- fprintf(stderr, "Usage: nbd-client [bs=blocksize] host port nbd_device [-swap] [-persist]\n");
+ fprintf(stderr, "Usage: nbd-client [bs=blocksize] [timeout=sec] host port nbd_device [-swap] [-persist]\n");
fprintf(stderr, "Or : nbd-client -d nbd_device\n");
fprintf(stderr, "Default value for blocksize is 1024 (recommended for ethernet)\n");
fprintf(stderr, "Allowed values for blocksize are 512,1024,2048,4096\n"); /* will be checked in kernel :) */
@@ -206,6 +217,11 @@
++argv; --argc; /* skip blocksize */
}
+ if (strncmp(argv[0], "timeout=", 8)==0) {
+ timeout=atoi(argv[0]+8);
+ ++argv; --argc; /* skip timeout */
+ }
+
if (argc==0) goto errmsg;
hostname=argv[0];
++argv; --argc; /* skip hostname */
@@ -239,6 +255,7 @@
negotiate(sock, &size64, &flags);
setsizes(nbd, size64, blocksize, flags);
+ set_timeout(nbd, timeout);
finish_sock(sock, nbd, swap);
/* Go daemon */
@@ -272,6 +289,7 @@
setsizes(nbd, size64, blocksize,
new_flags);
+ set_timeout(nbd, timeout);
finish_sock(sock,nbd,swap);
}
}
Reply to: