moving the collection of statistics to external process
by ybronhei@redhat.com
As part of an issue that if you push start for 200vms in the same time
it takes hours because undefined issue, we thought about moving the
collection of statistics outside vdsm.
It can help because the stat collection is an internal threads of vdsm
that can spend not a bit of a time, I'm not sure if it would help with
the issue of starting many vms simultaneously, but it might improve vdsm
response.
Currently we start thread for each vm and then collecting stats on them
in constant intervals, and it must effect vdsm if we have 200 thread
like this that can take some time. for example if we have connection
errors to storage and we can't receive its response, all the 200 threads
can get stuck and lock other threads (gil issue).
I wanted to know what do you think about it and if you have better
solution to avoid initiate so many threads? And if splitting vdsm is a
good idea here?
In first look, my opinion is that it can help and would be nice to have
vmStatisticService that runs and writes to separate log the vms status.
The problem with this solution is that if those interval functions
needs to communicate with internal parts of vdsm to set values or start
internal processes when something has changed, it depends on the stat
function.. and I'm not sure that stat function should control internal
flows.
Today to recognize connectivity error we count on this method, but we
can add polling mechanics for those issues (which can raise same
problems we are trying to deal with..)
I would like to here your ideas and comments.. thanks
--
Yaniv Bronhaim.
RedHat, Israel
09-7692289
054-7744187
11 years, 5 months
link state semantics
by asegurap@redhat.com
Hi list!
We are working on the new 3.2 feature for adding support for updating VM
devices, more specifically at the moment network devices.
There is one point of the design which is not yet consensual and we'd
need to agree on a proper and clean design that would satisfy us all:
My current proposal, as reflected by patch:
http://gerrit.ovirt.org/#/c/9560/5/vdsm_api/vdsmapi-schema.json
and its parent is to have a linkActive boolean that is true for link
status 'up' and false for link status 'down'.
We want to support a none (dummy) network that is used to dissociate vnics
from any real network. The semantics, as you can see in the patch are that
unless you specify a network, updateDevice will place the interface on that
network. However, Adam Litke argues that not specifying a network should
keep the vnic on the network it currently is, as network is an optional
parameter and 'linkActive' is also optional and has this "preserve current
state" semantics.
I can certainly see the merit of what Adam proposes, and the implementation
would be that linkActive becomes an enum like so:
{'enum': 'linkState'/* or linkActive */ , 'data': ['up', 'down', 'disconnected']}
With this change, network would only be changed if one different than the current
one is specified and the vnic would be taken to the dummy bridge when the linkState
would be set to 'disconnected'.
There is also an objection, raised by Adam about the semantics of portMirroring.
The current behavior from my patch is:
portMirroring is None or is not set -> No action taken.
portMirroring = [] -> No action taken.
portMirroring = [a,b,z] -> Set port mirroring for nets a,b and z to the specified vnic.
His proposal is:
portMirroring is None or is not set -> No action taken.
portMirroring = [] -> Unset port mirroring to the vnic that is currently set.
portMirroring = [a,b,z] -> Set port mirroring for nets a,b and z to the specified vnic.
I would really welcome comments on this to have finally an agreement to the api for this
feature.
Best,
Toni
11 years, 5 months
API.py validation
by asegurap@redhat.com
Hi all,
I am currently working in adding a new feature to vdsm which requires a new
entry point in vdsm, thus requiring:
- Parameter definitions in vdsm_api/vdsmapi-schema.json
- Implementation and checks in vdsm/API.py and other modules.
Typically, we check for presence absence of required/optional parameters in
API.py using utils.validateMinimalKeySet or just if else clauses. I think this
process could benefit from a more automatic and less duplicated effort, i.e.,
parsing vdsmapi-schema.json in a similar way as process-schema.py does to make
a memoized method that is able to check whether the api call is correct
according to the API definitions. A very good side effect would be that this
would really avoid us from forgetting to update the schema.
Best regards,
Toni
11 years, 5 months
Future of Vdsm network configuration - Thread mid-summary
by lpeer@redhat.com
Hi All,
We have been discussing $subject for a while and I'd like to summarized
what we agreed and disagreed on thus far.
The way I see it there are two related discussions:
1. Getting VDSM networking stack to be distribution agnostic.
- We are all in agreement that VDSM API should be generic enough to
incorporate multiple implementation. (discussed on this thread: Alon's
suggestion, Mark's patch for adding support for netcf etc.)
- We would like to maintain at least one implementation as the
working/up-to-date implementation for our users, this implementation
should be distribution agnostic (as we all acknowledge this is an
important goal for VDSM).
I also think that with the agreement of this community we can choose to
change our focus, from time to time, from one implementation to another
as we see fit (today it can be OVS+netcf and in a few months we'll use
the quantum based implementation if we agree it is better)
2. The second discussion is about persisting the network configuration
on the host vs. dynamically retrieving it from a centralized location
like the engine. Danken raised a concern that even if going with the
dynamic approach the host should persist the management network
configuration.
Obviously the second discussion influences the API modeling. Since I
think it would be challenging to add support for generic API and change
the current implementation to match the dynamic configuration approach
simultaneously I suggest we'll focus our efforts on one change at a time.
I suggest to have a discussion on the pro's and con's of dynamic
configuration and after we get to a consensus around that we can start
modeling the generic API.
thoughts? comments?
Livnat
11 years, 5 months
object instancing in the new VDSM API
by smizrahi@redhat.com
Currently the suggested scheme treats everything as instances and object have methods.
This puts instancing as the responsibility of the API bindings.
I suggest changing it to the way json was designed with namespaces and methods.
For example instead for the api being:
vm = host.getVMsList()[0]
vm.getInfo()
the API should be:
vmID = host.getVMsList()[0]
api.VMsManager.getVMInfo(vmID)
And it should be up to decide how to wrap everything in objects.
The problem with the API bindings controlling the instancing is that:
1) We have to *have* and *pass* implicit api obj which is problematic to maintain.
For example, you have to have the api object as a member of instance for the
method calls to work. This means that you can't recreate or pool API
objects easily. You effectively need to add a "move" method to move the
object to another API object to use it on a different host.
2) Because the objects are opaque it might be hard to know what fields of the
instance to persist to get the same object.
3) It breaks the distinction between by-value and by-reference objects.
4) Any serious user will make it's own instance classes that conform to it's
design and flow so they don't really add any convenience to anything apart
for tests.
You will create you're own VM object, and because it's in the manager scope
it will be the same instance across all hosts. Instead of being able to pass
the same ID to any host (as the vmID remains the same) you will have to
create and instance object to use either before every call for simplicity
or cache for each host for performance benefits.
5) It makes us pass a weird "__obj__" parameter to each call that symbolizes
self and makes it hard for a user that choose to use it's own bindings to
understand what it does.
6) It's syntactic sugar at best that adds needless limitation to how a user can
play with the IDs and the API.
I personally think there is a reason why json-rpc defines name-spaces and
methods and forgoes instance. It's simpler (for the implementation), more
flexible, and it give the user more choice. Trying to hack that in will just
cause needless complications IMHO. IDs should are just strings no need to complicate them
By-Value objects should still be defined and instantiated by the bindings because unlike IDs we need to make sure all the fields exist and are in the correct type.
11 years, 5 months
RFD: API: Identifying vdsm objects in the next-gen API
by agl@us.ibm.com
Today in vdsm, every object (StoragePool, StorageDomain, VM, Volume, etc) is
identified by a single UUID. On the surface, it seems like this is enough info
to properly identify a resource but in practice it's not. For example, when you
look at the API's dealing with Volumes, almost all of them require an sdUUID,
spUUID, and imgUUID in order to provide proper context for the operation.
Needing to provide these extra UUIDs is a burden on the API user because knowing
which values to pass requires internal knowledge of the API. For example, the
spUUID parameter is almost always just the connected storage pool. Since we
know there can currently be only one connected pool, the value is known.
I would like to move away from needing to understand all of these relationships
from the end user perspective by encapsulating the extra context into new object
identifier types as follows:
StoragePoolIdentifier:
{ 'storagepoolID': 'UUID' }
StorageDomainIdentifier:
{ 'storagepoolID*': 'UUID', 'storagedomainID': 'UUID' }
ImageIdentifier:
{ 'storagepoolID*': 'UUID', 'storagedomainID': 'UUID', 'imageID': 'UUID' }
VolumeIdentifier:
{ 'storagepoolID*': 'UUID', 'storagedomainID': 'UUID',
'imageID': 'UUID', 'volumeID': 'UUID' }
TaskIdentifier:
{ 'taskID': 'UUID' }
VMIdentifier:
{ 'vmID': 'UUID' }
In the new API, anytime a reference to an object is required, one of the above
structures must be passed in place of today's single UUID. In many cases, this
will allow us to reduce the number of parameters to the function since the
needed contextual parameters (spUUID, etc) will be part of the object's
identifier. Similarly, any time the API returns an object reference it would
return a *Identifier instead of a bare UUID.
These identifier types are basically opaque blobs to the API users and are only
ever generated by vdsm itself. Because of this, we can change the internal
structure of the identifier to require new information or (before freezing the
API) remove fields that no longer make sense.
I would greatly appreciate your comments on this proposal. If it seems
reasonable, I will revamp the current schema to make the necessary changes and
provide the Bridge patch functions to convert between the current implementation
and the new schema.
--- sample schema patch ---
commit 48f6b0f0a111dd0b372d211a4e566ce87f375cee
Author: Adam Litke <agl(a)us.ibm.com>
Date: Tue Nov 27 14:14:06 2012 -0600
schema: Introduce class identifier types
When calling API methods that belong to a particular class, a class instance
must be indicated by passing a set of identifiers in the request. The location
of these parameters within the request is: 'params' -> '__obj__'. Since this
set of identifiers must be used together to correctly instantiate an object, it
makes sense to define these as proper types within the API. Then, functions
that return an object (or list of objects) can refer to the correct type.
Signed-off-by: Adam Litke <agl(a)us.ibm.com>
diff --git a/vdsm_api/vdsmapi-schema.json b/vdsm_api/vdsmapi-schema.json
index 0418e6e..7e2e851 100644
--- a/vdsm_api/vdsmapi-schema.json
+++ b/vdsm_api/vdsmapi-schema.json
@@ -937,7 +937,7 @@
# Since: 4.10.0
##
{'command': {'class': 'Host', 'name': 'getConnectedStoragePools'},
- 'returns': ['StoragePool']}
+ 'returns': ['StoragePoolIdentifier']}
##
# @BlockDeviceType:
@@ -1572,7 +1572,7 @@
{'command': {'class': 'Host', 'name': 'getStorageDomains'},
'data': {'*storagepoolID': 'UUID', '*domainClass': 'StorageDomainImageClass',
'*storageType': 'StorageDomainType', '*remotePath': 'str'},
- 'returns': ['StorageDomain']}
+ 'returns': ['StorageDomainIdentifier']}
##
# @Host.getStorageRepoStats:
@@ -2406,7 +2406,7 @@
##
{'command': {'class': 'Host', 'name': 'getVMList'},
'data': {'*vmList': ['UUID']},
- 'returns': ['VM']}
+ 'returns': ['VMIdentifier']}
##
# @Host.ping:
@@ -2744,10 +2744,11 @@
'returns': 'ConnectionRefMap'}
## Category: @ISCSIConnection ##################################################
+
##
-# @ISCSIConnection:
+# @ISCSIConnectionIdentifier:
#
-# ISCSIConnection API object.
+# Identifier for an ISCSIConnection object.
#
# @host: A fully-qualified domain name (FQDN) or IP address
#
@@ -2757,11 +2758,21 @@
#
# @password: #optional The password associated with the given username
#
-# Since: 4.10.0
+# Since: 4.10.1
+##
+{'type': 'ISCSIConnectionIdentifier',
+ 'data': {'host': 'str', 'port': 'int', '*user': 'str', '*password': 'str'}}
+
+##
+# @ISCSIConnection:
+#
+# ISCSIConnection API object.
+#
+# @ident: The object identifier
+#
+# Since: 4.10.1
##
-{'class': 'ISCSIConnection',
- 'data': {'host': 'str', 'port': 'int', '*user': 'str',
- '*password': 'str'}}
+{'class': 'ISCSIConnection', 'ident': 'ISCSIConnectionIdentifier'}
##
# @ISCSIConnection.discoverSendTargets:
@@ -2777,10 +2788,11 @@
'returns': ['str']}
## Category: @Image ############################################################
+
##
-# @Image:
+# @ImageIdentifier:
#
-# Image API object.
+# Identifier for an Image object.
#
# @imageID: The UUID of the Image
#
@@ -2788,13 +2800,24 @@
#
# @storagedomainID: The UUID of the Storage Domain associated with the Image
#
-# Since: 4.10.0
+# Since: 4.10.1
##
-{'class': 'Image',
+{'type': 'ImageIdentifier',
'data': {'imageID': 'UUID', 'storagepoolID': 'UUID',
'storagedomainID': 'UUID'}}
##
+# @Image:
+#
+# Image API object.
+#
+# @ident: The object identifier
+#
+# Since: 4.10.1
+##
+{'class': 'Image', 'ident': 'ImageIdentifier'}
+
+##
# @Image.delete:
#
# Delete the Image and all of its Volumes.
@@ -2843,7 +2866,7 @@
# Since: 4.10.0
##
{'command': {'class': 'Image', 'name': 'getVolumes'},
- 'returns': ['Volume']}
+ 'returns': ['VolumeIdentifier']}
##
# @Image.mergeSnapshots:
@@ -2905,17 +2928,26 @@
## Category: @LVMVolumeGroup ###################################################
##
+# @LVMVolumeGroupIdentifier:
+#
+# An identifier for a LVMVolumeGroup object.
+#
+# @lvmvolumegroupID: The volume group UUID
+#
+# Since: 4.10.1
+##
+{'type': 'LVMVolumeGroupIdentifier', 'data': {'lvmvolumegroupID': 'UUID'}}
+
+##
# @LVMVolumeGroup:
#
# LVMVolumeGroup API object.
#
-# @lvmvolumegroupID: #optional Associate this object with an existing LVM
-# Volume Group
+# @ident: The object identifier
#
-# Since: 4.10.0
+# Since: 4.10.1
##
-{'class': 'LVMVolumeGroup',
- 'data': {'lvmvolumegroupID': 'UUID'}}
+{'class': 'LVMVolumeGroup', 'ident': 'LVMVolumeGroupIdentifier'}
##
# @LVMVolumeGroup.create:
@@ -2964,21 +2996,32 @@
## Category: @StorageDomain ####################################################
##
-# @StorageDomain:
+# @StorageDomainIdentifier:
#
-# StorageDomain API object.
+# An identifier for a StorageDomain object.
#
# @storagedomainID: Associate this object with a new or existing Storage Domain
#
# @storagepoolID: #optional The Storage Pool UUID if this Storage Domain is
# attached
#
-# Since: 4.10.0
+# Since: 4.10.1
##
-{'class': 'StorageDomain',
+{'type': 'StorageDomainIdentifier',
'data': {'storagedomainID': 'UUID', 'storagepoolID': 'UUID'}}
##
+# @StorageDomain:
+#
+# StorageDomain API object.
+#
+# @ident: The object identifier
+#
+# Since: 4.10.1
+##
+{'class': 'StorageDomain', 'ident': 'StorageDomainIdentifier'}
+
+##
# @StorageDomain.activate:
#
# Activate an attached but inactive Storage Domain.
@@ -3184,7 +3227,7 @@
# Since: 4.10.0
##
{'command': {'class': 'StorageDomain', 'name': 'getImages'},
- 'returns': ['Image']}
+ 'returns': ['ImageIdentifier']}
##
# @StorageDomainRole:
@@ -3295,7 +3338,7 @@
##
{'command': {'class': 'StorageDomain', 'name': 'getVolumes'},
'data': {'imageID': 'UUID'},
- 'returns': ['Volume']}
+ 'returns': ['VolumeIdentifier']}
##
# @StorageDomain.setDescription:
@@ -3355,15 +3398,26 @@
## Category: @StoragePool ######################################################
##
+# @StoragePoolIdentifier:
+#
+# An identifier for a StoragePool object.
+#
+# @storagepoolID: Associate this object with a new or existing Storage Pool
+#
+# Since: 4.10.1
+##
+{'type': 'StoragePoolIdentifier', 'data': {'storagepoolID': 'UUID'}}
+
+##
# @StoragePool:
#
# StoragePool API object.
#
-# @storagepoolID: Associate this object with a new or existing Storage Pool
+# @ident: The object identifier
#
-# Since: 4.10.0
+# Since: 4.10.1
##
-{'class': 'StoragePool', 'data': {'storagepoolID': 'UUID'}}
+{'class': 'StoragePool', 'ident': 'StoragePoolIdentifier'}
##
# @StoragePool.connect:
@@ -3629,7 +3683,7 @@
##
{'command': {'class': 'StoragePool', 'name': 'getDomainsContainingImage'},
'data': {'imageID': 'UUID', '*onlyDataDomains': 'bool'},
- 'returns': ['StorageDomain']}
+ 'returns': ['StorageDomainIdentifier']}
##
# @StoragePool.getIsoList:
@@ -4058,15 +4112,27 @@
## Category: @Task #############################################################
##
+# @TaskIdentifier:
+#
+# An identifier for a Task object.
+#
+# @taskID: The task UUID
+#
+# Since: 4.10.1
+##
+{'type': 'TaskIdentifier', 'data': {'taskID': 'UUID'}}
+
+
+##
# @Task:
#
# Task API object.
#
-# @taskID: Associate this object with an existing Task
+# @ident: The object identifier
#
-# Since: 4.10.0
+# Since: 4.10.1
##
-{'class': 'Task', 'data': {'taskID': 'UUID'}}
+{'class': 'Task', 'ident': 'TaskIdentifier'}
##
# @Task.clear:
@@ -4123,15 +4189,26 @@
## Category: @VM ###############################################################
##
+# @VMIdentifier:
+#
+# An identifier for a VM object.
+#
+# @vmID: The task UUID
+#
+# Since: 4.10.1
+##
+{'type': 'VMIdentifier', 'data': {'vmID': 'UUID'}}
+
+##
# @VM:
#
# VM API object.
#
-# @vmID: Associate this object with an existing VM
+# @ident: The object identifier
#
-# Since: 4.10.0
+# Since: 4.10.1
##
-{'class': 'VM', 'data': {'vmID': 'UUID'}}
+{'class': 'VM', 'ident': 'VMIdentifier'}
##
# @DriveSpecVolume:
@@ -5161,9 +5238,9 @@
## Category: @Volume ###########################################################
##
-# @Volume:
+# @VolumeIdentifier:
#
-# Volume API object.
+# An identifier for a Volume object.
#
# @volumeID: The UUID of the Volume
#
@@ -5173,13 +5250,24 @@
#
# @imageID: The Image associated with @UUID
#
-# Since: 4.10.0
+# Since: 4.10.1
##
-{'class': 'Volume',
+{'type': 'VolumeIdentifier',
'data': {'volumeID': 'UUID', 'storagepoolID': 'UUID',
'storagedomainID': 'UUID', 'imageID': 'UUID'}}
##
+# @Volume:
+#
+# Volume API object.
+#
+# @ident: The object identifier
+#
+# Since: 4.10.1
+##
+{'class': 'Volume', 'ident': 'VolumeIdentifier'}
+
+##
# @VolumeRole:
#
# An enumeration of Volume Roles.
--
Adam Litke <agl(a)us.ibm.com>
IBM Linux Technology Center
11 years, 5 months
cpu-host
by lhornyak@redhat.com
Hi,
I am working on a new feature called cpu-host, it will allow the vm's to use all of the host's CPU capabilities, even those not handled by libvirt.
The draft of the feature specification is here:
http://www.ovirt.org/Features/Cpu-host_Support
And I have two patches for vdsm to support this feature (we only need one)
- add a new flag (cpuHost) and if true just use the host's cpu
- XOR add a new cpuType, 'hostPassthrough' and if the cpu-type is hostPassthrough, then do not create a cpu model, but a cpu mode attribute instead
I would like to get some feedback from you to continue the spec!
Thank you,
Laszlo
11 years, 5 months