Commit 6147fe2e by Serge Hallyn Committed by Stéphane Graber

lxc-destroy: actually work if underlying fs is overlayfs

One of the 'features' of overlayfs is that depending on whether a file is on the upper or lower dir you get back a different device from stat. That breaks our lxc_rmdir_onedev. So at lxc_rmdir_ondev check the device of the directory being deleted. If it is overlayfs, then skip the device check. Note this is unrelated to overlayfs snapshots - in those cases when you delete a container, /var/lib/lxc/$container/ does not actually have an overlayfs under it. Rather, to reproduce this you would sudo mkdir /opt/{lower,upper,workdir} sudo mount -t overlayfs -o lower=/opt/lower,upper=/opt/upper,workdir=/opt/workdir \ lxc /var/lib/lxc sudo lxc-create -t download -n c1 -- -d ubuntu -r trusty -a amd64 sudo lxc-destroy -n c1 Signed-off-by: 's avatarSerge Hallyn <serge.hallyn@ubuntu.com> Tested-by: 's avatarMarko Ratkaj <marko.ratkaj@sartura.hr> Acked-by: 's avatarStéphane Graber <stgraber@ubuntu.com>
parent da2cac40
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <stddef.h> #include <stddef.h>
#include <string.h> #include <string.h>
#include <sys/types.h> #include <sys/types.h>
#include <sys/vfs.h>
#include <sys/stat.h> #include <sys/stat.h>
#include <sys/mman.h> #include <sys/mman.h>
#include <sys/param.h> #include <sys/param.h>
...@@ -46,7 +47,7 @@ ...@@ -46,7 +47,7 @@
lxc_log_define(lxc_utils, lxc); lxc_log_define(lxc_utils, lxc);
static int _recursive_rmdir_onedev(char *dirname, dev_t pdev) static int _recursive_rmdir(char *dirname, dev_t pdev, bool onedev)
{ {
struct dirent dirent, *direntp; struct dirent dirent, *direntp;
DIR *dir; DIR *dir;
...@@ -76,20 +77,21 @@ static int _recursive_rmdir_onedev(char *dirname, dev_t pdev) ...@@ -76,20 +77,21 @@ static int _recursive_rmdir_onedev(char *dirname, dev_t pdev)
failed=1; failed=1;
continue; continue;
} }
ret = lstat(pathname, &mystat); ret = lstat(pathname, &mystat);
if (ret) { if (ret) {
ERROR("%s: failed to stat %s", __func__, pathname); ERROR("%s: failed to stat %s", __func__, pathname);
failed=1; failed=1;
continue; continue;
} }
if (mystat.st_dev != pdev) if (onedev && mystat.st_dev != pdev)
continue; continue;
if (S_ISDIR(mystat.st_mode)) { if (S_ISDIR(mystat.st_mode)) {
if (_recursive_rmdir_onedev(pathname, pdev) < 0) if (_recursive_rmdir(pathname, pdev, onedev) < 0)
failed=1; failed=1;
} else { } else {
if (unlink(pathname) < 0) { if (unlink(pathname) < 0) {
ERROR("%s: failed to delete %s", __func__, pathname); SYSERROR("%s: failed to delete %s", __func__, pathname);
failed=1; failed=1;
} }
} }
...@@ -109,17 +111,41 @@ static int _recursive_rmdir_onedev(char *dirname, dev_t pdev) ...@@ -109,17 +111,41 @@ static int _recursive_rmdir_onedev(char *dirname, dev_t pdev)
return failed ? -1 : 0; 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 */ /* returns 0 on success, -1 if there were any failures */
extern int lxc_rmdir_onedev(char *path) extern int lxc_rmdir_onedev(char *path)
{ {
struct stat mystat; struct stat mystat;
bool onedev = true;
if (is_native_overlayfs(path)) {
onedev = false;
}
if (lstat(path, &mystat) < 0) { if (lstat(path, &mystat) < 0) {
ERROR("%s: failed to stat %s", __func__, path); ERROR("%s: failed to stat %s", __func__, path);
return -1; return -1;
} }
return _recursive_rmdir_onedev(path, mystat.st_dev); return _recursive_rmdir(path, mystat.st_dev, onedev);
} }
static int mount_fs(const char *source, const char *target, const char *type) static int mount_fs(const char *source, const char *target, const char *type)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment