Revision 105a40f2
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