Skip to content

Commit

Permalink
fix(Disks Menu): Apply suggestions from code review
Browse files Browse the repository at this point in the history
Co-authored-by: William Edwards <[email protected]>
  • Loading branch information
pastaq and ShadowApex committed Jul 16, 2024
1 parent 5860edc commit 54fba3c
Show file tree
Hide file tree
Showing 20 changed files with 701 additions and 371 deletions.
2 changes: 1 addition & 1 deletion core/systems/debug/logger.gd
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ func _stringify(arg1: Variant, arg2: Variant = null, arg3: Variant = null, arg4:
if argument is String:
array.push_back(argument as String)
continue
array.push_back(str(argument as String))
array.push_back(str(argument) as String)

return " ".join(array)

Expand Down
170 changes: 57 additions & 113 deletions core/systems/disks/steam_removable_media_manager.gd
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ class_name SteamRemovableMediaManager

var udisks2 := load("res://core/systems/disks/udisks2.tres") as UDisks2

var logger := Log.get_logger("SteaMRemovableMediaManager", Log.LEVEL.INFO)
var logger := Log.get_logger("SteamRemovableMediaManager", Log.LEVEL.INFO)

# TODO: Fix this workaround to allow similtaneous operations. Currently more than
# one operation will reset the drive nodes and permit undefined behavior.
Expand All @@ -18,33 +18,16 @@ const STEAMOS_TRIM_DEVICES = "/usr/bin/steamos-polkit-helpers/steamos-trim-devic
const BLOCK_PREFIX = "/org/freedesktop/UDisks2/block_devices"
const SDCARD_PATH = "/dev/mmcblk0"

const protected_mounts = [
"/",
"/boot",
"/boot/efi",
"/efi",
"/frzr_root",
"/frzr_root/boot",
"/home",
"/var",
"/var/cache",
"/var/log",
]

var format_capable: bool = false
var init_capable: bool = false
var format_sd_capable: bool = false
var retrigger_capable: bool = false
var trim_capable: bool = false


signal drives_updated(device_tree: Array[BlockDevice])

## Hierarchy of drive -> block device -> partitions -> mount points
## Used to display device information to the user.
var device_tree: Array[BlockDevice]

func _init() -> void:
if not udisks2.supports_disk_management():
return

# Check the required system files exist for steam_removable_media
if FileAccess.file_exists(SRM_FORMAT_MEDIA):
Expand All @@ -61,181 +44,142 @@ func _init() -> void:
if FileAccess.file_exists(STEAMOS_TRIM_DEVICES):
trim_capable = true

logger.debug("format_capable: " + str(format_capable))
logger.debug("init_capable: " + str(init_capable))
logger.debug("format_sd_capable: " + str(format_sd_capable))
logger.debug("retrigger_capable: " + str(retrigger_capable))
logger.debug("trim_capable: " + str(trim_capable))

# Get the current drives and ensure they are always up to date
udisks2.devices_updated.connect(update_drives)
update_drives()


## Rebuilds the device_tree with the current device list
func update_drives(devices: Array[BlockDevice] = []):
if devices == []:
logger.debug("Got empty array, grabbing devices from udisks2")
devices = udisks2.get_devices()
self.device_tree = []
for block in devices:
if not _block_device_has_protected_mount(block):
logger.debug(block.dbus_path, "has no protected mounts.")
device_tree.append(block)
self.drives_updated.emit(self.device_tree)
logger.debug("format_capable:", format_capable)
logger.debug("init_capable:", init_capable)
logger.debug("format_sd_capable:", format_sd_capable)
logger.debug("retrigger_capable:", retrigger_capable)
logger.debug("trim_capable:", trim_capable)


## Calls the SteamRemovableMedia format-media script to format a drive as EXT4
## and intialize it as a steam library
func format_drive(device: BlockDevice) -> void:
func format_drive(device: BlockDevice) -> Error:
if not format_capable:
logger.error("System is not format capable")
return
return ERR_UNAVAILABLE

# This should never hit if using our device tree, but the method is public so
# make sure.
if _block_device_has_protected_mount(device):
if udisks2.block_device_has_protected_mount(device):
logger.error("Attempted to format device with protected mount. Illegal Operation.")
return
return ERR_UNAUTHORIZED

var drive = "/dev" + device.dbus_path.trim_prefix(BLOCK_PREFIX)
logger.debug("Formatting drive: " + drive)
logger.debug("Formatting drive:", drive)
var args := ["--full", "--device", drive]
var result = await _execute_in_thread(SRM_FORMAT_MEDIA, args)
logger.debug("Got results: " + str(result[0]), str(result[1]))

logger.debug("Got results: ", result[0], result[1])
var success: bool = result[1] == 0
device.format_complete.emit(success)
if success:
return OK
return ERR_SCRIPT_FAILED


## Calls the SteamRemovableMedia init-media script to intialize a drive as a
## steam library
func init_steam_lib(partition: PartitionDevice) -> void:
func init_steam_lib(partition: PartitionDevice) -> Error:
if not init_capable:
logger.error("System cannot initialize steam libraries")
return
return ERR_UNAVAILABLE

# This should never hit if using our device tree, but the method is public so
# make sure.
if _partition_has_protected_mount(partition):
if udisks2.partition_has_protected_mount(partition):
logger.error("Attempted to initialize steam library on device with protected mount. Illegal Operation.")
return
return ERR_UNAUTHORIZED

var drive = "/dev" + partition.dbus_path.trim_prefix(BLOCK_PREFIX)
var drive := "/dev" + partition.dbus_path.trim_prefix(BLOCK_PREFIX)
logger.debug("Intitializing partition as Steam Library: " + drive)
var args := [drive]
var result = await _execute_in_thread(SRM_INIT_MEDIA, args)
logger.debug("Got results: " + str(result[0]), str(result[1]))
logger.debug("Got results:", result[0], result[1])

var success: bool = result[1] == 0
partition.init_complete.emit(success)
if success:
return OK
return ERR_SCRIPT_FAILED


## Calls the SteamRemovableMedia or SteamOS retrigger-automounts script to
## restart all the media-mount@ scripts.
func retrigger_automounts() -> void:
func retrigger_automounts() -> Error:
if not retrigger_capable:
logger.error("System is not retrigger capable")
return
return ERR_UNAVAILABLE

logger.debug("Retriggering Steam Automounts")
var result = await _execute_in_thread(STEAMOS_RETRIGGER_AUTOMOUNTS)
logger.debug("Got results: " + str(result[0]), str(result[1]))
logger.debug("Got results:", result[0], result[1])

var success: bool = result[1] == 0
#retrigger_complete.emit(success)
if success:
return OK
return ERR_SCRIPT_FAILED


## Calls the SteamRemovableMedia or SteamOS format-sd script to format mmcblk0
## as EXT4 and intialize it as a steam library
func format_sd_card() -> void:
func format_sd_card() -> Error:
if not format_sd_capable:
logger.error("System is not format capable")
return
return ERR_UNAVAILABLE

# Make sure the sd card isn't being used as a protected drive.
var sd_card: BlockDevice
for block in device_tree:
for block in udisks2.get_unprotected_devices():
if not block.dbus_path.contains("mmcblk0"):
continue
sd_card = block
if not sd_card:
logger.warn("Unable to find SD Card!")
return
if _block_device_has_protected_mount(sd_card):
logger.warn("Attempted to format SD Card with protected mount!")
return
return ERR_UNAUTHORIZED

logger.debug("Formatting SD Card: mmcblk0")
var result = await _execute_in_thread(STEAMOS_FORMAT_SDCARD)
logger.debug("Got results: " + str(result[0]), str(result[1]))
logger.debug("Got results:", result[0], result[1])

var success: bool = result[1] == 0
sd_card.format_complete.emit(success)
if success:
return OK
return ERR_SCRIPT_FAILED


## Calls the SteamRemovableMedia or SteamOS trim-devices script to perform a
## trim operation on mmcblk0.
func trim_sd_card() -> void:
func trim_sd_card() -> Error:
if not trim_capable:
logger.error("System is not trim capable")
return
return ERR_UNAVAILABLE

# Make sure the sd card isn't being used as a protected drive.
var sd_card: BlockDevice
for block in device_tree:
for block in udisks2.get_unprotected_devices():
if not block.dbus_path.contains("mmcblk0"):
continue
sd_card = block

if not sd_card:
logger.warn("Unable to find SD Card!")
return
if _block_device_has_protected_mount(sd_card):
logger.warn("Attempted to format SD Card with protected mount!")
return
return ERR_UNAUTHORIZED

logger.debug("Performing TRIM operation on SD Card: mmcblk0")
var result = await _execute_in_thread(STEAMOS_TRIM_DEVICES)
logger.debug("Got results: " + str(result[0]), str(result[1]))
logger.debug("Got results:", result[0], result[1])

var success: bool = result[1] == 0
sd_card.trim_complete.emit(success)


## Finds all partitions of the given block device and returns true if any of
## them have mounts in the protected_mounts list.
func _block_device_has_protected_mount(device: BlockDevice) -> bool:
logger.debug("Checking block device", device.dbus_path, "for protected mounts.")
# Get all the partition dbus paths of this block device
for partition in device.partitions:
if _partition_has_protected_mount(partition):
return true
return false


## Loops through all mount points of the given partition and returns true if any of
## them have mounts in the protected_mounts list.
func _partition_has_protected_mount(device: PartitionDevice) -> bool:
logger.debug("Checking partition", device.dbus_path, "for protected mounts.")
for mount_point in device.fs_mount_points:
logger.debug("Checking mount point", mount_point, "for protected mounts.")
if mount_point in protected_mounts:
logger.debug("Found a protected mount point on drive: " + device.dbus_path)
return true
return false

if success:
return OK
return ERR_SCRIPT_FAILED


func _execute_in_thread(path: String, args: Array = []) -> Array:
var thread: SharedThread = SharedThread.new()
thread.watchdog_enabled = false
block_operations = true
var thread_options := SharedThread.Option.NONE
var thread := SharedThread.new(thread_options)
thread.start()
var result = await thread.exec(_exec_call.bind(path, args))
var cmd := Command.new(path, args, thread)
var code := await cmd.execute() as int
thread.stop()
return result


## Executes the given command and arguments
func _exec_call(path: String, args: Array = []) -> Array:
var output = []
var exit_code := OS.execute(path, args, output)
return [output, exit_code]
block_operations = false
return [cmd.stdout, code]
69 changes: 64 additions & 5 deletions core/systems/disks/udisks2.gd
Original file line number Diff line number Diff line change
Expand Up @@ -21,21 +21,50 @@ const IFACE_PARTITION_TABLE := UDISKS2_BUS + ".PartitionTable"
const IFACE_DRIVE := UDISKS2_BUS + ".Drive"
const IFACE_NVME_CONTROLLER := UDISKS2_BUS + ".NVMe.Controller"

const protected_mounts = [
"/",
"/boot",
"/boot/efi",
"/efi",
"/frzr_root",
"/frzr_root/boot",
"/home",
"/var",
"/var/cache",
"/var/log",
]

var dbus := load("res://core/global/dbus_system.tres") as DBusManager
var manager := Manager.new(dbus.create_proxy(UDISKS2_BUS, UDISKS2_MANAGER_PATH))
var object_manager := dbus.ObjectManager.new(dbus.create_proxy(UDISKS2_BUS, UDISKS2_PATH))

signal devices_updated(devices: Array[BlockDevice])
signal unprotected_devices_updated(unprotected_devices: Array[BlockDevice])

var logger := Log.get_logger("UDisks2", Log.LEVEL.INFO)


## Returns true if UDisks2 can be used on this system
func supports_disk_management() -> bool:
return true
return dbus.bus_exists(UDISKS2_BUS)


func _init() -> void:
logger.debug("Initalizing UDisks2 Dbus interface.")
object_manager.interfaces_added.connect(_drives_updated)
object_manager.interfaces_removed.connect(_drives_updated)


## Signals when a changes to drives are detected
func _drives_updated(iface: String) -> void:
logger.trace("Update from interface:", iface)
var devices = get_devices()
devices_updated.emit(devices)
var unprotected_devices = get_unprotected_devices(devices)
unprotected_devices_updated.emit(unprotected_devices)


## Returns all the current block devices detected by UDisks2
func get_devices() -> Array[BlockDevice]:
var block_array: Array[BlockDevice] = []
Expand Down Expand Up @@ -81,14 +110,44 @@ func get_devices() -> Array[BlockDevice]:
for drive in drive_array:
if block.drive_path == drive.dbus_path:
block.drive = drive

return block_array


## Signals when a changes to drives are detected
func _drives_updated(iface: String) -> void:
logger.trace("Update from interface:", iface)
var devices = get_devices()
self.devices_updated.emit(devices)
## Returns all current devices that don't have protected mounts
func get_unprotected_devices(devices: Array[BlockDevice] = []):
var device_tree: Array[BlockDevice]
if devices == []:
logger.debug("Got empty array, grabbing devices from udisks2")
devices = get_devices()
for block in devices:
if not block_device_has_protected_mount(block):
logger.debug(block.dbus_path, "has no protected mounts.")
device_tree.append(block)
return device_tree


## Finds all partitions of the given block device and returns true if any of
## them have mounts in the protected_mounts list.
func block_device_has_protected_mount(device: BlockDevice) -> bool:
logger.debug("Checking block device", device.dbus_path, "for protected mounts.")
# Get all the partition dbus paths of this block device
for partition in device.partitions:
if partition_has_protected_mount(partition):
return true
return false


## Loops through all mount points of the given partition and returns true if any of
## them have mounts in the protected_mounts list.
func partition_has_protected_mount(device: PartitionDevice) -> bool:
logger.debug("Checking partition", device.dbus_path, "for protected mounts.")
for mount_point in device.fs_mount_points:
logger.debug("Checking mount point", mount_point, "for protected mounts.")
if mount_point in protected_mounts:
logger.debug("Found a protected mount point on drive: " + device.dbus_path)
return true
return false


func _id_type(device: DriveDevice) -> DriveDevice.INTERFACE_TYPE:
Expand Down
Loading

0 comments on commit 54fba3c

Please sign in to comment.