);
-static struct {
- const char *path;
- const char *suffix;
-} devPreserveMounts[] = {
- {"/dev/pts", "devpts"},
- {"/dev/shm", "devshm"},
- {"/dev/mqueue", "mqueue"},
-};
+#define PROC_MOUNTS "/proc/mounts"
+#define DEVPREFIX "/dev/"
struct _qemuDomainLogContext {
}
+/**
+ * qemuDomainGetPreservedMounts:
+ *
+ * Process list of mounted filesystems and:
+ * a) save all FSs mounted under /dev to @devPath
+ * b) generate backup path for all the entries in a)
+ *
+ * Any of the return pointers can be NULL.
+ *
+ * Returns 0 on success, -1 otherwise (with error reported)
+ */
static int
qemuDomainGetPreservedMounts(virQEMUDriverPtr driver,
virDomainObjPtr vm,
- char ***devMountsPath,
- size_t *ndevMountsPath)
+ char ***devPath,
+ char ***devSavePath,
+ size_t *ndevPath)
{
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
- char **paths;
- size_t i;
+ char **paths = NULL, **mounts = NULL;
+ size_t i, nmounts;
- if (VIR_ALLOC_N(paths, ARRAY_CARDINALITY(devPreserveMounts)) < 0)
+ if (virFileGetMountSubtree(PROC_MOUNTS, "/dev",
+ &mounts, &nmounts) < 0)
goto error;
- for (i = 0; i < ARRAY_CARDINALITY(devPreserveMounts); i++) {
+ if (!nmounts) {
+ if (ndevPath)
+ *ndevPath = 0;
+ return 0;
+ }
+
+ /* Okay, this is crazy. But virFileGetMountSubtree() fetched us all the
+ * mount points under /dev including /dev itself. Fortunately, the paths
+ * are sorted based on their length so we skip the first one (/dev) as it
+ * is handled differently anyway. */
+ VIR_DELETE_ELEMENT(mounts, 0, nmounts);
+
+ if (VIR_ALLOC_N(paths, nmounts) < 0)
+ goto error;
+
+ for (i = 0; i < nmounts; i++) {
if (virAsprintf(&paths[i], "%s/%s.%s",
cfg->stateDir, vm->def->name,
- devPreserveMounts[i].suffix) < 0)
+ mounts[i] + strlen(DEVPREFIX)) < 0)
goto error;
}
- *devMountsPath = paths;
- *ndevMountsPath = ARRAY_CARDINALITY(devPreserveMounts);
+ if (devPath)
+ *devPath = mounts;
+ else
+ virStringListFreeCount(mounts, nmounts);
+
+ if (devSavePath)
+ *devSavePath = paths;
+ else
+ virStringListFreeCount(paths, nmounts);
+
+ if (ndevPath)
+ *ndevPath = nmounts;
+
virObjectUnref(cfg);
return 0;
error:
- virStringListFreeCount(paths, ARRAY_CARDINALITY(devPreserveMounts));
+ virStringListFreeCount(mounts, nmounts);
+ virStringListFreeCount(paths, nmounts);
virObjectUnref(cfg);
return -1;
}
}
-#define DEVPREFIX "/dev/"
-
#if defined(__linux__)
static int
qemuDomainCreateDevice(const char *device,
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
const unsigned long mount_flags = MS_MOVE;
char *devPath = NULL;
- char **devMountsPath = NULL;
+ char **devMountsPath = NULL, **devMountsSavePath = NULL;
size_t ndevMountsPath = 0, i;
int ret = -1;
goto cleanup;
if (qemuDomainGetPreservedMounts(driver, vm,
- &devMountsPath, &ndevMountsPath) < 0)
+ &devMountsPath, &devMountsSavePath,
+ &ndevMountsPath) < 0)
goto cleanup;
if (qemuDomainSetupDev(driver, vm, devPath) < 0)
/* Save some mount points because we want to share them with the host */
for (i = 0; i < ndevMountsPath; i++) {
- if (mount(devPreserveMounts[i].path, devMountsPath[i],
+ if (mount(devMountsPath[i], devMountsSavePath[i],
NULL, mount_flags, NULL) < 0) {
virReportSystemError(errno,
_("Unable to move %s mount"),
- devPreserveMounts[i].path);
+ devMountsPath[i]);
goto cleanup;
}
}
}
for (i = 0; i < ndevMountsPath; i++) {
- if (virFileMakePath(devPreserveMounts[i].path) < 0) {
+ if (virFileMakePath(devMountsPath[i]) < 0) {
virReportSystemError(errno, _("Cannot create %s"),
- devPreserveMounts[i].path);
+ devMountsPath[i]);
goto cleanup;
}
- if (mount(devMountsPath[i], devPreserveMounts[i].path,
+ if (mount(devMountsSavePath[i], devMountsPath[i],
NULL, mount_flags, NULL) < 0) {
virReportSystemError(errno,
_("Failed to mount %s on %s"),
- devMountsPath[i],
- devPreserveMounts[i].path);
+ devMountsSavePath[i],
+ devMountsPath[i]);
goto cleanup;
}
}
virObjectUnref(cfg);
VIR_FREE(devPath);
virStringListFreeCount(devMountsPath, ndevMountsPath);
+ virStringListFreeCount(devMountsSavePath, ndevMountsPath);
return ret;
}
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
int ret = -1;
char *devPath = NULL;
- char **devMountsPath = NULL;
- size_t ndevMountsPath = 0, i;
+ char **devMountsSavePath = NULL;
+ size_t ndevMountsSavePath = 0, i;
if (!virBitmapIsBitSet(cfg->namespaces, QEMU_DOMAIN_NS_MOUNT) ||
!virQEMUDriverIsPrivileged(driver)) {
goto cleanup;
if (qemuDomainGetPreservedMounts(driver, vm,
- &devMountsPath, &ndevMountsPath) < 0)
+ NULL, &devMountsSavePath,
+ &ndevMountsSavePath) < 0)
goto cleanup;
if (virFileMakePath(devPath) < 0) {
goto cleanup;
}
- for (i = 0; i < ndevMountsPath; i++) {
- if (virFileMakePath(devMountsPath[i]) < 0) {
+ for (i = 0; i < ndevMountsSavePath; i++) {
+ if (virFileMakePath(devMountsSavePath[i]) < 0) {
virReportSystemError(errno,
_("Failed to create %s"),
- devMountsPath[i]);
+ devMountsSavePath[i]);
goto cleanup;
}
}
if (ret < 0) {
if (devPath)
unlink(devPath);
- for (i = 0; i < ndevMountsPath; i++)
- unlink(devMountsPath[i]);
+ for (i = 0; i < ndevMountsSavePath; i++)
+ unlink(devMountsSavePath[i]);
}
- virStringListFreeCount(devMountsPath, ndevMountsPath);
+ virStringListFreeCount(devMountsSavePath, ndevMountsSavePath);
VIR_FREE(devPath);
virObjectUnref(cfg);
return ret;
{
virQEMUDriverConfigPtr cfg = virQEMUDriverGetConfig(driver);
char *devPath = NULL;
- char **devMountsPath = NULL;
- size_t ndevMountsPath = 0, i;
+ char **devMountsSavePath = NULL;
+ size_t ndevMountsSavePath = 0, i;
if (!qemuDomainNamespaceEnabled(vm, QEMU_DOMAIN_NS_MOUNT))
goto cleanup;
if (qemuDomainGetPreservedMounts(driver, vm,
- &devMountsPath, &ndevMountsPath) < 0)
+ NULL, &devMountsSavePath,
+ &ndevMountsSavePath) < 0)
goto cleanup;
if (rmdir(devPath) < 0) {
/* Bet effort. Fall through. */
}
- for (i = 0; i < ndevMountsPath; i++) {
- if (rmdir(devMountsPath[i]) < 0) {
+ for (i = 0; i < ndevMountsSavePath; i++) {
+ if (rmdir(devMountsSavePath[i]) < 0) {
virReportSystemError(errno,
_("Unable to remove %s"),
- devMountsPath[i]);
+ devMountsSavePath[i]);
/* Bet effort. Fall through. */
}
}
cleanup:
virObjectUnref(cfg);
- virStringListFreeCount(devMountsPath, ndevMountsPath);
+ virStringListFreeCount(devMountsSavePath, ndevMountsSavePath);
VIR_FREE(devPath);
}