File: //usr/lib/yum-plugins/ovl.py
from yum.plugins import TYPE_CORE
from os import walk, path, fstat
requires_api_version = '2.3'
plugin_type = (TYPE_CORE,)
VERBOSE_DEBUGLEVEL = 3
def _stat_ino_fp(fp):
"""
Get the inode number from file descriptor
"""
return fstat(fp.fileno()).st_ino
def get_file_list(rpmpath):
"""
Enumerate all files in a directory
"""
for root, _, files in walk(rpmpath):
for f in files:
yield path.join(root, f)
def for_each_file(files, cb, m='rb'):
"""
Open each file with mode specified in `m`
and invoke `cb` on each of the file objects
"""
if not files or not cb:
return []
ret = []
for f in files:
with open(f, m) as fp:
ret.append(cb(fp))
return ret
def do_detect_copy_up(files):
"""
Open the files first R/O, then R/W and count unique
inode numbers
"""
num_files = len(files)
lower = for_each_file(files, _stat_ino_fp, 'rb')
upper = for_each_file(files, _stat_ino_fp, 'ab')
diff = set(lower + upper)
return len(diff) - num_files
def init_hook(conduit):
rpmdb_path = conduit._base.rpmdb._rpmdbpath
try:
files = list(get_file_list(rpmdb_path))
copied_num = do_detect_copy_up(files)
conduit.info(VERBOSE_DEBUGLEVEL, "ovl: Copying up (%i) files from OverlayFS lower layer" % copied_num)
except Exception as e:
conduit.error(1, "ovl: Error while doing RPMdb copy-up:\n%s" % e)