69a5f4bf9f
52691f99-qemu-mig-crash.patch boo#908008 OBS-URL: https://build.opensuse.org/package/show/Virtualization/libvirt?expand=0&rev=424
156 lines
4.9 KiB
Diff
156 lines
4.9 KiB
Diff
From 72fecf1813b9e77a7f89bc1e708f91bdab7d9ad4 Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?C=C3=A9dric=20Bosdonnat?= <cbosdonnat@suse.com>
|
|
Date: Fri, 21 Nov 2014 17:45:55 +0100
|
|
Subject: [PATCH 4/5] lxc: be more patient while resolving symlinks
|
|
|
|
Resolving symlinks can fail before mounting any file system if one file
|
|
system depends on another being mounted. Symlinks are now resolved in
|
|
two passes:
|
|
|
|
* Before any file system is mounted, but then we are more gentle if
|
|
the source path can't be accessed
|
|
* Right before mounting a file system, so that we are sure that we
|
|
have the resolved path... but then if it can't be accessed we raise
|
|
an error.
|
|
---
|
|
src/conf/domain_conf.h | 1 +
|
|
src/lxc/lxc_container.c | 77 ++++++++++++++++++++++++++++++++++---------------
|
|
2 files changed, 54 insertions(+), 24 deletions(-)
|
|
|
|
Index: libvirt-1.2.10/src/conf/domain_conf.h
|
|
===================================================================
|
|
--- libvirt-1.2.10.orig/src/conf/domain_conf.h
|
|
+++ libvirt-1.2.10/src/conf/domain_conf.h
|
|
@@ -814,6 +814,7 @@ struct _virDomainFSDef {
|
|
virDomainDeviceInfo info;
|
|
unsigned long long space_hard_limit; /* in bytes */
|
|
unsigned long long space_soft_limit; /* in bytes */
|
|
+ bool symlinksResolved;
|
|
};
|
|
|
|
|
|
Index: libvirt-1.2.10/src/lxc/lxc_container.c
|
|
===================================================================
|
|
--- libvirt-1.2.10.orig/src/lxc/lxc_container.c
|
|
+++ libvirt-1.2.10/src/lxc/lxc_container.c
|
|
@@ -609,6 +609,48 @@ static int lxcContainerUnmountSubtree(co
|
|
return ret;
|
|
}
|
|
|
|
+static int lxcContainerResolveSymlinks(virDomainFSDefPtr fs, bool gentle)
|
|
+{
|
|
+ char *newroot;
|
|
+
|
|
+ if (!fs->src || fs->symlinksResolved)
|
|
+ return 0;
|
|
+
|
|
+ if (access(fs->src, F_OK)) {
|
|
+ if (gentle) {
|
|
+ /* Just ignore the error for the while, we'll try again later */
|
|
+ VIR_DEBUG("Skipped unaccessible '%s'", fs->src);
|
|
+ return 0;
|
|
+ } else {
|
|
+ virReportSystemError(errno,
|
|
+ _("Failed to access '%s'"), fs->src);
|
|
+ return -1;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ VIR_DEBUG("Resolving '%s'", fs->src);
|
|
+ if (virFileResolveAllLinks(fs->src, &newroot) < 0) {
|
|
+ if (gentle) {
|
|
+ VIR_DEBUG("Skipped non-resolvable '%s'", fs->src);
|
|
+ return 0;
|
|
+ } else {
|
|
+ virReportSystemError(errno,
|
|
+ _("Failed to resolve symlink at %s"),
|
|
+ fs->src);
|
|
+ }
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ /* Mark it resolved to skip it the next time */
|
|
+ fs->symlinksResolved = true;
|
|
+
|
|
+ VIR_DEBUG("Resolved '%s' to %s", fs->src, newroot);
|
|
+
|
|
+ VIR_FREE(fs->src);
|
|
+ fs->src = newroot;
|
|
+
|
|
+ return 0;
|
|
+}
|
|
|
|
static int lxcContainerPrepareRoot(virDomainDefPtr def,
|
|
virDomainFSDefPtr root,
|
|
@@ -635,6 +677,9 @@ static int lxcContainerPrepareRoot(virDo
|
|
return -1;
|
|
}
|
|
|
|
+ if (lxcContainerResolveSymlinks(root, false) < 0)
|
|
+ return -1;
|
|
+
|
|
if (virAsprintf(&dst, "%s/%s.root",
|
|
LXC_STATE_DIR, def->name) < 0)
|
|
return -1;
|
|
@@ -1555,6 +1600,9 @@ static int lxcContainerMountAllFS(virDom
|
|
if (STREQ(vmDef->fss[i]->dst, "/"))
|
|
continue;
|
|
|
|
+ if (lxcContainerResolveSymlinks(vmDef->fss[i], false) < 0)
|
|
+ return -1;
|
|
+
|
|
if (lxcContainerUnmountSubtree(vmDef->fss[i]->dst,
|
|
false) < 0)
|
|
return -1;
|
|
@@ -1738,37 +1786,18 @@ static int lxcContainerSetupPivotRoot(vi
|
|
return ret;
|
|
}
|
|
|
|
-
|
|
-static int lxcContainerResolveSymlinks(virDomainDefPtr vmDef)
|
|
+static int lxcContainerResolveAllSymlinks(virDomainDefPtr vmDef)
|
|
{
|
|
- char *newroot;
|
|
size_t i;
|
|
|
|
VIR_DEBUG("Resolving symlinks");
|
|
|
|
for (i = 0; i < vmDef->nfss; i++) {
|
|
virDomainFSDefPtr fs = vmDef->fss[i];
|
|
- if (!fs->src)
|
|
- continue;
|
|
-
|
|
- if (access(fs->src, F_OK)) {
|
|
- virReportSystemError(errno,
|
|
- _("Failed to access '%s'"), fs->src);
|
|
+ /* In the first pass, be gentle as some files may
|
|
+ depend on other filesystems to be mounted */
|
|
+ if (lxcContainerResolveSymlinks(fs, true) < 0)
|
|
return -1;
|
|
- }
|
|
-
|
|
- VIR_DEBUG("Resolving '%s'", fs->src);
|
|
- if (virFileResolveAllLinks(fs->src, &newroot) < 0) {
|
|
- virReportSystemError(errno,
|
|
- _("Failed to resolve symlink at %s"),
|
|
- fs->src);
|
|
- return -1;
|
|
- }
|
|
-
|
|
- VIR_DEBUG("Resolved '%s' to %s", fs->src, newroot);
|
|
-
|
|
- VIR_FREE(fs->src);
|
|
- fs->src = newroot;
|
|
}
|
|
VIR_DEBUG("Resolved all filesystem symlinks");
|
|
|
|
@@ -2107,7 +2136,7 @@ static int lxcContainerChild(void *data)
|
|
goto cleanup;
|
|
}
|
|
|
|
- if (lxcContainerResolveSymlinks(vmDef) < 0)
|
|
+ if (lxcContainerResolveAllSymlinks(vmDef) < 0)
|
|
goto cleanup;
|
|
|
|
VIR_DEBUG("Setting up pivot");
|