storage/reflink: _update_loopdev_sizes() without losetup
Factor out a function, and use the LOOP_SET_CAPACITY ioctl instead of going through losetup.
This commit is contained in:
		
							parent
							
								
									385ba91772
								
							
						
					
					
						commit
						fb06a8089a
					
				| @ -28,7 +28,6 @@ import fcntl | |||||||
| import glob | import glob | ||||||
| import logging | import logging | ||||||
| import os | import os | ||||||
| import re |  | ||||||
| import subprocess | import subprocess | ||||||
| import tempfile | import tempfile | ||||||
| from contextlib import contextmanager, suppress | from contextlib import contextmanager, suppress | ||||||
| @ -36,7 +35,8 @@ from contextlib import contextmanager, suppress | |||||||
| import qubes.storage | import qubes.storage | ||||||
| 
 | 
 | ||||||
| BLKSIZE = 512 | BLKSIZE = 512 | ||||||
| FICLONE = 1074041865  # see ioctl_ficlone manpage | FICLONE = 1074041865        # defined in <linux/fs.h> | ||||||
|  | LOOP_SET_CAPACITY = 0x4C07  # defined in <linux/loop.h> | ||||||
| LOGGER = logging.getLogger('qubes.storage.reflink') | LOGGER = logging.getLogger('qubes.storage.reflink') | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| @ -246,12 +246,7 @@ class ReflinkVolume(qubes.storage.Volume): | |||||||
|             self.size = size |             self.size = size | ||||||
|             return self |             return self | ||||||
| 
 | 
 | ||||||
|         # resize any corresponding loop devices |         _update_loopdev_sizes(self._path_dirty) | ||||||
|         out = _cmd('losetup', '--associated', self._path_dirty) |  | ||||||
|         for match in re.finditer(br'^(/dev/loop[0-9]+): ', out, re.MULTILINE): |  | ||||||
|             loop_dev = match.group(1).decode('ascii') |  | ||||||
|             _cmd('losetup', '--set-capacity', loop_dev) |  | ||||||
| 
 |  | ||||||
|         return self |         return self | ||||||
| 
 | 
 | ||||||
|     def export(self): |     def export(self): | ||||||
| @ -395,6 +390,19 @@ def _create_sparse_file(path, size): | |||||||
|         tmp.truncate(size) |         tmp.truncate(size) | ||||||
|         LOGGER.info('Created sparse file: %s', tmp.name) |         LOGGER.info('Created sparse file: %s', tmp.name) | ||||||
| 
 | 
 | ||||||
|  | def _update_loopdev_sizes(img): | ||||||
|  |     ''' Resolve img; update the size of loop devices backed by it. ''' | ||||||
|  |     needle = os.fsencode(os.path.realpath(img)) + b'\n' | ||||||
|  |     for sys_path in glob.iglob('/sys/block/loop[0-9]*/loop/backing_file'): | ||||||
|  |         try: | ||||||
|  |             with open(sys_path, 'rb') as sys_io: | ||||||
|  |                 if sys_io.read() != needle: | ||||||
|  |                     continue | ||||||
|  |         except FileNotFoundError: | ||||||
|  |             continue | ||||||
|  |         with open('/dev/' + sys_path.split('/')[3]) as dev_io: | ||||||
|  |             fcntl.ioctl(dev_io.fileno(), LOOP_SET_CAPACITY) | ||||||
|  | 
 | ||||||
| def _copy_file(src, dst): | def _copy_file(src, dst): | ||||||
|     ''' Copy src to dst as a reflink if possible, sparse if not. ''' |     ''' Copy src to dst as a reflink if possible, sparse if not. ''' | ||||||
|     if not os.path.exists(src): |     if not os.path.exists(src): | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Rusty Bird
						Rusty Bird