How does lxd create directories from images when using the directory storage driver?

I’m trying to understand how lxd creates directories with the right uid/gid from images when using the directory storage driver.

If I export my ubuntu image, I get a squashfs with uid/gid 0 for files owned by root.

However, when I create a container with the image, the rootfs directory has shifted uid’s/gid’s to match the idmap for the container.

How is that directory being created with the correct uid/gid? What code is responsible for this?

It’s in LXD itself, we have uid/gid shifting logic that kicks in either at creation or first start of the container. That’s unless you’re using shiftfs which then has the kernel doing the shifting in-kernel rather than on-disk (but based on your description, you’re not).

No, I’m not using shiftfs.

What I’m really trying to figure out is how LXD is shifting the uid/gid of files without dropping capability flags.

Is it doing something other than or in addition to walking the tree and shifting with chown()?

Or is it shifting those uid’s as it unpacks the image onto the filesystem?

LXD’s shifting logic is aware of capabilities and acl extended attributes, we read those, translate them to their namespace-specific variant and write them.

1 Like

awesome, thank you! so the shifting logic inside LXD is a lot more comprehensive than what the fuidshift tool does, it sounds like.

Looks like we can get the same effect outside of lxd by just using bindfs or shiftfs. I guess fuidshift is more or less obsoleted by those.