Fix dashcam detection for whole-disk (superfloppy) SD card formats
First real-hardware test revealed the connected dashcam's SD card ships factory-formatted with no partition table - lsblk reports it as a bare "disk" with an fstype set directly, never as a child "part". The previous detection logic only matched type=="part", so it silently missed this real device entirely. list_usb_storage_partitions() now also matches whole-disk USB devices that have no children and an fstype set directly on them, in addition to the existing partition-table case. Verified against a fixture built from this dashcam's actual `lsblk -J` output. Co-authored-by: Copilot <[email protected]>
This commit is contained in:
+20
-7
@@ -7,12 +7,14 @@ etc. - all common dashcam brands are covered since we just walk the whole
|
|||||||
filesystem for video extensions instead of assuming a specific folder name),
|
filesystem for video extensions instead of assuming a specific folder name),
|
||||||
then unmounts it again.
|
then unmounts it again.
|
||||||
|
|
||||||
Detection is done via `lsblk`, filtering for partitions whose parent disk is
|
Detection is done via `lsblk`, filtering for volumes whose parent disk is
|
||||||
attached over USB (TRAN == "usb"). This is what actually distinguishes a
|
attached over USB (TRAN == "usb"). This is what actually distinguishes a
|
||||||
plugged-in dashcam/USB stick from the Pi's own storage (the boot/root
|
plugged-in dashcam/USB stick from the Pi's own storage (the boot/root
|
||||||
partitions are on the onboard SD card, transport "mmc", never "usb") - so
|
partitions are on the onboard SD card, transport "mmc", never "usb") - so
|
||||||
it's safe to run against real hardware without risk of touching the Pi's own
|
it's safe to run against real hardware without risk of touching the Pi's own
|
||||||
filesystem, regardless of which /dev/sdX letter the kernel happens to assign.
|
filesystem, regardless of which /dev/sdX letter the kernel happens to assign.
|
||||||
|
Both real partitions and whole-disk "superfloppy" (no partition table)
|
||||||
|
layouts are matched - some dashcam SD cards ship factory-formatted that way.
|
||||||
"""
|
"""
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
@@ -32,12 +34,19 @@ DEFAULT_DESTINATION = os.path.join(
|
|||||||
|
|
||||||
|
|
||||||
def list_usb_storage_partitions():
|
def list_usb_storage_partitions():
|
||||||
"""Return a list of dicts describing USB-attached storage partitions.
|
"""Return a list of dicts describing USB-attached storage volumes.
|
||||||
|
|
||||||
Each dict has: path, fstype, label, size, mountpoint. Only partitions
|
Each dict has: path, fstype, label, size, mountpoint. Only volumes whose
|
||||||
whose parent disk reports TRAN "usb" are included - this is what makes
|
parent disk reports TRAN "usb" are included - this is what makes the
|
||||||
the detection brand/device-agnostic (no hardcoded /dev/sda) while still
|
detection brand/device-agnostic (no hardcoded /dev/sda) while still
|
||||||
being safe (never matches the Pi's own onboard mmc storage).
|
being safe (never matches the Pi's own onboard mmc storage).
|
||||||
|
|
||||||
|
Includes both real partitions (type "part", the common case) *and*
|
||||||
|
whole-disk USB devices with an `fstype` set directly on them (type
|
||||||
|
"disk" but no partition table - a "superfloppy" layout with no MBR/GPT).
|
||||||
|
Several real dashcam SD cards ship formatted this way straight from the
|
||||||
|
factory - lsblk reports them as a bare "disk" with an fstype, never as a
|
||||||
|
child "part", so excluding them would silently miss those cameras.
|
||||||
"""
|
"""
|
||||||
try:
|
try:
|
||||||
result = subprocess.run(
|
result = subprocess.run(
|
||||||
@@ -61,7 +70,12 @@ def list_usb_storage_partitions():
|
|||||||
def walk(devices, inherited_tran=None):
|
def walk(devices, inherited_tran=None):
|
||||||
for device in devices:
|
for device in devices:
|
||||||
tran = device.get("tran") or inherited_tran
|
tran = device.get("tran") or inherited_tran
|
||||||
if device.get("type") == "part" and tran == "usb":
|
children = device.get("children") or []
|
||||||
|
is_partition = device.get("type") == "part"
|
||||||
|
is_superfloppy_disk = (
|
||||||
|
device.get("type") == "disk" and not children and device.get("fstype")
|
||||||
|
)
|
||||||
|
if tran == "usb" and (is_partition or is_superfloppy_disk):
|
||||||
partitions.append(
|
partitions.append(
|
||||||
{
|
{
|
||||||
"path": device.get("path"),
|
"path": device.get("path"),
|
||||||
@@ -71,7 +85,6 @@ def list_usb_storage_partitions():
|
|||||||
"mountpoint": device.get("mountpoint"),
|
"mountpoint": device.get("mountpoint"),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
children = device.get("children") or []
|
|
||||||
if children:
|
if children:
|
||||||
walk(children, tran)
|
walk(children, tran)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user