The way OSTree supports multiple operating system versions installed is quite simple; we boot into a chroot.
Boot process details
The "normal" boot process looks like this:
BIOS bootloader kernel initramfs (dracut) mount root filesystem on /sysroot move /proc /sys from / to /sysroot move /sysroot to / exec /sbin/init
The OSTree boot process looks like this:
BIOS bootloader kernel initramfs (dracut) mount root filesystem on /sysroot parse ostree=OSNAME/TARGET argument from kernel command line, resolving it to /sysroot/ostree/deploy/OSNAME/TARGET move /proc /sys from / to /sysroot/ostree/deploy/OSNAME/TARGET bind mount /sysroot/ostree/deploy/OSNAME/TARGET/sysroot to /sysroot/ostree/deploy bind mount the configuration store /sysroot/ostree/deploy/OSNAME/TARGET-etc to /sysroot/ostree/deploy/OSNAME/TARGET/etc bind mount /sysroot/ostree/deploy/OSNAME/TARGET/home to /home (and the same for /tmp /root) bind mount /sysroot/ostree/deploy/OSNAME/var to /sysroot/ostree/deploy/OSNAME/TARGET/var (makes /var shared among deployments for OSNAME) make a readonly bind mount over /sysroot/ostree/deploy/OSNAME/TARGET move /sysroot/ostree/deploy/OSNAME/TARGET to / exec /sbin/init
Bind mount layout
You'll note in OSTree we share /home with whatever distribution (if any) is installed in /. This implies that we need to share uid/gid mappings.
We don't share /var; that would create a lot of potential sources of conflict. In practice, all operating systems one boots with OSTree must not outright fail when presented with contents of /var they don't expect. Ideally in fact, all data stored there that's parsed should be both forwards and backwards compatible.
Everything else (/usr, /lib) is considered part of the operating system, and has a read-only bind mount over it. We might later poke a hole through this for /usr/local (which would point to /ostree/local).