1. 8

    I’m surprised there’s no mention of the obvious solution. select/poll with a timeout. get back EINTR, you got sigchild. get back 0, timed out.

    1. 2

      Maybe I’m misunderstanding, but how does that help with a timeout on, say, mkdir(2)?

      1. 4

        It doesn’t, but I’m not sure that what people think would happen is what’s going to happen. mkdir isn’t usually interruptible. If your NFS server goes away, you’ll have an unkillable process until it comes back. You’re not going to work around that with threads or alarm signals or whatever. The issues go much deeper.

        1. 2

          Is this a place where expanding AIO might be useful? I have not used AIO other than poked around the man pages in FreeBSD a bit. I’m not really sure why making file reads/writes needs a whole new abstraction, though…

          1. 4

            So one other thing is that mkdir is going to call malloc in a half dozen places on the way down. Any one of those calls can block indefinitely for memory to become available, and they can’t be interrupted because the callers don’t check for null. Real time kernels are the next aisle over.

            1. 3

              Expanding AIO requires major kernel restructuring of what is currently straight line code so that either it’s explicitly asynchronous or the current synchronous code is always spawned in a new kernel thread with notification on completion or error. Neither are small efforts, which is a good part of why the (kernel) answer so far has often been some version of ‘if you want this, use user-level threads to do it yourself’.

            2. 2

              What a user friendly program can do then? Run all file system touching syscalls in separate process? If it hangs give an option to the user to kill it (and leave a zombie I presume) or wait and notify when it will resume?

              It’s honest question. I personally think it is sensible to create a separate process.

              1. 3

                Yes. This is very sensible and it is the exact model encouraged by erlang.

                It doesn’t have to be a separate process (isolated fork) though– a pthread is usually fine as long as your data flows go the right way.

                1. 3

                  Ignore it until it goes away? It’s funny, last week we had a rant that unix sucks because worse is better means all these silly errors have to be handled by userland. Now we have a syscall which handles retries and failure for you and people want the opposite.

                  1. 2

                    Document that you don’t support NFS. Advise your users to use CIFS instead (seriously, it behaves much more nicely, even when both ends are unix).

                  2. 1

                    If your NFS server goes away, you’ll have an unkillable process until it comes back.

                    mount_nfs -i ... shudders

                2. 2

                  Or another signal.

                  Or you’re running under xen.

                  1. 1

                    It would be nice if all system calls had an asynchronous version which returned a completion fd. Select()/poll()/kqueue()/epoll() on it to your hearts content. This would also be great for async io, with the caveat that the read/write buffers can’t be touched until completion gets signalled.

                    It’s not likely to happen, though.

                    1. 1

                      Well, think about some other cases… like chdir(). What async semantics do you want there?

                      1. 1

                        chdir() is one of the easier cases. Keep a reference to the current directory until you successfully look up the new directory. Then change over atomically and signal a success. The chdir() will either take effect some time between the system call being invoked and the completion being signalled, or you will get a failure.

                        It gets harder with system calls that can have partial effects before failures. mkdir, for example, may successfully the directory, but if it’s on an NFS mount, the connection may die before you can get a response. That means that the operations aren’t idempotent, and blind retries might break.

                        It’s not trivial to retrofit async actions in, but it would still be nice if it could happen.