Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
user:rion [2026/10/05 00:47] – rionuser:rion [2026/10/05 12:04] (current) – rion
Line 12: Line 12:
 The Storage Manager introduced in Batocera v43 allows multiple locally attached drives to be combined into a single ROM library without requiring symbolic links, manual mounts, or custom scripts. The Storage Manager introduced in Batocera v43 allows multiple locally attached drives to be combined into a single ROM library without requiring symbolic links, manual mounts, or custom scripts.
  
-Advanced users can also create manual MergerFS pools that include network/NAS mounts. This is configured in ''/boot/batocera-boot.conf'' and is not managed by the Storage Manager user interface. See [[#network_nas_storage_advanced|Network/NAS Storage (Advanced)]].+Advanced network/NAS and manual MergerFS setups are documented later on this page, after the Storage Manager limitations. Most users with locally attached storage do not need that configuration.
 </WRAP> </WRAP>
  
Line 55: Line 55:
 /userdata/roms /userdata/roms
 </code> </code>
- 
-==== Which storage method should I use? ==== 
- 
-Batocera has several storage mechanisms that solve different problems. They should not be treated as interchangeable. 
- 
-^ Method ^ Best used for ^ What it does ^ 
-| **Storage Manager** | Multiple locally attached ROM drives | Builds a MergerFS union at ''/userdata/roms'' and manages it from EmulationStation | 
-| **sharedevice=DEV / ANYEXTERNAL** | Moving all userdata to one selected device, or to the first suitable external device | Mounts another device as the active userdata storage | 
-| **sharedevice=DEVICES** | Mounting selected local partitions or subdirectories over specific userdata folders | Bind-mounts selected local storage over individual targets such as ROMS, SAVES or BIOS | 
-| **sharedevice=NETWORK** | Replacing all or selected userdata folders with SMB/NFS shares | Mounts network storage directly on the requested userdata paths | 
-| **Manual S12mergerfs pool** | Combining local folders and network/NAS folders in one union | Builds an advanced MergerFS pool from explicitly configured branches | 
- 
-<WRAP tip> 
-If the goal is simply to add a second, third or fourth locally attached ROM drive, use the graphical Storage Manager. If the goal is to combine a NAS with local ROM storage in the same ''/userdata/roms'' namespace, use the advanced manual MergerFS method documented below. 
-</WRAP> 
  
 ===== Requirements ===== ===== Requirements =====
Line 207: Line 192:
  
 Games can be distributed across multiple drives while still appearing as one collection inside EmulationStation. Games can be distributed across multiple drives while still appearing as one collection inside EmulationStation.
 +
 +===== Internal Drives =====
 +
 +The Storage Manager is not limited to removable USB devices.
 +
 +Additional internal drives can also be used.
 +
 +For example:
 +
 +<code>
 +/media/roms1/roms
 +/media/roms2/roms
 +</code>
 +
 +As long as the drive is mounted by Batocera and contains a root-level ''roms'' folder, it can be merged into the Storage Manager.
 +
 +This includes:
 +
 +  * SATA hard drives
 +  * SATA SSDs
 +  * NVMe SSDs
 +  * USB storage devices
 +  * SD cards
 +
 +<WRAP info>
 +The drive name does not matter. What matters is that the mounted drive contains a root-level ''roms'' folder.
 +</WRAP>
 +
 +==== Automatic detection and safety filtering ====
 +
 +The Storage Manager backend watches the common Linux block-device families used by Batocera, including ''sdX'', NVMe and MMC devices. Its explicit initial-scan and ignore re-detection loops enumerate those device families, so unusual block-device classes are better handled through the manual storage mechanisms unless they are known to trigger the Storage Manager through another Batocera path. The backend also contains several safety filters intended to avoid treating system, firmware and recovery storage as game disks.
 +
 +Among other checks, the current implementation:
 +
 +  * Skips the disk backing ''/boot'' or ''/userdata''
 +  * Skips EFI System, Microsoft Reserved and Windows Recovery partition GUIDs
 +  * Skips partitions marked hidden or no-automount
 +  * Filters many Android/Qualcomm firmware and system partition labels
 +  * Does not offer the automatic blank-disk format prompt for disks of 4 GiB or smaller
 +  * Ignores swap partitions
 +  * Skips local disks already claimed by UUID-based ''sharedevice...'' manual configuration
 +
 +These checks are safeguards, not a substitute for verifying the disk shown by a format prompt. Always confirm the device and capacity before formatting.
 +
 +<WRAP info>
 +Some of the protection checks intentionally use broad filesystem-label and partition-label matches. External media using names associated with system partitions, for example ''userdata'', ''recovery'', ''vendor'' or ''persist'', can therefore be skipped by automatic detection. If a perfectly usable external partition does not appear in Storage Manager, its filesystem label and partition label are worth checking in ''/var/log/batocera-storage.log''.
 +</WRAP>
 +
 +==== Ignoring a drive ====
 +
 +The Storage Manager backend supports an ''ignore.drives'' list in ''/boot/batocera-boot.conf''. Ignoring a drive disables Storage Manager automation for that drive. It does not necessarily prevent Batocera from mounting a readable partition.
 +
 +If an ignored drive contains a root-level ''roms'' directory, the drive can remain mounted under ''/media'', but Storage Manager will skip adding it to the ROM pool or prompting to merge it. Blank ignored drives also do not trigger the format prompt.
 +
 +The ignore entry is based on a persistent **whole-disk** identifier when one is available, rather than only on a temporary ''/dev/sdX'' name. In practice, ignoring a physical disk disables Storage Manager automation for its partitions as well.
 +
 +The current backend provides an ''ignore'' action but no matching ''unignore'' action. The persistent state is simply the space-separated ''ignore.drives'' value in ''/boot/batocera-boot.conf''. To reverse an ignore, that stored identifier has to be removed from the configuration and the drive re-detected, reconnected or detected again after a reboot.
 +
 +==== Mount-point naming ====
 +
 +For automatically mounted partitions, Storage Manager builds a mount point under ''/media''. If the filesystem has a label, the sanitized label is used; otherwise the partition device name is used. If that mount point already exists, a numeric suffix such as ''_1'' is added.
 +
 +<WRAP tip>
 +Use unique filesystem labels for ROM drives. The Storage Manager configuration stores branch paths such as ''/media/MyDrive/roms''. Duplicate labels can produce suffixed mount points and make path identity less predictable across reconnects.
 +</WRAP>
 +
 +===== Safe Drive Removal =====
 +
 +
 +
 +Drives can be safely removed from:
 +
 +  * **Main Menu**
 +  * **System Settings**
 +  * **Eject an Extra Disk**
 +
 +{{wiki:use_external_storage_safe_eject_menu.png?nolink&576|Safe eject menu}}
 +
 +After selecting the drive, Batocera asks for confirmation before removing it from the storage pool.
 +
 +{{wiki:use_external_storage_safe_eject_confirmation.png?nolink&576|Eject confirmation}}
 +
 +Batocera automatically updates the storage pool and refreshes the game lists.
 +
 +{{wiki:use_external_storage_drive_ejected.png?nolink&576|Drive ejected}}
 +
 +Games stored only on the removed drive will disappear from the library until that drive is connected and merged again.
 +
 +The **Eject an Extra Disk** list is generated from branches saved in ''mergerfs.roms''. It is therefore a list of drives currently managed as Storage Manager pool branches, not a generic eject list for every filesystem mounted under ''/media''.
 +
 +<WRAP important>
 +Prefer the Storage Manager eject action over physically unplugging a drive while Batocera is running. The backend has cleanup logic for an unexpected removal, but active writes cannot be made safe after the device has already disappeared.
 +</WRAP>
 +
 +==== Missing at boot, safe eject, and live unplug are different ====
 +
 +The Storage Manager keeps configured branches in ''mergerfs.roms''. During a pool refresh, a branch whose directory is currently missing is skipped from the live pool rather than automatically deleted from the saved configuration. If that same drive later appears again at the same mount path, Storage Manager can refresh the pool and re-add it automatically.
 +
 +By contrast, using **Eject an Extra Disk** removes that branch from ''mergerfs.roms''. A live unplug event is also routed through the eject/cleanup path when Batocera can identify the removed mount. In those cases, reconnecting the drive requires it to be merged again.
 +
 +This distinction is useful for systems where a configured drive is sometimes powered off before Batocera boots. Leaving it configured but absent at boot is different from explicitly ejecting it.
 +
 +===== What Gets Merged? =====
 +
 +The graphical Storage Manager merges only the ROM library:
 +
 +<code>
 +/userdata/roms
 +</code>
 +
 +Folders such as:
 +
 +<code>
 +/userdata/bios
 +/userdata/saves
 +/userdata/screenshots
 +/userdata/themes
 +/userdata/music
 +</code>
 +
 +remain on internal storage.
 +
 +The graphical Storage Manager does not merge BIOS files, save files, screenshots, themes, or music.
 +
 +Advanced manual MergerFS pools are separate from the graphical Storage Manager and can technically target other directories, but those pools are not managed by the Storage Manager interface.
 +
 +===== Internal ROM Preservation =====
 +
 +When the first additional ROM drive is merged, Batocera preserves the existing internal ROM collection.
 +
 +Internally, existing ROMs stored in:
 +
 +<code>
 +/userdata/roms
 +</code>
 +
 +are moved into:
 +
 +<code>
 +/userdata/.roms_base
 +</code>
 +
 +This allows internal ROMs to remain visible alongside ROMs stored on merged drives.
 +
 +If all merged drives are later removed, Batocera restores the internal ROM library back to the normal ''/userdata/roms'' location.
 +
 +During restoration, the current implementation uses ''rsync --ignore-existing''. Existing destination files are therefore not overwritten by files of the same name from ''.roms_base''. If restoration fails, Batocera keeps ''.roms_base'' instead of deleting it so the preserved data is not discarded.
 +
 +===== Limitations =====
 +
 +Automatic detection by the graphical Storage Manager currently requires this layout:
 +
 +<code>
 +<drive>/roms
 +</code>
 +
 +Nested ROM folders are not detected automatically.
 +
 +Example:
 +
 +<code>
 +<drive>/Batocera/roms
 +</code>
 +
 +is not automatically merged.
 +
 +This limitation does not apply to advanced manual MergerFS branches, where an explicit nested path can be configured.
 +
 +The graphical Storage Manager merges only the ROM library. Other userdata folders remain independent unless they are configured separately using advanced manual storage methods.
 +
 +<WRAP tip>
 +For most users adding locally attached USB drives, SSDs, hard drives or SD cards, the Storage Manager sections above are all that is needed.
 +
 +The remaining sections are for advanced setups, manual storage configuration, network/NAS integration, implementation details and troubleshooting.
 +</WRAP>
 +
 +===== Other Storage Methods (Advanced) =====
 +
 +Batocera has several storage mechanisms that solve different problems. They should not be treated as interchangeable.
 +
 +^ Method ^ Best used for ^ What it does ^
 +| **Storage Manager** | Multiple locally attached ROM drives | Builds a MergerFS union at ''/userdata/roms'' and manages it from EmulationStation |
 +| **sharedevice=DEV / ANYEXTERNAL** | Moving all userdata to one selected device, or to the first suitable external device | Mounts another device as the active userdata storage |
 +| **sharedevice=DEVICES** | Mounting selected local partitions or subdirectories over specific userdata folders | Bind-mounts selected local storage over individual targets such as ROMS, SAVES or BIOS |
 +| **sharedevice=NETWORK** | Replacing all or selected userdata folders with SMB/NFS shares | Mounts network storage directly on the requested userdata paths |
 +| **Manual S12mergerfs pool** | Combining local folders and network/NAS folders in one union | Builds an advanced MergerFS pool from explicitly configured branches |
 +
 +<WRAP tip>
 +If the goal is simply to add a second, third or fourth locally attached ROM drive, use the graphical Storage Manager. If the goal is to combine a NAS with local ROM storage in the same ''/userdata/roms'' namespace, use the advanced manual MergerFS method documented below.
 +</WRAP>
  
 ===== Network/NAS Storage (Advanced) ===== ===== Network/NAS Storage (Advanced) =====
 +
 +<WRAP important>
 +This section is **not required for normal Storage Manager use**. If all ROM drives are attached locally, use the graphical Storage Manager described above.
 +</WRAP>
  
 The graphical Storage Manager currently focuses on locally attached storage devices. Batocera also includes a separate boot-time MergerFS service that can build manual pools from local storage, removable media and already-mounted network shares. The graphical Storage Manager currently focuses on locally attached storage devices. Batocera also includes a separate boot-time MergerFS service that can build manual pools from local storage, removable media and already-mounted network shares.
Line 398: Line 577:
  
 This explains why an already-configured ROM drive detected during early boot can be queued first and only joined to the live pool after the base ''/userdata'' storage has finished mounting. This explains why an already-configured ROM drive detected during early boot can be queued first and only joined to the live pool after the base ''/userdata'' storage has finished mounting.
- 
-===== Internal Drives ===== 
- 
-The Storage Manager is not limited to removable USB devices. 
- 
-Additional internal drives can also be used. 
- 
-For example: 
- 
-<code> 
-/media/roms1/roms 
-/media/roms2/roms 
-</code> 
- 
-As long as the drive is mounted by Batocera and contains a root-level ''roms'' folder, it can be merged into the Storage Manager. 
- 
-This includes: 
- 
-  * SATA hard drives 
-  * SATA SSDs 
-  * NVMe SSDs 
-  * USB storage devices 
-  * SD cards 
- 
-<WRAP info> 
-The drive name does not matter. What matters is that the mounted drive contains a root-level ''roms'' folder. 
-</WRAP> 
- 
-==== Automatic detection and safety filtering ==== 
- 
-The Storage Manager backend watches the common Linux block-device families used by Batocera, including ''sdX'', NVMe and MMC devices. Its explicit initial-scan and ignore re-detection loops enumerate those device families, so unusual block-device classes are better handled through the manual storage mechanisms unless they are known to trigger the Storage Manager through another Batocera path. The backend also contains several safety filters intended to avoid treating system, firmware and recovery storage as game disks. 
- 
-Among other checks, the current implementation: 
- 
-  * Skips the disk backing ''/boot'' or ''/userdata'' 
-  * Skips EFI System, Microsoft Reserved and Windows Recovery partition GUIDs 
-  * Skips partitions marked hidden or no-automount 
-  * Filters many Android/Qualcomm firmware and system partition labels 
-  * Does not offer the automatic blank-disk format prompt for disks of 4 GiB or smaller 
-  * Ignores swap partitions 
-  * Skips local disks already claimed by UUID-based ''sharedevice...'' manual configuration 
- 
-These checks are safeguards, not a substitute for verifying the disk shown by a format prompt. Always confirm the device and capacity before formatting. 
- 
-<WRAP info> 
-Some of the protection checks intentionally use broad filesystem-label and partition-label matches. External media using names associated with system partitions, for example ''userdata'', ''recovery'', ''vendor'' or ''persist'', can therefore be skipped by automatic detection. If a perfectly usable external partition does not appear in Storage Manager, its filesystem label and partition label are worth checking in ''/var/log/batocera-storage.log''. 
-</WRAP> 
- 
-==== Ignoring a drive ==== 
- 
-The Storage Manager backend supports an ''ignore.drives'' list in ''/boot/batocera-boot.conf''. Ignoring a drive disables Storage Manager automation for that drive. It does not necessarily prevent Batocera from mounting a readable partition. 
- 
-If an ignored drive contains a root-level ''roms'' directory, the drive can remain mounted under ''/media'', but Storage Manager will skip adding it to the ROM pool or prompting to merge it. Blank ignored drives also do not trigger the format prompt. 
- 
-The ignore entry is based on a persistent **whole-disk** identifier when one is available, rather than only on a temporary ''/dev/sdX'' name. In practice, ignoring a physical disk disables Storage Manager automation for its partitions as well. 
- 
-The current backend provides an ''ignore'' action but no matching ''unignore'' action. The persistent state is simply the space-separated ''ignore.drives'' value in ''/boot/batocera-boot.conf''. To reverse an ignore, that stored identifier has to be removed from the configuration and the drive re-detected, reconnected or detected again after a reboot. 
- 
-==== Mount-point naming ==== 
- 
-For automatically mounted partitions, Storage Manager builds a mount point under ''/media''. If the filesystem has a label, the sanitized label is used; otherwise the partition device name is used. If that mount point already exists, a numeric suffix such as ''_1'' is added. 
- 
-<WRAP tip> 
-Use unique filesystem labels for ROM drives. The Storage Manager configuration stores branch paths such as ''/media/MyDrive/roms''. Duplicate labels can produce suffixed mount points and make path identity less predictable across reconnects. 
-</WRAP> 
- 
-===== Safe Drive Removal ===== 
- 
-  
- 
-Drives can be safely removed from: 
- 
-  * **Main Menu** 
-  * **System Settings** 
-  * **Eject an Extra Disk** 
- 
-{{wiki:use_external_storage_safe_eject_menu.png?nolink&576|Safe eject menu}} 
- 
-After selecting the drive, Batocera asks for confirmation before removing it from the storage pool. 
- 
-{{wiki:use_external_storage_safe_eject_confirmation.png?nolink&576|Eject confirmation}} 
- 
-Batocera automatically updates the storage pool and refreshes the game lists. 
- 
-{{wiki:use_external_storage_drive_ejected.png?nolink&576|Drive ejected}} 
- 
-Games stored only on the removed drive will disappear from the library until that drive is connected and merged again. 
- 
-The **Eject an Extra Disk** list is generated from branches saved in ''mergerfs.roms''. It is therefore a list of drives currently managed as Storage Manager pool branches, not a generic eject list for every filesystem mounted under ''/media''. 
- 
-<WRAP important> 
-Prefer the Storage Manager eject action over physically unplugging a drive while Batocera is running. The backend has cleanup logic for an unexpected removal, but active writes cannot be made safe after the device has already disappeared. 
-</WRAP> 
- 
-==== Missing at boot, safe eject, and live unplug are different ==== 
- 
-The Storage Manager keeps configured branches in ''mergerfs.roms''. During a pool refresh, a branch whose directory is currently missing is skipped from the live pool rather than automatically deleted from the saved configuration. If that same drive later appears again at the same mount path, Storage Manager can refresh the pool and re-add it automatically. 
- 
-By contrast, using **Eject an Extra Disk** removes that branch from ''mergerfs.roms''. A live unplug event is also routed through the eject/cleanup path when Batocera can identify the removed mount. In those cases, reconnecting the drive requires it to be merged again. 
- 
-This distinction is useful for systems where a configured drive is sometimes powered off before Batocera boots. Leaving it configured but absent at boot is different from explicitly ejecting it. 
- 
-===== What Gets Merged? ===== 
- 
-The graphical Storage Manager merges only the ROM library: 
- 
-<code> 
-/userdata/roms 
-</code> 
- 
-Folders such as: 
- 
-<code> 
-/userdata/bios 
-/userdata/saves 
-/userdata/screenshots 
-/userdata/themes 
-/userdata/music 
-</code> 
- 
-remain on internal storage. 
- 
-The graphical Storage Manager does not merge BIOS files, save files, screenshots, themes, or music. 
- 
-Advanced manual MergerFS pools are separate from the graphical Storage Manager and can technically target other directories, but those pools are not managed by the Storage Manager interface. 
- 
-===== Internal ROM Preservation ===== 
- 
-When the first additional ROM drive is merged, Batocera preserves the existing internal ROM collection. 
- 
-Internally, existing ROMs stored in: 
- 
-<code> 
-/userdata/roms 
-</code> 
- 
-are moved into: 
- 
-<code> 
-/userdata/.roms_base 
-</code> 
- 
-This allows internal ROMs to remain visible alongside ROMs stored on merged drives. 
- 
-If all merged drives are later removed, Batocera restores the internal ROM library back to the normal ''/userdata/roms'' location. 
- 
-During restoration, the current implementation uses ''rsync --ignore-existing''. Existing destination files are therefore not overwritten by files of the same name from ''.roms_base''. If restoration fails, Batocera keeps ''.roms_base'' instead of deleting it so the preserved data is not discarded. 
- 
-===== Limitations ===== 
- 
-Automatic detection by the graphical Storage Manager currently requires this layout: 
- 
-<code> 
-<drive>/roms 
-</code> 
- 
-Nested ROM folders are not detected automatically. 
- 
-Example: 
- 
-<code> 
-<drive>/Batocera/roms 
-</code> 
- 
-is not automatically merged. 
- 
-This limitation does not apply to advanced manual MergerFS branches, where an explicit nested path can be configured. 
- 
-The graphical Storage Manager merges only the ROM library. Other userdata folders remain independent unless they are configured separately using advanced manual storage methods. 
  
 ===== Advanced Technical Details ===== ===== Advanced Technical Details =====
  • user/rion.1791161236.txt.gz
  • Last modified: 14 days ago
  • by rion