[libvirt] creating stream

Hi. I know that libvirt devs does not like devs that used internal rpc of libvirt... I need to create stream to use with upload/download and as i see it does not created via rpc call, can you suggest me what files i need to check to understand how virStreamNew works and how to read write works internally? Thanks! -- Vasiliy Tolstov, e-mail: v.tolstov@selfip.ru

2017-04-05 1:35 GMT+03:00 Vasiliy Tolstov <v.tolstov@selfip.ru>:
Hi. I know that libvirt devs does not like devs that used internal rpc of libvirt... I need to create stream to use with upload/download and as i see it does not created via rpc call, can you suggest me what files i need to check to understand how virStreamNew works and how to read write works internally? Thanks!
Anybody can helps? -- Vasiliy Tolstov, e-mail: v.tolstov@selfip.ru

On 04/05/2017 12:35 AM, Vasiliy Tolstov wrote:
Hi. I know that libvirt devs does not like devs that used internal rpc of libvirt...
Not entirely true. We like all devs, but we just discourage people to use our RPC as it's internal. It doesn't offer the full set of features provided by libvirt APIs: for instance some drivers (e.g. ESX) don't use it and use curl instead to communicate with remote hypervisor. The second reason is that we might change the RPC suddenly without prior notice and thus your application would just stop working.
I need to create stream to use with upload/download and as i see it does not created via rpc call, can you suggest me what files i need to check to understand how virStreamNew works and how to read write works internally? Thanks!
The libvirt streams are a bit kind of magic. Esp. on RPC level. Basically, when client and server wants to transfer some data over a stream, both of them call virStreamNew() which creates a local object which so far is not tied to the other stream in any way. The point where these two streams start to be connected is the public API that involves the stream, for instance virStorageVolDownload(). The streams can be viewed as an UNIX socket or some other type of socket. virStreamSend() corresponds to write() and virStreamRecv() then corresponds to read(). So if one side sends some data to the stream, the other side can receive the data. On the code level, there's again a driver that implements the methods as there are several implementations available. Firstly, there's network implementation in our RPC code (this is responsible for transferring stream data to the other side), then there's local implementation for working with files (virFDStream), and finally ESX has its own implementation (it uses curl for fetching/uploading data onto ESX hypervisor). I'm currently working on sparse streams (so that files transferred through our streams stay sparse), and let me tell you - the code is pretty complicated. http://libvirt.org/internals/rpc.html Michal

2017-04-05 16:09 GMT+03:00 Michal Privoznik <mprivozn@redhat.com>:
On 04/05/2017 12:35 AM, Vasiliy Tolstov wrote:
Hi. I know that libvirt devs does not like devs that used internal rpc of libvirt...
Not entirely true. We like all devs, but we just discourage people to use our RPC as it's internal. It doesn't offer the full set of features provided by libvirt APIs: for instance some drivers (e.g. ESX) don't use it and use curl instead to communicate with remote hypervisor. The second reason is that we might change the RPC suddenly without prior notice and thus your application would just stop working.
I know that, but also i know that libvirt does not break compatibility with older clients =). So this is not big problem.
I need to create stream to use with upload/download and as i see it does not created via rpc call, can you suggest me what files i need to check to understand how virStreamNew works and how to read write works internally? Thanks!
The libvirt streams are a bit kind of magic. Esp. on RPC level. Basically, when client and server wants to transfer some data over a stream, both of them call virStreamNew() which creates a local object which so far is not tied to the other stream in any way. The point where these two streams start to be connected is the public API that involves the stream, for instance virStorageVolDownload().
The streams can be viewed as an UNIX socket or some other type of socket. virStreamSend() corresponds to write() and virStreamRecv() then corresponds to read(). So if one side sends some data to the stream, the other side can receive the data.
On the code level, there's again a driver that implements the methods as there are several implementations available. Firstly, there's network implementation in our RPC code (this is responsible for transferring stream data to the other side), then there's local implementation for working with files (virFDStream), and finally ESX has its own implementation (it uses curl for fetching/uploading data onto ESX hypervisor).
I'm currently working on sparse streams (so that files transferred through our streams stay sparse), and let me tell you - the code is pretty complicated.
http://libvirt.org/internals/rpc.html
Michal
Thanks, now i'm interesting in rpc level with upload and download features of stream. So i try to find rpc message that sended to libvirt daemon to create stream and what messages sended from client to server to indicate on which stream it belongs. And big thanks for sparse streams, they will be very useful. -- Vasiliy Tolstov, e-mail: v.tolstov@selfip.ru

