no-allocate.sh 2.4 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677
  1. #!/bin/sh
  2. # make sure that dd doesn't allocate memory unnecessarily
  3. # Copyright (C) 2013-2018 Free Software Foundation, Inc.
  4. # This program is free software: you can redistribute it and/or modify
  5. # it under the terms of the GNU General Public License as published by
  6. # the Free Software Foundation, either version 3 of the License, or
  7. # (at your option) any later version.
  8. # This program is distributed in the hope that it will be useful,
  9. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. # GNU General Public License for more details.
  12. # You should have received a copy of the GNU General Public License
  13. # along with this program. If not, see <https://www.gnu.org/licenses/>.
  14. . "${srcdir=.}/tests/init.sh"; path_prepend_ ./src
  15. print_ver_ dd
  16. # Determine basic amount of memory needed.
  17. echo . > f || framework_failure_
  18. vm=$(get_min_ulimit_v_ timeout 10 dd if=f of=f2 status=none) \
  19. || skip_ "this shell lacks ulimit support"
  20. rm f f2 || framework_failure_
  21. # count and skip are zero, we don't need to allocate memory
  22. (ulimit -v $vm && dd bs=30M count=0) || fail=1
  23. (ulimit -v $vm && dd ibs=30M count=0) || fail=1
  24. (ulimit -v $vm && dd obs=30M count=0) || fail=1
  25. check_dd_seek_alloc() {
  26. local file="$1"
  27. local buf="$2"
  28. test "$file" = 'in' && { dd_file=if; dd_op=skip; }
  29. test "$file" = 'out' && { dd_file=of; dd_op=seek; }
  30. test "$buf" = 'in' && { dd_buf=ibs; }
  31. test "$buf" = 'out' && { dd_buf=obs; }
  32. test "$buf" = 'both' && { dd_buf=bs; }
  33. # Provide input to the "tape"
  34. timeout 10 dd count=1 if=/dev/zero of=tape&
  35. # Allocate buffer and read from the "tape"
  36. (ulimit -v $vm \
  37. && timeout 10 dd $dd_buf=30M $dd_op=1 count=0 $dd_file=tape)
  38. local ret=$?
  39. # Be defensive in case the tape reader is blocked for some reason
  40. test $ret = 124 && framework_failure_
  41. # This should happen without delay,
  42. # and is used to ensure we've not multiple writers to the "tape"
  43. wait
  44. # We want the "tape" reader to fail iff allocating
  45. # a large buffer corresponding to the file being read
  46. case "$file$buf" in
  47. inout|outin) test $ret = 0;;
  48. *) test $ret != 0;;
  49. esac
  50. }
  51. # Use a fifo for which seek fails, but read does not.
  52. # For non seekable output we need to allocate a buffer
  53. # when simulating seeking with a read.
  54. if mkfifo tape; then
  55. for file in 'in' 'out'; do
  56. for buf in 'both' 'in' 'out'; do
  57. check_dd_seek_alloc "$file" "$buf" || fail=1
  58. done
  59. done
  60. fi
  61. Exit $fail