POSIX 兼容性

JuiceFS 借助于 pjdfstest 和 LTP 来验证其对 POSIX 的兼容性。

Pjdfstest

Pjdfstest 是一个用来帮助验证 POSIX 系统调用的测试集,JuiceFS 通过了其最新的 8813 项测试:

  1. All tests successful.
  2. Test Summary Report
  3. -------------------
  4. /root/soft/pjdfstest/tests/chown/00.t (Wstat: 0 Tests: 1323 Failed: 0)
  5. TODO passed: 693, 697, 708-709, 714-715, 729, 733
  6. Files=235, Tests=8813, 233 wallclock secs ( 2.77 usr 0.38 sys + 2.57 cusr 3.93 csys = 9.65 CPU)
  7. Result: PASS

此外,JuiceFS 还提供:

  • 关闭再打开(close-to-open)一致性。一旦一个文件写入完成并关闭,之后的打开和读操作保证可以访问之前写入的数据。如果是在同一个挂载点,所有写入的数据都可以立即读。
  • 重命名以及所有其他元数据操作都是原子的,由元数据引擎的事务机制保证。
  • 当文件被删除后,同一个挂载点上如果已经打开了,文件还可以继续访问。
  • 支持 mmap
  • 支持 fallocate 以及空洞
  • 支持扩展属性
  • 支持 BSD 锁(flock)
  • 支持 POSIX 记录锁(fcntl)

LTP

LTP(Linux Test Project)是一个由 IBM,Cisco 等多家公司联合开发维护的项目,旨在为开源社区提供一个验证 Linux 可靠性和稳定性的测试集。LTP 中包含了各种工具来检验 Linux 内核和相关特性;JuiceFS 通过了其中与文件系统相关的大部分测试例。

测试环境

  • 测试主机: Amazon EC2: c5d.xlarge (4C 8G)
  • 操作系统: Ubuntu 20.04.1 LTS (Kernel 5.4.0-1029-aws)
  • 对象存储: Amazon S3
  • JuiceFS 版本: 0.17-dev (2021-09-16 292f2b65)

测试步骤

  1. 在 GitHub 下载 LTP 源码包
  2. 解压后编译安装:
  1. $ tar -jvxf ltp-full-20210524.tar.bz2
  2. $ cd ltp-full-20210524
  3. $ ./configure
  4. $ make all
  5. $ make install
  1. 测试工具安装在 /opt/ltp,需先切换到此目录:
  1. $ cd /opt/ltp

测试配置文件在 runtest 目录下;为方便测试,删去了 fssyscalls 中部分压力测试和与文件系统不想关的条目(参见附录,修改后保存到文件 fs-jfssyscalls-jfs),然后执行命令:

  1. $ ./runltp -d /mnt/jfs -f fs_bind,fs_perms_simple,fsx,io,smoketest,fs-jfs,syscalls-jfs

测试结果

  1. Testcase Result Exit Value
  2. -------- ------ ----------
  3. fcntl17 FAIL 7
  4. fcntl17_64 FAIL 7
  5. getxattr05 CONF 32
  6. ioctl_loop05 FAIL 4
  7. ioctl_ns07 FAIL 1
  8. lseek11 CONF 32
  9. open14 CONF 32
  10. openat03 CONF 32
  11. setxattr03 FAIL 6
  12. -----------------------------------------------
  13. Total Tests: 1270
  14. Total Skipped Tests: 4
  15. Total Failures: 5
  16. Kernel Version: 5.4.0-1029-aws
  17. Machine Architecture: x86_64

其中跳过和失败的测试例原因如下:

  • fcntl17,fcntl17_64:在 POSIX locks 加锁时需要文件系统自动检测死锁,目前 JuiceFS 尚不支持
  • getxattr05:需要设置 ACL,目前 JuiceFS 尚不支持
  • ioctl_loop05,ioctl_ns07,setxattr03:需要调用 ioctl,目前 JuiceFS 尚不支持
  • lseek11:需要 lseek 处理 SEEK_DATA 和 SEEK_HOLE 标记位,目前 JuiceFS 用的是内核通用实现,尚不支持这两个 flags
  • open14,openat03:需要 open 处理 O_TMPFILE 标记位,由于 FUSE 不支持,JuiceFS 也无法实现

附录

