Revision 84c08e4e 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,
......
87 97
    constants.HV_KVM_FLAG:
88 98
      hv_base.ParamInSet(False, constants.HT_KVM_FLAG_VALUES),
89 99
    constants.HV_VHOST_NET: hv_base.NO_CHECK,
100
    constants.HV_KVM_USE_CHROOT: hv_base.NO_CHECK,
90 101
    }
91 102

  
92 103
  _MIGRATION_STATUS_RE = re.compile('Migration\s+status:\s+(\w+)',
......
230 241
    return utils.PathJoin(cls._CONF_DIR, "%s.runtime" % instance_name)
231 242

  
232 243
  @classmethod
244
  def _InstanceChrootDir(cls, instance_name):
245
    """Returns the name of the KVM chroot dir of the instance
246

  
247
    """
248
    return utils.PathJoin(cls._CHROOT_DIR, instance_name)
249

  
250
  @classmethod
233 251
  def _TryReadUidFile(cls, uid_file):
234 252
    """Try to read a uid file
235 253

  
......
246 264

  
247 265
  @classmethod
248 266
  def _RemoveInstanceRuntimeFiles(cls, pidfile, instance_name):
249
    """Removes an instance's rutime sockets/files.
267
    """Removes an instance's rutime sockets/files/dirs.
250 268

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

  
262 298
  def _WriteNetScript(self, instance, seq, nic):
263 299
    """Write a script to connect a net interface to the proper bridge.
......
529 565
    if hvp[constants.HV_USE_LOCALTIME]:
530 566
      kvm_cmd.extend(['-localtime'])
531 567

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

  
532 571
    # Save the current instance nics, but defer their expansion as parameters,
533 572
    # as we'll need to generate executable temp files for them.
534 573
    kvm_nics = instance.nics
......
644 683
        raise errors.HypervisorError("Failed to open VNC password file %s: %s"
645 684
                                     % (vnc_pwd_file, err))
646 685

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

  
647 690
    if security_model == constants.HT_SM_POOL:
648 691
      ss = ssconf.SimpleStore()
649 692
      uid_pool = uidpool.ParseUidPool(ss.GetUidPool(), separator="\n")

Also available in: Unified diff