diff --git a/lib/backend.py b/lib/backend.py
index 98d61ef10f238e919978f029eaa39f563b92553b..57b31a9caf5c06bc367cdf197e387436eb8f1e2c 100644
--- a/lib/backend.py
+++ b/lib/backend.py
@@ -203,7 +203,7 @@ def _BuildUploadFileList():
 
   for hv_name in constants.HYPER_TYPES:
     hv_class = hypervisor.GetHypervisorClass(hv_name)
-    allowed_files.update(hv_class.GetAncillaryFiles())
+    allowed_files.update(hv_class.GetAncillaryFiles()[0])
 
   return frozenset(allowed_files)
 
diff --git a/lib/cmdlib.py b/lib/cmdlib.py
index 7d126899d04748135abae78cf4d363d2a6cbc246..6151ddb62631b5ee2572640dba1a4a96f4761e24 100644
--- a/lib/cmdlib.py
+++ b/lib/cmdlib.py
@@ -3760,7 +3760,7 @@ def _ComputeAncillaryFiles(cluster, redist):
   # Files which should only be on VM-capable nodes
   files_vm = set(filename
     for hv_name in cluster.enabled_hypervisors
-    for filename in hypervisor.GetHypervisor(hv_name).GetAncillaryFiles())
+    for filename in hypervisor.GetHypervisor(hv_name).GetAncillaryFiles()[0])
 
   # Filenames must be unique
   assert (len(files_all | files_all_opt | files_mc | files_vm) ==
diff --git a/lib/hypervisor/hv_base.py b/lib/hypervisor/hv_base.py
index 7c4b1b59d0df5ebf0e9b1df9ff13b7af63811361..5fe197837e71e1e7ecea3174d63fe1935e2c5e04 100644
--- a/lib/hypervisor/hv_base.py
+++ b/lib/hypervisor/hv_base.py
@@ -133,6 +133,7 @@ class BaseHypervisor(object):
   """
   PARAMETERS = {}
   ANCILLARY_FILES = []
+  ANCILLARY_FILES_OPT = []
   CAN_MIGRATE = False
 
   def __init__(self):
@@ -221,13 +222,16 @@ class BaseHypervisor(object):
     """Return a list of ancillary files to be copied to all nodes as ancillary
     configuration files.
 
-    @rtype: list of strings
-    @return: list of absolute paths of files to ship cluster-wide
+    @rtype: (list of absolute paths, list of absolute paths)
+    @return: (all files, optional files)
 
     """
     # By default we return a member variable, so that if an hypervisor has just
     # a static list of files it doesn't have to override this function.
-    return cls.ANCILLARY_FILES
+    assert set(cls.ANCILLARY_FILES).issuperset(cls.ANCILLARY_FILES_OPT), \
+      "Optional ancillary files must be a subset of ancillary files"
+
+    return (cls.ANCILLARY_FILES, cls.ANCILLARY_FILES_OPT)
 
   def Verify(self):
     """Verify the hypervisor.
diff --git a/lib/hypervisor/hv_kvm.py b/lib/hypervisor/hv_kvm.py
index c4b05b117d0f16714c169de624740ab38cb9fd29..ccf9f7d85daf0159771c376e2e9179b8d35c7dde 100644
--- a/lib/hypervisor/hv_kvm.py
+++ b/lib/hypervisor/hv_kvm.py
@@ -475,6 +475,9 @@ class KVMHypervisor(hv_base.BaseHypervisor):
   ANCILLARY_FILES = [
     _KVM_NETWORK_SCRIPT,
     ]
+  ANCILLARY_FILES_OPT = [
+    _KVM_NETWORK_SCRIPT,
+    ]
 
   def __init__(self):
     hv_base.BaseHypervisor.__init__(self)
diff --git a/lib/hypervisor/hv_xen.py b/lib/hypervisor/hv_xen.py
index 3468fbe0964f4a95690503fa1844ae50e3613191..ffeb01768d7d73fa1298d2b7601546be0988d895 100644
--- a/lib/hypervisor/hv_xen.py
+++ b/lib/hypervisor/hv_xen.py
@@ -55,6 +55,9 @@ class XenHypervisor(hv_base.BaseHypervisor):
     XL_CONFIG_FILE,
     VIF_BRIDGE_SCRIPT,
     ]
+  ANCILLARY_FILES_OPT = [
+    XL_CONFIG_FILE,
+    ]
 
   @staticmethod
   def _ConfigFileName(instance_name):
@@ -589,6 +592,9 @@ class XenHvmHypervisor(XenHypervisor):
   ANCILLARY_FILES = XenHypervisor.ANCILLARY_FILES + [
     constants.VNC_PASSWORD_FILE,
     ]
+  ANCILLARY_FILES_OPT = XenHypervisor.ANCILLARY_FILES_OPT + [
+    constants.VNC_PASSWORD_FILE,
+    ]
 
   PARAMETERS = {
     constants.HV_ACPI: hv_base.NO_CHECK,