mirror of
https://github.com/xcat2/confluent.git
synced 2026-08-03 16:07:00 +00:00
Fingerprint installation media off the event loop
scan_iso walks an entire ISO with blocking libarchive reads, yielding only once per entry, and the header-sum branch of fingerprint reads the whole file with no yield at all. Both run in the daemon, reached from MediaImporter.init on every fingerprint and importing request. The scan costs about 8us per entry and is indifferent to media size, since libarchive seeks past file data rather than reading it: measured at 80ms for 10k entries whether the image is 0.2 GB or 8.8 GB, and at 310ms for 40k. The header-sum branch is the one that scales with size, reading a multi-gigabyte image end to end. Make the pair plain functions and hand them to a thread instead.
This commit is contained in:
@@ -834,7 +834,7 @@ def fingerprint_initramfs(archive):
|
||||
return None
|
||||
|
||||
|
||||
async def scan_iso(archive):
|
||||
def scan_iso(archive):
|
||||
scanudf = False
|
||||
filesizes = {}
|
||||
filecontents = {}
|
||||
@@ -845,7 +845,6 @@ async def scan_iso(archive):
|
||||
for ent in reader:
|
||||
if str(ent).endswith('TRANS.TBL'):
|
||||
continue
|
||||
await asyncio.sleep(0)
|
||||
filesizes[str(ent)] = ent.size
|
||||
if str(ent) == 'README.TXT':
|
||||
readmecontents = b''
|
||||
@@ -909,13 +908,13 @@ def parse_bfb(archive):
|
||||
archive.seek(currsize, os.SEEK_CUR)
|
||||
return None
|
||||
|
||||
async def fingerprint(archive):
|
||||
def fingerprint(archive):
|
||||
archive.seek(0)
|
||||
header = archive.read(32768)
|
||||
archive.seek(32769)
|
||||
if archive.read(6) == b'CD001\x01':
|
||||
# ISO image
|
||||
isoinfo = await scan_iso(archive)
|
||||
isoinfo = scan_iso(archive)
|
||||
name = None
|
||||
for fun in globals():
|
||||
if fun.startswith('check_'):
|
||||
@@ -947,7 +946,7 @@ async def import_image(filename, callback, backend=False, mfd=None, custtargpath
|
||||
archive = os.fdopen(int(mfd), 'rb')
|
||||
else:
|
||||
archive = open(filename, 'rb')
|
||||
identity = await fingerprint(archive)
|
||||
identity = await asyncio.to_thread(fingerprint, archive)
|
||||
if not identity:
|
||||
return -1
|
||||
identity, imginfo, funname = identity
|
||||
@@ -1207,7 +1206,7 @@ class MediaImporter(object):
|
||||
else:
|
||||
medfile = open(media, 'rb')
|
||||
try:
|
||||
identity = await fingerprint(medfile)
|
||||
identity = await asyncio.to_thread(fingerprint, medfile)
|
||||
finally:
|
||||
if not self.medfile:
|
||||
medfile.close()
|
||||
|
||||
Reference in New Issue
Block a user