Revision 105a40f2 lib/hypervisor/hv_kvm/monitor.py

b/lib/hypervisor/hv_kvm/monitor.py
431 431

  
432 432
      return response[self._RETURN_KEY]
433 433

  
434
  def AddFd(self, fds):
435
    """Pass file descriptor to kvm process via qmp socket using SCM_RIGHTS
434
  def AddFd(self, fd):
435
    """Wrapper around add-fd qmp command
436 436

  
437
    Add the fds to an fdset so that they can be used later by hot-add commands
437
    Use fdsend to send fd to a running process via SCM_RIGHTS and then add-fd
438
    qmp command to add it to an fdset so that it can be used later by
439
    disk hotplugging.
438 440

  
439
    @type fds: list
440
    @param fds: The list of file descriptors to pass
441
    @type fd: int
442
    @param fd: The file descriptor to pass
441 443

  
442
    @return: The fdset ID that the fds have been added to
443
      (None if operation fails)
444
    @return: The fdset ID that the fd has been added to
445
    @raise errors.HypervisorError: If add-fd fails for some reason
444 446

  
445 447
    """
446 448
    self._check_connection()
447

  
448
    if not fdsend or "add-fd" not in self.supported_commands:
449
      return None
450

  
451 449
    try:
450
      fdsend.sendfds(self.sock, " ", fds=[fd])
452 451
      # Omit fdset-id and let qemu create a new one (see qmp-commands.hx)
453
      command = {"execute": "add-fd"}
454
      fdsend.sendfds(self.sock, serializer.Dump(command), fds=fds)
455
      # Get the response out of the buffer
456
      response = self._GetResponse("add-fd")
452
      response = self.Execute("add-fd")
457 453
      fdset = response["fdset-id"]
458
      logging.info("Sent fds %s and added to fdset %s", fds, fdset)
459 454
    except errors.HypervisorError, err:
460
      # In case _GetResponse() fails
461
      fdset = None
462
      logging.info("Sending fds %s failed: %s", fds, err)
455
      logging.info("Passing fd %s via SCM_RIGHTS failed: %s", fd, err)
456
      raise
463 457

  
464 458
    return fdset
465 459

  
466 460
  def RemoveFdset(self, fdset):
467
    """Remove the file descriptor previously passed
461
    """Wrapper around remove-fd qmp command
468 462

  
469
    After qemu has dup'd the fd (e.g. during disk hotplug),
470
    it can be safely removed.
463
    Remove the file descriptor previously passed. After qemu has dup'd the fd
464
    (e.g. during disk hotplug), it can be safely removed.
471 465

  
472 466
    """
473 467
    self._check_connection()
474
    # Omit the fd to cleanup all fds in the fdset (see qmp-commands.hx)
475
    command = "remove-fd"
476
    arguments = {"fdset-id": fdset}
477
    logging.info("Removing fdset %s", fdset)
468
    # Omit the fd to cleanup all fds in the fdset (see qemu/qmp-commands.hx)
478 469
    try:
479
      self.Execute(command, arguments=arguments)
470
      self.Execute("remove-fd", {"fdset-id": fdset})
480 471
    except errors.HypervisorError, err:
481
      logging.info("Removing %s fdset failed: %s", fdset, err)
472
      # There is no big deal if we cannot remove an fdset. This cleanup here is
473
      # done on a best effort basis. Upon next hot-add a new fdset will be
474
      # created. If we raise an exception here, that is after drive_add has
475
      # succeeded, the whole hot-add action will fail and the runtime file will
476
      # not be updated which will make the instance non migrate-able
477
      logging.info("Removing fdset with id %s failed: %s", fdset, err)

Also available in: Unified diff