#2 ECONNRESET not handled

closed-fixed
nobody
None
5
2012-09-03
2010-10-12
David Rennalls
No

Often while using large .isos mounted over httpfs the server will unexpectedly close the connection resulting in an ECONNRESET. This socket error is not handled in the code so it results in httpfs2 exiting, so the file operation above also fails. Attached is a patch I did to work around this limitation and handle the ECONNRESET cases.
Note: The patch includes the patch for another bug I raised https://sourceforge.net/tracker/?func=detail&aid=2994555&group_id=171260&atid=857286 (Cannot mount .isos larger than 2G (INT_MAX) on 32-bit arch)

Discussion

  • David Rennalls
    David Rennalls
    2010-10-12

    file size + ECONNRESET handling patch

     
    Attachments
  • David Rennalls
    David Rennalls
    2010-10-12

    Patch (as attached) against the source in httpfs2-0.1.4.tar.gz

    --- httpfs2.c.orig 2010-05-19 13:18:40.000000000 -0400
    +++ httpfs2.c 2010-05-19 13:21:39.000000000 -0400
    @@ -102,7 +102,7 @@

    static struct_url main_url;

    -static ssize_t get_stat(struct_url*, struct stat * stbuf);
    +static size_t get_stat(struct_url*, struct stat * stbuf);
    static ssize_t get_data(struct_url*, off_t start, size_t size);
    static int open_client_socket(struct_url *url);
    static int close_client_socket(struct_url *url);
    @@ -185,7 +185,7 @@
    * The FUSE operations originally ripped from the hello_ll sample.
    */

    -static int httpfs_stat(fuse_ino_t ino, struct stat *stbuf)
    +static size_t httpfs_stat(fuse_ino_t ino, struct stat *stbuf)
    {
    stbuf->st_ino = ino;
    switch (ino) {
    @@ -598,9 +598,9 @@
    }
    close_client_socket(&main_url);
    struct stat st;
    - long long size = get_stat(&main_url, &st);
    + size_t size = get_stat(&main_url, &st);
    if(size >= 0) {
    - fprintf(stderr, "file size: \t%lld\n", size);
    + fprintf(stderr, "file size: \t%u\n", size);
    }else{
    return 3;
    }
    @@ -878,6 +878,7 @@
    }
    if (connect(url->sockfd, (struct sockaddr*) &sa, sa_len) < 0) {
    errno_report("couldn't connect socket");
    + close(url->sockfd);
    return -1;
    }

    @@ -1078,7 +1079,7 @@
    */
    errno = 0;
    res = write_client_socket(url, buf, bytes);
    - if ( ((res <= 0) && ! errno) || (errno == EAGAIN) || (errno == EPIPE)) {
    + if ( ((res <= 0) && ! errno) || (errno == EAGAIN) || (errno == EPIPE) || (errno == ECONNRESET)) {
    errno_report("exchange: failed to send request, retrying"); /* DEBUG */
    close_client_force(url);
    continue;
    @@ -1088,7 +1089,7 @@
    return res;
    }
    res = read_client_socket(url, buf, HEADER_SIZE);
    - if ( ((res <= 0) && ! errno) || (errno == EAGAIN) || (errno == EPIPE)) {
    + if ( ((res <= 0) && ! errno) || (errno == EAGAIN) || (errno == EPIPE) || (errno == ECONNRESET)) {
    errno_report("exchange: did not receive a reply, retrying"); /* DEBUG */
    close_client_force(url);
    continue;
    @@ -1117,7 +1118,7 @@
    * to determine the file size
    */

    -static ssize_t get_stat(struct_url *url, struct stat * stbuf) {
    +static size_t get_stat(struct_url *url, struct stat * stbuf) {
    char buf[HEADER_SIZE];

    if( exchange(url, buf, "HEAD", &(url->file_size), 0, 0, 0) < 0 )

     
  • Sorry abot the delay, did not notice the SF mail.

    Thanks for the patches.

    Unfortunately, the ECONNRESET is not a documented return value of read nor recv so it is not handled.

    Is it documented in any standard?

    I think I get EPIPE in this case.

    Can you provide more details about the system on which you are getting the issue?

     
  • Also, how does this relate to the ISO size?

    httpfs always downloads the file in chunks so the file size has nothing to do with this.

    In fact, for the return 3 to happen you would have to get reset on the very first request. If you got it on any subsequent request you would just get I/O error. If the very first request to a server returns ECONNRESET then it means that the server is not accessible and any further attempts are futile unless you have something very strange going on in your network.

     
  • A build option added in 0.1.5 to handle this error. I am not convinced that this error should ever happen with server that actually works.

     
    • status: open --> open-fixed
     
    • status: open-fixed --> closed-fixed