kvm: Minor refactor of MonitorSocket

Create socket upon connect(), keep the status of connection
(self._connected = False) in close(), make existing connect()
method protected and let connect() act as a reconnect method.

Signed-off-by: Dimitris Aragiorgis <dimara@grnet.gr>
Reviewed-by: Hrvoje Ribicic <riba@google.com>
utils: Introduce GetFreeSlot() function

Since this is a generic function that implements bitarray logic move
it from kvm to utils so that it can be easily used across all modules.

Make it raise errors.GenericError if it cannot find a free slot in
the given bitarray.

We add this function in a separate utils module (bitarrays) that can be
extended in the future. Currently only the network module and the
KVM hypervisor make use of bitarrays. This patch is a step forward
unifying these pieces of code and make both use the same bitarray
utility functions.

Add unittest for bitarrays utils module.

Signed-off-by: Dimitris Aragiorgis <dimara@grnet.gr>
Reviewed-by: Hrvoje Ribicic <riba@google.com>
qmp: Refactor of add-fd and remove-fd commands

Instead of sending the qmp command along with the SCM_RIGHTS control
message we send just a blank (idea taken from qemu iotests). Then we
invoke the corresponding command (add-fd, remove-fd) with the
regular way (qmp.Execute). Since the qmp connection does not close
in between the fds will be added properly.

AddFd() wrapper will be used for disk hot-add except for the case
where we have userspace access mode. Make it raise HypervisorError
if the command fails for some reason so that any hotplug action that
takes place will abort.

Signed-off-by: Dimitris Aragiorgis <dimara@grnet.gr>
Reviewed-by: Hrvoje Ribicic <riba@google.com>
qmp: Add GetFd() wrapper around getfd command

getfd qmp command will be used to pass an fd using SCM_RIGHTS
and name it properly so that NIC hot-add can take place.

Signed-off-by: Dimitris Aragiorgis <dimara@grnet.gr>
Reviewed-by: Hrvoje Ribicic <riba@google.com>
qmp: Add helper methods to verify hotplug support

Introduce CheckDiskHotAddSupport() and CheckNicHotAddSupport()
helper methods that will be used to verify hotplug support.
Both check for fdsend python module and if the required qmp
commands are supported.

Signed-off-by: Dimitris Aragiorgis <dimara@grnet.gr>
Reviewed-by: Hrvoje Ribicic <riba@google.com>
qmp: Helper methods for parsing query-pci output

Introduce GetPCIDevices() that gets the devices of the first PCI bus
of a running instance, HasPCIDevice() that will be used to verify
if a specific device is correctly hotplugged or not, and
GetFreePCISlot() that will be used during hot-add to find the first
available PCI slot of a running instance.

Signed-off-by: Dimitris Aragiorgis <dimara@grnet.gr>
Reviewed-by: Hrvoje Ribicic <riba@google.com>
qmp: Add NIC hotplugging related methods

HotAddNic() uses netdev_add and device_add after passing the tapfd
to the running process with the GetFd() helper method.

HotDelNic() uses device_del and netdev_del qmp commands.

Signed-off-by: Dimitris Aragiorgis <dimara@grnet.gr>
Reviewed-by: Hrvoje Ribicic <riba@google.com>
qmp: Add Disk hotplugging related methods

HotAddDisk() uses blockdev-add and device_add after getting the
drive fd and passing it with the AddFd() helper method. Please note
that in case of userspace access mode this step will be omitted.

HotDelDisk() uses device_del. Please note that drive_del is
currently not supported in qmp and thus hmp should be used instead.

Signed-off-by: Dimitris Aragiorgis <dimara@grnet.gr>
Reviewed-by: Hrvoje Ribicic <riba@google.com>
kvm: New _with_qmp decorator

The decorator takes the hypervisor and the instance object as passed
to all hotplug related commands and ensures a valid QmpConnection()
object is found in hypervisor's qmp attribute.

This decorator is responsible for all actions related to the
QmpConnection (e.g. init, connect, close) and for proper exception
propagation. In order to be safe against nested invocations we close
the connection only if we create it.

Signed-off-by: Dimitris Aragiorgis <dimara@grnet.gr>
Reviewed-by: Hrvoje Ribicic <riba@google.com>
monitor: Close socket fd if already connected

