SHA256
1
0
forked from pool/libvirt
libvirt/72fecf1-lxc-resolve-symlinks.patch
Cédric Bosdonnat d6a22feac8 Accepting request 262985 from home:cbosdonnat:branches:Virtualization
- Fix potential crasher in virt-aa-helper
  2222123-virt-aa-helper-crash.patch
- ip link add now needs the 'name' parameter.
  433b427-iplink-name.patch
- Fixes for virt-sandbox-service to work:
  - Allow adding virt-sandbox service config to apparmor rules.
    c264eea-virt-aa-helper-sandbox.patch
  - fix symlink resolving for containers to start.
    72fecf1-lxc-resolve-symlinks.patch
  - fix unmounting file system if it contains the source to mount.
    e50457d-lxc-unmount-check.patch

- Remove security_driver = "none" in qemu config. This completely
  disabled all security drivers instead of probing them.
- Changed default value of QEMU's security_default_confined to 0 to
  keep QEMU domains unconfined by default.

OBS-URL: https://build.opensuse.org/request/show/262985
OBS-URL: https://build.opensuse.org/package/show/Virtualization/libvirt?expand=0&rev=422
2014-11-25 13:41:55 +00:00

159 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(-)
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index d428451..dcb30bc 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -821,6 +821,7 @@ struct _virDomainFSDef {
virDomainDeviceInfo info;
unsigned long long space_hard_limit; /* in bytes */
unsigned long long space_soft_limit; /* in bytes */
+ bool symlinksResolved;
};
diff --git a/src/lxc/lxc_container.c b/src/lxc/lxc_container.c
index db823d6..12f3a41 100644
--- a/src/lxc/lxc_container.c
+++ b/src/lxc/lxc_container.c
@@ -608,6 +608,48 @@ static int lxcContainerUnmountSubtree(const char *prefix,
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,
@@ -634,6 +676,9 @@ static int lxcContainerPrepareRoot(virDomainDefPtr def,
return -1;
}
+ if (lxcContainerResolveSymlinks(root, false) < 0)
+ return -1;
+
if (virAsprintf(&dst, "%s/%s.root",
LXC_STATE_DIR, def->name) < 0)
return -1;
@@ -1552,6 +1597,9 @@ static int lxcContainerMountAllFS(virDomainDefPtr vmDef,
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;
@@ -1735,37 +1783,18 @@ static int lxcContainerSetupPivotRoot(virDomainDefPtr vmDef,
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");
@@ -2106,7 +2135,7 @@ static int lxcContainerChild(void *data)
goto cleanup;
}
- if (lxcContainerResolveSymlinks(vmDef) < 0)
+ if (lxcContainerResolveAllSymlinks(vmDef) < 0)
goto cleanup;
VIR_DEBUG("Setting up pivot");
--
2.1.2