mirror of
https://github.com/DarrylNixon/melamine.git
synced 2024-04-22 06:27:20 -07:00
ext2/3 is hard, use find as backup
This commit is contained in:
parent
155b3e2006
commit
068d47703a
2 changed files with 36 additions and 3 deletions
|
@ -35,6 +35,7 @@ class ShredDir(AsyncObject):
|
|||
self.mount_points.add(self.mount_point)
|
||||
self.fs_handler = await mount_to_fs_handler(self.mount_point)
|
||||
self.byte_size = sum(item.byte_size for item in self.contents)
|
||||
self.inode = path.stat().st_ino
|
||||
|
||||
async def _get_contents(self) -> List:
|
||||
contents = []
|
||||
|
@ -63,13 +64,30 @@ class ShredDir(AsyncObject):
|
|||
def __hash__(self) -> int:
|
||||
return hash(self.absolute_path)
|
||||
|
||||
async def delete_hardlinks_by_inode(self) -> None:
|
||||
logger.info(f"Finding and deleting hardlinks inside {self.absolute_path.name}")
|
||||
for path in self.contents:
|
||||
await path.delete_hardlinks_by_inode()
|
||||
|
||||
proc = await asyncio.create_subprocess_exec("find", str(self.mount_point), "-inum", self.get_inode(), "-delete")
|
||||
stdout, _ = await proc.communicate()
|
||||
|
||||
if proc.returncode != 0:
|
||||
err = f"Unable to delete hardlinks for {self.absolute_path.name}"
|
||||
logger.error(err)
|
||||
raise RuntimeError(err)
|
||||
|
||||
logger.info(f"Deleted hardlink for {self.absolute_path.name}")
|
||||
|
||||
|
||||
class ShredFile(AsyncObject):
|
||||
"""Class for tracking each file to be shredded."""
|
||||
|
||||
async def __init__(self, path: Path) -> None:
|
||||
self.absolute_path = path.resolve().absolute()
|
||||
self.byte_size = path.stat().st_size
|
||||
stat = path.stat()
|
||||
self.byte_size = stat.st_size
|
||||
self.inode = stat.st_ino
|
||||
self.mount_point = find_mount(self.absolute_path)
|
||||
self.fs_handler = await mount_to_fs_handler(self.mount_point)
|
||||
self.hardlinks = None
|
||||
|
@ -145,6 +163,17 @@ class ShredFile(AsyncObject):
|
|||
def __hash__(self) -> int:
|
||||
return hash(self.absolute_path)
|
||||
|
||||
async def delete_hardlinks_by_inode(self) -> None:
|
||||
proc = await asyncio.create_subprocess_exec("find", str(self.mount_point), "-inum", self.get_inode(), "-delete")
|
||||
stdout, _ = await proc.communicate()
|
||||
|
||||
if proc.returncode != 0:
|
||||
err = f"Unable to delete hardlinks for {self.absolute_path.name}"
|
||||
logger.error(err)
|
||||
raise RuntimeError(err)
|
||||
|
||||
logger.info("Deleted hardlink for {self.absolute_path.name}")
|
||||
|
||||
|
||||
async def get_all_hardlinks(paths: Set[Union[ShredFile, ShredDir]]) -> None:
|
||||
for path in paths:
|
||||
|
|
|
@ -12,7 +12,6 @@ async def main(job: argparse.Namespace) -> bool:
|
|||
It is called by the CLI and builds a job queue based on the arguments passed.
|
||||
"""
|
||||
new_paths = set()
|
||||
logger.info(f"job type is {type(job)}")
|
||||
|
||||
# Expand all directories and files, and collect mount point information
|
||||
for path in job.paths:
|
||||
|
@ -28,9 +27,14 @@ async def main(job: argparse.Namespace) -> bool:
|
|||
else:
|
||||
raise TypeError(f"Not a file or directory: {path}")
|
||||
|
||||
# Get hardlinks to subsequently unlink for all files
|
||||
# Try to delete hardlinks based on the filesystem type
|
||||
job.paths = await get_all_hardlinks(new_paths)
|
||||
|
||||
# Just in case, use "find" to delete any remaining hardlinks
|
||||
# from the mount point
|
||||
for path in job.paths:
|
||||
await path.delete_hardlinks_by_inode()
|
||||
|
||||
# Shred all physical files including hardlinks
|
||||
for path in job.paths:
|
||||
if isinstance(path, ShredFile):
|
||||
|
|
Loading…
Reference in a new issue