util/rmrf: use immutable helpers
Make use of the new immutable-flag ioctl helpers. While at it, move the `chmod` to `fchmod` and re-use the open file-descriptor. Document the behavior and move the `fchmod` into its own try-block for the same reasons as the `ioctl` call: We rely on the following unlink() to catch any errors. Errors in the fixperms() step are non-consequential.
This commit is contained in:
parent
e5ff287f5a
commit
1cdf2be0ac
1 changed files with 23 additions and 22 deletions
|
|
@ -11,11 +11,11 @@ removed.
|
|||
"""
|
||||
|
||||
|
||||
import array
|
||||
import fcntl
|
||||
import os
|
||||
import shutil
|
||||
|
||||
import osbuild.util.linux as linux
|
||||
|
||||
|
||||
__all__ = [
|
||||
"rmtree",
|
||||
|
|
@ -52,27 +52,28 @@ def rmtree(path: str):
|
|||
function is used internally). Consult its documentation for details.
|
||||
"""
|
||||
|
||||
def clear_mutable_flag(path):
|
||||
FS_IOC_GETFLAGS = 0x80086601
|
||||
FS_IOC_SETFLAGS = 0x40086602
|
||||
FS_IMMUTABLE_FL = 0x010
|
||||
|
||||
fd = -1
|
||||
try:
|
||||
fd = os.open(path, os.O_RDONLY)
|
||||
flags = array.array('L', [0])
|
||||
fcntl.ioctl(fd, FS_IOC_GETFLAGS, flags, True)
|
||||
flags[0] &= ~FS_IMMUTABLE_FL
|
||||
fcntl.ioctl(fd, FS_IOC_SETFLAGS, flags, False)
|
||||
except OSError:
|
||||
pass # clearing flags is best effort
|
||||
finally:
|
||||
if fd > -1:
|
||||
os.close(fd)
|
||||
|
||||
def fixperms(p):
|
||||
clear_mutable_flag(p)
|
||||
os.chmod(p, 0o777)
|
||||
fd = None
|
||||
try:
|
||||
fd = os.open(p, os.O_RDONLY)
|
||||
|
||||
# The root-only immutable flag prevents files from being unlinked
|
||||
# or modified. Clear it, so we can unlink the file-system tree.
|
||||
try:
|
||||
linux.ioctl_toggle_immutable(fd, False)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
# If we do not have sufficient permissions on a directory, we
|
||||
# cannot traverse it, nor unlink its content. Make sure to set
|
||||
# sufficient permissions up front.
|
||||
try:
|
||||
os.fchmod(fd, 0o777)
|
||||
except OSError:
|
||||
pass
|
||||
finally:
|
||||
if fd is not None:
|
||||
os.close(fd)
|
||||
|
||||
def unlink(p):
|
||||
try:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue