If while reading a file from fusefs signal is received, then read(2) will return 0 and errno 0 (just like EOF) instead of EINTR. How-To-Repeat: /* --------------------------- fuse.c ------------------------ */ #include <fuse.h> #include <string.h> #include <sys/stat.h> #include <stdlib.h> #include <unistd.h> int fs_getattr(const char *name, struct stat *st) { st->st_mode = S_IFREG; st->st_size = 1; return 0; } int fs_read(const char *name, char *buf, size_t bufSize, off_t off, struct fuse_file_info *fi) { sleep(10); return 1; } int main(int argc, char **argv) { struct fuse_operations operations; memset(&operations, 0, sizeof(operations)); operations.read = fs_read; operations.getattr = fs_getattr; return fuse_main(argc, argv, &operations, NULL); } /* ----------------------------------------------------------- */ /* ------------------------- reader.c ------------------------ */ #include <stdio.h> #include <unistd.h> #include <fcntl.h> #include <stdlib.h> #include <errno.h> #include <signal.h> void on_alarm(int s) { fprintf(stderr, "alarm\n"); } int main(int argc, char **argv) { int fd, readed; char buf[16]; if(argc < 2) exit(255); fd = open(argv[1], O_RDONLY); if(fd < 0) { perror("open"); exit(errno); } /* handler required, SIG_IGN will mask the error */ signal(SIGALRM, on_alarm); alarm(1); readed = read(fd, buf, sizeof(buf)); fprintf(stderr, "Readed: %d, errno=%d\n", (int)readed, (int)errno); return 0; } /* ---------------------------------------------------------- */ # cc -o fs -Wall -D_FILE_OFFSET_BITS=64 -DFUSE_USE_VERSION=26 -I/usr/local/include -L/usr/local/lib -pthread -lfuse fuse.c # cc -o reader -Wall reader.c # mkdir mnt # ./fs -o allow_other -o direct_io mnt # ./reader mnt <<< sleep for 1 second >>> alarm Readed: 0, errno=0
Responsible Changed From-To: freebsd-bugs->freebsd-fs Over to maintainer(s).
For bugs matching the following criteria: Status: In Progress Changed: (is less than) 2014-06-01 Reset to default assignee and clear in-progress tags. Mail being skipped
Is this still present? I had a quick look around but don't see any recent changes that I would expect to fix this.
I cannot reproduce this on 12.0. The signal does not interrupt the read(2).
(In reply to Alan Somers from comment #4) > The signal does not interrupt the read(2). Hm, isn't that part of the bug? Signals are supposed to interrupt blocked I/O; not interrupting explains the symptoms from the description mostly (sleep, then signal handler, then read returns zero).
That said, it seems like all sleeps in the read path in sys/fs/fuse use PCATCH. There is a PCATCH-less tsleep associated with flush, but I don't know why that would be invoked for a read.
(In reply to Conrad Meyer from comment #6) Sigh. Yes, we PCATCH, *but*: 314 static int 315 fticket_wait_answer(struct fuse_ticket *ftick) 316 { ... 334 fuse_block_sigs(&tset); 335 err = msleep(ftick, &ftick->tk_aw_mtx, PCATCH, "fu_ans", 336 data->daemon_timeout * hz); 337 fuse_restore_sigs(&tset); We block all signals but SIGKILL.
Firstly, let me thank you for such a good reproduction case. This is certainly the best reproduction case I've ever seen for a user-reported fuse bug, and it ranks highly for the best reproduction cases I've ever seen for a user-reported bug on any project. That said, I'm going to close the issue because I can't reproduce it. Judging by the date of your post, you were probably using the sysutils/fusefs-kmod port, which has been replaced by the in-tree fusefs(5) driver. There have been many improvements. I plan to tackle interruptibility in bug 236530.