[TN#009] Netatalk and ZFS nbmand property
- Author
- Ralph Böhme
- Published on
- April 17, 2012
Running the Netatalk test-suite with a volume on a ZFS set with ZFS property nbmand set to on causes nearly all tests to fail. The reason is (and it’s something Oracle hides well under the covers): it modifies POSIX semantics up to a point that POSIX compliant applications fail left and right.
We’ve written and attached a small C program which demonstrates the effect. It opens a file in read/write mode, then forks a child process and in the child process tries to rename the file.
Expected result on a POSIX conforming platform: success.
Actual result with nbmand=on: permission denied.
Usage:
$ gcc -o nbmand-demo nbmand-demo.c
$ cd /path/zfs-set/with/nbmand=off
$ touch file
$ /path/to/nbmand-demo file
… success …
$ cd /path/zfs-set/with/nbmand=on
$ touch file
$ /path/to/nbmand-demo file
… failure …
Therefor it is necessary to turn nbmand to off on any ZFS dataset you use for Netatalk AFP volumes.
nbmand-demo.c
#define _FILE_OFFSET_BITS 64 #include#include #include #include #include #include int main(int argc, char *argv[]) { const char *file; struct flock fl; int fd; pid_t pid; if (argc != 2) { printf("usage: %s FILE\n", argv[0]); exit(1); } file = argv[1]; printf("Press to open file \"%s\": ", file); getchar(); if ((fd = open(file, O_RDWR)) == -1) { perror("open"); exit(1); } if ((pid = fork()) == -1) { perror("fork"); exit(1); } if (pid == 0) { /* Child */ printf("Press to rename file \"%s\" -> \"tmp\": ", file); getchar(); if (rename(file, "tmp") == -1) { perror("rename"); } else { printf("renamed.\n"); rename("tmp", file); } printf("Press to exit"); getchar(); exit(0); } /* Parent */ if (waitpid(pid, NULL, 0) != pid) { perror("waitpid"); exit(1); } close(fd); return 0; }