<div dir="auto">Architecturally, separating the data and control channels feels like the right approach - whether nbd or something else. Would need signposting for those of us who routinely implement firewalling on hosts, but that's a detail.<div dir="auto"><br></div><div dir="auto">I presume there's no flow control on streams at the moment? </div><div dir="auto"><br></div><div dir="auto">Cheers, </div><div dir="auto"><br></div><div dir="auto">Peter </div></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Wed, 22 Jan 2020, 12:18 Daniel P. Berrangé, <<a href="mailto:berrange@redhat.com">berrange@redhat.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">On Wed, Jan 22, 2020 at 01:01:42PM +0100, Michal Privoznik wrote:<br>
> On 1/22/20 11:11 AM, Michal Privoznik wrote:<br>
> > On 1/22/20 10:03 AM, R. Diez wrote:<br>
> > > Hi all:<br>
> > > <br>
> > > I am using the libvirt version that comes with Ubuntu 18.04.3 LTS.<br>
> > <br>
> > I'm sorry, I don't have Ubuntu installed anywhere to look the version<br>
> > up. Can you run 'virsh version' to find it out for me please?<br>
> <br>
> Nevermind, I've managed to reproduce with the latest libvirt anyway.<br>
> <br>
> > <br>
> > > <br>
> > > I have written a script that backs up my virtual machines every<br>
> > > night. I want to limit the amount of memory that this backup<br>
> > > operation consumes, mainly to prevent page cache thrashing. I have<br>
> > > described the Linux page cache thrashing issue in detail here:<br>
> > > <br>
> > > <a href="http://rdiez.shoutwiki.com/wiki/Today%27s_Operating_Systems_are_still_incredibly_brittle#The_Linux_Filesystem_Cache_is_Braindead" rel="noreferrer noreferrer" target="_blank">http://rdiez.shoutwiki.com/wiki/Today%27s_Operating_Systems_are_still_incredibly_brittle#The_Linux_Filesystem_Cache_is_Braindead</a><br>
> > > <br>
> > > <br>
> > > The VM virtual disk weighs 140 GB at the moment. I thought 500 MiB<br>
> > > of RAM should be more than enough to back it up, so I added the<br>
> > > following options to the systemd service file associated to the<br>
> > > systemd timer I am using:<br>
> > > <br>
> > >    MemoryLimit=500M<br>
> > > <br>
> > > However, the OOM is killing "virsh vol-download":<br>
> > > <br>
> > > Jan 21 23:40:00 GS-CEL-L kernel: [55535.913525] [  pid  ]   uid <br>
> > > tgid total_vm      rss pgtables_bytes swapents oom_score_adj name<br>
> > > Jan 21 23:40:00 GS-CEL-L kernel: [55535.913527] [  13232]  1000<br>
> > > 13232     5030      786    77824      103             0<br>
> > > BackupWindows10<br>
> > > Jan 21 23:40:00 GS-CEL-L kernel: [55535.913528] [  13267]  1000<br>
> > > 13267     5063      567    73728      132             0<br>
> > > BackupWindows10<br>
> > > Jan 21 23:40:00 GS-CEL-L kernel: [55535.913529] [  13421]  1000<br>
> > > 13421     5063      458    73728      132             0<br>
> > > BackupWindows10<br>
> > > Jan 21 23:40:00 GS-CEL-L kernel: [55535.913530] [  13428]  1000<br>
> > > 13428 712847   124686  5586944   523997             0 virsh<br>
> > > Jan 21 23:40:00 GS-CEL-L kernel: [55535.913532] oom-kill:constraint=CONSTRAINT_MEMCG,nodemask=(null),cpuset=/,mems_allowed=0,oom_memcg=/system.slice/VmBackup.service,task_memcg=/system.slice/VmBackup.service,task=virsh,pid=13428,uid=1000<br>
> > > <br>
> > > Jan 21 23:40:00 GS-CEL-L kernel: [55535.913538] Memory cgroup out of<br>
> > > memory: Killed process 13428 (virsh) total-vm:2851388kB,<br>
> > > anon-rss:486180kB, file-rss:12564kB, shmem-rss:0kB<br>
> > > <br>
> > > I wonder why "virsh vol-download" needs so much RAM. It does not get<br>
> > > killed straight away, it takes a few minutes to get killed. It<br>
> > > starts using a VMSIZE of around 295 MiB, which is not really frugal<br>
> > > for a file download operation, but then it grows and grows.<br>
> > <br>
> > This is very likely a memory leak somewhere.<br>
> <br>
> Actually, it is not. It's caused by our design of the client event loop. If<br>
> there are any incoming data, read as much as possible placing them at the<br>
> end of linked list of incoming stream data (stream is a way that libvirt<br>
> uses to transfer binary data). Problem is that instead of returning NULL to<br>
> our malloc()-s once the limit is reached, kernel decides to kill us.<br>
> <br>
> For anybody with libvirt insight: virNetClientIOHandleInput() -><br>
> virNetClientCallDispatch() -> virNetClientCallDispatchStream() -><br>
> virNetClientStreamQueuePacket().<br>
> <br>
> <br>
> The obvious fix would be to stop processing incoming packets if stream has<br>
> "too much" data cached (define "too much"). But this may lead to<br>
> unresponsive client event loop - if the client doesn't pull data from<br>
> incoming stream fast enough they won't be able to make any other RPC.<br>
<br>
IMHO if they're not pulling stream data and still expecting to make<br>
other RPC calls in a timely manner, then their code is broken.<br>
<br>
Having said that, in retrospect I rather regret ever implementing our<br>
stream APIs as we did. We really should have just exposed an API which<br>
lets you spawn an NBD server associated with a storage volume, or<br>
tunnelled NBD over libvirtd. The former is probably our best strategy<br>
these days, now that NBD has native TLS support.<br>
<br>
Regards,<br>
Daniel<br>
-- <br>
|: <a href="https://berrange.com" rel="noreferrer noreferrer" target="_blank">https://berrange.com</a>      -o-    <a href="https://www.flickr.com/photos/dberrange" rel="noreferrer noreferrer" target="_blank">https://www.flickr.com/photos/dberrange</a> :|<br>
|: <a href="https://libvirt.org" rel="noreferrer noreferrer" target="_blank">https://libvirt.org</a>         -o-            <a href="https://fstop138.berrange.com" rel="noreferrer noreferrer" target="_blank">https://fstop138.berrange.com</a> :|<br>
|: <a href="https://entangle-photo.org" rel="noreferrer noreferrer" target="_blank">https://entangle-photo.org</a>    -o-    <a href="https://www.instagram.com/dberrange" rel="noreferrer noreferrer" target="_blank">https://www.instagram.com/dberrange</a> :|<br>
<br>
</blockquote></div>