<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">On Wed, Jan 22, 2014 at 8:36 AM, Matthias Bolte <span dir="ltr"><<a href="mailto:matthias.bolte@googlemail.com" target="_blank">matthias.bolte@googlemail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">2014/1/22 Adam Walters <<a href="mailto:adam@pandorasboxen.com">adam@pandorasboxen.com</a>>:<br>
<div><div class="h5">> On Mon, Jan 20, 2014 at 11:27 AM, Daniel P. Berrange <<a href="mailto:berrange@redhat.com">berrange@redhat.com</a>><br>
> wrote:<br>
>><br>
>> On Fri, Dec 20, 2013 at 11:03:53PM -0500, Adam Walters wrote:<br>
>> > This patchset adds a driver named 'config' that allows access to<br>
>> > configuration<br>
>> > data, such as secret and storage definitions. This is a pre-requisite<br>
>> > for my<br>
>> > next patchset which resolves the race condition on libvirtd startup and<br>
>> > the<br>
>> > circular dependencies between QEMU and the storage driver.<br>
>><br>
>> I vaguely recall something being mentioned in the past, but not the<br>
>> details. Can you explain the details of the circular dependancy<br>
>> problem that you're currently facing ?<br>
>><br>
>> > The basic rationale behind this idea is that there exist circumstances<br>
>> > under<br>
>> > which a driver may need to access things such as secrets during a time<br>
>> > at<br>
>> > which there is no active connection to a hypervisor. Without a<br>
>> > connection,<br>
>> > the data can't be accessed currently. I felt that this was a much<br>
>> > simpler<br>
>> > solution to the problem that building new APIs that do not require a<br>
>> > connection<br>
>> > to operate.<br>
>><br>
>> We have a handful of places in our code where we call out to public<br>
>> APIs to implement some piece of functionality. I've never been all<br>
>> that happy about these scenarios. If we call the public API directly,<br>
>> they cause havoc with error reporting because we end up dispatching<br>
>> and resetting errors in the middle of an nested API call. Calling the<br>
>> driver methods directly by doing conn->driver->invokeMethod() is<br>
>> somewhat tedious & error prone because we're then skipping various<br>
>> sanity tests that the public APIs do.  With ACL checking now implemented<br>
>> we also have the slightly odd situation that a public API check which<br>
>> is documented as requiring permission 'xxxx' may also require permissions<br>
>> 'yyyy' and 'zzzz' to deal with other public APIs we invoke secretly.<br>
>><br>
>> I think there is a fairly strong argument that our internal<br>
>> implementations<br>
>> could be decoupled from the public APIs, so we can call methods internally<br>
>> without having to go via the public APIs at all.<br>
>><br>
>> On the flip side though, there's also a long term desire to separate<br>
>> the different drivers into separate daemons, eg so the secrets driver<br>
>> might move into a  libvirt-secretsd daemon, which might explicitly<br>
>> require use to go via the public APIs.<br>
><br>
><br>
> Mulling this over last night, I think there may be an alternative<br>
> implementation<br>
> that would be sustainable long-term. You mentioned a desire to split the<br>
> drivers<br>
> into separate daemons eventually... It might seem silly today, but what if I<br>
> went<br>
> ahead and implemented a connection URI for each of the existing drivers?<br>
> This<br>
> would result in a 'network:///', 'secrets:///', 'storage:///', etc. Once<br>
> complete, the<br>
> existing code base could slowly be updated to utilize connections to those<br>
> new<br>
> URIs in preparation for splitting the code out into daemons. This would end<br>
> up<br>
> with the current libvirtd process eventually becoming a connection broker,<br>
> with<br>
> a compatibility shim to allow access to the API as it is currently defined<br>
> for<br>
> backwards compatibility.<br>
<br>
</div></div>But keep in mind that there is not only one network, secrets or<br>
storage driver. For example, the ESX hypervisor driver comes with its<br>
own ESX specific storage and network subdriver. It's the same for the<br>
VirtualBox, HyperV ans Parallels hypervisor driver. Today those are<br>
bundled under the URI of their hypervisor drivers: esx://, vbox://,<br>
hyperv:// and parallels://. How does this workout with a URI per<br>
subdriver?<br></blockquote><div><br></div><div>Honestly, I don't know how that would work out. To be perfectly honest,</div><div>I have not played around with any of the hypervisor drivers other than</div><div>the QEMU and LXC drivers, which both use the libvirt generic storage</div>
<div>and network drivers. Mainly, my thoughts were to suggest a possible</div><div>alternative to 'config:///' driver, which Daniel had pointed out may not</div><div>be a good long-term solution to the problem. The generic 'config:///'</div>
<div>driver fixes the immediate need, but would not really make sense if</div><div>and when libvirt gets split into multiple daemons. At that point, there</div><div>will likely be a need for some form (possibly internal-only) of connection</div>
<div>URI for each daemon.</div><div><br></div><div>Though, if the ESX driver, for example, uses its own network driver, can</div><div>you list the ESX networks through the libvirt net-list command? If not,</div><div>then a change like that shouldn't really affect them, at least in theory.</div>
<div>If you can list them, then perhaps an architecture there you have a few</div><div>more daemons may fix it. Something like 'libvirt-esx-bridged' would handle</div><div>the libvirt<->esx bridge. Then you could move the code from the esx driver</div>
<div>that handles the networking over to the network driver. Similar theory of</div><div>operation for other drivers. The bridge daemon would not have any</div><div>dependencies, and thus could start before anything else. A setup like</div>
<div>this would cause libvirt to expand into a lot of different processes, though,</div><div>so I don't know if that would work out well, either. Perhaps for drivers like this,</div><div>the 'libvirt-esxd' process could run two threads. One is a communication</div>
<div>bridge, while the other could be the hypervisor driver.</div><div><br></div><div>Basically just thinking out loud here, but not coming up with a whole lot of</div><div>options to fix the circular dependencies currently present while also</div>
<div>providing an easy migration path going forward to allow splitting libvirt into</div><div>multiple processes while simultaneously not muddying the public API in the</div><div>short-term. What would make that easier would be a method to make the</div>
<div>'config:///' URI only usable from explicitly allowed locations (in this case only</div><div>from within the storage driver). That would allow the code I wrote to solve the</div><div>current problem without really muddying the public APIs, since there would be</div>
<div>some measure of control over who could utilize the new driver. Any additional</div><div>use would require a patch to libvirt to enable it, thus prompting discussion over</div><div>why the access is needed at all.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<span class="HOEnZb"><font color="#888888"><br>
--<br>
Matthias Bolte<br>
<a href="http://photron.blogspot.com" target="_blank">http://photron.blogspot.com</a><br>
</font></span></blockquote></div><br></div></div>