On Wed, 2017-04-05 at 16:17 +0300, Vasiliy Tolstov wrote:
I know that, but also i know that libvirt does not break compatibility with older clients =).
That is true as long as you stick with the public API. If you start messing with the internal RPC and a change in libvirt breaks your code, you get to keep both pieces. -- Andrea Bolognani / Red Hat / Virtualization

2017-04-05 17:53 GMT+03:00 Andrea Bolognani <abologna@redhat.com>:
That is true as long as you stick with the public API.
If you start messing with the internal RPC and a change in libvirt breaks your code, you get to keep both pieces.
I think in case of internal rpc i need to monitor each libvirt release and check git diff or src/remote/remote_protocol.x -- Vasiliy Tolstov, e-mail: v.tolstov@selfip.ru

On 04/05/2017 09:11 PM, Vasiliy Tolstov wrote:
2017-04-05 17:53 GMT+03:00 Andrea Bolognani <abologna@redhat.com>:
That is true as long as you stick with the public API.
If you start messing with the internal RPC and a change in libvirt breaks your code, you get to keep both pieces.
I think in case of internal rpc i need to monitor each libvirt release and check git diff or src/remote/remote_protocol.x
Still, you will lack support for some drivers (e.g. ESX, Hyperv, XEN, local test driver). Why do you want to hook on the RPC anyway? Michal

2017-04-06 8:35 GMT+03:00 Michal Privoznik <mprivozn@redhat.com>:
Still, you will lack support for some drivers (e.g. ESX, Hyperv, XEN, local test driver). Why do you want to hook on the RPC anyway?
My use case only qemu, so all the simple. Also i think that integration tests covers changes from libvirt side and if libvirt internally change something integration test fails. -- Vasiliy Tolstov, e-mail: v.tolstov@selfip.ru

On 04/05/2017 09:11 PM, Vasiliy Tolstov wrote:
2017-04-05 17:53 GMT+03:00 Andrea Bolognani <abologna@redhat.com>:
That is true as long as you stick with the public API.
If you start messing with the internal RPC and a change in libvirt breaks your code, you get to keep both pieces.
I think in case of internal rpc i need to monitor each libvirt release and check git diff or src/remote/remote_protocol.x
That is not going to be enough. The RPC protocol is spread among other files too. You really should not hook into our RPC protocol. My question is still unanswered though - why do you need it anyway? Michal

2017-04-06 14:59 GMT+03:00 Michal Privoznik <mprivozn@redhat.com>:
That is not going to be enough. The RPC protocol is spread among other files too. You really should not hook into our RPC protocol.
My question is still unanswered though - why do you need it anyway?
Now only for fun, later - i want to try implement libvirt proxy with ability to selective deny some features in the middle -- Vasiliy Tolstov, e-mail: v.tolstov@selfip.ru

On Thu, Apr 06, 2017 at 03:01:40PM +0300, Vasiliy Tolstov wrote:
2017-04-06 14:59 GMT+03:00 Michal Privoznik <mprivozn@redhat.com>:
That is not going to be enough. The RPC protocol is spread among other files too. You really should not hook into our RPC protocol.
My question is still unanswered though - why do you need it anyway?
Now only for fun, later - i want to try implement libvirt proxy with ability to selective deny some features in the middle
We already have a fine grained access control system that can be used to restrict feature access... Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://entangle-photo.org -o- http://search.cpan.org/~danberr/ :|

2017-04-06 15:05 GMT+03:00 Daniel P. Berrange <berrange@redhat.com>:
We already have a fine grained access control system that can be used to restrict feature access...
I know, but i need to proxy - say have one endpoint for array of libvirt hosts. Not worry this is fun and i think for someone this is useful to understand how libvirt works internally. -- Vasiliy Tolstov, e-mail: v.tolstov@selfip.ru