We close the socket fd only if we have an active connection.
We hide this logic in the public close() method, and all
the actions are moved to a private method.

Signed-off-by: Dimitris Aragiorgis <dimara@grnet.gr>
Reviewed-by: Hrvoje Ribicic <riba@google.com>
hotplug: Use QMP in VerifyHotplugSupport

This used to check whether a specific hotplug action is supported.
Since everything is about to be done via qmp commands delegate these
checks to QmpConnection class.

Signed-off-by: Dimitris Aragiorgis <dimara@grnet.gr>
Reviewed-by: Hrvoje Ribicic <riba@google.com>
hotplug: Use QMP in VerifyHotplugCommand

This used to check whether a specific hotplug action has succeeded.
Use HasPCIDevice() qmp method to verify if the requested device
exists or not.

Signed-off-by: Dimitris Aragiorgis <dimara@grnet.gr>
Reviewed-by: Hrvoje Ribicic <riba@google.com>
netdev: Refactor OpenTap for future use

Make OpenTap() helper method to take a dictionary with the features
that should be enabled or not. Currently these features are: vhost,
vnet_hdr, multiqueue.

In case vhost is enabled, along with the tapfds we return a list of
vhostfds after opening /dev/vhost-net. This regularly is done by the
qemu process if vhost=on is passed in --netdev option, but in case
of hotplug and if the qemu process does not run with root privileges
we must get the fds and pass them via SCM_RIGHTS prior qemu uses
them.

Signed-off-by: Dimitris Aragiorgis <dimara@grnet.gr>
Reviewed-by: Hrvoje Ribicic <riba@google.com>
kvm: Refactor _GetNetworkDeviceFeatures() helper

Make _GetNetworkDeviceFeatures() return a tuple of (dict, str, str).
The first item should be a dictionary including the enabled
netdev/device features (vhost, vnet_hdr, mq). The other two are
strings to be appended to --netdev and --device qemu options.

Signed-off-by: Dimitris Aragiorgis <dimara@grnet.gr>
Reviewed-by: Hrvoje Ribicic <riba@google.com>
monitor: Extend HotAddNic() for advanced features

In case vhost is enabled we have to pass the vhostfds as returned by
OpenTap() via SCM_RIGHTS prior issuing netdev_add command with vhost
and vhostfds extra arguments.

In case multiqueue is enabled we add the mq and vectors extra
arguments to netdev_add command.

Signed-off-by: Dimitris Aragiorgis <dimara@grnet.gr>
Reviewed-by: Hrvoje Ribicic <riba@google.com>
kvm: Use the new interface during instance start

Use new OpenTap() and _GetNetworkDeviceFeatures() interfaces
during _ExecuteKVMRuntime().

Signed-off-by: Dimitris Aragiorgis <dimara@grnet.gr>
Reviewed-by: Hrvoje Ribicic <riba@google.com>
hotplug: Use QMP during HotAddDevice

During device hot-add use new QMP helper methods: GetFreePCISlot()
for allocating a free PCI slot, HotAddDisk() for disk hotplug and
HotAddNic() for NIC hotplug.

Signed-off-by: Dimitris Aragiorgis <dimara@grnet.gr>
Reviewed-by: Hrvoje Ribicic <riba@google.com>
hotplug: Use QMP during HotDelDevice

During device hot-del use new QMP helper methods: HotDelDisk() for
disk hotplug and HotDelNic() for NIC hotplug.

Signed-off-by: Dimitris Aragiorgis <dimara@grnet.gr>
Reviewed-by: Hrvoje Ribicic <riba@google.com>
hotplug: Remove unused code after refacoring

All HMP related code gets removed since everything is done via QMP.

Signed-off-by: Dimitris Aragiorgis <dimara@grnet.gr>
Reviewed-by: Hrvoje Ribicic <riba@google.com>
hotplug: Is not supported for QEMU < 1.7

Change the bulk check of whether hotplug is supported or not.
Only versions >= 1.7 support the required qmp commands.

Signed-off-by: Dimitris Aragiorgis <dimara@grnet.gr>
Reviewed-by: Hrvoje Ribicic <riba@google.com>