(stat(...) == -1 || faccessat(...) == -1) && errno == EINTR ?!??
Konstantin Kharlamov
hi-angel@yandex.ru
Sun Feb 14 20:46:59 GMT 2021
On Sun, 2021-02-14 at 19:58 +0100, Tobias Bading wrote:
> Hello Konstantin,
>
> thanks for trying to reproduce the problem. Could you please try
>
> void handler (int signum)
> {
> }
>
> and
>
> timer.it_value.tv_usec = timer.it_interval.tv_usec = 1000000 / 10000;
>
> to increase the rate of SIGALRMs to 10000 (or even higher) per second?
> For me this reproduces the error also on shares that looked like they
> weren't affected when only 50 signals per second were created. There
> seems to be only a very short time window in which some piece of
> (probably CIFS-related) kernel code can be thrown of the rails by a
> signal, and the length of that time window probably depends on the
> performance of client and server, the network connection and whatnot.
> Since you're using a local share, your time window to produce the error
> is probably much smaller than mine.
Thanks, did that, I ran the testcase under `time` utility:
λ time ./a
^C
./a 18.98s user 49.15s system 99% cpu 1:08.69 total
So, it ran for a minute before I interrupted it with ^C, no fails observed.
For the record, here's the code I used (the smb share is mounted under /tmp/mnt, and
it's a localhost share).
#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[] = "/tmp/mnt/";
void handler (int signum)
{
}
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 / 10000;
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;
}
I built it with `gcc dont-interrupt-me.c -o a -g3 -O0`
More information about the Libc-help
mailing list