You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

113 lines
3.3 KiB

  1. One of the 'features' of overlayfs is that depending on whether a file
  2. is on the upper or lower dir you get back a different device from stat.
  3. That breaks our lxc_rmdir_onedev.
  4. So at lxc_rmdir_ondev check the device of the directory being deleted.
  5. If it is overlayfs, then skip the device check.
  6. Note this is unrelated to overlayfs snapshots - in those cases when you
  7. delete a container, /var/lib/lxc/$container/ does not actually have an
  8. overlayfs under it. Rather, to reproduce this you would
  9. sudo mkdir /opt/{lower,upper,workdir}
  10. sudo mount -t overlayfs -o lower=/opt/lower,upper=/opt/upper,workdir=/opt/workdir \
  11. lxc /var/lib/lxc
  12. sudo lxc-create -t download -n c1 -- -d ubuntu -r trusty -a amd64
  13. sudo lxc-destroy -n c1
  14. Signed-off-by: Serge Hallyn <serge.hallyn@ubuntu.com>
  15. ---
  16. src/lxc/utils.c | 39 ++++++++++++++++++++++++++++++++-------
  17. 1 file changed, 32 insertions(+), 7 deletions(-)
  18. --- a/src/lxc/utils.c
  19. +++ b/src/lxc/utils.c
  20. @@ -29,6 +29,7 @@
  21. #include <stddef.h>
  22. #include <string.h>
  23. #include <sys/types.h>
  24. +#include <sys/vfs.h>
  25. #include <sys/stat.h>
  26. #include <sys/mman.h>
  27. #include <sys/param.h>
  28. @@ -68,8 +69,8 @@
  29. lxc_log_define(lxc_utils, lxc);
  30. -static int _recursive_rmdir_onedev(char *dirname, dev_t pdev,
  31. - const char *exclude, int level)
  32. +static int _recursive_rmdir(char *dirname, dev_t pdev,
  33. + const char *exclude, int level, bool onedev)
  34. {
  35. struct dirent dirent, *direntp;
  36. DIR *dir;
  37. @@ -106,7 +107,7 @@ static int _recursive_rmdir_onedev(char
  38. if (ret < 0) {
  39. switch(errno) {
  40. case ENOTEMPTY:
  41. - INFO("Not deleting snapshots");
  42. + INFO("Not deleting snapshot %s", pathname);
  43. hadexclude = true;
  44. break;
  45. case ENOTDIR:
  46. @@ -129,14 +130,14 @@ static int _recursive_rmdir_onedev(char
  47. failed=1;
  48. continue;
  49. }
  50. - if (mystat.st_dev != pdev)
  51. + if (onedev && mystat.st_dev != pdev)
  52. continue;
  53. if (S_ISDIR(mystat.st_mode)) {
  54. - if (_recursive_rmdir_onedev(pathname, pdev, exclude, level+1) < 0)
  55. + if (_recursive_rmdir(pathname, pdev, exclude, level+1, onedev) < 0)
  56. failed=1;
  57. } else {
  58. if (unlink(pathname) < 0) {
  59. - ERROR("%s: failed to delete %s", __func__, pathname);
  60. + SYSERROR("%s: failed to delete %s", __func__, pathname);
  61. failed=1;
  62. }
  63. }
  64. @@ -158,17 +159,41 @@ static int _recursive_rmdir_onedev(char
  65. return failed ? -1 : 0;
  66. }
  67. +/* we have two different magic values for overlayfs, yay */
  68. +#define OVERLAYFS_SUPER_MAGIC 0x794c764f
  69. +#define OVERLAY_SUPER_MAGIC 0x794c7630
  70. +/*
  71. + * In overlayfs, st_dev is unreliable. so on overlayfs we don't do
  72. + * the lxc_rmdir_onedev()
  73. + */
  74. +static bool is_native_overlayfs(const char *path)
  75. +{
  76. + struct statfs sb;
  77. +
  78. + if (statfs(path, &sb) < 0)
  79. + return false;
  80. + if (sb.f_type == OVERLAYFS_SUPER_MAGIC ||
  81. + sb.f_type == OVERLAY_SUPER_MAGIC)
  82. + return true;
  83. + return false;
  84. +}
  85. +
  86. /* returns 0 on success, -1 if there were any failures */
  87. extern int lxc_rmdir_onedev(char *path, const char *exclude)
  88. {
  89. struct stat mystat;
  90. + bool onedev = true;
  91. +
  92. + if (is_native_overlayfs(path)) {
  93. + onedev = false;
  94. + }
  95. if (lstat(path, &mystat) < 0) {
  96. ERROR("%s: failed to stat %s", __func__, path);
  97. return -1;
  98. }
  99. - return _recursive_rmdir_onedev(path, mystat.st_dev, exclude, 0);
  100. + return _recursive_rmdir(path, mystat.st_dev, exclude, 0, onedev);
  101. }
  102. static int mount_fs(const char *source, const char *target, const char *type)