2017-04-06 15:06 GMT+03:00 Vasiliy Tolstov <v.tolstov@selfip.ru>:
We already have a fine grained access control system that can be used to restrict feature access...
Also i don't think that libvirt access control have ability to deny access based on function and payload. For example i need to deny for some users ability to create domain with memory more then 10G or network with type nat. -- Vasiliy Tolstov, e-mail: v.tolstov@selfip.ru

On Thu, Apr 06, 2017 at 03:09:12PM +0300, Vasiliy Tolstov wrote:
2017-04-06 15:06 GMT+03:00 Vasiliy Tolstov <v.tolstov@selfip.ru>:
We already have a fine grained access control system that can be used to restrict feature access...
Also i don't think that libvirt access control have ability to deny access based on function and payload. For example i need to deny for some users ability to create domain with memory more then 10G or network with type nat.
Trying todo that kind of config access control at the libvirt API level is doomed to failure. The ability to pass in an XML document describing a guest gives you privileges equivalent to root. There are so many ways you can use the XML document give a guest access to host resources, that trying to do access restrictions based on XML content is impractical. You are inevitably going to miss the existance of certain XML features and thus think you have a locked down system where in fact you've left plenty of backdoors to exploit it. Every time QEMU or libvirt are upgraded new features are introduced so again what you thought was secure may now suddenly be insecure. This is why we explicitly don't expose this info to the access control framework. You need to have a much higher level representation of the guest configuration data & related resources in order to do practical access control on usage of individual guest config features. Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://entangle-photo.org -o- http://search.cpan.org/~danberr/ :|

On Thu, Apr 06, 2017 at 03:06:49PM +0300, Vasiliy Tolstov wrote:
2017-04-06 15:05 GMT+03:00 Daniel P. Berrange <berrange@redhat.com>:
We already have a fine grained access control system that can be used to restrict feature access...
I know, but i need to proxy - say have one endpoint for array of libvirt hosts. Not worry this is fun and i think for someone this is useful to understand how libvirt works internally.
Hiding multiple hosts behind the libvirt API doesn't really work for the majority of our API objects, as the object model is designed around a single host concept. You need a different level of API abstraction to effectively manage a pool of multiple hosts. Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://entangle-photo.org -o- http://search.cpan.org/~danberr/ :|

2017-04-06 15:09 GMT+03:00 Daniel P. Berrange <berrange@redhat.com>:
Hiding multiple hosts behind the libvirt API doesn't really work for the majority of our API objects, as the object model is designed around a single host concept. You need a different level of API abstraction to effectively manage a pool of multiple hosts.
May be you right. But why not try to do and check... -- Vasiliy Tolstov, e-mail: v.tolstov@selfip.ru

On Thu, Apr 06, 2017 at 03:16:44PM +0300, Vasiliy Tolstov wrote:
2017-04-06 15:09 GMT+03:00 Daniel P. Berrange <berrange@redhat.com>:
Hiding multiple hosts behind the libvirt API doesn't really work for the majority of our API objects, as the object model is designed around a single host concept. You need a different level of API abstraction to effectively manage a pool of multiple hosts.
May be you right. But why not try to do and check...
Sure you're free to check if you don't believe me. I'm just making suggestion to save you wasting your time. Regards, Daniel -- |: http://berrange.com -o- http://www.flickr.com/photos/dberrange/ :| |: http://libvirt.org -o- http://virt-manager.org :| |: http://entangle-photo.org -o- http://search.cpan.org/~danberr/ :|

2017-04-05 22:11 GMT+03:00 Vasiliy Tolstov <v.tolstov@selfip.ru>:
I think in case of internal rpc i need to monitor each libvirt release and check git diff or src/remote/remote_protocol.x
I think about api breaking and create generator for rpm messages using remote_protocol.x data. So i think i have something like wireshark dissector method and in case of new release i can easy check what methods are different. -- Vasiliy Tolstov, e-mail: v.tolstov@selfip.ru
participants (4)
-
Andrea Bolognani
-
Daniel P. Berrange
-
Michal Privoznik
-
Vasiliy Tolstov