We're sorry but this page doesn't work properly without JavaScript enabled. Please enable it to continue.
Feedback

Containers and Steam

00:00

Formal Metadata

Title
Containers and Steam
Subtitle
Putting games under pressure
Title of Series
Number of Parts
490
Author
License
CC Attribution 2.0 Belgium:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal purpose as long as the work is attributed to the author in the manner specified by the author or licensor.
Identifiers
Publisher
Release Date
Language

Content Metadata

Subject Area
Genre
Abstract
The availability of namespaces inside user sessions is increasing, and Valve's Steam game distribution platform is taking advantage of this for better gaming on Linux. A recent beta of Steam for Linux adds pressure-vessel, an experimental mechanism developed by Collabora to put games in containers. This gives the game partial isolation from various aspects of the host system, and in particular allows it to use a runtime library stack that is not entangled with the host's, with different games using different runtimes. Meanwhile, the unofficial Steam Flatpak app distributed on Flathub puts the entire Steam client and all of its games in a container. This gives the Steam client more thorough isolation from the host system, but all the games have to share that single container. In this talk, pressure-vessel developer and Flatpak contributor Simon McVittie will compare the two approaches and the challenges they encounter, and look at where Steam containers might go in the future.
33
35
Thumbnail
23:38
52
Thumbnail
30:38
53
Thumbnail
16:18
65
71
Thumbnail
14:24
72
Thumbnail
18:02
75
Thumbnail
19:35
101
Thumbnail
12:59
106
123
Thumbnail
25:58
146
Thumbnail
47:36
157
Thumbnail
51:32
166
172
Thumbnail
22:49
182
Thumbnail
25:44
186
Thumbnail
40:18
190
195
225
Thumbnail
23:41
273
281
284
Thumbnail
09:08
285
289
Thumbnail
26:03
290
297
Thumbnail
19:29
328
Thumbnail
24:11
379
Thumbnail
20:10
385
Thumbnail
28:37
393
Thumbnail
09:10
430
438
Game theoryPressureDatabaseComputer animation
Open setGame theoryWindowOperating systemData storage deviceNeuroinformatikGame theoryQuicksortMobile appProjective planeDistribution (mathematics)Operator (mathematics)Information technology consultingGeneric programmingLibrary (computing)
Open setRun time (program lifecycle phase)Game theoryOperating systemLibrary (computing)Gastropod shell1 (number)Portable communications devicePhysical systemException handlingScripting languageComputer animation
Device driverOpen setProper mapKernel (computing)Distribution (mathematics)Asynchronous Transfer ModeOperator (mathematics)Operating systemOpen sourceLibrary (computing)Computer animation
Distribution (mathematics)Open setBefehlsprozessorKernel (computing)Device driverBinary fileScalable Coherent InterfaceCore dumpModule (mathematics)Revision controlKernel (computing)Standard deviationDevice driverSystem callComputer programmingMereologySpacetimeMatching (graph theory)Library (computing)ImplementationRight angleRun time (program lifecycle phase)Different (Kate Ryan album)Open sourceMathematicsBinary codeEmailFunctional (mathematics)TelecommunicationSoftware maintenanceCode
Open setLie groupDevice driverPhysical systemGame theoryLibrary (computing)Run time (program lifecycle phase)Exception handlingRevision controlCuboidBitComputer animation
Distribution (mathematics)Open setWindowFiber bundleMaxima and minimaState transition systemRevision controlDevice driverGraph (mathematics)Run time (program lifecycle phase)Game theoryCodeLine (geometry)Run time (program lifecycle phase)DiagramRevision controlLibrary (computing)Symbol tableResultantDecision theoryBoundary value problemSoftware testingArithmetic progressionPhysical systemHacker (term)Computer animation
Open setOpen sourceCodeLibrary (computing)Integrated development environmentComputer-assisted translationGame theoryComputer programmingRun time (program lifecycle phase)Computer animation
Integrated development environmentOpen setGame theoryInformation securityAreaSynchronizationCodeClient (computing)Point cloudMereologyGame theoryDevice driverSynchronizationBoundary value problemPhysical systemDirectory serviceHacker (term)Modal logicCodeNP-hardKeyboard shortcutComputer hardwareRight angleComputer animation
Open setGame theoryClient (computing)FreewareMobile appPhysical systemClient (computing)Set (mathematics)Library (computing)Computer animation
Open setBoundary value problemClient (computing)Run time (program lifecycle phase)Software development kitInformation securityGame theoryPlug-in (computing)Right angleLibrary (computing)Device driverPhysical systemComputer animation
Game theoryClient (computing)Open setInformationInformation securityIdentity managementConstraint (mathematics)Computer animation
Open setGamma functionDevice driverCompilerColor managementGame theoryGame theoryIntegrated development environmentMultiplication sign1 (number)Run time (program lifecycle phase)Library (computing)Computer animationLecture/Conference
PressureOpen setGame theoryIntegrated development environmentGame theory1 (number)Run time (program lifecycle phase)Revision controlOcean currentPressureStrategy gameMultiplication signComputer animation
Game theoryOpen setPrincipal ideal domainVideo trackingClient (computing)Parallel portCodeIntegrated development environmentFreewareRun time (program lifecycle phase)Software developerComputer animation
Open setComa BerenicesLibrary (computing)View (database)Right angleBeta functionComputer configurationClient (computing)BitComputer animationSource codeLecture/Conference
Graphical user interfaceGame theoryLine (geometry)Run time (program lifecycle phase)Game controllerMoment (mathematics)Source codeLecture/Conference
Telephone number mappingSoftware developerProcess (computing)Revision controlGame theoryNormal (geometry)Software testingQuicksort
Telephone number mappingGastropod shellRun time (program lifecycle phase)Computer configurationLibrary (computing)Axiom of choice
Computer-assisted translationIntegrated development environmentGame theoryVariable (mathematics)BitPhysical systemFunction (mathematics)Device driverGastropod shell
Computer animation
Game theoryVideo game consoleExecution unitFacebookPoint cloudOpen sourceSource code
Transcript: English(auto-generated)
Okay, next up we've got Simon Margaret here who's going to be talking to us about containers and Steam. Hello, so unlike most of the people who've been speaking in this room, I'm not talking about like mission-critical services,
I'm not talking about like securing your database or anything like that, I just want to play Half-Life. So I'm sure you all know about Steam, it's Valve's app store for mostly games, a few non-game apps as well.
On Windows, on Mac, on their own Debian-derived operating system, SteamOS, and on generic Linux. The games are labeled as SteamOS, but actually they work fine on most distributions, sort of. I work at a company called Collabora, we are an open-source consultancy and my current project is helping Valve with the Steam runtime,
which is how their Linux games manage to work, mostly correctly, on SteamOS, on Debian, on Fedora, on Arch, whatever. The problem is, if you buy a game, quite reasonably, you want to play it, you want it to work on your computer.
But Linux distributions are all different. Does it use libjpeg6 or libjpeg9? Does it use libssl 1.0 or 1.1 or something from the distant past?
You can't really know quite what you're targeting, or you sort of can, because the LSB exists, but that's got like three libraries in it and no operating systems actually use it anyway. So it's not a great baseline for running all your games on.
So, Valve invented this thing called the Steam runtime. This is from like 2012, 2013, something like that. So you have your host system. I'm a Debian developer, so my host system is obviously Debian. And inside that, we have this box. There's a horrible shell script that sets up an LD library path about this long,
so that a bunch of libraries from the Steam runtime get used instead of the ones from your host system. So this is the traditional solution for portable games. You bundle all your libraries with your game, except
Valve have bundled all their libraries with their launcher, so that all the games get to share them. And the Steam runtime releases, there is one so far, are named after Team Fortress 2 characters, so this is Scout.
And if your operating system is similar enough to Ubuntu from the distant past, you can run your game and it works. Yeah, that LD library path is a massive oversimplification. The real one is huge.
The problem is, you know I said if your operating system is similar enough to Ubuntu from the distant past, turns out in the modern operating system, this doesn't work. So the major things we have to get from the operating system are the graphics, one of them is the graphics driver.
So in the open source world, we all want to use Mesa or potentially some other open source driver, but yeah, it's Mesa. And if you, and Mesa needs a bunch of dependencies. No, I don't want to restart Steam. Right. Thank you Steam, offline mode, well respected.
So we need dependencies for the open source drivers, we need the LLVM libraries, which are enormous, we need the standard C++ runtime because of that, which is pretty big, we need libdrm, we need libgcc, that's kind of core thing, kind of important.
And we need GNPC obviously. And if your GPU is from like this year, you need a version of Mesa that supports your GPU, so really recent as well. And there is kind of anecdotal evidence that if your kernel and Mesa are about the same age, that's probably going to work best.
The kernel is meant to be perfectly backwards compatible at all times, but that's really hard. So it's just mostly backwards compatible. And then the other side, the other side of things, we have the proprietary NVIDIA driver and historically the proprietary FGLRX driver for ATI stuff as well.
And these are similar to Mesa. They have a user space part and they have a kernel side part. Unlike Mesa, they require the kernel module and the user space part to be exactly the same version. The communication between them is not backwards compatible, it's not forwards compatible, they have to match.
So you can't bundle the user space part of the graphics driver because then it won't match the kernel part for most of your users and that's not good. Also, I mentioned glibc. Glibc is kind of fundamental, we can't really get away from that.
And it has this thing, the dynamic linker, which is what actually starts your program like your game or whatever. And the path to that is hard coded. It's part of the ELF headers of every binary. You can't change it, it's part of the ABI. You don't get to choose what path people are using there.
It calls into libdl, which is the actual implementation of loading shared libraries. If they don't match, their assumptions are going to fail because it's like, call this function, this private function in libdl that does the stuff we want. Oops, it's not there. Call this other one, oops, it does something different. Bad news.
Similarly, libdl is inextricably linked to libc and libc is linked up with libpthread, which does locking and stuff like that kind of thing. And if they don't match, you're in a situation that the glibc maintainers have never tested, can't really be expected to have ever tested.
It's like, this is not going to work. So we don't have graphics drivers in Steam runtime and we don't have glibc. And unfortunately, if you are using the graphics drivers from the host system, they will depend on a version of libllvm and all that, that is at least the one they were compiled against.
A reasonable assumption, except if you have replaced all the libraries with Ubuntu from the distant past, that assumption breaks, your game crashes, which is why the 2013 era Steam runtime stopped working. So what we now have, you'll notice it's the same diagram, but the box is
a bit paler now, because instead of having, we're using all the libraries from the runtime, we are now looking at those libraries, comparing them with what's on the host system and picking whichever one we think is newer.
So if you are running the Steam runtime on something really ancient, like Ubuntu 12 or SteamOS 2, which is pretty old by now or something like that, a bunch of the libraries in the Steam runtime that Valve consider important for games will have been upgraded.
So for example, we have a newer version of GNU TLS, we have a newer version of SDL, and it will prefer to use them. Others of your system libraries are going to be newer, like in practice, you will have a newer like libjpeg or GTK or whatever, and we'll use those from your host system instead of ours.
And again, the LD library path is a mile long, even longer in this case, in fact. And it works great, except comparing versions of libraries, you might think, oh yeah, yeah, you just look at the symlink, it's a symlink to like libcurl.so.4.1.2.3, you compare that with libcurl.so.4.3.8, and you can see which one is newer.
Except a few libraries, the so name, the canonical name of the library is just a regular file, not a symlink. So you can't easily tell which is newer. We have some code in progress to improve on this by looking at the symbols exported by
the library and the version symbols and that kind of thing and making a better educated guess. But it's still fundamentally a guess. If your libcurl is newer on the host system, as it often will be, it might not be the same ABI we've got as a result of some, with hindsight, bad decisions made several years ago in Debian that have since been fixed.
But the Steam runtime is based on a version before that was fixed, so yeah. And OpenSSL removes symbols from its ABI when you turn off support for insecure SSL versions. So if you have a library that calls into it, like libcurl or something, it may not work
with the host's libSSL because even if the so name is the same, that symbol has gone away. So we have to hack things like libcurl to not try and use the old SSL versions even if it detects them. Also, the dotted line on my diagram is not a hard boundary.
Game vendors will often compile their game, test their game, it works, good, ship it. Even if some of their dependencies are in fact things that came from outside the runtime and we never shipped a copy of that. If you happen to have that on your host system, their game works, great.
If you don't, problem. So, big thing I've been working on lately is pressure vessel. This is a little open source program recycling a bunch of code from Flatpak. So Steam is still in the old style runtime.
But as a child process, we have bubble wrap, represented here by its mascot of a bubble wrap cat. This makes a little container, so quite similar to what Flatpak does, much of the same code. In this container, it's a very strict scout environment.
You get the libraries from scout and no more. If your library is correctly done, was built in a scout environment, like Half Life for example, it works fine. If your game is one from a less strict publisher, it probably won't work. But it didn't work for some people anyway, right? So at least they can QA it.
If they test in this very strict container, it should work for everyone. Hard part of this is we have to hoover up the graphics drivers from the host system. And because they have dependencies, we still have to get the dependencies into the container somehow.
And there's some mad hacks in pressure vessel to make this work. Remember I said the ld.so path was hard coded. We have to bind mount the right ld.so over the top of it to make this work. We wish we didn't have to do this, but it's kind of necessary. Because the graphics driver in your container wouldn't support your hardware because it's old.
As an experimental side benefit, we can do other fun container things. So we can give you a separate home directory for each game. So that anything in that home directory, we know it came from that game. We can send it to the Steam cloud. You get your save games everywhere.
Except currently this feature, the actual Steam client doesn't know about the separate home directories. So cloud auto sync is worse with this feature. And the Steam workshop also doesn't know about this yet. Unlike a lot of container stuff, we're not trying to do security here. It's not a security boundary. It would be nice, but it's not the priority right now.
Meanwhile, you may recognize this guy giving a talk in a room similar to this one two years ago. So Flatpak has come along. People in the community, not me, have made the Steam client into an unofficial Flatpak app.
So here we have Flatpak on my Debian host system. Starts the container using bubble wrap. This container is using the free desktop SDK, which is a set of libraries done by the fredesktop.org people. And inside that we have the traditional Scout runtime, just the way it was a few slides ago.
So this is a security boundary, at least a little bit. It's kind of porous right now, but we'll get better. As far as the Steam runtime is concerned, the fredesktop SDK is in the role of the host system.
So we get the graphics drivers from the Flatpak runtime. We get some libraries from the Flatpak runtime. And a unique feature of this thing is that there is some madness with an LD audit plugin inside the container to force broken games to work even if they bundle libraries they shouldn't.
Which is great and I'm amazed it works and we should steal it. Unfortunately, combining these two is pretty difficult because some of the constraints that are put on Flatpak containers mean we can't enter another container.
So the stuff we want to do in future, old games have to keep working even if your GPU is new. For new games we want new runtimes, so more Team Fortress characters. We currently have a runtime being tested called Soldier, which is somewhat newer than Scout.
Heavy and Spy are slightly older ones that we tried but abandoned. And when we go into this newer runtime environment, we don't want to repeat the mistakes of the past
and have your game not work reliably. In a new distribution in like five years time or ten years time. So we want everyone who is testing their game in Soldier to be testing it in a strict Soldier environment that they can't accidentally pick up dependencies on libraries we don't have and that kind of thing.
So one strategy for this is that because we've got pressure vessel, we don't need to pick the same runtime every time. So if we imagine that Half-Life had been ported to be built in Soldier rather than in Spy, we could just make a different container.
And this means not all the games have to have the same runtime. The games don't have to have the same runtime as the Steam client, everything's great. Another possibility is because mistakes have been made and blame was ascribed, some games have dependencies that are not in the Scout environment.
But those games basically work on Scout in Debian 10, we have like empirical evidence that that works. So why don't we put the old runtime inside the new runtime and use the fact that the new runtime is pretty similar to a current version of, for example, Debian.
And that might well make games more reliable. And again we don't want to do this for future games, it's just for current ones. And finally, we have this setup that I have been trying to get working. Flatpak now has support for what they call sub-sandboxing,
where instead of making another container inside your container, which you're not allowed to do, you can send an IPC request out to Flatpak and say, please make me a container, make it look like this, go. And so you have the Steam client in your original container in the Free Desktop SDK environment.
And then over here, you have Half Life in your Scout container. Flatpak can't currently do this. There is not all the code yet to be able to ask it to use a totally different runtime. But the Flatpak developers seem to be fairly receptive to the idea that that's something they might do in future.
So hopefully we can get that working and have these parallel containers, and Flatpak users will be able to benefit from this multiple runtime thing.
Any questions? Or alternatively, do you want a demo? Right. So here is the reason Steam was nagging me to update it. This is not a special magic hacked up Steam. This is just the normal public beta of the Steam client.
I don't even have access to the private ones. And the only thing I've done a bit differently is I've run it with this magical option to ask Pressure Vessel to give me a GUI instead of just running the game straight off.
You can get the magic incantations for how to control Pressure Vessel from the source code. So this will take a moment because it may have to unpack my runtime. Okay. So I have this little test UI that I've asked for. Normally you wouldn't get this. Normally you'd just get a game. This is my development version that has all sorts of inadvisable options,
like making a process ID namespace, which doesn't even work because it confuses Steam. So I'm running it in the Scout runtime. It's giving me a choice of runtimes. I have a copy of Soldier available.
I have this option here to put an LD library path runtime inside the container. That doesn't work yet. And I'm going to tell it to run a shell instead of actually running Half Life. So this is a thing I think I put in for debugging the environment. This is an exterm inside my container. So if I cat etc OS release, you can see that this is not my Debian host system.
This is a purely Scout container slash etc and slash user and all the rest of it came from Scout. Except for this overrides directory, which has all the stuff I've yanked in from my host system to get my graphics drivers working.
And this shell has the command to run stuffed into this variable. So you can run your game. A bit of logging happens and welcome to Black Mesa.
And we're out of time. Thank you.