This patch adds XML processing for the network filter schema
and extends the domain XML processing to parse the top level
referenced filter along with potentially provided parameters
Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
Signed-off-by: Gerhard Stenzel <gerhard.stenzel@de.ibm.com>
This patch adds the definition of the wire format for RPC calls
and implementation of the RPC client & server code
Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
This patch adds the implementation of the public API for the network
filtering (ACL) extensions to libvirt.c .
Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
This patch adds recursive locks necessary due to the processing of
network filter XML that can reference other network filters, including
references that cause looks. Loops in the XML are prevented but their
detection requires recursive locks.
Signed-off-by: Stefan Berger <stefanb@us.ibm.com>
To find out where the net type 'direct' needs to be handled I introduced
the 'enum virDomainNetType' in the virDomainNetDef structure and let the
compiler tell me where the case statement is missing. Then I added the
unhandled device statement to the UML driver.
* src/conf/domain_conf.h: change _virDomainNetDef type from int to
virDomainNetType enum
* src/conf/domain_conf.c src/lxc/lxc_driver.c src/qemu/qemu_conf.c
src/uml/uml_conf.c: make sure all enum cases are properly handled
in switches
Use the new virDomainUpdateDeviceFlags API to allow the VNC password
to be changed on the fly
* src/internal.h: Define STREQ_NULLABLE() which is like STREQ()
but does not crash if either argument is NULL, and treats two
NULLs as equal.
* src/libvirt_private.syms: Export virDomainGraphicsTypeToString
* src/qemu/qemu_driver.c: Support VNC password change on a live
machine
* src/qemu/qemu_monitor.c: Disable crazy debugging info. Treat a
NULL password as "" (empty string), allowing passwords to be
disabled in the monitor
Expand the parser for the standalone <device> XML format to
allow inclusion of the <graphics> device type
* src/conf/domain_conf.h: Add virDomainGraphicsDef to
the virDomainDeviceDef struct
* src/conf/domain_conf.c: Wire up parser for virDomainGraphicsDef
to virDomainDeviceDefParse method
To allow the new virDomainUpdateDeviceFlags() API to be universally
used with all drivers, this patch adds an impl to all the current
drivers which support CDROM or Floppy disk media change via the
current virDomainAttachDeviceFlags API
* src/qemu/qemu_driver.c, src/vbox/vbox_tmpl.c,
src/xen/proxy_internal.c, src/xen/xen_driver.c,
src/xen/xend_internal.c: Implement media change via the
virDomainUpdateDeviceFlags API
* src/xen/xen_driver.h, src/xen/xen_hypervisor.c,
src/xen/xen_inotify.c, src/xen/xm_internal.c,
src/xen/xs_internal.c: Stubs for Xen driver entry points
This defines the wire format for the new virDomainUpdateDeviceFlags()
API, and implements the server & client side of the marshalling code.
* daemon/remote.c: Server side dispatch for virDomainUpdateDeviceFlags
* src/remote/remote_driver.c: Client side serialization for
virDomainUpdateDeviceFlags
* src/remote/remote_protocol.x: Define wire format for
virDomainUpdateDeviceFlags
* daemon/remote_dispatch_args.h, daemon/remote_dispatch_prototypes.h,
daemon/remote_dispatch_table.h, src/remote/remote_protocol.c,
src/remote/remote_protocol.h: Re-generate code
The current virDomainAttachDevice API can be (ab)used to change
the media of an existing CDROM/Floppy device. Going forward there
will be more devices that can be configured on the fly and overloading
virDomainAttachDevice for this is not too pleasant. This patch adds
a new virDomainUpdateDeviceFlags() explicitly just for modifying
existing devices.
* include/libvirt/libvirt.h.in: Add virDomainUpdateDeviceFlags
* src/driver.h: Internal API for virDomainUpdateDeviceFlags
* src/libvirt.c, src/libvirt_public.syms: Glue public API to
driver API
* src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/opennebula/one_driver.c,
src/openvz/openvz_driver.c, src/phyp/phyp_driver.c, src/qemu/qemu_driver.c,
src/remote/remote_driver.c, src/test/test_driver.c, src/uml/uml_driver.c,
src/vbox/vbox_tmpl.c, src/xen/xen_driver.c, src/xenapi/xenapi_driver.c: Add
stubs for new driver entry point
This introduces a new event type
VIR_DOMAIN_EVENT_ID_GRAPHICS
The same event can be emitted in 3 scenarios
typedef enum {
VIR_DOMAIN_EVENT_GRAPHICS_CONNECT = 0,
VIR_DOMAIN_EVENT_GRAPHICS_INITIALIZE,
VIR_DOMAIN_EVENT_GRAPHICS_DISCONNECT,
} virDomainEventGraphicsPhase;
Connect/disconnect are triggered at socket accept/close.
The initialize phase is immediately after the protocol
setup and authentication has completed. ie when the
client is authorized and about to start interacting with
the graphical desktop
This event comes with *a lot* of potential information
- IP address, port & address family of client
- IP address, port & address family of server
- Authentication scheme (arbitrary string)
- Authenticated subject identity. A subject may have
multiple identities with some authentication schemes.
For example, vencrypt+sasl results in a x509dname
and saslUsername identities.
This results in a very complicated callback :-(
typedef enum {
VIR_DOMAIN_EVENT_GRAPHICS_ADDRESS_IPV4,
VIR_DOMAIN_EVENT_GRAPHICS_ADDRESS_IPV6,
} virDomainEventGraphicsAddressType;
struct _virDomainEventGraphicsAddress {
int family;
const char *node;
const char *service;
};
typedef struct _virDomainEventGraphicsAddress virDomainEventGraphicsAddress;
typedef virDomainEventGraphicsAddress *virDomainEventGraphicsAddressPtr;
struct _virDomainEventGraphicsSubject {
int nidentity;
struct {
const char *type;
const char *name;
} *identities;
};
typedef struct _virDomainEventGraphicsSubject virDomainEventGraphicsSubject;
typedef virDomainEventGraphicsSubject *virDomainEventGraphicsSubjectPtr;
typedef void (*virConnectDomainEventGraphicsCallback)(virConnectPtr conn,
virDomainPtr dom,
int phase,
virDomainEventGraphicsAddressPtr local,
virDomainEventGraphicsAddressPtr remote,
const char *authScheme,
virDomainEventGraphicsSubjectPtr subject,
void *opaque);
The wire protocol is similarly complex
struct remote_domain_event_graphics_address {
int family;
remote_nonnull_string node;
remote_nonnull_string service;
};
const REMOTE_DOMAIN_EVENT_GRAPHICS_IDENTITY_MAX = 20;
struct remote_domain_event_graphics_identity {
remote_nonnull_string type;
remote_nonnull_string name;
};
struct remote_domain_event_graphics_msg {
remote_nonnull_domain dom;
int phase;
remote_domain_event_graphics_address local;
remote_domain_event_graphics_address remote;
remote_nonnull_string authScheme;
remote_domain_event_graphics_identity subject<REMOTE_DOMAIN_EVENT_GRAPHICS_IDENTITY_MAX>;
};
This is currently implemented in QEMU for the VNC graphics
protocol, but designed to be usable with SPICE graphics in
the future too.
* daemon/remote.c: Dispatch graphics events to client
* examples/domain-events/events-c/event-test.c: Watch for
graphics events
* include/libvirt/libvirt.h.in: Define new graphics event ID
and callback signature
* src/conf/domain_event.c, src/conf/domain_event.h,
src/libvirt_private.syms: Extend API to handle graphics events
* src/qemu/qemu_driver.c: Connect to the QEMU monitor event
for VNC events and emit a libvirt graphics event
* src/remote/remote_driver.c: Receive and dispatch graphics
events to application
* src/remote/remote_protocol.x: Wire protocol definition for
graphics events
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h,
src/qemu/qemu_monitor_json.c: Watch for VNC_CONNECTED,
VNC_INITIALIZED & VNC_DISCONNETED events from QEMU monitor
This introduces a new event type
VIR_DOMAIN_EVENT_ID_IO_ERROR
This event includes the action that is about to be taken
as a result of the watchdog triggering
typedef enum {
VIR_DOMAIN_EVENT_IO_ERROR_NONE = 0,
VIR_DOMAIN_EVENT_IO_ERROR_PAUSE,
VIR_DOMAIN_EVENT_IO_ERROR_REPORT,
} virDomainEventIOErrorAction;
In addition it has the source path of the disk that had the
error and its unique device alias. It does not include the
target device name (/dev/sda), since this would preclude
triggering IO errors from other file backed devices (eg
serial ports connected to a file)
Thus there is a new callback definition for this event type
typedef void (*virConnectDomainEventIOErrorCallback)(virConnectPtr conn,
virDomainPtr dom,
const char *srcPath,
const char *devAlias,
int action,
void *opaque);
This is currently wired up to the QEMU block IO error events
* daemon/remote.c: Dispatch IO error events to client
* examples/domain-events/events-c/event-test.c: Watch for
IO error events
* include/libvirt/libvirt.h.in: Define new IO error event ID
and callback signature
* src/conf/domain_event.c, src/conf/domain_event.h,
src/libvirt_private.syms: Extend API to handle IO error events
* src/qemu/qemu_driver.c: Connect to the QEMU monitor event
for block IO errors and emit a libvirt IO error event
* src/remote/remote_driver.c: Receive and dispatch IO error
events to application
* src/remote/remote_protocol.x: Wire protocol definition for
IO error events
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h,
src/qemu/qemu_monitor_json.c: Watch for BLOCK_IO_ERROR event
from QEMU monitor
This introduces a new event type
VIR_DOMAIN_EVENT_ID_WATCHDOG
This event includes the action that is about to be taken
as a result of the watchdog triggering
typedef enum {
VIR_DOMAIN_EVENT_WATCHDOG_NONE = 0,
VIR_DOMAIN_EVENT_WATCHDOG_PAUSE,
VIR_DOMAIN_EVENT_WATCHDOG_RESET,
VIR_DOMAIN_EVENT_WATCHDOG_POWEROFF,
VIR_DOMAIN_EVENT_WATCHDOG_SHUTDOWN,
VIR_DOMAIN_EVENT_WATCHDOG_DEBUG,
} virDomainEventWatchdogAction;
Thus there is a new callback definition for this event type
typedef void (*virConnectDomainEventWatchdogCallback)(virConnectPtr conn,
virDomainPtr dom,
int action,
void *opaque);
* daemon/remote.c: Dispatch watchdog events to client
* examples/domain-events/events-c/event-test.c: Watch for
watchdog events
* include/libvirt/libvirt.h.in: Define new watchdg event ID
and callback signature
* src/conf/domain_event.c, src/conf/domain_event.h,
src/libvirt_private.syms: Extend API to handle watchdog events
* src/qemu/qemu_driver.c: Connect to the QEMU monitor event
for watchdogs and emit a libvirt watchdog event
* src/remote/remote_driver.c: Receive and dispatch watchdog
events to application
* src/remote/remote_protocol.x: Wire protocol definition for
watchdog events
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h,
src/qemu/qemu_monitor_json.c: Watch for WATCHDOG event
from QEMU monitor
This introduces a new event type
VIR_DOMAIN_EVENT_ID_RTC_CHANGE
This event includes the new UTC offset measured in seconds.
Thus there is a new callback definition for this event type
typedef void (*virConnectDomainEventRTCChangeCallback)(virConnectPtr conn,
virDomainPtr dom,
long long utcoffset,
void *opaque);
If the guest XML configuration for the <clock> is set to
offset='variable', then the XML will automatically be
updated with the new UTC offset value. This ensures that
during migration/save/restore the new offset is preserved.
* daemon/remote.c: Dispatch RTC change events to client
* examples/domain-events/events-c/event-test.c: Watch for
RTC change events
* include/libvirt/libvirt.h.in: Define new RTC change event ID
and callback signature
* src/conf/domain_event.c, src/conf/domain_event.h,
src/libvirt_private.syms: Extend API to handle RTC change events
* src/qemu/qemu_driver.c: Connect to the QEMU monitor event
for RTC changes and emit a libvirt RTC change event
* src/remote/remote_driver.c: Receive and dispatch RTC change
events to application
* src/remote/remote_protocol.x: Wire protocol definition for
RTC change events
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h,
src/qemu/qemu_monitor_json.c: Watch for RTC_CHANGE event
from QEMU monitor
The reboot event is not a normal lifecycle event, since the
virtual machine on the host does not change state. Rather the
guest OS is resetting the virtual CPUs. ie, the QEMU process
does not restart. Thus, this does not belong in the current
lifecycle events callback.
This introduces a new event type
VIR_DOMAIN_EVENT_ID_REBOOT
It takes no parameters, besides the virDomainPtr, so it can
use the generic callback signature.
* daemon/remote.c: Dispatch reboot events to client
* examples/domain-events/events-c/event-test.c: Watch for
reboot events
* include/libvirt/libvirt.h.in: Define new reboot event ID
* src/conf/domain_event.c, src/conf/domain_event.h,
src/libvirt_private.syms: Extend API to handle reboot events
* src/qemu/qemu_driver.c: Connect to the QEMU monitor event
for reboots and emit a libvirt reboot event
* src/remote/remote_driver.c: Receive and dispatch reboot
events to application
* src/remote/remote_protocol.x: Wire protocol definition for
reboot events
To avoid confusion, rename the current REMOTE_PROC_DOMAIN_EVENT
message to REMOTE_PROC_DOMAIN_EVENT_LIFECYCLE. This does not
cause ABI problems, since the names are only relevant at the source
code level. On the wire they encoding is a plain integer whose
value does not change
* src/remote/remote_protocol.x: Rename REMOTE_PROC_DOMAIN_EVENT
to REMOTE_PROC_DOMAIN_EVENT_LIFECYCLE.
* daemon/remote.c, src/remote/remote_driver.c: Update code for
renamed event
This wires up the remote driver to handle the new events APIs.
The public API allows an application to request a callback filters
events to a specific domain object, and register multiple callbacks
for the same event type. On the wire there are two strategies for
this
- Register multiple callbacks with the remote daemon, each
with filtering as needed
- Register only one callback per event type, with no filtering
Both approaches have potential inefficiency. In the first scheme,
the same event gets sent over the wire many times if multiple
callbacks are registered. With the second scheme, unneccessary
events get sent over the wire if a per-domain filter is set on
the client. The second scheme is far easier to implement though,
so this patch takes that approach.
* daemon/dispatch.h: Don't export remoteRelayDomainEvent since it
is no longer needed for unregistering callbacks, instead the
unique callback ID is used
* daemon/libvirtd.c, daemon/libvirtd.h: Track and unregister
callbacks based on callback ID, instead of function pointer
* daemon/remote.c: Switch over to using virConnectDomainEventRegisterAny
instead of legacy virConnectDomainEventRegister function. Refactor
remoteDispatchDomainEventSend() to cope with arbitrary event types
* src/driver.h, src/driver.c: Move verify() call into source file
instead of header, to avoid polluting the global namespace with
the verify function name
* src/remote/remote_driver.c: Implement new APIs for event
registration. Refactor processCallDispatchMessage() to cope
with arbitrary incoming event types. Merge remoteDomainQueueEvent()
into processCallDispatchMessage() to avoid duplication of code.
Rename remoteDomainReadEvent() to remoteDomainReadEventLifecycle()
* src/remote/remote_protocol.x: Define wire format for the new
virConnectDomainEventRegisterAny and virConnectDomainEventDeregisterAny
functions
The libvirtd daemon impl will need to switch over to using the
new event APIs. To make this simpler, ensure all drivers currently
providing events support both the new APIs and old APIs.
* src/lxc/lxc_driver.c, src/qemu/qemu_driver.c, src/test/test_driver.c,
src/vbox/vbox_tmpl.c, src/xen/xen_driver.c: Implement the new
virConnectDomainEvent(Dereg|Reg)isterAny driver entry points
The current internal domain events API tracks callbacks based on
the function pointer, and only supports lifecycle events. This
adds new internal APIs for registering callbacks for other event
types. These new APIs are postfixed with the word 'ID' to indicate
that they operated based on event ID, instead of hardcoded to
lifecycle events
* src/conf/domain_event.c, src/conf/domain_event.h,
src/libvirt_private.syms: Add new APIs for handling callbacks
for non-lifecycle events
The internal domain events APIs are designed to handle the lifecycle
events. This needs to be refactored to allow arbitrary new event
types to be handled.
* The signature of virDomainEventDispatchFunc changes to use
virConnectDomainEventGenericCallback instead of the lifecycle
event specific virConnectDomainEventCallback
* Every registered callback gains a unique ID to allow its
removal based on ID, instead of function pointer
* Every registered callback gains an 'eventID' to allow callbacks
for different types of events to be distinguished
* virDomainEventDispatch is adapted to filter out callbacks
whose eventID does not match the eventID of the event being
dispatched
* virDomainEventDispatch is adapted to filter based on the
domain name and uuid, if this filter is set for a callback.
* virDomainEvent type/detail fields are moved into a union to
allow different data fields for other types of events to be
added later
* src/conf/domain_event.h, src/conf/domain_event.c: Refactor
to allow handling of different types of events
* src/lxc/lxc_driver.c, src/qemu/qemu_driver.c,
src/remote/remote_driver.c, src/test/test_driver.c,
src/xen/xen_driver.c: Change dispatch function signature
to use virConnectDomainEventGenericCallback
The virtual box driver was directly accesing the domain events
structs instead of using the APIs provided. To prevent this kind
of abuse, make the struct definitions private, forcing use of the
internal APIs. This requires adding one extra internal API.
* src/conf/domain_event.h, src/conf/domain_event.c: Move
virDomainEventCallback and virDomainEvent structs into
the source file instead of header
* src/vbox/vbox_tmpl.c: Use official APIs for dispatching domain
events instead of accessing structs directly.
The current API for domain events has a number of problems
- Only allows for domain lifecycle change events
- Does not allow the same callback to be registered multiple times
- Does not allow filtering of events to a specific domain
This introduces a new more general purpose domain events API
typedef enum {
VIR_DOMAIN_EVENT_ID_LIFECYCLE = 0, /* virConnectDomainEventCallback */
...more events later..
}
int virConnectDomainEventRegisterAny(virConnectPtr conn,
virDomainPtr dom, /* Optional, to filter */
int eventID,
virConnectDomainEventGenericCallback cb,
void *opaque,
virFreeCallback freecb);
int virConnectDomainEventDeregisterAny(virConnectPtr conn,
int callbackID);
Since different event types can received different data in the callback,
the API is defined with a generic callback. Specific events will each
have a custom signature for their callback. Thus when registering an
event it is neccessary to cast the callback to the generic signature
eg
int myDomainEventCallback(virConnectPtr conn,
virDomainPtr dom,
int event,
int detail,
void *opaque)
{
...
}
virConnectDomainEventRegisterAny(conn, NULL,
VIR_DOMAIN_EVENT_ID_LIFECYCLE,
VIR_DOMAIN_EVENT_CALLBACK(myDomainEventCallback)
NULL, NULL);
The VIR_DOMAIN_EVENT_CALLBACK() macro simply does a "bad" cast
to the generic signature
* include/libvirt/libvirt.h.in: Define new APIs for registering
domain events
* src/driver.h: Internal driver entry points for new events APIs
* src/libvirt.c: Wire up public API to driver API for events APIs
* src/libvirt_public.syms: Export new APIs
* src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/opennebula/one_driver.c,
src/openvz/openvz_driver.c, src/phyp/phyp_driver.c,
src/qemu/qemu_driver.c, src/remote/remote_driver.c,
src/test/test_driver.c, src/uml/uml_driver.c,
src/vbox/vbox_tmpl.c, src/xen/xen_driver.c,
src/xenapi/xenapi_driver.c: Stub out new API entries
The keys of entries in a VMX file are case insensitive. Both scsi0:1.fileName
and scsi0:1.filename are valid. Therefore, make the conf parser compare names
case insensitive in VMX mode to accept every capitalization variation.
Also add test cases for this.
<source file=''/> results in def->disks[i]->src == NULL. But
vboxDomainDefineXML and vboxDomainAttachDevice didn't check
def->disks[i]->src for NULL and expected it to be a valid string.
Add checks for def->disks[i]->src != NULL to fix the segfault.
* src/Makefile.am (augeas-check): New target, just to give the existing
rule a name. At the same time, prefix the commands with $(AM_V_GEN),
to avoid unexpected build output with V=0 which is the default.
Before, this function would blindly accept an invalid def->dst
and then abuse the idx=-1 it would get from virDiskNameToIndex,
when passing it invalid strings like "xvda:disk" and "sda1".
Now, this function returns -1 upon failure.
* src/conf/domain_conf.c (virDomainDiskDefAssignAddress): as above.
Update callers.
* src/conf/domain_conf.h: Update prototype.
* src/qemu/qemu_conf.c: Update callers.
Even if gnulib can provide stubs, it won't help that much. So just
replace affected util functions (virFileOperation and virDirCreate)
with stubs on Windows. Both functions aren't used on libvirt's
client side, so this is fine for MinGW builds.
This symbol is conditional, it would need to be exported conditional to
work properly with MinGW. So just remove it, as no other driver register
function is listed in the symbols files.
If esxVI_String_DeepCopyValue or esxVI_SelectionSpec_AppendToList fail
then selectionSpec would leak. Add a free call in the failure path to
fix the leak.
This is actually a consequence of the reworked required parameter
checking: Unify the required parameter check into a Validate function
instead of doing it separately im the (de)serialization part.
The required parameter checking for the mapped methods parameter was
done in the (de)serialize functions before. Now it's explicitly done
in the mapped method itself.
Invoking virDomainSetMemory() on lxc driver results in libvirtd
segfault when cgroups has not been configured on the host.
Ensure driver->cgroup is non-null before invoking
virCgroupForDomain(). To prevent similar segfaults in the future,
ensure driver parameter to virCgroupForDomain() is non-null before
dereferencing.
"virsh dominfo <vm>" crashes if there's no primary security driver set
since we only intialize the secmodel.model and secmodel.doi if we have
one. Attached patch checks for securityPrimaryDriver instead of
securityDriver since the later is always set in qemudSecurityInit().
Closes: http://bugs.debian.org/574359
Attempt to turn on vhost-net mode for devices of type NETWORK, BRIDGE,
and DIRECT (macvtap).
* src/qemu/qemu_conf.h: add vhostfd to qemuBuildHostNetStr prototype
add qemudOpenVhostNet prototype new flag to set when :,vhost=" found in
qemu help
* src/qemu/qemu_conf.c: * set QEMUD_CMD_FLAG_VNET_HOST is ",vhost=" found
in qemu help
- qemudOpenVhostNet - opens /dev/vhost-net to pass to qemu if everything
is in place to use it.
- qemuBuildHostNetStr - add vhostfd to commandline if it's not empty
(higher levels decide whether or not to fill it in)
- qemudBuildCommandLine - if /dev/vhost-net is successfully opened, add
its fd to tapfds array so it isn't closed on qemu exec, and populate
vhostfd_name to be passed in to commandline builder.
* src/qemu/qemu_driver.c: add filler 0 for new arg to qemuBuildHostNetStr,
along with a note that this must be implemented in order for hot-plug of
vhost-net virtio devices to work properly (once qemu "netdev_add" monitor
command is implemented).
POSIX states that creation of a mutex with default attributes
is unspecified whether the mutex is recursive or non-recursive.
We specifically want non-recursive (deadlock is desirable in
flushing out coding bugs that used our mutex incorrectly).
* src/util/threads-pthread.c (virMutexInit): Specifically request
non-recursive mutex, rather than relying on unspecified default.
Currently no command can be sent to a qemu process while another job is
active. This patch adds support for signaling long-running jobs (such as
migration) so that other threads may request predefined operations to be
done during such jobs. Two signals are defined so far:
- QEMU_JOB_SIGNAL_CANCEL
- QEMU_JOB_SIGNAL_SUSPEND
The first one is used by qemuDomainAbortJob.
The second one is used by qemudDomainSuspend for suspending a domain
during migration, which allows for changing live migration into offline
migration. However, there is a small issue in the way qemudDomainSuspend
is currently implemented for migrating domains. The API calls returns
immediately after signaling migration job which means it is asynchronous
in this specific case.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
* src/qemu/qemu_driver.c (qemudDomainAttachSCSIDisk): The ".controller"
member is an index, and *may* be 0. As such, the commit that we're
reverting broke SCSI disk hot-plug on controller 0.
Reported by Wolfgang Mauerer.
We need to call PrepareHostdevs to determine the USB device path before
any security calls. PrepareHostUSBDevices was also incorrectly skipping
all USB devices.
* src/qemu/qemu_conf.c: add the ",readonly=on" for read-only disks
and also parse it back in qemuParseCommandLineDisk()
* tests/qemuxml2argvtest.c
tests/qemuxml2argvdata/qemuxml2argv-disk-drive-readonly-disk.args
tests/qemuxml2argvdata/qemuxml2argv-disk-drive-readonly-disk.xml:
add a specific regression test
The nodeGetInfo code was always assuming that machine had a
single NUMA node, which is not correct. The good news is that
libnuma gives us this information pretty easily, so let's
properly report it.
NOTE: With recent hardware starting to support CPU hot-add
and hot-remove, both this code and the nodeCapsInitNUMA()
code are quickly going to become obsolete. We'll have to
think of a more dynamic solution for dealing with NUMA
nodes and CPUs that can come and go at will.
Signed-off-by: Chris Lalancette <clalance@redhat.com>
Currently if you dump the core of a qemu guest with
qemudDomainCoreDump, subsequent commands will hang
up libvirtd. This is because qemudDomainCoreDump
uses qemuDomainWaitForMigrationComplete, which expects
the qemuDriverLock to be held when it's called. This
patch does the simple thing and moves the qemuDriveUnlock
to the end of the qemudDomainCoreDump so that the driver
lock is held for the entirety of the call (as it is done
in qemudDomainSave). We will probably want to make the
lock more fine-grained than that in the future, but
we can fix both qemudDomainCoreDump and qemudDomainSave
at the same time.
Signed-off-by: Chris Lalancette <clalance@redhat.com>
The code to add job support into libvirtd caused a problem
in qemudDomainSetVcpus. In particular, a qemuDomainObjEndJob()
call was added at the end of the function, but a
corresponding qemuDomainObjBeginJob() was not. Additionally,
a call to qemuDomainObj{Enter,Exit}Monitor() was also missed
in qemudDomainHotplugVcpus(). These missing calls conspired to
cause a hang in the libvirtd process after the command was
finished. Fix this by adding the missing calls.
Signed-off-by: Chris Lalancette <clalance@redhat.com>
As previously discussed[1], this patch removes the
qemudDomainSetMaxMemory() function, since it doesn't
work. This means that instead of getting somewhat
cryptic errors, you will now get:
error: Unable to change MaxMemorySize
error: this function is not supported by the hypervisor: virDomainSetMaxMemory
Which describes the situation perfectly.
[1] https://www.redhat.com/archives/libvir-list/2010-February/msg00928.html
Signed-off-by: Chris Lalancette <clalance@redhat.com>
When using the JSON monitor, qemuMonitorJSONExtractCPUInfo
was returning 0 on success. Unfortunately, higher levels of
the cpuinfo code expect that it returns the number of CPUs
it found on success. This one-line patch fixes it so that
it returns the correct number. This makes "virsh vcpuinfo <domain>"
work when using the JSON monitor.
Signed-off-by: Chris Lalancette <clalance@redhat.com>
As pointed out by eblake, I made a real hash of the
nodeinfo code with commit
aa2f6f96dd. This patch
cleans it up:
1) Do more work at compile time instead of runtime (minor)
2) Properly handle the hex digits that come from
/sys/devices/system/cpu/cpu*/topology/thread_siblings
3) Fix up some error paths that could cause SEGV
4) Used unsigned's for the cpu numbers (cpu -1 doesn't
make any sense)
Along with the recent patch from jdenemar to zero out
the nodeinfo structure, I've re-tested this on the
machines having the problems, and it seems to be good.
Signed-off-by: Chris Lalancette <clalance@redhat.com>
It is a bad idea to call gettext on an already-translated
string. In cases where a string must be translated separately
from where it is exposed to xgettext, the gettext manual
recommends the idiom of N_() wrapping gettext_noop for
marking the string.
* src/internal.h (N_): Fix definition to match gettext manual.
* tools/virsh.c: (cmdHelp, cmdList, cmdDomstate, cmdDominfo)
(cmdVcpuinfo, vshUsage): Replace incorrect use of N_ with _.
(vshCmddefHelp): Likewise. Mark C format strings appropriately.
The nodeinfo structure wasn't initialized in qemu driver and with the
recent change in CPU topology parsing, old value of nodeinfo->sockets
could be used and incremented giving totally bogus results.
Let's just wipe the structure completely.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
A few more non-literal format strings in error log messages have crept
in. Fix them in the standard way - turn the format string into "%s"
with the original string as the arg.
If a special cache strategy for a disk has been specified in a domain
definition, but no driverName has been set, virDomainGetXMLDesc would not
include the <driver> tag at all.
* src/conf/domain_conf.c: make sure any <driver> tag setting is
serialized if set.
The current code for "nodeinfo" is pretty naive
about socket and thread information. To determine the
sockets, it just takes the number of cpus and divides
by the number of cores. For the thread count, it always
sets it to 1. With more recent Intel machines, however,
hyperthreading is again an option, meaning that these
heuristics no longer work and give bogus numbers. This
patch goes through /sys to get the additional
information so we properly report it.
Note that I had to edit the tests not to report on
socket and thread counts, since these are determined
dynamically now.
v2: As pointed out by Eric Blake, gnulib provides
count-one-bits (which is LGPLv2+). Use it instead
of a hand-coded popcnt.
Signed-off-by: Chris Lalancette <clalance@redhat.com>
When adding domainMemoryStats API support for the qemu driver, I didn't
follow the locking rules exactly. The job condition must be held when
executing monitor commands. This corrects the segfaults I was seeing
when calling domainMemoryStats in a multi-threaded environment.
* src/qemu/qemu_driver.c: in qemudDomainMemoryStats() add missing
calls to qemuDomainObjBeginJob/qemuDomainObjEndJob
doTunnelSendAll function (used by QEMU migration) uses a 64k buffer on
the stack, which could be problematic. This patch replaces that with a
buffer from the heap.
While in the neighborhood, this patch also improves error reporting in
the case that saferead fails - previously, virStreamAbort() was called
(resetting errno) before reporting the error. It's been changed to
report the error first.
* src/qemu/qemu_driver.c: fix doTunnelSendAll() to use a malloc'ed
buffer
* src/qemu/qemu_driver.c (qemudDomainAttachSCSIDisk): Handle
the (theoretical) case of an empty controller list, so that
clang does not think the subsequent dereference of "cont"
would dereference an undefined variable (due to preceding
loop not iterating even once).
* src/qemu/qemu_driver.c (qemudDomainRestore): A corrupt save file
(in particular, a too-large header.xml_len value) would cause an
unwarranted out-of-memory error. Do not trust the just-read
header.xml_len. Instead, merely use that as a hint, and
read/allocate up to that number of bytes from the file.
Also verify that header.xml_len is positive; if it were negative,
passing it to virFileReadLimFD could cause trouble.
to saferead_lim, which interprets it as a size_t.
* src/util/util.c (virFileReadLimFD): Do not malfunction when
maxlen < -1. Return -1,EINVAL in that case. Handle maxlen==0
in the same manner.
* src/xen/proxy_internal.c (xenProxyDomainDumpXML): An invalid packet
could include a too-large "ans.len" value, which would make us allocate
too much memory and then copy data from beyond the end of "ans",
possibly evoking a segfault. Ensure that the value we use is no
larger than the remaining portion of "ans".
Also, change unnecessary memmove to memcpy (src and dest obviously
do not overlap, so no need to use memmove).
(xenProxyDomainGetOSType): Likewise.
(xenProxyGetCapabilities): Likewise.
The code erroneously searched the entire "reply" for a comma, when
its intent was to search only that portion after "balloon: actual="
* src/qemu/qemu_monitor_text.c (qemuMonitorTextGetMemoryStats):
Search for "," only starting *after* the BALLOON_PREFIX string.
Otherwise, we'd be more prone to false positives.
Changeset
commit 5073aa994a
Author: Cole Robinson <crobinso@redhat.com>
Date: Mon Jan 11 11:40:46 2010 -0500
Added support for product/vendor based passthrough, but it only
worked at the security driver layer. The main guest XML config
was not updated with the resolved bus/device ID. When the QEMU
argv refactoring removed use of product/vendor, this then broke
launching guests.
THe solution is to move the product/vendor resolution up a layer
into the QEMU driver. So the first thing QEMU does is resolve
the product/vendor to a bus/device and updates the XML config
with this info. The rest of the code, including security drivers
and QEMU argv generated can now rely on bus/device always being
set.
* src/util/hostusb.c, src/util/hostusb.h: Split vendor/product
resolution code out of usbGetDevice and into usbFindDevice.
Add accessors for bus/device ID
* src/security/virt-aa-helper.c, src/security/security_selinux.c,
src/qemu/qemu_security_dac.c: Remove vendor/product from the
usbGetDevice() calls
* src/qemu/qemu_driver.c: Use usbFindDevice to resolve vendor/product
into a bus/device ID
The pci_del command is not being ported to QMP. Convert all the
QEMU hotplug code over to use device_del whenever it is available
to avoid the pci_del problem
* src/qemu/qemu_driver.c: Convert unplug code to device_del
Previously hot-unplug could not be supported for USB devices
in QEMU, since usb_del required the guest visible address
which libvirt never knows. With 'device_del' command we can
now unplug based on device alias, so support that.
* src/qemu/qemu_driver.c: Use device_del to remove USB devices
Upstart crashes & burns in a heap if $TERM environment variable
is missing. Presumably the kernel always sets this when booting
init on a real machine, so libvirt should set it for containers
too.
To make a typical inittab / mingetty setup happier, we need to
symlink the primary console /dev/pts/0 to /dev/tty1.
Improve logging in certain scenarios to make troubleshooting
easier
* src/lxc/lxc_container.c: Create /dev/tty1 and set $TERM
When using the 'ns' cgroup controller, the moment a process calls
'unshare(CLONE_NEWNS)', it will be given a private cgroup tree
under its current location. This really messages up the LXC
controller process, because it ends up creating the containers'
cgroup in the wrong place. The fix is fairly easy, just move
the cgroup setup before the code which calls unshare(). The
'ns' controller will still create extra undesired cgroups, but
they at least won't break libvirt's setup now.
The patch also adds a missing cgroups allow rule for /dev/tty
device node
When getting the driver/domain cgroup it is possible to specify
whether it should be auto created. If auto-creation was turned
off, libvirt still mistakenly created its own top level cgroup
* src/util/cgroup.c: Honour autocreate flag for top level cgroup
This allows the config to have a setting that means "leave it alone",
eg when building a pool where the directory already exists the user
may want the current uid/gid of the directory left intact. This
actually gets us back to older behavior - before recent changes to the
pool building code, we weren't as insistent about honoring the uid/gid
settings in the XML, and virt-manager was taking advantage of this
behavior.
As a side benefit, removing calls to getuid/getgid from the XML
parsing functions also seems like a good idea. And having a default
that is different from a common/useful value (0 == root) is a good
thing in general, as it removes ambiguity from decisions (at least one
place in the code was checking for (perms.uid == 0) to see if a
special uid was requested).
Note that this will only affect newly created pools and volumes. Due
to the way that the XML is parsed, then formatted for newly created
volumes, all existing pools/volumes already have an explicit uid and
gid set.
src/conf/storage_conf.c: Remove calls to setuid/setgid for default values
of uid/gid, and set them to -1 instead
src/storage/storage_backend.c:
src/storage/storage_backend_fs.c:
Make account for the new default values of perms.uid
and perms.gid.
With the recent changes to the linking defaults in Fedora 13 (namely
enabling --no-add-needed behaviour by default), we have to pass the
dlopen()-providing libraries directly at the link of the module; use the
same AC_SEARCH_LIBS function as used before to look for it and add it to
the Makefile.
QEMU has a monitor command 'set_cpu' which allows a specific
CPU to be toggled between online& offline state. libvirt CPU
hotplug does not work in terms of individual indexes CPUs.
Thus to support this, we iteratively toggle the online state
when the total number of vCPUs is adjusted via libvirt
NB, currently untested since QEMU segvs when running this!
* src/qemu/qemu_driver.c: Toggle online state for CPUs when
doing hotplug
* src/qemu/qemu_monitor.c, src/qemu/qemu_monitor.h,
src/qemu/qemu_monitor_json.c, src/qemu/qemu_monitor_json.h,
src/qemu/qemu_monitor_text.c, src/qemu/qemu_monitor_text.h: Add
monitor API for toggling a CPU's online status via 'set_cpu
The storage backend implementations all presume that the XML parser
is validating correctness of the source specification. The check for
a source device was lost at some point. This allowed for a potential
crash in the disk backend. Re-introduce the sanity check
* src/conf/storage_conf.c: Re-add check for source device
When trying to delete a pool the error message claimed the volume
could not be deleted.
* src/storage/storage_driver.c: Error message referred to
volumes instead of pools
The QMP code was running query-migration instead of query-migrate.
This doesn't work so well
* src/qemu/qemu_monitor_json.c: s/query-migration/query-migrate/
The code to remove the cgroup after QEMU failed to startup could
be obscuring a real error from earlier on. It is not neccessary
to raise an error in this case, so tell cgroups to keep quiet
* src/qemu/qemu_driver.c: Don't raise cgroups error in QEMU start
cleanup code.
The QEMU hotunplug code for PCI devices was looking at host
devices in the guest config without first filtering non
PCI devices. This means it was reading garbage
* src/qemu/qemu_driver.c: Filter out non-PCI devices
Commit 3c12a67b76 added
a dependency on the NFS_SUPER_MAGIC macro, which is
defined in linux/magic.h. Unfortunately linux/magic.h
is not available in RHEL-5, and causes a compile error.
Just define it locally, since this is something that
can't change.
Signed-off-by: Chris Lalancette <clalance@redhat.com>
Move *all* file operations related to creation and writing of libvirt
header to the domain save file into a hook function that is called by
virFileOperation. First try to call virFileOperation as root. If that
fails with EACCESS, and (in the case of Linux) statfs says that we're
trying to save the file on an NFS share, rerun virFileOperation,
telling it to fork a child process and setuid to the qemu user. This
is the only way we can successfully create a file on a root-squashed
NFS server.
This patch (along with setting dynamic_ownership=0 in qemu.conf)
makes qemudDomainSave work on root-squashed NFS.
* src/qemu/qemu_driver.c: provide new qemudDomainSaveFileOpHook()
utility, use it in qemudDomainSave() if normal creation of the
file as root failed, and after checking the filesystem type for
the storage is NFS. In that case we also bypass the security
driver, as this would fail on NFS.
If qemudDomainRestore fails to open the domain save file, create a
pipe, then fork a process that does setuid(qemu_user) and opens the
file, then reads this file and stuffs it into the pipe. the parent
libvirtd process will use the other end of the pipe as its fd, then
reap the child process after it's done reading.
This makes domain restore work on a root-squash NFS share that is only
visible to the qemu user.
* src/qemu/qemu_driver.c: add new qemudOpenAsUID() helper function,
and use it in qemudDomainRestore() if reading as root directly failed.
The USB/PCI device hotplug code for the QEMU driver was forgetting
to allocate a unique device alias.
* src/qemu/qemu_driver.c: Fill in device alias for USB/PCI devices
The code assumed that 'device_add' returned an empty string upon
success. This is not true, it sometimes prints random debug info.
THus we need to check for an explicit fail string
* src/qemu/qemu_monitor_text.c: Fix error checking of the device_add
monitor command
Another warning caught by coverity. Continue to perform best-effort
closing and resource release, but warn the caller about the failure.
* src/esx/esx_driver.c (esxClose): Return an error on failure to close.
Various safezero() implementations used either -1, errno or -errno
return values. This patch fixes them all to return -1 and set errno
appropriately.
There was also a bug in size parameter passed to safewrite() which could
result in an attempt to write gigabytes out of a megabyte buffer.
Signed-off-by: Jiri Denemark <jdenemar@redhat.com>
When a VM save attempt failed, the VM would be left in a paused
state. It is neccessary to resume CPU execution upon failure
if it was running originally
* src/qemu/qemu_driver.c: Resume CPUs upon save failure
This supports cancellation of jobs for the QEMU driver against
the virDomainMigrate, virDomainSave and virDomainCoreDump APIs.
It is not yet supported for the virDomainRestore API, although
it is desirable.
* src/qemu/qemu_driver.c: Issue 'migrate_cancel' command if
virDomainAbortJob is issued during a migration operation
* tools/virsh.c: Add a domjobabort command
This defines the wire protocol for the new API
* src/remote/remote_protocol.x: Wire protocol definition
* src/remote/remote_driver.c,daemon/remote.c: Client and server
side implementation
* daemon/remote_dispatch_args.h, daemon/remote_dispatch_prototypes.h,
daemon/remote_dispatch_table.h, src/remote/remote_protocol.c,
src/remote/remote_protocol.h: Re-generate from remote_protocol.x
This provides the internal glue for the driver API
* src/driver.h: Internal API contract
* src/libvirt.c, src/libvirt_public.syms: Connect public API
to driver API
* src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/opennebula/one_driver.c,
src/openvz/openvz_driver.c, src/phyp/phyp_driver.c,
src/qemu/qemu_driver.c, src/remote/remote_driver.c,
src/test/test_driver.c src/uml/uml_driver.c, src/vbox/vbox_tmpl.c,
src/xen/xen_driver.c: Stub out entry points
Introduce support for virDomainGetJobInfo in the QEMU driver. This
allows for monitoring of any API that uses the 'info migrate' monitor
command. ie virDomainMigrate, virDomainSave and virDomainCoreDump
Unfortunately QEMU does not provide a way to monitor incoming migration
so we can't wire up virDomainRestore yet.
The virsh tool gets a new command 'domjobinfo' to query status
* src/qemu/qemu_driver.c: Record virDomainJobInfo and start time
in qemuDomainObjPrivatePtr objects. Add generic shared handler
for calling 'info migrate' with all migration based APIs.
* src/qemu/qemu_monitor_text.c: Fix parsing of 'info migration' reply
* tools/virsh.c: add new 'domjobinfo' command to query progress
* src/remote/remote_protocol.x: Define wire protocol format
for virDomainGetJobInfo API
* src/remote/remote_driver.c, daemon/remote.c: Implement client
and server marshalling code for virDomainGetJobInfo()
* daemon/remote_dispatch_args.h, daemon/remote_dispatch_prototypes.h
daemon/remote_dispatch_ret.h, daemon/remote_dispatch_table.h,
src/remote/remote_protocol.c, src/remote/remote_protocol.h: Rebuild
files from src/remote/remote_protocol.x
The internal glue layer for the new pubic API
* src/driver.h: Define internal driver API contract
* src/libvirt.c, src/libvirt_public.syms: Wire up public
API to internal driver API
* src/esx/esx_driver.c, src/lxc/lxc_driver.c, src/opennebula/one_driver.c,
src/openvz/openvz_driver.c, src/phyp/phyp_driver.c,
src/qemu/qemu_driver.c, src/remote/remote_driver.c,
src/test/test_driver.c, src/uml/uml_driver.c, src/vbox/vbox_tmpl.c,
src/xen/xen_driver.c: Stub new entry point
All other uses of get_str_prop in this file that ignored
failure explicitly cast to void.
* src/node_device/node_device_hal.c (dev_create): Silence coverity
warning.
A number of the error messages raised when parsing USB devices
refered to PCI devices by mistake
* src/qemu/qemu_conf.c: s/PCI/USB/ in qemuParseCommandLineUSB()
when the underlying qemu supports the drive/device model and the
controller has been added this way.
* src/qemu/qemu_driver.c: use qemuMonitorDelDevice() when detaching
PCI controller and if supported
* src/qemu/qemu_monitor.[ch]: add new qemuMonitorDelDevice() function
* src/qemu/qemu_monitor_json.[ch]: JSON backend for DelDevice command
* src/qemu/qemu_monitor_text.[ch]: Text backend for DelDevice command
* src/qemu/qemu_driver.c: in qemudDomainDetachPciControllerDevice()
when a controller is not present in the system anymore, the PCI
address must be deleted from libvirt's hashtable because it can
be re-used for other purposes.
* src/qemu/qemu_driver.c: in qemudDomainAttachDevice(), one must not
delete the data part when the operation succeeds because it is
required later on. The correct pattern to handlethe parsed
representation of the device information on success
is dev->data.controller = NULL; virDomainDeviceDefFree(dev);,
which leaves the structure pointed at by data in memory.
* src/cpu/cpu_x86.c (x86Decode): Don't dereference NULL when passed
a NULL "models" pointer, or when passed a nonzero "nmodels" value
and a corresponding NULL models[i].
* src/phyp/phyp_driver.c (phypUUIDTable_Push): Move incr/decr
of ptr/nread into the loop where those variables are used.
Also, remove "exit" label and just-preceding "goto".
Allow an arbitrary timezone with QEMU by setting the $TZ environment
variable when launching QEMU
* src/qemu/qemu_conf.c: Set TZ environment variable if a timezone
is requested
* tests/qemuxml2argvtest.c: Add test case for timezones
* tests/qemuxml2argvdata/qemuxml2argv-clock-france.xml,
tests/qemuxml2argvdata/qemuxml2argv-clock-france.args: Data
for timezone tests
This extends the XML to allow for
<clock offset='timezone' timezone='Europe/Paris'/>
This is useful if the admin has not configured any timezone on the
host OS, but still wants to synchronize a guest to a specific one.
* src/conf/domain_conf.h, src/conf/domain_conf.c: Support extra
'timezone' attribute on clock configuration
* docs/schemas/domain.rng: Add 'timezone' attribute
* src/xen/xend_internal.c, src/xen/xm_internal.c: Reject configs
with a configurable timezone
This allows QEMU guests to be started with an arbitrary clock
offset
The test case can't actually be enabled, since QEMU argv expects
an absolute timestring, and this will obviously change every
time the test runs :-( Hopefully QEMU will allow a relative
time offset in the future.
* src/qemu/qemu_conf.c, src/qemu/qemu_conf.h: Use the -rtc arg
if available to support variable clock offset mode
* tests/qemuhelptest.c: Add QEMUD_CMD_FLAG_RTC for qemu 0.12.1
* qemuxml2argvdata/qemuxml2argv-clock-variable.args,
qemuxml2argvdata/qemuxml2argv-clock-variable.xml,
qemuxml2argvtest.c: Test case, except we can't actually enable
it yet.
This introduces a third option for clock offset synchronization,
that allows an arbitrary / variable adjustment to be set. In
essence the XML contains the time delta in seconds, relative to
UTC.
<clock offset='variable' adjustment='123465'/>
The difference from 'utc' mode, is that management apps should
track adjustments and preserve them at next reboot.
* docs/schemas/domain.rng: Schema for new clock mode
* src/conf/domain_conf.c, src/conf/domain_conf.h: Parse
new clock time delta
* src/libvirt_private.syms, src/util/xml.c, src/util/xml.h: Add
virXPathLongLong() method
The XML will soon be extended to allow more than just a simple
localtime/utc boolean flag. This change replaces the plain
'int localtime' with a separate struct to prepare for future
extension
* src/conf/domain_conf.c, src/conf/domain_conf.h: Add a new
virDomainClockDef structure
* src/libvirt_private.syms: Export virDomainClockOffsetTypeToString
and virDomainClockOffsetTypeFromString
* src/qemu/qemu_conf.c, src/vbox/vbox_tmpl.c, src/xen/xend_internal.c,
src/xen/xm_internal.c: Updated to use new structure for localtime
While building under RHEL-5, I got a compile warning because
virDomainObjFormat was defined but not used. That came about
because in RHEL-5 we build with "#define PROXY", and
virDomainObjFormat is only used with !PROXY. Move the
define.
Signed-off-by: Chris Lalancette <clalance@redhat.com>
* src/openvz/openvz_conf.c (openvzGetVEID): Always call fclose.
Diagnose parse failure also when vzlist output is empty.
If somehow we read a -1, diagnose that (albeit as a parse failure).
Kind of minor, but it annoys me that the default auth callback
doesn't put a space between the prompt and the input, like a typical
terminal, ssh, etc. This patch changes the current prompt:
Please enter your authentication name:myuser
to
Please enter your authentication name: myuser
In bug 567931 we found that virt-top would exit occasionally
when the terminal window was resized. Tracking this down it
turned out that SIGWINCH was being delivered to the process at
exactly the point where the libvirt remote driver was calling
poll(2) waiting for a reply from libvirtd.
This caused the poll(2) call to be interrupted (returning errno
EINTR). However handling EINTR the same way as EAGAIN was not
the solution to this problem since we found previously that this
would break Ctrl-C handling (commit 47fec8eac2).
The correct solution is to mask out SIGWINCH for the duration
of the poll(2) system call. The per-thread mask is changed and
restored immediately after the call. Since we are using
pthread_sigmask, this should not affect other threads, and
since we restore the signal mask immediately afterwards it should
not affect the current thread visibly either. Other possibly
problematic signals are SIGCHLD and SIGPIPE and these are
masked too.
Note use of ignore_value: It's not fatal if we cannot mask out
SIGWINCH, and in any case pthread_sigmask never fails on Linux
as long as you supply the correct arguments.
I tested this patch and it cures the original problem with
virt-top.
Create the filesystem on the partition used by the pool
* configure.ac: check for mkfs availability
* libvirt.spec.in: add extra require on util-linux for mkfs
* src/storage/storage_backend_fs.c: run mkfs with the expected
fs type when creating a filesystem pool
We were using 'Y' to mean exabyte, when the correct abbreviation would be
'E' ('Y' is yettabyte, which is exabyte * 1024 * 1024). While it isn't
strictly backwards compatible, I highly doubt anyone was actually using
this broken behavior, so I don't see any harm in in dropping 'Y' handling.
Recently we introduced O_DSYNC flag when creating raw storage files to
avoid filling all disk cache with dirty pages. However, the patch got
lost when virStorageBackendCreateRaw was reworked using
virFileOperation. Let's use O_DSYNC again.
* src/xen/xend_internal.c (xenDaemonDomainSetAutostart): Avoid a NULL
dereference upon non-SEXPR_VALUE'd on_xend_start. This bug was
introduced by commit 37ce5600c0.
There were a few operations on the storage volume file that were still
being done as root, which will fail if the file is on a root-squashed
NFS share. The result was that attempts to create a storage volume of
type "raw" on a root-squashed NFS share would fail.
This patch uses the newly introduced "hook" function in
virFileOperation to execute all those file operations in the child
process that's run under the uid that owns the file (and, presumably,
has permission to write to the NFS share)
* src/storage/storage_backend.c: use virFileOperation() in
virStorageBackendCreateRaw, turning virStorageBackendCreateRaw()
into a new createRawFileOpHook() hook
It turns out it is also useful to be able to perform other operations
on a file created while running as a different uid (eg, write things
to that file), and possibly to do this to a file that already
exists. This patch adds an optional hook function to the renamed (for
more accuracy of purpose) virFileOperation; the hook will be called
after the file has been opened (possibly created) and gid/mode
checked/set, before closing it.
As with the other operations on the file, if the VIR_FILE_OP_AS_UID
flag is set, this hook function will be called in the context of a
child process forked from the process that called virFileOperation.
The implication here is that, while all data in memory is available to
this hook function, any modification to that data will not be seen by
the caller - the only indication in memory of what happened in the
hook will be the return value (which the hook should set to 0 on
success, or one of the standard errno values on failure).
Another piece of making the function more flexible was to add an
"openflags" argument. This arg should contain exactly the flags to be
passed to open(2), eg O_RDWR | O_EXCL, etc.
In the process of adding the hook to virFileOperation, I also realized
that the bits to fix up file owner/group/mode settings after creation
were being done in the parent process, which could fail, so I moved
them to the child process where they should be.
* src/util/util.[ch]: rename and rework virFileCreate-->virFileOperation,
and redo flags in virDirCreate
* storage/storage_backend.c, storage/storage_backend_fs.c: update the
calls to virFileOperation/virDirCreate to reflect changes in the API,
but don't yet take advantage of the hook.
Fix multiple veth problem.
NETIF setting was overwritten after first CT because any CT could not be
found by name.
* src/openvz/openvz_conf.c src/openvz/openvz_conf.h: add the
openvzGetVEID lookup function
* src/openvz/openvz_driver.c: use it in openvzDomainSetNetwork()
If the hostname as returned by "gethostname" resolves
to "localhost" (as it does with the broken Fedora-12
installer), then live migration will fail because the
source will try to migrate to itself. Detect this
situation up-front and abort the live migration before
we do any real work.
* src/util/util.h src/util/util.c: add a new virGetHostnameLocalhost
with an optional localhost check, and rewire virGetHostname() to use
it
* src/libvirt_private.syms: expose the new function
* src/qemu/qemu_driver.c: use it in qemudDomainMigratePrepare2()
* src/xen/xend_internal.c (xenDaemonDomainSetAutostart): Rewrite to
avoid dereferencing the result of sexpr_lookup. While in this
particular case, it was guaranteed never to be NULL, due to the
preceding "if sexpr_node(...)" guard, it's cleaner to skip the
sexpr_node call altogether, and also saves a lookup.
This patch sets or unsets the IFF_VNET_HDR flag depending on what device
is used in the VM. The manipulation of the flag is done in the open
function and is only fatal if the IFF_VNET_HDR flag could not be cleared
although it has to be (or if an ioctl generally fails). In that case the
macvtap tap is closed again and the macvtap interface torn.
* src/qemu/qemu_conf.c src/qemu/qemu_conf.h: pass qemuCmdFlags to
qemudPhysIfaceConnect()
* src/util/macvtap.c src/util/macvtap.h: add vnet_hdr boolean to
openMacvtapTap(), and private function configMacvtapTap()
* src/qemu/qemu_driver.c: add extra qemuCmdFlags when calling
qemudPhysIfaceConnect()
For __virExec() this is a semantic NOP except for when fork()
fails. __virExec() would previously forget to restore the signal mask
in this case; virFork() corrects this behavior.
virFileCreate() and virDirCreate() gain the code to reset the logging
and properly deal with the signal handling race condition.
This also removes a log message that had a typo ("cannot fork o create
file '%s'") - this error is now logged in a more generic manner in
virFork() (more generic, but really just as informative, since the
fact that it's forking to create a file is immaterial to the fact that
it simply can't fork)
* src/util/util.c: use the generic virFork() in the 3 functions
virFork() contains bookkeeping that must be done any time a process
forks. Currently this includes:
1) Call virLogLock() prior to fork() and virLogUnlock() just after,
to avoid a deadlock if some other thread happens to hold that lock
during the fork.
2) Reset the logging hooks and send all child process log messages to
stderr.
3) Block all signals prior to fork(), then either a) reset the signal
mask for the parent process, or b) clear the signal mask for the
child process.
Note that the signal mask handling in __virExec erroneously fails to
restore the signal mask when fork() fails. virFork() fixes this
problem.
Other than this, it attempts to behave as closely to fork() as
possible (including preserving errno for the caller), with a couple
exceptions:
1) The return value is 0 (success) or -1 (failure), while the pid is
returned via the pid_t* argument. Like fork(), if pid < 0 there is
no child process, otherwise both the child and the parent will
return to the caller, and both should look at the return value,
which will indicate if some of the extra processing outlined above
encountered an error.
2) If virFork() returns with pid < 0 or with a return value < 0
indicating an error condition, the error has already been
reported. You can log an additional message if you like, but it
isn't necessary, and may be awkwardly extraneous.
Note that virFork()'s child process will *never* call _exit() - if a
child process is created, it will return to the caller.
* util.c util.h: add virFork() function, based on what is currently
done in __virExec().
Support virtio-serial controller and virtio channel in QEMU backend.
Will output
the following for virtio-serial controller:
-device
virtio-serial-pci,id=virtio-serial0,bus=pci.0,addr=0x4,max_ports=16,vectors=4
and the following for a virtio channel:
-chardev pty,id=channel0 \
-device
virtserialport,bus=virtio-serial0.0,chardev=channel0,name=org.linux-kvm.port.0
* src/qemu/qemu_conf.c: Add argument output for virtio
* tests/qemuxml2argvtest.c
tests/qemuxml2argvdata/qemuxml2argv-channel-virtio.args: Add test for
QEMU command line generation
Add support for virtio-serial by defining a new 'virtio' channel target type
and a virtio-serial controller. Allows the following to be specified in a
domain:
<controller type='virtio-serial' index='0' ports='16' vectors='4'/>
<channel type='pty'>
<target type='virtio' name='org.linux-kvm.port.0'/>
<address type='virtio-serial' controller='0' bus='0'/>
</channel>
* docs/schemas/domain.rng: Add virtio-serial controller and virtio
channel type.
* src/conf/domain_conf.[ch]: Domain parsing/serialization for
virtio-serial controller and virtio channel.
* tests/qemuxml2xmltest.c
tests/qemuxml2argvdata/qemuxml2argv-channel-virtio.xml: add domain xml
parsing test
* src/libvirt_private.syms src/qemu/qemu_conf.c:
virDomainDefAddDiskControllers() renamed to
virDomainDefAddImplicitControllers()
Remove virDomainDevicePCIAddressEqual and virDomainDeviceDriveAddressEqual,
which are defined but not used anywhere.
* src/conf/domain_conf.[ch] src/libvirt_private.syms: Remove
virDomainDevicePCIAddressEqual and virDomainDeviceDriveAddressEqual.
Currently we just error with ex. 'virbr0: No such device'.
Since we are using public API calls here, we need to ensure that any
raised error is properly saved and restored, since API entry points
always reset messages.
virGetLastError returns NULL if no error has been set, not on
allocation error like virSetError assumed. Use virLastErrorObject
instead. This fixes virSetError when no error is currently stored.
Rework and simplification of teardown of the macvtap device.
Basically all devices with the same MAC address and link device are kept
alive and not attempted to be torn down. If a macvtap device linked to a
physical interface with a certain MAC address 'M' is to be created it
will automatically fail if the interface is 'up'ed and another macvtap
with the same properties (MAC addr 'M', link dev) happens to be 'up'.
This will prevent the VM from starting or the device from being attached
to a running VM. Stale interfaces are assumed to be there for some
reason and not stem from libvirt.
In the VM shutdown path, it's assuming that an interface name is always
available so that if the device type is DIRECT it can be torn down
using its name.
* src/util/macvtap.h src/libvirt_macvtap.syms: change of deleting routine
* src/util/macvtap.c: cleanups and change of deleting routine
* src/qemu/qemu_driver.c: change cleanup on shutdown
* src/qemu/qemu_conf.c: don't delete Macvtap in qemudPhysIfaceConnect()
The QEMU JSON monitor changed balloon commands to return/accept
bytes instead of kilobytes. Update libvirt to cope with this
* src/qemu/qemu_monitor_json.c: Expect/use bytes for ballooning