Live data from Hacker News

Linux Namespaces and Go Don't Mix

weave.works

21–30 of 175 posts

Re: Linux Namespaces and Go Don't Mix

#21
post #5

Earlier quoted context omitted.

Better alternative to C with the same low level control? Why not C++?

I don't know, exactly, but I know with some confidence that C++ has never had significant uptake among ops and systems people. The folks who build systems, run systems, and dip into code on occasion to make the systems run, but not as their full-time job, have never (to my knowledge) fallen in love with C++. They probably all know some C, Perl, and Python...maybe not a lick of C++ (except the "C" part). I think C++ m…

I agree that rust will have an adoption problem amongst part-timers. Rust code is unreadable until you spend a few days with it and writing it requires a week or two of wrestling with the borrow checker.

In contrast, one of the reasons I'm a big fan of go is it is extremely easy to read for almost anyone. People pick it up very quickly.

Re: Linux Namespaces and Go Don't Mix

#22
post #3

Earlier quoted context omitted.

No, it's a lot messier than C. In a regular C program (not using any special libraries for M:N threading) you wouldn't have to spawn an entirely separate process. This issue is one of the downsides of Go's M:N scheduling. The OS is simply not aware of what the Go runtime is doing, and as a result you get impedance mismatches like this. It "raises a few eyebrows" because M:N scheduling is unpopular outside of Go and E…

Historically, much (I would probably argue most) C concurrency has been implemented with fork. Certainly not all, and there are many ways to handle it in C...but fork is really common, and I don't think it's considered all that big of a deal to do so. It is idiomatic (at least historically and across maybe billions of lines of C code), and not much harder to reason about than many kinds of thread implementation in C;…

I mostly agree. Of course, for as cheap as a fork can be (and in Linux it's very cheap), it's not as cheap as a systemcall.

When changing namespace happens often in a hot path, forking might not be fast enough.

I disagree with Walton that the blame is on the N:M threading. It's really on the Linux kernel that has never made a clean distinction between threads and processes, both in kernel and in the APIs.

Re: Linux Namespaces and Go Don't Mix

#23
post #12
post #2

This leads to go code being roughly as messy/clumsy as C (or whatever else) code in the sections that need concurrency and also need to change namespace. That's unfortunate, but I don't know that it really "raises a few eyebrows". I mean, what's the better alternative to Go for this work? Maybe Rust? It is, at least more controllable at a lower level...but, not as easy to pick up for people coming from a C/Python/Per…

Rust is much better for this (though I still feel some of the fork/exec interface has similar warts to Go). However, you're wrong in saying that it's "roughly as messy/clumsy" as C. Let me tell you how runc works. runc is written in Go, and we take an OCI configuration file. Because we can't just fork and set up all of the namespaces in Go, we have a C function called nsexec which is specified as __attribute__((const…

Thanks for explaining how it's done in runc. That does sound pretty awful. So, even though the initialization can be outsourced to a C function, you still would prefer to be working entirely in C? Are there no advantages to Go for runc? And, would it be possible for someone to write a somewhat standardized Go library for doing this grunt work?

Is it merely fear of C that keeps so much of the container infrastructure on Go? I've only spent a couple of weeks looking peripherally at Go, and I already like it better than C (which I've poked at peripherally for ~25 years), but I don't know it well enough to know its warts.

Re: Linux Namespaces and Go Don't Mix

#24

Author of the go netlink library here. I've run into this issue a number of times. There has been conversation in the past about adding some kind of new runtime command like LockOSThread to prevent new threads from being spawned, but it didn't gain any momentum. Even though I am a big fan of go, I've personally built two container runtimes in other languages do to the namespace clumsiness. Personally, I think rust is…

>" I've personally built two container runtimes in other languages do to the namespace clumsiness."

Can you share any details on those other container runtimes?

Re: Linux Namespaces and Go Don't Mix

#25
post #8

Earlier quoted context omitted.

> I mean, what's the better alternative to Go for this work? Maybe Rust? It is, at least more controllable at a lower level...but, not as easy to pick up for people coming from a C/Python/Perl/Ruby systems and ops background. You know, it's interesting. I've been programming with Python for about 6 years now. I've also picked up Javascript, SQL, bash, and PHP along the way. I'm always gaining a little bit of C knowle…

> You don't really know if your code will work until you compile. This is true in every text-based programming language. s/compile/execute/ for interpreted or repl-based languages.

