public inbox for libc-help@sourceware.org
 help / color / mirror / Atom feed
From: Tobias Bading <tbading@web.de>
To: libc-help@sourceware.org
Subject: Re: (stat(...) == -1 || faccessat(...) == -1) && errno == EINTR ?!??
Date: Sun, 14 Feb 2021 13:18:40 +0100	[thread overview]
Message-ID: <d24710ab-d78f-37b6-5b3d-5c16db67d332@web.de> (raw)
In-Reply-To: <c67bcb6b-a628-9d29-3655-3a406a52d996@web.de>

[-- Attachment #1: Type: text/plain, Size: 2496 bytes --]

Hello again.

I've been able to reproduce the problem with the attached program. With
SIGALRMs firing 10 times per second, I get maybe a dozen "handler
called" lines before stat() or faccessat() fails with errno EINTR. When
I increase the rate to 50 SIGALRMs per second, the very first stat()
fails in every test run.

Specifying SA_RESTART in sigaction() has no effect.

Unfortunately, I don't have any other network shares available at the
moment to test whether only CIFS through VPN is affected, or the problem
would occur with e.g. NFS or CIFS without a VPN as well.

Tobias

---

On 14.02.21 12:13, Tobias Bading wrote:
> Hi.
>
> A few days ago I encountered strange problems at home while using GNU
> Emacs on GNU/Linux with Windows SMB shares in the office automounted
> through the company's VPN.
>
> Details and my current findings on the Emacs devel mailing list:
> https://lists.gnu.org/archive/html/emacs-devel/2021-02/msg00835.html.
>
> TL;DR:
> Emacs' stat() and faccessat() calls sometimes return -1 and set errno
> to EINTR (according to strace). Most of the time the interruption
> seems to come from a SIGIO, but at least once a SIGCHLD was in the mix
> as well.
>
> The behavior of returning with errno == EINTR seems to be new and/or
> some kind of bug, because otherwise Emacs would handle that case with
> TEMP_FAILURE_RETRY() or something to that effect, right? I've used
> pretty much the same Emacs in the office (on an older GNU/Linux
> release) for ages with the same Windows SMB shares and never had this
> problem.
>
> The GNU/Linux man pages of stat() and faccessat() don't mention EINTR
> at all, and neither does POSIX
> (https://pubs.opengroup.org/onlinepubs/9699919799/).
>
> So I guess the one million dollar question is this:
> Are stat() and faccessat() permitted to return -1 with errno == EINTR,
> or does that violate the POSIX (or some other) spec?
>
> I'll probably write a small test program next to check if I can
> reproduce this problem outside of Emacs, maybe with a simple SIGALRM
> and an endless loop of stat()/faccessat() calls. If that reproduces
> the problem it would be nice to know whether using SA_RESTART in
> sigaction() has any effect.
>
> Any ideas are very welcome... :)
>
> Tobias
>
> PS: I'm running Ubuntu focal (20.04.2 LTS, amd64), which currently
> uses libc-bin 2.31-0ubuntu9.2, kernel linux-image-5.4.0-64-generic and
> openconnect 8.05-1 to access the VPN.
>


[-- Attachment #2: dont-interrupt-me.c --]
[-- Type: text/x-csrc, Size: 1104 bytes --]

#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <sys/types.h>
#include <unistd.h>

static const char path[] = "/smb/server/share/dir/subdir";

void handler (int signum)
{
  static const char t[] = "handler called\n";
  write (1, t, sizeof t);
}

int main ()
{
  struct stat st;
  struct sigaction action;
  struct itimerval timer;

  memset (&action, 0, sizeof action);
  action.sa_handler = handler;
  action.sa_flags = SA_RESTART;
  if (sigaction (SIGALRM, &action, NULL))
  {
    perror ("sigaction() failed");
    return 1;
  }

  timer.it_value.tv_sec  = timer.it_interval.tv_sec  = 0;
  timer.it_value.tv_usec = timer.it_interval.tv_usec = 1000000 / 10;
  if (setitimer (ITIMER_REAL, &timer, NULL))
  {
    perror ("setitimer() failed");
    return 1;
  }

  for (;;)
  {
    int r = stat (path, &st);
    if (r)
    {
      perror ("stat() failed");
      return 1;
    }

    r = faccessat (AT_FDCWD, path, R_OK, 0);
    if (r)
    {
      perror ("faccessat() failed");
      return 1;
    }
  }

  return 0;
}


  reply	other threads:[~2021-02-14 12:18 UTC|newest]

Thread overview: 20+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-02-14 11:13 Tobias Bading
2021-02-14 12:18 ` Tobias Bading [this message]
2021-02-14 13:17   ` Tobias Bading
2021-02-14 15:14     ` Godmar Back
2021-02-14 15:20       ` Godmar Back
2021-02-14 17:30       ` Tobias Bading
2021-02-14 22:04         ` Godmar Back
2021-02-15  9:15           ` Tobias Bading
2021-02-15  9:24             ` Florian Weimer
2021-02-15  9:43               ` Tobias Bading
2021-02-15  9:45                 ` Florian Weimer
2021-02-15 10:02                   ` Tobias Bading
2021-02-15 10:20                     ` Florian Weimer
2021-02-15 10:36                       ` Tobias Bading
2021-02-15  8:33         ` Tobias Bading
2021-02-15  8:45           ` Konstantin Kharlamov
2021-02-15 10:25             ` Tobias Bading
2021-02-14 17:56   ` Konstantin Kharlamov
2021-02-14 18:58     ` Tobias Bading
2021-02-14 20:46       ` Konstantin Kharlamov

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=d24710ab-d78f-37b6-5b3d-5c16db67d332@web.de \
    --to=tbading@web.de \
    --cc=libc-help@sourceware.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).