virStorageFileFormatTypeFromString;
virStorageFileGetMetadata;
virStorageFileGetMetadataFromFD;
+virStorageFileIsSharedFS;
# threads.h
virMutexInit;
int stdin_fd);
static void qemudShutdownVMDaemon(struct qemud_driver *driver,
- virDomainObjPtr vm);
+ virDomainObjPtr vm,
+ int migrated);
static int qemudDomainGetMaxVcpus(virDomainPtr dom);
VIR_DOMAIN_EVENT_STOPPED_FAILED :
VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN);
- qemudShutdownVMDaemon(driver, vm);
+ qemudShutdownVMDaemon(driver, vm, 0);
if (!vm->persistent)
virDomainRemoveInactive(&driver->domains, vm);
else
/* We can't get the monitor back, so must kill the VM
* to remove danger of it ending up running twice if
* user tries to start it again later */
- qemudShutdownVMDaemon(driver, obj);
+ qemudShutdownVMDaemon(driver, obj, 0);
if (!obj->persistent)
virDomainRemoveInactive(&driver->domains, obj);
else
if (driver->securityDriver &&
driver->securityDriver->domainRestoreSecurityAllLabel)
- driver->securityDriver->domainRestoreSecurityAllLabel(vm);
+ driver->securityDriver->domainRestoreSecurityAllLabel(vm, 0);
if (driver->securityDriver &&
driver->securityDriver->domainReleaseSecurityLabel)
driver->securityDriver->domainReleaseSecurityLabel(vm);
abort:
/* We jump here if we failed to initialize the now running VM
* killing it off and pretend we never started it */
- qemudShutdownVMDaemon(driver, vm);
+ qemudShutdownVMDaemon(driver, vm, 0);
if (logfile != -1)
close(logfile);
static void qemudShutdownVMDaemon(struct qemud_driver *driver,
- virDomainObjPtr vm) {
+ virDomainObjPtr vm,
+ int migrated) {
int ret;
int retries = 0;
qemuDomainObjPrivatePtr priv = vm->privateData;
if (!virDomainObjIsActive(vm))
return;
- VIR_DEBUG("Shutting down VM '%s'", vm->def->name);
+ VIR_DEBUG("Shutting down VM '%s' migrated=%d", vm->def->name, migrated);
/* This method is routinely used in clean up paths. Disable error
* reporting so we don't squash a legit error. */
/* Reset Security Labels */
if (driver->securityDriver &&
driver->securityDriver->domainRestoreSecurityAllLabel)
- driver->securityDriver->domainRestoreSecurityAllLabel(vm);
+ driver->securityDriver->domainRestoreSecurityAllLabel(vm, migrated);
if (driver->securityDriver &&
driver->securityDriver->domainReleaseSecurityLabel)
driver->securityDriver->domainReleaseSecurityLabel(vm);
goto endjob;
}
- qemudShutdownVMDaemon(driver, vm);
+ qemudShutdownVMDaemon(driver, vm, 0);
event = virDomainEventNewFromObj(vm,
VIR_DOMAIN_EVENT_STOPPED,
VIR_DOMAIN_EVENT_STOPPED_DESTROYED);
ret = 0;
/* Shut it down */
- qemudShutdownVMDaemon(driver, vm);
+ qemudShutdownVMDaemon(driver, vm, 0);
event = virDomainEventNewFromObj(vm,
VIR_DOMAIN_EVENT_STOPPED,
VIR_DOMAIN_EVENT_STOPPED_SAVED);
endjob:
if ((ret == 0) && (flags & VIR_DUMP_CRASH)) {
- qemudShutdownVMDaemon(driver, vm);
+ qemudShutdownVMDaemon(driver, vm, 0);
event = virDomainEventNewFromObj(vm,
VIR_DOMAIN_EVENT_STOPPED,
VIR_DOMAIN_EVENT_STOPPED_CRASHED);
qemust = qemuStreamMigOpen(st, unixfile);
if (qemust == NULL) {
- qemudShutdownVMDaemon(driver, vm);
+ qemudShutdownVMDaemon(driver, vm, 0);
if (!vm->persistent) {
if (qemuDomainObjEndJob(vm) > 0)
virDomainRemoveInactive(&driver->domains, vm);
}
/* Clean up the source domain. */
- qemudShutdownVMDaemon(driver, vm);
+ fprintf(stderr, "******************* MIG \n");
+ qemudShutdownVMDaemon(driver, vm, 1);
+ fprintf(stderr, "******************* YEEHAAA\n");
resume = 0;
event = virDomainEventNewFromObj(vm,
}
virDomainSaveStatus(driver->caps, driver->stateDir, vm);
} else {
- qemudShutdownVMDaemon(driver, vm);
+ qemudShutdownVMDaemon(driver, vm, 0);
event = virDomainEventNewFromObj(vm,
VIR_DOMAIN_EVENT_STOPPED,
VIR_DOMAIN_EVENT_STOPPED_FAILED);
*/
if (virDomainObjIsActive(vm)) {
- qemudShutdownVMDaemon(driver, vm);
+ qemudShutdownVMDaemon(driver, vm, 0);
event = virDomainEventNewFromObj(vm,
VIR_DOMAIN_EVENT_STOPPED,
VIR_DOMAIN_EVENT_STOPPED_FROM_SNAPSHOT);
static int
-qemuSecurityDACRestoreSecurityImageLabel(virDomainObjPtr vm ATTRIBUTE_UNUSED,
- virDomainDiskDefPtr disk)
+qemuSecurityDACRestoreSecurityImageLabelInt(virDomainObjPtr vm ATTRIBUTE_UNUSED,
+ virDomainDiskDefPtr disk,
+ int migrated)
{
if (!driver->privileged || !driver->dynamicOwnership)
return 0;
if (!disk->src)
return 0;
+ /* If we have a shared FS & doing migrated, we must not
+ * change ownership, because that kills access on the
+ * destination host which is sub-optimal for the guest
+ * VM's I/O attempts :-)
+ */
+ if (migrated) {
+ int rc = virStorageFileIsSharedFS(disk->src);
+ if (rc < 0)
+ return -1;
+ if (rc == 1) {
+ VIR_DEBUG("Skipping image label restore on %s because FS is shared",
+ disk->src);
+ return 0;
+ }
+ }
+
return qemuSecurityDACRestoreSecurityFileLabel(disk->src);
}
+static int
+qemuSecurityDACRestoreSecurityImageLabel(virDomainObjPtr vm,
+ virDomainDiskDefPtr disk)
+{
+ return qemuSecurityDACRestoreSecurityImageLabelInt(vm, disk, 0);
+}
+
+
static int
qemuSecurityDACSetSecurityPCILabel(pciDevice *dev ATTRIBUTE_UNUSED,
const char *file,
static int
-qemuSecurityDACRestoreSecurityAllLabel(virDomainObjPtr vm)
+qemuSecurityDACRestoreSecurityAllLabel(virDomainObjPtr vm,
+ int migrated)
{
int i;
int rc = 0;
if (!driver->privileged || !driver->dynamicOwnership)
return 0;
- VIR_DEBUG("Restoring security label on %s", vm->def->name);
+ VIR_DEBUG("Restoring security label on %s migrated=%d",
+ vm->def->name, migrated);
for (i = 0 ; i < vm->def->nhostdevs ; i++) {
if (qemuSecurityDACRestoreSecurityHostdevLabel(vm,
rc = -1;
}
for (i = 0 ; i < vm->def->ndisks ; i++) {
- if (qemuSecurityDACRestoreSecurityImageLabel(vm,
- vm->def->disks[i]) < 0)
+ if (qemuSecurityDACRestoreSecurityImageLabelInt(vm,
+ vm->def->disks[i],
+ migrated) < 0)
rc = -1;
}
static int
-qemuSecurityStackedRestoreSecurityAllLabel(virDomainObjPtr vm)
+qemuSecurityStackedRestoreSecurityAllLabel(virDomainObjPtr vm,
+ int migrated)
{
int rc = 0;
if (driver->securitySecondaryDriver &&
driver->securitySecondaryDriver->domainRestoreSecurityAllLabel &&
- driver->securitySecondaryDriver->domainRestoreSecurityAllLabel(vm) < 0)
+ driver->securitySecondaryDriver->domainRestoreSecurityAllLabel(vm, migrated) < 0)
rc = -1;
if (driver->securityPrimaryDriver &&
driver->securityPrimaryDriver->domainRestoreSecurityAllLabel &&
- driver->securityPrimaryDriver->domainRestoreSecurityAllLabel(vm) < 0)
+ driver->securityPrimaryDriver->domainRestoreSecurityAllLabel(vm, migrated) < 0)
rc = -1;
return rc;
static int
-AppArmorRestoreSecurityAllLabel(virDomainObjPtr vm)
+AppArmorRestoreSecurityAllLabel(virDomainObjPtr vm,
+ int migrated ATTRIBUTE_UNUSED)
{
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
int rc = 0;
typedef int (*virSecurityDomainReserveLabel) (virDomainObjPtr sec);
typedef int (*virSecurityDomainReleaseLabel) (virDomainObjPtr sec);
typedef int (*virSecurityDomainSetAllLabel) (virDomainObjPtr sec);
-typedef int (*virSecurityDomainRestoreAllLabel) (virDomainObjPtr vm);
+typedef int (*virSecurityDomainRestoreAllLabel) (virDomainObjPtr vm,
+ int migrated);
typedef int (*virSecurityDomainGetProcessLabel) (virDomainObjPtr vm,
virSecurityLabelPtr sec);
typedef int (*virSecurityDomainSetProcessLabel) (virSecurityDriverPtr drv,
}
static int
-SELinuxRestoreSecurityImageLabel(virDomainObjPtr vm,
- virDomainDiskDefPtr disk)
+SELinuxRestoreSecurityImageLabelInt(virDomainObjPtr vm,
+ virDomainDiskDefPtr disk,
+ int migrated)
{
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
if (!disk->src)
return 0;
+ /* If we have a shared FS & doing migrated, we must not
+ * change ownership, because that kills access on the
+ * destination host which is sub-optimal for the guest
+ * VM's I/O attempts :-)
+ */
+ if (migrated) {
+ int rc = virStorageFileIsSharedFS(disk->src);
+ if (rc < 0)
+ return -1;
+ if (rc == 1) {
+ VIR_DEBUG("Skipping image label restore on %s because FS is shared",
+ disk->src);
+ return 0;
+ }
+ }
+
return SELinuxRestoreSecurityFileLabel(disk->src);
}
+
+static int
+SELinuxRestoreSecurityImageLabel(virDomainObjPtr vm,
+ virDomainDiskDefPtr disk)
+{
+ return SELinuxRestoreSecurityImageLabelInt(vm, disk, 0);
+}
+
+
static int
SELinuxSetSecurityImageLabel(virDomainObjPtr vm,
virDomainDiskDefPtr disk)
}
static int
-SELinuxRestoreSecurityAllLabel(virDomainObjPtr vm)
+SELinuxRestoreSecurityAllLabel(virDomainObjPtr vm,
+ int migrated ATTRIBUTE_UNUSED)
{
const virSecurityLabelDefPtr secdef = &vm->def->seclabel;
int i;
rc = -1;
}
for (i = 0 ; i < vm->def->ndisks ; i++) {
- if (SELinuxRestoreSecurityImageLabel(vm,
- vm->def->disks[i]) < 0)
+ if (SELinuxRestoreSecurityImageLabelInt(vm,
+ vm->def->disks[i],
+ migrated) < 0)
rc = -1;
}
#include <unistd.h>
#include <fcntl.h>
+#ifdef __linux__
+# include <linux/magic.h>
+# include <sys/statfs.h>
+#endif
#include "dirname.h"
#include "memory.h"
#include "virterror_internal.h"
+#include "logging.h"
#define VIR_FROM_THIS VIR_FROM_STORAGE
return ret;
}
+
+
+#ifdef __linux__
+
+# ifndef OCFS2_SUPER_MAGIC
+# define OCFS2_SUPER_MAGIC 0x7461636f
+# endif
+# ifndef GFS2_MAGIC
+# define GFS2_MAGIC 0x01161970
+# endif
+# ifndef AFS_FS_MAGIC
+# define AFS_FS_MAGIC 0x6B414653
+# endif
+
+
+int virStorageFileIsSharedFS(const char *path)
+{
+ struct statfs sb;
+
+ if (statfs(path, &sb) < 0) {
+ virReportSystemError(errno,
+ _("cannot determine filesystem for '%s'"),
+ path);
+ return -1;
+ }
+
+ VIR_DEBUG("Check if path %s with FS magic %lld is shared",
+ path, (long long int)sb.f_type);
+
+ if (sb.f_type == NFS_SUPER_MAGIC ||
+ sb.f_type == GFS2_MAGIC ||
+ sb.f_type == OCFS2_SUPER_MAGIC ||
+ sb.f_type == AFS_FS_MAGIC) {
+ return 1;
+ }
+
+ return 0;
+}
+#else
+int virStorageFileIsSharedFS(const char *path ATTRIBUTE_UNUSED)
+{
+ /* XXX implement me :-) */
+ return 0;
+}
+#endif
int fd,
virStorageFileMetadata *meta);
+int virStorageFileIsSharedFS(const char *path);
+
#endif /* __VIR_STORAGE_FILE_H__ */