[libvirt] Redesigning Libvirt: Adopting use of a safe language

Daniel P. Berrange berrange at redhat.com
Mon Nov 20 16:57:56 UTC 2017


On Mon, Nov 20, 2017 at 05:36:24PM +0100, Martin Kletzander wrote:
> On Mon, Nov 20, 2017 at 03:25:33PM +0000, Daniel P. Berrange wrote:
> > 
> > I shouldn't have used the word "allocation" in my paragraph above. As
> > you say, both languages have similar needs around allocation. The difference
> > I meant is around deallocation policy - in Rust, object lifetime is is a more
> > explicit decision on control of the progammer, as opposed to Go's garbage
> > collection.  From what I've read Rust approach to deallocation is much
> > closer to the C++ concept of "smart pointers", eg this
> > 
> >  http://pcwalton.github.io/blog/2013/03/18/an-overview-of-memory-management-in-rust/
> > 
> 
> This is kind of old, that code wouldn't run with newer Rust.  I guess
> that is from far ago when it was not stabilized at all.  It is a bit
> smarter now.  The fact that you have control over when the value is
> getting freed is true, however you rarely have to think about that.
> What's more important is that the compiler prevents you from accessing
> value from multiple places or not knowing who "owns" (think of it as
> "who should take care of freeing it") the variable.  If you give the
> ownership to someone you can't access it.  The difference I see is that
> if you access it after some other part of the code is responsible for
> that variable in Rust the compiler will cut you off unless you clearly
> specify how the memory space related to the variable is supposed to be
> handled.  In Go it will just work (with potential bug) but it will not
> crash because GC will not clean it up when someone can still access it.
> Granted this is usually problem with concurrent threads/coroutines (which
> I don't know how they handle access concurrent access in Go).  Also, for
> example Rust doesn't allow you to have value accessible from multiple
> threads unless it is guarded by thread-safe reference counter and does
> not allow you to modify it unless it is guarded by Mutex, RWLock or s
> one of the Atomic types.  Again, I don't know Go that much, I'm still
> yet to delve into the deep unknowns of it, but I haven't heard about it
> providing such safety.

The example you give about Rust not permitting concurrent usage is
one of the unique features I alluded to that Go doesn't have. 


> > On the choice of language, I will say C is a turn off to many people
> > as it is (not unreasonably) viewed as archaic, hard to learn and
> > difficult to write good code in.
> > 
> 
> I would say this highly depends on what area you are coming from.  In
> the cloud world it would be viewed way differently than in the
> dark^Wlow-level side of things.  I don't want to compare libvirt to the
> kernel for example, but I haven't heard about C being a turn-off there.

I'm wary of using the kernel as an anology for anything, because it
is special in oh so many ways from "regular" projects...

The closest comparison is K8s -> Docker, and there I do see more
engagement from Kubernetes devs down into Docker code than I ever
saw from OpenStack dev down into libvirt code. There's only so
far you can usefully take these comparisons though.

> > When I worked in OpenStack it was a constant battle to get people to
> > consider enhancements to libvirt instead of reinventing it in Python.
> > It was a hard sell because most python dev just didn't want to use C
> > at all because it has a high curve to contributors, even if libvirt
> > as a community is welcoming. As a result OpenStack pretty much reinvented
> 
> I'm sorry, but I think only handful of us (yeah, I think and hope I
> could count myself amoungst that group) are welcoming.  But it's
> actually where I see one of the big turn-offs.

Perhaps "welcoming" was overstating things - perhaps more "not aggressively
hostile" would be a better way of saying it.


> > > How do we deal with problems/bugs in dependence libraries?  I know, all
> > > the projects are pretty new, so they might be nicer to contributors.  If
> > > they are not, we might need to fork or rewrite the code.  Bam, another
> > > chance of losing workforce.
> > 
> > Many C libs we depend on have been around along time so are more
> > mature, but are also more conservative  in accepting changes,
> > especially if they touch API. On balance I don't think there would
> > be a big difference either way in this area.
> > 
> 
> ... OK, I hope so and if you say so I will blindly believe that ;)