I disagree. For instance, if I'm writing something in C and I know that it is syntactically and semantically correct, I know that it will definitely compile.

Go hijacks control flow and makes it more difficult to reason about how your code will be compiled and executed. At least that is true in my personal experience.

Re: Linux Namespaces and Go Don't Mix

#26
post #5

Earlier quoted context omitted.

Better alternative to C with the same low level control? Why not C++?

Because C++ is vastly more complex than either C or Go.

In C, I could not find good libraries for basic stuff (dynamic string manipulation, variable-sized arrays, hash tables). I tried glib but it was much worse than C++'s STL.

It is entirely possible to write C-style programs in C++ (very few classes, globals all over the place) and so on, and at least for me, C-style software in C++ are much safer/easier to debug than C-style software in C .

Re: Linux Namespaces and Go Don't Mix

#27

Author of the go netlink library here. I've run into this issue a number of times. There has been conversation in the past about adding some kind of new runtime command like LockOSThread to prevent new threads from being spawned, but it didn't gain any momentum. Even though I am a big fan of go, I've personally built two container runtimes in other languages do to the namespace clumsiness. Personally, I think rust is…

>" I've personally built two container runtimes in other languages do to the namespace clumsiness." Can you share any details on those other container runtimes?

One was a simplified runtime in c, similar to a stripped down version of systemd-nspawn. I can hopefully share the other one in a few weeks. I'm going through an open source approval process for it.

Re: Linux Namespaces and Go Don't Mix

#28

Earlier quoted context omitted.

> I mean, what's the better alternative to Go for this work? Maybe Rust? It is, at least more controllable at a lower level...but, not as easy to pick up for people coming from a C/Python/Perl/Ruby systems and ops background. You know, it's interesting. I've been programming with Python for about 6 years now. I've also picked up Javascript, SQL, bash, and PHP along the way. I'm always gaining a little bit of C knowle…

Yes but the problem with languages like Nim is lack of support and maturity. Go is more versatile and at the same time more mature than anything out there. It is a different design and it excels in what it does (considering all tradeoffs now). Will Nim be as versatile and solid as Go in the future? Hard to predict but i would say no. You need a solid financial backing and certain amount of adoption where people actua…

> Yes but the problem with languages like Nim is lack of support and maturity.

Agreed, that's why I don't use it for anything super important yet. Nim is approaching a 1.0 release soon. Go has a similar problem in that it is maintained almost entirely by Google who has a history of dropping projects without warning.

> Go is more versatile and at the same time more mature than anything out there.

This is objectively incorrect. In fact, Go aims precisely to be non-versatile for the sake of simplicity. That is why Go does not have generics for instance.

> It is a different design and it excels in what it does (considering all tradeoffs now)

I don't think it's design is all that different. It looks like a stripped down version of C and it's definitely not the first PL focused on concurrency.

> Will Nim be as versatile and solid as Go in the future?

Nim is already leagues above Go in the versatility(I assume you mean flexibility?) department. As far Nim being as "solid" as Go, I'm not entirely sure what you mean. If you're asking about stability, I believe that Nim can reach a similar level of stability as Go, yes.

> You need a solid financial backing and certain amount of adoption where people actually write software that makes them money.

I agree with this. However, it's not always a quick process. The only reason Go is as popular as it is is because of Google's size and reputation(edited). Every programmer on Earth heard of Go within a few days of it's official release. Nim is taking a slow roll approach. Look at Python. It took almost 15 years before it started getting really popular.

All that said, I didn't come into this thread to argue about Go vs Nim. I've been accused of shilling Nim in the past. I'm sorry that I like talking about PLs I enjoy using.

Re: Linux Namespaces and Go Don't Mix

#29

Earlier quoted context omitted.

> I mean, what's the better alternative to Go for this work? Maybe Rust? It is, at least more controllable at a lower level...but, not as easy to pick up for people coming from a C/Python/Perl/Ruby systems and ops background. You know, it's interesting. I've been programming with Python for about 6 years now. I've also picked up Javascript, SQL, bash, and PHP along the way. I'm always gaining a little bit of C knowle…

>You don't really know if your code will work until you compile. You are supposed to "compile on save".

I usually do this, but sometimes I'm writing a really long function or something and I want to save part way through so I don't lose my progress from some unlikely, yet catastrophic, failure.
Post reply on HN