mirror of
https://github.com/freemkv/libfreemkv.git
synced 2026-10-07 18:13:10 +00:00
fix(macos): keep optical drive identity stable during exclusive access
This commit is contained in:
@@ -1,5 +1,9 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
## Unreleased
|
||||||
|
|
||||||
|
- macOS optical-drive enumeration keeps the same IOKit service selector with or without mounted media, so exclusive access during a rip does not turn one drive into two identities.
|
||||||
|
|
||||||
## [1.8.0] — 2026-10-05
|
## [1.8.0] — 2026-10-05
|
||||||
|
|
||||||
### Breaking
|
### Breaking
|
||||||
|
|||||||
@@ -179,10 +179,9 @@ static int registry_entry_bsd_name(io_registry_entry_t entry, char *buf, size_t
|
|||||||
return ok;
|
return ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Empty optical drives have a service node but no IOMedia node, hence
|
// Optical services outlive their IOMedia nodes, which disappear for an empty
|
||||||
// no BSD diskN name. Use the service's IOKit registry ID as an opaque selector
|
// tray and during exclusive access. Use the service registry ID as the stable
|
||||||
// until media appears. It is process/boot-local, which is sufficient for the
|
// selector throughout insertion, ripping and ejection (until unplug/reboot).
|
||||||
// list-then-open GUI flow.
|
|
||||||
static int registry_id_selector(io_registry_entry_t entry, char *buf, size_t buflen) {
|
static int registry_id_selector(io_registry_entry_t entry, char *buf, size_t buflen) {
|
||||||
uint64_t registry_id = 0;
|
uint64_t registry_id = 0;
|
||||||
if (IORegistryEntryGetRegistryEntryID(entry, ®istry_id) != KERN_SUCCESS) return 0;
|
if (IORegistryEntryGetRegistryEntryID(entry, ®istry_id) != KERN_SUCCESS) return 0;
|
||||||
@@ -864,9 +863,10 @@ static int visit_list(io_service_t svc, void *ctx) {
|
|||||||
memset(info, 0, sizeof(*info));
|
memset(info, 0, sizeof(*info));
|
||||||
|
|
||||||
bdsvc_device_info(svc, info);
|
bdsvc_device_info(svc, info);
|
||||||
if (!bdsvc_to_bsd_name(svc, info->device_selector, sizeof(info->device_selector))) {
|
// IOMedia (and its diskN name) disappears during exclusive access. The
|
||||||
registry_id_selector(svc, info->device_selector, sizeof(info->device_selector));
|
// optical service survives: always use its ID so a busy drive cannot be
|
||||||
}
|
// enumerated as a second, apparently empty drive after opening it.
|
||||||
|
registry_id_selector(svc, info->device_selector, sizeof(info->device_selector));
|
||||||
if (info->device_selector[0]) lc->count++;
|
if (info->device_selector[0]) lc->count++;
|
||||||
return lc->count >= lc->max ? 2 : 0;
|
return lc->count >= lc->max ? 2 : 0;
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -561,8 +561,8 @@ pub(crate) fn open_with(device: &Path, halt: &crate::halt::Halt) -> Result<Box<d
|
|||||||
/// no firmware reset, no init.
|
/// no firmware reset, no init.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct DriveInfo {
|
pub struct DriveInfo {
|
||||||
/// Platform device path: `/dev/sgN` (Linux), `/dev/diskN` or an opaque
|
/// Platform device path: `/dev/sgN` (Linux), a stable optical-service
|
||||||
/// `ioreg:<id>` selector for an empty optical drive (macOS), `\\.\CdRomN`
|
/// `ioreg:<id>` selector (macOS), `\\.\CdRomN`
|
||||||
/// (Windows).
|
/// (Windows).
|
||||||
pub path: String,
|
pub path: String,
|
||||||
/// SCSI INQUIRY vendor identifier (e.g. `"HL-DT-ST"`).
|
/// SCSI INQUIRY vendor identifier (e.g. `"HL-DT-ST"`).
|
||||||
|
|||||||
Reference in New Issue
Block a user