Mostly I'm basing this off what I see with Docker and Kubernetes.
They both relying on a huge number of 3rd party Go modules, and
their needs & scale at least on a par with libvirts. IOW, if it
is good enough for them, its a sign it would be good enough for
us.


> > > The build process is that all the binaries are static, right?  Or all
> > > the go code is static and it only has dynamic dependencies on C
> > > libraries? In such a project as libvirt, wouldn't that mean that the
> > > processes we run will be pretty heavy-weight?
> > 
> > Yes, all the Go code is statically linked - only C libs are dyn
> > loaded. This doesn't have any impact on runtime, because even if
> > the binary was 100's of MB in size, the kernel is only ever going
> > to page in sections of that file which are actually executed.
> > 
> 
> But the code that is used by each binary will be present as many times
> as that binary is running since it is not dynamically loaded, right?

The memory mapping associated with /usr/bin/foo is still shared across
all instances of 'foo' that are executing.

If you have /usr/bin/foo and /usr/bin/bar though, which both static
linked to 'wizz', then you would get two copies of 'wizz' in memory
though.

> > The main impact is that if a dependancy gets an update (eg for
> > a security fix) all downstream apps need rebuilding.
> 
> Well, that sucks, but it's not a deal-breaker.

NB, same as ocaml and a few other languages in Fedora too.


> > > You can't just clone a repo, cd into it and build it.  You have to get
> > > the dependencies in a special manner, for that you have to have GOPATH
> > > set and based on that you have to have your directories setup similarly
> > > to what Go expects, then you need GOBIN if you want to build something
> > > and other stuff that's just not nice and doesn't make much sense.  At
> > > least for newcomers.  Simply the fact that it seems to me like Go is
> > > trying to go against the philosophy of "Do one thing and do it well".  I
> > > know everyone is about having the build described in the same language
> > > as the project, but what comes out of it is not something I prefer.
> > 
> > This is relataed to the thing I mention above where historically
> > everything was just splattered into $GOPATH. Most apps have gone
> > towards the vendoring concept where every dep is self-contained
> > in your local checkout.
> > 
> 
> I have to read up on the basics on how to do a proper first-time setup
> for Go.  And maybe everything will be sunshine and rainbows from that
> point forward.  It's just that I don't like the fact that it's
> non-intuitive.  Is it possible somehow to just build some code without
> actually dealing with bunch of dependencies and all the setup?  To give
> an example, is there a way to differentiate the compiler from the
> dependency handling and build processes?  Like gcc and
> autoconf/automake/make or rustc and cargo?

The compiler binary 'go' expects all the deps to have been pulled
down locally. It will search for them in either GOPATH (the traditional
location), or local vendor/ dir (the modern location), searching
vendor/ first.  The process of actually getting those deps installed
is handled by a separate tool. On my most recent code I used a tool
called 'glide', but Go is in process of unifying on a tool called "dep".

You still need to normally checkout in $GOPATH/src/$REPOURL

eg when checking out

   https://github.com/dicot-project/dicot-api

it would go into

   $GOPATH/src/github.com/dicot-project/dicot-api

It would be possible to avoid this, if I made the makefile auto-populate
a $GOPATH with symlinnks, but I've not bothered to try that, as the use
of $GOPATH layout doesn't really bother me now that the 3rd party deps
are isolated into the vendor/ dir. 

> > > I'm not against using another language to make some stuff better.  I
> > > guess it is kind of visible from the mail that I like Rust, but I'm not
> > > against other languages as well.  I just want this to be full on
> > > discussion and I want my opinion to be expressed.  Thanks for
> > > _listening_ ;)
> > 
> > Either Rust or Go would be a step forward over staying exclusively
> > with C IMHO, so at least we agree that there are potential benefits
> > to either :-)
> > 
> 
> Yeah.  Good luck with evaluating the responses.  I hope we won't need to
> change our Code of Conduct or even resort to voting...

I think we're a way off actually getting to the point of decision making.
I would view refactoring of libvirtd into modular deamons as the more
pressing problem to tackle. Language choice is a more long term thing
to consider. Realistically it would need a real world proof of concept
illustrating the usage of $LANG in combination with C, with our codebase,
to be able to properly understand what it would look like for libvirts
POV.

Regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|




More information about the libvir-list mailing list