let storage_entry = bool_entry "storage_use_nbdkit"
+ let filesystem_entry = str_array_entry "shared_filesystems"
+
(* Entries that used to exist in the config which are now
* deleted. We keep on parsing them so we don't break
* ability to parse old configs after upgrade
| swtpm_entry
| capability_filters_entry
| storage_entry
+ | filesystem_entry
| obsolete_entry
let comment = [ label "#comment" . del /#[ \t]*/ "# " . store /([^ \t\n][^\n]*)?/ . del /\n/ "\n" ]
# note that the default might change in future releases.
#
#storage_use_nbdkit = @USE_NBDKIT_DEFAULT@
+
+# libvirt will normally prevent migration if the storage backing the VM is not
+# on a shared filesystems. Sometimes, however, the storage *is* shared despite
+# not being detected as such: for example, this is the case when one of the
+# hosts involved in the migration is exporting its local storage to the other
+# one via NFS.
+#
+# Any directory listed here will be assumed to live on a shared filesystem,
+# making migration possible in scenarios such as the one described above. It's
+# the system's administrator responsibility to ensure that other hosts can
+# access this directory.
+#
+# This option is not symmetrical and should only be used on hosts where the
+# storage is being exported from. It must not be used on hosts accessing the
+# storage via a remote protocol.
+#
+# NOTE: this option is intended to help in very specific scenarios that are
+# rarely encountered. If you find yourself reaching for this option, consider
+# reworking your environment so that it follows a more common architecture
+# rather than using it.
+#
+#shared_filesystems = [
+# "/path/to/images",
+# "/path/to/nvram",
+# "/path/to/swtpm"
+#]
g_strfreev(cfg->capabilityfilters);
+ g_strfreev(cfg->sharedFilesystems);
+
g_free(cfg->deprecationBehavior);
}
}
+static int
+virQEMUDriverConfigLoadFilesystemEntry(virQEMUDriverConfig *cfg,
+ virConf *conf)
+{
+ char **iter;
+
+ if (virConfGetValueStringList(conf, "shared_filesystems", false,
+ &cfg->sharedFilesystems) < 0)
+ return -1;
+
+ if (!cfg->sharedFilesystems)
+ return 0;
+
+ /* The paths provided by the user might contain trailing slashes
+ * and other fun diversions, which would break the naive string
+ * comparisons that we're later going to use them for */
+ for (iter = cfg->sharedFilesystems; *iter; iter++) {
+ char *canon = virFileCanonicalizePath(*iter);
+ g_free(*iter);
+ *iter = canon;
+ }
+
+ return 0;
+}
+
+
int virQEMUDriverConfigLoadFile(virQEMUDriverConfig *cfg,
const char *filename,
bool privileged)
if (virQEMUDriverConfigLoadStorageEntry(cfg, conf) < 0)
return -1;
+ if (virQEMUDriverConfigLoadFilesystemEntry(cfg, conf) < 0)
+ return -1;
+
return 0;
}
bool storageUseNbdkit;
virQEMUSchedCore schedCore;
+
+ char **sharedFilesystems;
};
G_DEFINE_AUTOPTR_CLEANUP_FUNC(virQEMUDriverConfig, virObjectUnref);
{ "deprecation_behavior" = "none" }
{ "sched_core" = "none" }
{ "storage_use_nbdkit" = "@USE_NBDKIT_DEFAULT@" }
+{ "shared_filesystems"
+ { "1" = "/path/to/images" }
+ { "2" = "/path/to/nvram" }
+ { "3" = "/path/to/swtpm" }
+}