#include <stddef.h>
#include <string.h>
#include <sys/types.h>
+#include <sys/vfs.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/param.h>
lxc_log_define(lxc_utils, lxc);
-static int _recursive_rmdir_onedev(char *dirname, dev_t pdev,
- const char *exclude, int level)
+static int _recursive_rmdir(char *dirname, dev_t pdev,
+ const char *exclude, int level, bool onedev)
{
struct dirent dirent, *direntp;
DIR *dir;
if (ret < 0) {
switch(errno) {
case ENOTEMPTY:
- INFO("Not deleting snapshots");
+ INFO("Not deleting snapshot %s", pathname);
hadexclude = true;
break;
case ENOTDIR:
failed=1;
continue;
}
- if (mystat.st_dev != pdev)
+ if (onedev && mystat.st_dev != pdev)
continue;
if (S_ISDIR(mystat.st_mode)) {
- if (_recursive_rmdir_onedev(pathname, pdev, exclude, level+1) < 0)
+ if (_recursive_rmdir(pathname, pdev, exclude, level+1, onedev) < 0)
failed=1;
} else {
if (unlink(pathname) < 0) {
- ERROR("%s: failed to delete %s", __func__, pathname);
+ SYSERROR("%s: failed to delete %s", __func__, pathname);
failed=1;
}
}
return failed ? -1 : 0;
}
+/* we have two different magic values for overlayfs, yay */
+#define OVERLAYFS_SUPER_MAGIC 0x794c764f
+#define OVERLAY_SUPER_MAGIC 0x794c7630
+/*
+ * In overlayfs, st_dev is unreliable. so on overlayfs we don't do
+ * the lxc_rmdir_onedev()
+ */
+static bool is_native_overlayfs(const char *path)
+{
+ struct statfs sb;
+
+ if (statfs(path, &sb) < 0)
+ return false;
+ if (sb.f_type == OVERLAYFS_SUPER_MAGIC ||
+ sb.f_type == OVERLAY_SUPER_MAGIC)
+ return true;
+ return false;
+}
+
/* returns 0 on success, -1 if there were any failures */
extern int lxc_rmdir_onedev(char *path, const char *exclude)
{
struct stat mystat;
+ bool onedev = true;
+
+ if (is_native_overlayfs(path)) {
+ onedev = false;
+ }
if (lstat(path, &mystat) < 0) {
ERROR("%s: failed to stat %s", __func__, path);
return -1;
}
- return _recursive_rmdir_onedev(path, mystat.st_dev, exclude, 0);
+ return _recursive_rmdir(path, mystat.st_dev, exclude, 0, onedev);
}
static int mount_fs(const char *source, const char *target, const char *type)