<div dir="ltr"><br><div><div class="gmail_extra"><br><div class="gmail_quote">On Wed, Apr 15, 2015 at 6:43 PM, Michal Privoznik <span dir="ltr"><<a href="mailto:mprivozn@redhat.com" target="_blank">mprivozn@redhat.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span class="">On 15.04.2015 16:38, Pavel Boldin wrote:<br>
> Michal,<br>
><br>
> On Wed, Apr 15, 2015 at 10:54 AM, Michal Privoznik <<a href="mailto:mprivozn@redhat.com">mprivozn@redhat.com</a>><br>
> wrote:<br>
><br>
>> On <a href="tel:26.03.2015%2015" value="+12603201515">26.03.2015 15</a>:48, Pavel Boldin wrote:<br>
>>> Dear Libvirt Developers,<br>
>>><br>
>>><br>
>>> I'm working to implement feature request [1]. The feature request<br>
>> proposes<br>
>>> to enhance `libvirt' code so the API caller can specify which block<br>
>> devices<br>
>>> are to be migrated using e.g. parameters in the `virDomainMigrateToURI3'<br>
>>> call.<br>
>><br>
>> Correct. My idea is to add pairs of typed parameters to the<br>
>> virDomainMigrate3() and virDomainMigrateToURI3() API. These are the only<br>
>> migrate APIs that accept virTypedParameter. The rest of migrate APIs are<br>
>> just too old and not extensible, so they must continue working as they<br>
>> are now. However, those two APIs - they can be passed new pairs, e.g.<br>
>> ("migrate_disk", "vda"). Now, mgmt applications will want to specify<br>
>> more than one disk to migrate, obviously. We have two options:<br>
>><br>
>> 1) make "migrate_disk" accept stringyfied array of disk targets, e.g.<br>
>> "migrate_disk": "vda,vdb,sda". This is not so pleasant to work with from<br>
>> client applications. Constructing the string would be awful.<br>
>><br>
> My concern was that some drivers may allow commas inside the drive names.<br>
> So this is obviously wrong thing to do then.<br>
<br>
</span>That's why I've chosen to work purely with disk target at NBD level. We<br>
have strong rules what characters can occur there. Moreover, it's fairly<br>
easy to derive qemu disk ID from the target. Oh, and we require targets<br>
to be unique throughout the domain. So I think it's the best option for<br>
the extension you're planning.<br></blockquote><div>As far as I remember, libvirt-1.2.2 does not support tunneled migration through NBD.<br> <br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<span class=""><br>
><br>
><br>
>><br>
>> 2) make virTypedParam* APIs accept more than one values to a key, e.g.<br>
>> {("migrate_disk", "vda"), ("migrate_disk", "vdb"), ("migrate_disk",<br>
>> "sda")}. Currently, this is supported on RPC, but some virTypedParam*<br>
>> APIs are not really prepared for this. If I had to name some from the<br>
>> top of my head: virTypedParamsGet().<br>
>><br>
> As far as I see there is a line 420 in src/util/virtypedparam.c:<br>
> /* The following APIs are public and their signature may never change. */<br>
<br>
</span>Of course. They would still return the first value found. But that's not<br>
a problem. The paragraph is more like an intro than a suggestion to<br>
change them.<br>
<span class=""><br>
><br>
> So, the functions need to be implemented anew.<br>
<br>
</span>Some of them. Correct.<br>
<span class=""><br>
><br>
><br>
><br>
>><br>
>> I view virTyped* as an associative array. So 2) is practically enabling<br>
>> multi value associative array. So I guess the first step would be to<br>
>> introduce new API (maybe set of APIs?) that are aware of this.<br>
>><br>
> I guess the first function to implement would be virTypedParamsGetNth()<br>
> that is able to retrieve nth parameter with that name.<br>
> While this is easy to implement there are details remain:<br>
><br>
</span>>    1. Should we implement a new set of virTypedParamsGetNth<TYPE> for each<br>
<span class="">>    of the TYPE or should we start with just the 'String'?<br>
</span>>    2. Since virTypedParamsGet<TYPE> is just a virTypedParamsGetNth<TYPE><br>
<span class="">>    with N=0 should we make old functions just call new ones with N=0?<br>
><br>
<br>
</span>Hm.. what about this, introduce just this new function:<br>
<br>
virTypedParamsGetArrayForKey(.., const char *key, ...)<br>
<br>
which will iterate through an array of typed params, producing a new<br>
array which will, however, contain only the selected key. For instance,<br>
if called over<br>
<br>
{(key1, val1), (key1, val2), (key2, val3), (key4, val4)}<br>
<br>
with key==key1 it would create array<br>
<br>
{(key1, val1), (key1, val2)}<br>
<br>
with key==key2 it would create array<br>
<br>
{(key2, val3)}<br>
<br>
And so on. For selecting Nth item in the array, we can just use basic C<br>
array selector []. Oh, I don't like the function name much btw, but it<br>
serves the example sake here.<br></blockquote><div>Well, this approach allows us to return virTypedParamPtr array of any type. So this is more general and the latter can be implemented as a call to this one.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
The other option would be to have a different function:<br>
<br>
char **<br>
virTypedParamGetStringList( ..., const char *key)<br>
<br>
which will produce a string list of values assigned with the @key. The<br>
list will be NULL terminated of course. Again, the function name is<br>
horrible, but it's just an example.<br>
<br>
In fact, the latter approach would be much more easier to use, so I vote<br>
for it.<br></blockquote><div>Yeah, and it is much easier to add an extra parameter `char **migrate_disk' to all the QEMU functions stack.<br><br></div><div>I think I will implement both, second one calling first one.<br></div><div> <br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
Oh, and these functions I came up with - they don't even need to be<br>
public! We can keep them private and live happily ever after. Well, not<br>
quite - the virTypedParamsValidate() will require some changes too, but<br>
whatever.<br></blockquote><div>We will need to add a `virTypedParamsValidateDups' function or something like that.<br></div><div><br></div><div>I'm going to start looking into the code now. Hopefully, I will have an API implementation till the end of the week.<br></div><div><br></div><div>No comments below this line.<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<span class=""><br>
><br>
><br>
>><br>
>> Then, virDomainMigrate*3() can just use this in the following way:<br>
>><br>
>> a) when no "migrate_disk" is specified, the current behaviour is preserved<br>
>><br>
>> b) when there are some disk selected for storage migration, since at<br>
>> this point we have virTyped* APIs to work with multivalue, we can get<br>
>> the array of disk targets to migrate and instruct qemu to just migrate<br>
>> them.<br>
>><br>
>> Now, qemu has split storage and internal state migration into two<br>
>> streams. The first one is called NBD and libvirt selectively choses<br>
>> disks to migrate. For the other stream you don't have to care about.<br>
>> Look at qemuMigrationDriveMirror() and you'll see how libvirt instructs<br>
>> qemu to selectively migrate only some disks. The "migrate_disk" array<br>
>> would need to be propagated down here then.<br>
>><br>
> My concern is I would, most likely, have to backport these to our versions.<br>
<br>
</span>I'm not sure onto how old release, but in general, the smaller the patch<br>
is, the easier to backport it is also ;-)<br>
<span class="HOEnZb"><font color="#888888"><br>
Michal<br>
</font></span></blockquote></div><br>Pavel<br></div></div></div>