mirror of
https://github.com/containers/fuse-overlayfs.git
synced 2025-08-03 09:55:57 -04:00

Previously, fuse-overlayfs always used user.fuseoverlayfs.override_stat for the upper layer while honoring user.containers.override_stat for lower layers so that it can consume a layer created by containers/storage. It turned out that containers/storage also needs to get the overriding extended attribute set by fuse-overlayfs and to set one for the upper layer to make the root directory of the upper layer inherit the mode of a lower layer. Adding code to get and to set user.fuseoverlayfs.override_stat to containers/storage is a bit ugly. The underlying problem is that fuse-overlayfs changes what name to use ad hoc. Fix it by always preferring user.containers.override_stat, which containers/storage honors, over user.fuseoverlayfs.overlayfs, which is specific to fuse-overlayfs. Signed-off-by: Akihiko Odaki <odaki@rsg.ci.i.u-tokyo.ac.jp>
52 lines
1.3 KiB
Python
Executable File
52 lines
1.3 KiB
Python
Executable File
#!/bin/python
|
|
|
|
import os
|
|
import sys
|
|
import stat
|
|
import errno
|
|
|
|
XATTR_OVERRIDE_STAT_PRIVILEGED = "security.fuseoverlayfs.override_stat"
|
|
XATTR_OVERRIDE_CONTAINERS_STAT = "user.fuseoverlayfs.override_stat"
|
|
|
|
if os.geteuid() == 0:
|
|
xattr_name = XATTR_OVERRIDE_STAT_PRIVILEGED
|
|
else:
|
|
xattr_name = XATTR_OVERRIDE_CONTAINERS_STAT
|
|
|
|
cwd_fd = os.open(".", os.O_PATH)
|
|
|
|
def fix_path(path):
|
|
st = os.lstat(path)
|
|
content = "%s:%s:%o" % (st.st_uid, st.st_gid, stat.S_IMODE(st.st_mode))
|
|
|
|
try:
|
|
os.setxattr(path, xattr_name, str.encode(content), flags=os.XATTR_CREATE, follow_symlinks=False)
|
|
except Exception as e:
|
|
if e.errno == errno.EEXIST:
|
|
print("attr %s already present for %s: %s" % (xattr_name, path, e.errno))
|
|
return
|
|
raise e
|
|
|
|
fd = os.open(path, os.O_PATH|os.O_NOFOLLOW|os.O_NONBLOCK)
|
|
try:
|
|
proc_path = "/proc/self/fd/%d" % fd
|
|
os.chmod(proc_path, 0o755)
|
|
except Exception as e:
|
|
if e.errno != errno.ENOTSUP:
|
|
raise e
|
|
finally:
|
|
os.close(fd)
|
|
|
|
|
|
def fix_mode_directory(d):
|
|
for root, dirs, files in os.walk(d, topdown=False):
|
|
for i in dirs+files:
|
|
path = os.path.join(root, i)
|
|
fix_path(path)
|
|
fix_path(d)
|
|
|
|
for i in sys.argv[1:]:
|
|
fix_mode_directory(i)
|
|
|
|
|