fssyscalls 文件中删去的测试例:

  1. # fs --> fs-jfs
  2. gf01 growfiles -W gf01 -b -e 1 -u -i 0 -L 20 -w -C 1 -l -I r -T 10 -f glseek20 -S 2 -d $TMPDIR
  3. gf02 growfiles -W gf02 -b -e 1 -L 10 -i 100 -I p -S 2 -u -f gf03_ -d $TMPDIR
  4. gf03 growfiles -W gf03 -b -e 1 -g 1 -i 1 -S 150 -u -f gf05_ -d $TMPDIR
  5. gf04 growfiles -W gf04 -b -e 1 -g 4090 -i 500 -t 39000 -u -f gf06_ -d $TMPDIR
  6. gf05 growfiles -W gf05 -b -e 1 -g 5000 -i 500 -t 49900 -T10 -c9 -I p -u -f gf07_ -d $TMPDIR
  7. gf06 growfiles -W gf06 -b -e 1 -u -r 1-5000 -R 0--1 -i 0 -L 30 -C 1 -f g_rand10 -S 2 -d $TMPDIR
  8. gf07 growfiles -W gf07 -b -e 1 -u -r 1-5000 -R 0--2 -i 0 -L 30 -C 1 -I p -f g_rand13 -S 2 -d $TMPDIR
  9. gf08 growfiles -W gf08 -b -e 1 -u -r 1-5000 -R 0--2 -i 0 -L 30 -C 1 -f g_rand11 -S 2 -d $TMPDIR
  10. gf09 growfiles -W gf09 -b -e 1 -u -r 1-5000 -R 0--1 -i 0 -L 30 -C 1 -I p -f g_rand12 -S 2 -d $TMPDIR
  11. gf10 growfiles -W gf10 -b -e 1 -u -r 1-5000 -i 0 -L 30 -C 1 -I l -f g_lio14 -S 2 -d $TMPDIR
  12. gf11 growfiles -W gf11 -b -e 1 -u -r 1-5000 -i 0 -L 30 -C 1 -I L -f g_lio15 -S 2 -d $TMPDIR
  13. gf12 mkfifo $TMPDIR/gffifo17; growfiles -b -W gf12 -e 1 -u -i 0 -L 30 $TMPDIR/gffifo17
  14. gf13 mkfifo $TMPDIR/gffifo18; growfiles -b -W gf13 -e 1 -u -i 0 -L 30 -I r -r 1-4096 $TMPDIR/gffifo18
  15. gf14 growfiles -W gf14 -b -e 1 -u -i 0 -L 20 -w -l -C 1 -T 10 -f glseek19 -S 2 -d $TMPDIR
  16. gf15 growfiles -W gf15 -b -e 1 -u -r 1-49600 -I r -u -i 0 -L 120 -f Lgfile1 -d $TMPDIR
  17. gf16 growfiles -W gf16 -b -e 1 -i 0 -L 120 -u -g 4090 -T 101 -t 408990 -l -C 10 -c 1000 -S 10 -f Lgf02_ -d $TMPDIR
  18. gf17 growfiles -W gf17 -b -e 1 -i 0 -L 120 -u -g 5000 -T 101 -t 499990 -l -C 10 -c 1000 -S 10 -f Lgf03_ -d $TMPDIR
  19. gf18 growfiles -W gf18 -b -e 1 -i 0 -L 120 -w -u -r 10-5000 -I r -l -S 2 -f Lgf04_ -d $TMPDIR
  20. gf19 growfiles -W gf19 -b -e 1 -g 5000 -i 500 -t 49900 -T10 -c9 -I p -o O_RDWR,O_CREAT,O_TRUNC -u -f gf08i_ -d $TMPDIR
  21. gf20 growfiles -W gf20 -D 0 -b -i 0 -L 60 -u -B 1000b -e 1 -r 1-256000:512 -R 512-256000 -T 4 -f gfbigio-$$ -d $TMPDIR
  22. gf21 growfiles -W gf21 -D 0 -b -i 0 -L 60 -u -B 1000b -e 1 -g 20480 -T 10 -t 20480 -f gf-bld-$$ -d $TMPDIR
  23. gf22 growfiles -W gf22 -D 0 -b -i 0 -L 60 -u -B 1000b -e 1 -g 20480 -T 10 -t 20480 -f gf-bldf-$$ -d $TMPDIR
  24. gf23 growfiles -W gf23 -D 0 -b -i 0 -L 60 -u -B 1000b -e 1 -r 512-64000:1024 -R 1-384000 -T 4 -f gf-inf-$$ -d $TMPDIR
  25. gf24 growfiles -W gf24 -D 0 -b -i 0 -L 60 -u -B 1000b -e 1 -g 20480 -f gf-jbld-$$ -d $TMPDIR
  26. gf25 growfiles -W gf25 -D 0 -b -i 0 -L 60 -u -B 1000b -e 1 -r 1024000-2048000:2048 -R 4095-2048000 -T 1 -f gf-large-gs-$$ -d $TMPDIR
  27. gf26 growfiles -W gf26 -D 0 -b -i 0 -L 60 -u -B 1000b -e 1 -r 128-32768:128 -R 512-64000 -T 4 -f gfsmallio-$$ -d $TMPDIR
  28. gf27 growfiles -W gf27 -b -D 0 -w -g 8b -C 1 -b -i 1000 -u -f gfsparse-1-$$ -d $TMPDIR
  29. gf28 growfiles -W gf28 -b -D 0 -w -g 16b -C 1 -b -i 1000 -u -f gfsparse-2-$$ -d $TMPDIR
  30. gf29 growfiles -W gf29 -b -D 0 -r 1-4096 -R 0-33554432 -i 0 -L 60 -C 1 -u -f gfsparse-3-$$ -d $TMPDIR
  31. gf30 growfiles -W gf30 -D 0 -b -i 0 -L 60 -u -B 1000b -e 1 -o O_RDWR,O_CREAT,O_SYNC -g 20480 -T 10 -t 20480 -f gf-sync-$$ -d $TMPDIR
  32. rwtest01 export LTPROOT; rwtest -N rwtest01 -c -q -i 60s -f sync 10%25000:$TMPDIR/rw-sync-$$
  33. rwtest02 export LTPROOT; rwtest -N rwtest02 -c -q -i 60s -f buffered 10%25000:$TMPDIR/rw-buffered-$$
  34. rwtest03 export LTPROOT; rwtest -N rwtest03 -c -q -i 60s -n 2 -f buffered -s mmread,mmwrite -m random -Dv 10%25000:$TMPDIR/mm-buff-$$
  35. rwtest04 export LTPROOT; rwtest -N rwtest04 -c -q -i 60s -n 2 -f sync -s mmread,mmwrite -m random -Dv 10%25000:$TMPDIR/mm-sync-$$
  36. rwtest05 export LTPROOT; rwtest -N rwtest05 -c -q -i 50 -T 64b 500b:$TMPDIR/rwtest01%f
  37. iogen01 export LTPROOT; rwtest -N iogen01 -i 120s -s read,write -Da -Dv -n 2 500b:$TMPDIR/doio.f1.$$ 1000b:$TMPDIR/doio.f2.$$
  38. quota_remount_test01 quota_remount_test01.sh
  39. isofs isofs.sh
  40. # syscalls --> syscalls-jfs
  41. bpf_prog05 bpf_prog05
  42. cacheflush01 cacheflush01
  43. chown01_16 chown01_16
  44. chown02_16 chown02_16
  45. chown03_16 chown03_16
  46. chown04_16 chown04_16
  47. chown05_16 chown05_16
  48. clock_nanosleep03 clock_nanosleep03
  49. clock_gettime03 clock_gettime03
  50. leapsec01 leapsec01
  51. close_range01 close_range01
  52. close_range02 close_range02
  53. fallocate06 fallocate06
  54. fchown01_16 fchown01_16
  55. fchown02_16 fchown02_16
  56. fchown03_16 fchown03_16
  57. fchown04_16 fchown04_16
  58. fchown05_16 fchown05_16
  59. fcntl06 fcntl06
  60. fcntl06_64 fcntl06_64
  61. getegid01_16 getegid01_16
  62. getegid02_16 getegid02_16
  63. geteuid01_16 geteuid01_16
  64. geteuid02_16 geteuid02_16
  65. getgid01_16 getgid01_16
  66. getgid03_16 getgid03_16
  67. getgroups01_16 getgroups01_16
  68. getgroups03_16 getgroups03_16
  69. getresgid01_16 getresgid01_16
  70. getresgid02_16 getresgid02_16
  71. getresgid03_16 getresgid03_16
  72. getresuid01_16 getresuid01_16
  73. getresuid02_16 getresuid02_16
  74. getresuid03_16 getresuid03_16
  75. getrusage04 getrusage04
  76. getuid01_16 getuid01_16
  77. getuid03_16 getuid03_16
  78. ioctl_sg01 ioctl_sg01
  79. fanotify16 fanotify16
  80. fanotify18 fanotify18
  81. fanotify19 fanotify19
  82. lchown01_16 lchown01_16
  83. lchown02_16 lchown02_16
  84. lchown03_16 lchown03_16
  85. mbind02 mbind02
  86. mbind03 mbind03
  87. mbind04 mbind04
  88. migrate_pages02 migrate_pages02
  89. migrate_pages03 migrate_pages03
  90. modify_ldt01 modify_ldt01
  91. modify_ldt02 modify_ldt02
  92. modify_ldt03 modify_ldt03
  93. move_pages01 move_pages01
  94. move_pages02 move_pages02
  95. move_pages03 move_pages03
  96. move_pages04 move_pages04
  97. move_pages05 move_pages05
  98. move_pages06 move_pages06
  99. move_pages07 move_pages07
  100. move_pages09 move_pages09
  101. move_pages10 move_pages10
  102. move_pages11 move_pages11
  103. move_pages12 move_pages12
  104. msgctl05 msgctl05
  105. msgstress04 msgstress04
  106. openat201 openat201
  107. openat202 openat202
  108. openat203 openat203
  109. madvise06 madvise06
  110. madvise09 madvise09
  111. ptrace04 ptrace04
  112. quotactl01 quotactl01
  113. quotactl04 quotactl04
  114. quotactl06 quotactl06
  115. readdir21 readdir21
  116. recvmsg03 recvmsg03
  117. sbrk03 sbrk03
  118. semctl08 semctl08
  119. semctl09 semctl09
  120. set_mempolicy01 set_mempolicy01
  121. set_mempolicy02 set_mempolicy02
  122. set_mempolicy03 set_mempolicy03
  123. set_mempolicy04 set_mempolicy04
  124. set_thread_area01 set_thread_area01
  125. setfsgid01_16 setfsgid01_16
  126. setfsgid02_16 setfsgid02_16
  127. setfsgid03_16 setfsgid03_16
  128. setfsuid01_16 setfsuid01_16
  129. setfsuid02_16 setfsuid02_16
  130. setfsuid03_16 setfsuid03_16
  131. setfsuid04_16 setfsuid04_16
  132. setgid01_16 setgid01_16
  133. setgid02_16 setgid02_16
  134. setgid03_16 setgid03_16
  135. sgetmask01 sgetmask01
  136. setgroups01_16 setgroups01_16
  137. setgroups02_16 setgroups02_16
  138. setgroups03_16 setgroups03_16
  139. setgroups04_16 setgroups04_16
  140. setregid01_16 setregid01_16
  141. setregid02_16 setregid02_16
  142. setregid03_16 setregid03_16
  143. setregid04_16 setregid04_16
  144. setresgid01_16 setresgid01_16
  145. setresgid02_16 setresgid02_16
  146. setresgid03_16 setresgid03_16
  147. setresgid04_16 setresgid04_16
  148. setresuid01_16 setresuid01_16
  149. setresuid02_16 setresuid02_16
  150. setresuid03_16 setresuid03_16
  151. setresuid04_16 setresuid04_16
  152. setresuid05_16 setresuid05_16
  153. setreuid01_16 setreuid01_16
  154. setreuid02_16 setreuid02_16
  155. setreuid03_16 setreuid03_16
  156. setreuid04_16 setreuid04_16
  157. setreuid05_16 setreuid05_16
  158. setreuid06_16 setreuid06_16
  159. setreuid07_16 setreuid07_16
  160. setuid01_16 setuid01_16
  161. setuid03_16 setuid03_16
  162. setuid04_16 setuid04_16
  163. shmctl06 shmctl06
  164. socketcall01 socketcall01
  165. socketcall02 socketcall02
  166. socketcall03 socketcall03
  167. ssetmask01 ssetmask01
  168. swapoff01 swapoff01
  169. swapoff02 swapoff02
  170. swapon01 swapon01
  171. swapon02 swapon02
  172. swapon03 swapon03
  173. switch01 endian_switch01
  174. sysinfo03 sysinfo03
  175. timerfd04 timerfd04
  176. perf_event_open02 perf_event_open02
  177. statx07 statx07
  178. io_uring02 io_uring02