Revision 547a63b7 lib/hypervisor/hv_kvm.py

b/lib/hypervisor/hv_kvm.py
23 23

  
24 24
"""
25 25

  
26
import errno
26 27
import os
27 28
import os.path
28 29
import re
......
51 52
  _UIDS_DIR = _ROOT_DIR + "/uid" # contains instances reserved uids
52 53
  _CTRL_DIR = _ROOT_DIR + "/ctrl" # contains instances control sockets
53 54
  _CONF_DIR = _ROOT_DIR + "/conf" # contains instances startup data
54
  _DIRS = [_ROOT_DIR, _PIDS_DIR, _UIDS_DIR, _CTRL_DIR, _CONF_DIR]
55
  # KVM instances with chroot enabled are started in empty chroot directories.
56
  _CHROOT_DIR = _ROOT_DIR + "/chroot" # for empty chroot directories
57
  # After an instance is stopped, its chroot directory is removed.
58
  # If the chroot directory is not empty, it can't be removed.
59
  # A non-empty chroot directory indicates a possible security incident.
60
  # To support forensics, the non-empty chroot directory is quarantined in
61
  # a separate directory, called 'chroot-quarantine'.
62
  _CHROOT_QUARANTINE_DIR = _ROOT_DIR + "/chroot-quarantine"
63
  _DIRS = [_ROOT_DIR, _PIDS_DIR, _UIDS_DIR, _CTRL_DIR, _CONF_DIR,
64
           _CHROOT_DIR, _CHROOT_QUARANTINE_DIR]
55 65

  
56 66
  PARAMETERS = {
57 67
    constants.HV_KERNEL_PATH: hv_base.OPT_FILE_CHECK,
......
89 99
    constants.HV_KVM_FLAG:
90 100
      hv_base.ParamInSet(False, constants.HT_KVM_FLAG_VALUES),
91 101
    constants.HV_VHOST_NET: hv_base.NO_CHECK,
102
    constants.HV_KVM_USE_CHROOT: hv_base.NO_CHECK,
92 103
    }
93 104

  
94 105
  _MIGRATION_STATUS_RE = re.compile('Migration\s+status:\s+(\w+)',
......
232 243
    return utils.PathJoin(cls._CONF_DIR, "%s.runtime" % instance_name)
233 244

  
234 245
  @classmethod
246
  def _InstanceChrootDir(cls, instance_name):
247
    """Returns the name of the KVM chroot dir of the instance
248

  
249
    """
250
    return utils.PathJoin(cls._CHROOT_DIR, instance_name)
251

  
252
  @classmethod
235 253
  def _TryReadUidFile(cls, uid_file):
236 254
    """Try to read a uid file
237 255

  
......
248 266

  
249 267
  @classmethod
250 268
  def _RemoveInstanceRuntimeFiles(cls, pidfile, instance_name):
251
    """Removes an instance's rutime sockets/files.
269
    """Removes an instance's rutime sockets/files/dirs.
252 270

  
253 271
    """
254 272
    utils.RemoveFile(pidfile)
......
260 278
    utils.RemoveFile(uid_file)
261 279
    if uid is not None:
262 280
      uidpool.ReleaseUid(uid)
281
    try:
282
      chroot_dir = cls._InstanceChrootDir(instance_name)
283
      utils.RemoveDir(chroot_dir)
284
    except OSError, err:
285
      if err.errno == errno.ENOTEMPTY:
286
        # The chroot directory is expected to be empty, but it isn't.
287
        new_chroot_dir = tempfile.mkdtemp(dir=cls._CHROOT_QUARANTINE_DIR,
288
                                          prefix="%s-%s-" %
289
                                          (instance_name,
290
                                           utils.TimestampForFilename()))
291
        logging.warning("The chroot directory of instance %s can not be"
292
                        " removed as it is not empty. Moving it to the"
293
                        " quarantine instead. Please investigate the"
294
                        " contents (%s) and clean up manually",
295
                        instance_name, new_chroot_dir)
296
        utils.RenameFile(chroot_dir, new_chroot_dir)
297
      else:
298
        raise
263 299

  
264 300
  def _WriteNetScript(self, instance, seq, nic):
265 301
    """Write a script to connect a net interface to the proper bridge.
......
531 567
    if hvp[constants.HV_USE_LOCALTIME]:
532 568
      kvm_cmd.extend(['-localtime'])
533 569

  
570
    if hvp[constants.HV_KVM_USE_CHROOT]:
571
      kvm_cmd.extend(['-chroot', self._InstanceChrootDir(instance.name)])
572

  
534 573
    # Save the current instance nics, but defer their expansion as parameters,
535 574
    # as we'll need to generate executable temp files for them.
536 575
    kvm_nics = instance.nics
......
646 685
        raise errors.HypervisorError("Failed to open VNC password file %s: %s"
647 686
                                     % (vnc_pwd_file, err))
648 687

  
688
    if hvp[constants.HV_KVM_USE_CHROOT]:
689
      utils.EnsureDirs([(self._InstanceChrootDir(name),
690
                         constants.SECURE_DIR_MODE)])
691

  
649 692
    if security_model == constants.HT_SM_POOL:
650 693
      ss = ssconf.SimpleStore()
651 694
      uid_pool = uidpool.ParseUidPool(ss.GetUidPool(), separator="\n")

Also available in: Unified diff