Skip to content

MSC exclusive access support. #8814

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed

Conversation

iabdalkader
Copy link
Contributor

@iabdalkader iabdalkader commented Jun 24, 2022

For review & feedback

This is just a new idea/proposal/RFC for MSC exclusive access (mainly for ports using Tinyusb). Exclusive access is enforced from higher-level VFS functions, and works like the following:

  • STATUS disk ioctl is implemented and returns "protected" if the block device is used by MSC (mounted by PC).
  • Any write access from the device is denied, by higher-level VFS functions when the disk is protected.
  • When the storage is ejected, the filesystem is remounted, to update the filesystem for the device (and this is done in mp_sched/VM context to avoid critical sections).
  • Any following write access to the filesystem works, because the MSC has released the block device.
  • USB enable/init is moved after _boot.py runs to allow any mkfs calls from _boot.py to create a filesystem, however once USB/MSC is enabled, the ioctl will return protected when status is queried.
  • Finally, the exclusive access is configurable with the macro MICROPY_HW_USB_MSC_EXCLUSIVE_ACCESS.

Example:

>>> import os
>>> os.listdir()
['test.txt', 'README.txt', 'microdot_asyncio.py', 'microdot.py', 'main.py']

>>> f = open("test.txt", "w")
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
OSError: 30

# === NOTE: Disk ejected at this point, debug output:
>>> tinyusb_helpers.c: Disk ejected, remount read/write

>>> f = open("test.txt", "w")
>>> f.write("HelloWorld!")
11
>>> f.close()

@iabdalkader
Copy link
Contributor Author

@robert-hh

}

void tud_msc_remount(void) {
mp_sched_schedule_node(&mp_remount_sched_node, tud_msc_remount_task);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At which state will tud_msc_remount be called? Only when the device is ejected? Or is it possible that the PC may remount the drive? I cannot do that with my Linux box. If the board has always go through a power cycle, then it's fine.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Assuming that a board with MSC support will start in locally write protected mode. What happens if the board is running stand-alone? Can it tell that there is no MSC mounted? Then the drive must be mounted write enabled.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It gets called when the device is ejected. It may be possible to remount a safely-removed/ejected drive, but I think that disconnects power from the port anyway, I will have to test to confirm. However, I think that's a very unlikely case that shouldn't be handled, not sure if it should remount as read-only after giving write access to the device.

Copy link
Contributor

@robert-hh robert-hh Jun 25, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm chewing on the timing issue. At the moment, the board starts with write enabled, to be able to create a file system, if it does not exist. Then it mounts the flash drive, which must be write protected if MSC is used. It could decide based on the status of the IOCTL_STATUS call. But how long does that status change take?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OK. So the tud_msc_start_stop_cb() is only called on eject. The ud_msc_inquiry_cb() is called on start, as well as the tud_msc_capacity_cb(). So we could use these as indicator, that a PC is attempting to connect.
The tud_msc_test_unit_ready_cb() is called regularly.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

With the softreboot the file is gone. test without the soft reboot.
But I found a possible reason at my set-up: In tud_msc_remount_task() you have a check for len == 1. That is the length of the mount point name. On my set-up, the length is 6. So the remount never happens.
Changing the it to len == 6, the code is executed, and I can single-step it in the debugger. Then I see a strange phenomenon: while single stepping though unmount, remount, .., the PC still shows: "Unmount in progress, please do not remove the drive". Only after the remount function is finished, this message disappears. So it looks like in addition to the non-matching length check, the remount at the board was too early.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So it looks like in addition to the non-matching length check, the remount at the board was too early.

maybe a false alarm: The PC/USB simple code waits for tud_msc_start_stop_cb() to finish.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes maybe because you're single stepping the function. The remount is scheduled, so this function returns immediately. Anyway, the mount point of the MSC filesystem should be defined somewhere, or even better if it's detected dynamically somehow, but I'm not sure how to do that.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I single stepped in the tud_msc_remount_task() function. So I know it is called.
At the moment, the internal flash is the first mounted file system. I do not know if we can reliably assume that this is always the case.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If we do not find a good solution, we could at least defer opening the file system for write until the next soft boot. That's at least safe.

@robert-hh
Copy link
Contributor

Thanks for this PR. It helps a lot. I'll carry that over for the MIMXRT port and report the results.

@iabdalkader
Copy link
Contributor Author

Thanks for this PR. It helps a lot. I'll carry that over for the MIMXRT port and report the results.

I may rework some of the code here, maybe add a vfs_mount option to remount as read-only, define the mount point of the MSC block device or find a better way to detect it, but the functionality should stay the same.

@iabdalkader iabdalkader force-pushed the msc_exclusive_access branch from 4193957 to f22cf66 Compare June 25, 2022 12:09
robert-hh added a commit to robert-hh/micropython that referenced this pull request Jun 25, 2022
Porting PR micropython#8814 of @iabdalkader to the mimxrt platform.
- When the board is mounted to a PC, local write access is blocked.
- Local write access will be re-enabled again if the disk is ejected.
- If the board is not connected to a PC on start-up, local write access
  is enabled.
- The status of the write access can be determined by bdev.ioctl(7, 0).
  If the device is mounted, it return 1, otherwise 0.
robert-hh added a commit to robert-hh/micropython that referenced this pull request Jun 25, 2022
Porting PR micropython#8814 of @iabdalkader to the mimxrt platform.
- When the board is mounted to a PC, local write access is blocked.
- Local write access will be re-enabled again if the disk is ejected.
- If the board is not connected to a PC on start-up, local write access
  is enabled.
- The status of the write access can be determined by bdev.ioctl(7, 0).
  If the device is mounted, it return 1, otherwise 0.
robert-hh added a commit to robert-hh/micropython that referenced this pull request Jun 25, 2022
Porting PR micropython#8814 of @iabdalkader to the mimxrt platform.
- When the board is mounted to a PC, local write access is blocked.
- Local write access will be re-enabled again if the disk is ejected.
- If the board is not connected to a PC on start-up, local write access
  is enabled.
- The status of the write access can be determined by bdev.ioctl(7, 0).
  If the device is mounted to a PAC and thus local write access is
  blocked, it return 1, otherwise 0.
- low level write/erase using the block device calls are still possible.
  It is up to the user to check the device status ahead.
@iabdalkader iabdalkader force-pushed the msc_exclusive_access branch from f22cf66 to 3ab4efd Compare June 25, 2022 15:13
@iabdalkader iabdalkader force-pushed the msc_exclusive_access branch from 3ab4efd to fd327d2 Compare June 25, 2022 16:29
robert-hh added a commit to robert-hh/micropython that referenced this pull request Jun 26, 2022
Porting PR micropython#8814 of @iabdalkader to the mimxrt platform.
- When the board is mounted to a PC, local write access is blocked.
- Local write access will be re-enabled again if the disk is ejected.
- If the board is not connected to a PC on start-up, local write access
  is enabled.
- The status of the write access can be determined by bdev.ioctl(7, 0).
  If the device is mounted to a PAC and thus local write access is
  blocked, it return 1, otherwise 0.
- low level write/erase using the block device calls are still possible.
  It is up to the user to check the device status ahead.
robert-hh added a commit to robert-hh/micropython that referenced this pull request Jul 1, 2022
Porting PR micropython#8814 of @iabdalkader to the mimxrt platform.
- When the board is mounted to a PC, local write access is blocked.
- Local write access will be re-enabled again if the disk is ejected.
- If the board is not connected to a PC on start-up, local write access
  is enabled.
- The status of the write access can be determined by bdev.ioctl(7, 0).
  If the device is mounted to a PAC and thus local write access is
  blocked, it return 1, otherwise 0.
- low level write/erase using the block device calls are still possible.
  It is up to the user to check the device status ahead.
robert-hh added a commit to robert-hh/micropython that referenced this pull request Jul 5, 2022
Porting PR micropython#8814 of @iabdalkader to the mimxrt platform.
- When the board is mounted to a PC, local write access is blocked.
- Local write access will be re-enabled again if the disk is ejected.
- If the board is not connected to a PC on start-up, local write access
  is enabled.
- The status of the write access can be determined by bdev.ioctl(7, 0).
  If the device is mounted to a PAC and thus local write access is
  blocked, it return 1, otherwise 0.
- low level write/erase using the block device calls are still possible.
  It is up to the user to check the device status ahead.
robert-hh added a commit to robert-hh/micropython that referenced this pull request Jul 18, 2022
Porting PR micropython#8814 of @iabdalkader to the mimxrt platform.
- When the board is mounted to a PC, local write access is blocked.
- Local write access will be re-enabled again if the disk is ejected.
- If the board is not connected to a PC on start-up, local write access
  is enabled.
- The status of the write access can be determined by bdev.ioctl(7, 0).
  If the device is mounted to a PAC and thus local write access is
  blocked, it return 1, otherwise 0.
- low level write/erase using the block device calls are still possible.
  It is up to the user to check the device status ahead.
robert-hh added a commit to robert-hh/micropython that referenced this pull request Jul 20, 2022
Porting PR micropython#8814 of @iabdalkader to the mimxrt platform.
- When the board is mounted to a PC, local write access is blocked.
- Local write access will be re-enabled again if the disk is ejected.
- If the board is not connected to a PC on start-up, local write access
  is enabled.
- The status of the write access can be determined by bdev.ioctl(7, 0).
  If the device is mounted to a PAC and thus local write access is
  blocked, it return 1, otherwise 0.
- low level write/erase using the block device calls are still possible.
  It is up to the user to check the device status ahead.
robert-hh added a commit to robert-hh/micropython that referenced this pull request Jul 29, 2022
Porting PR micropython#8814 of @iabdalkader to the mimxrt platform.
- When the board is mounted to a PC, local write access is blocked.
- Local write access will be re-enabled again if the disk is ejected.
- If the board is not connected to a PC on start-up, local write access
  is enabled.
- The status of the write access can be determined by bdev.ioctl(7, 0).
  If the device is mounted to a PAC and thus local write access is
  blocked, it return 1, otherwise 0.
- low level write/erase using the block device calls are still possible.
  It is up to the user to check the device status ahead.
robert-hh added a commit to robert-hh/micropython that referenced this pull request Aug 30, 2022
Porting PR micropython#8814 of @iabdalkader to the mimxrt platform.
- When the board is mounted to a PC, local write access is blocked.
- Local write access will be re-enabled again if the disk is ejected.
- If the board is not connected to a PC on start-up, local write access
  is enabled.
- The status of the write access can be determined by bdev.ioctl(7, 0).
  If the device is mounted to a PAC and thus local write access is
  blocked, it return 1, otherwise 0.
- low level write/erase using the block device calls are still possible.
  It is up to the user to check the device status ahead.
robert-hh added a commit to robert-hh/micropython that referenced this pull request Sep 16, 2022
Porting PR micropython#8814 of @iabdalkader to the mimxrt platform.
- When the board is mounted to a PC, local write access is blocked.
- Local write access will be re-enabled again if the disk is ejected.
- If the board is not connected to a PC on start-up, local write access
  is enabled.
- The status of the write access can be determined by bdev.ioctl(7, 0).
  If the device is mounted to a PAC and thus local write access is
  blocked, it return 1, otherwise 0.
- low level write/erase using the block device calls are still possible.
  It is up to the user to check the device status ahead.
robert-hh added a commit to robert-hh/micropython that referenced this pull request Nov 17, 2022
Porting PR micropython#8814 of @iabdalkader to the mimxrt platform.
- When the board is mounted to a PC, local write access is blocked.
- Local write access will be re-enabled again if the disk is ejected.
- If the board is not connected to a PC on start-up, local write access
  is enabled.
- The status of the write access can be determined by bdev.ioctl(7, 0).
  If the device is mounted to a PAC and thus local write access is
  blocked, it return 1, otherwise 0.
- low level write/erase using the block device calls are still possible.
  It is up to the user to check the device status ahead.
robert-hh added a commit to robert-hh/micropython that referenced this pull request Nov 18, 2022
Porting PR micropython#8814 of @iabdalkader to the mimxrt platform.
- When the board is mounted to a PC, local write access is blocked.
- Local write access will be re-enabled again if the disk is ejected.
- If the board is not connected to a PC on start-up, local write access
  is enabled.
- The status of the write access can be determined by bdev.ioctl(7, 0).
  If the device is mounted to a PAC and thus local write access is
  blocked, it return 1, otherwise 0.
- low level write/erase using the block device calls are still possible.
  It is up to the user to check the device status ahead.
robert-hh added a commit to robert-hh/micropython that referenced this pull request Dec 15, 2022
Porting PR micropython#8814 of @iabdalkader to the mimxrt platform.
- When the board is mounted to a PC, local write access is blocked.
- Local write access will be re-enabled again if the disk is ejected.
- If the board is not connected to a PC on start-up, local write access
  is enabled.
- The status of the write access can be determined by bdev.ioctl(7, 0).
  If the device is mounted to a PAC and thus local write access is
  blocked, it return 1, otherwise 0.
- low level write/erase using the block device calls are still possible.
  It is up to the user to check the device status ahead.
robert-hh added a commit to robert-hh/micropython that referenced this pull request Mar 7, 2023
Porting PR micropython#8814 of @iabdalkader to the mimxrt platform.
- When the board is mounted to a PC, local write access is blocked.
- Local write access will be re-enabled again if the disk is ejected.
- If the board is not connected to a PC on start-up, local write access
  is enabled.
- The status of the write access can be determined by bdev.ioctl(7, 0).
  If the device is mounted to a PAC and thus local write access is
  blocked, it return 1, otherwise 0.
- low level write/erase using the block device calls are still possible.
  It is up to the user to check the device status ahead.
robert-hh added a commit to robert-hh/micropython that referenced this pull request Mar 23, 2023
Porting PR micropython#8814 of @iabdalkader to the mimxrt platform.
- When the board is mounted to a PC, local write access is blocked.
- Local write access will be re-enabled again if the disk is ejected.
- If the board is not connected to a PC on start-up, local write access
  is enabled.
- The status of the write access can be determined by bdev.ioctl(7, 0).
  If the device is mounted to a PAC and thus local write access is
  blocked, it return 1, otherwise 0.
- low level write/erase using the block device calls are still possible.
  It is up to the user to check the device status ahead.
robert-hh added a commit to robert-hh/micropython that referenced this pull request May 4, 2023
Porting PR micropython#8814 of @iabdalkader to the mimxrt platform.
- When the board is mounted to a PC, local write access is blocked.
- Local write access will be re-enabled again if the disk is ejected.
- If the board is not connected to a PC on start-up, local write access
  is enabled.
- The status of the write access can be determined by bdev.ioctl(7, 0).
  If the device is mounted to a PAC and thus local write access is
  blocked, it return 1, otherwise 0.
- low level write/erase using the block device calls are still possible.
  It is up to the user to check the device status ahead.
robert-hh added a commit to robert-hh/micropython that referenced this pull request May 19, 2023
Porting PR micropython#8814 of @iabdalkader to the mimxrt platform.
- When the board is mounted to a PC, local write access is blocked.
- Local write access will be re-enabled again if the disk is ejected.
- If the board is not connected to a PC on start-up, local write access
  is enabled.
- The status of the write access can be determined by bdev.ioctl(7, 0).
  If the device is mounted to a PAC and thus local write access is
  blocked, it return 1, otherwise 0.
- low level write/erase using the block device calls are still possible.
  It is up to the user to check the device status ahead.

Signed-off-by: robert-hh <robert@hammelrath.com>
robert-hh added a commit to robert-hh/micropython that referenced this pull request Jun 2, 2023
Porting PR micropython#8814 of @iabdalkader to the mimxrt platform.
- When the board is mounted to a PC, local write access is blocked.
- Local write access will be re-enabled again if the disk is ejected.
- If the board is not connected to a PC on start-up, local write access
  is enabled.
- The status of the write access can be determined by bdev.ioctl(7, 0).
  If the device is mounted to a PAC and thus local write access is
  blocked, it return 1, otherwise 0.
- low level write/erase using the block device calls are still possible.
  It is up to the user to check the device status ahead.

Signed-off-by: robert-hh <robert@hammelrath.com>
@iabdalkader iabdalkader deleted the msc_exclusive_access branch June 24, 2023 07:45
robert-hh added a commit to robert-hh/micropython that referenced this pull request Jun 26, 2023
Porting PR micropython#8814 of @iabdalkader to the mimxrt platform.
- When the board is mounted to a PC, local write access is blocked.
- Local write access will be re-enabled again if the disk is ejected.
- If the board is not connected to a PC on start-up, local write access
  is enabled.
- The status of the write access can be determined by bdev.ioctl(7, 0).
  If the device is mounted to a PAC and thus local write access is
  blocked, it return 1, otherwise 0.
- low level write/erase using the block device calls are still possible.
  It is up to the user to check the device status ahead.

Signed-off-by: robert-hh <robert@hammelrath.com>
robert-hh added a commit to robert-hh/micropython that referenced this pull request Jul 2, 2023
Porting PR micropython#8814 of @iabdalkader to the mimxrt platform.
- When the board is mounted to a PC, local write access is blocked.
- Local write access will be re-enabled again if the disk is ejected.
- If the board is not connected to a PC on start-up, local write access
  is enabled.
- The status of the write access can be determined by bdev.ioctl(7, 0).
  If the device is mounted to a PAC and thus local write access is
  blocked, it return 1, otherwise 0.
- low level write/erase using the block device calls are still possible.
  It is up to the user to check the device status ahead.

Signed-off-by: robert-hh <robert@hammelrath.com>
robert-hh added a commit to robert-hh/micropython that referenced this pull request Dec 9, 2023
Porting PR micropython#8814 of @iabdalkader to the mimxrt platform.
- When the board is mounted to a PC, local write access is blocked.
- Local write access will be re-enabled again if the disk is ejected.
- If the board is not connected to a PC on start-up, local write access
  is enabled.
- The status of the write access can be determined by bdev.ioctl(7, 0).
  If the device is mounted to a PAC and thus local write access is
  blocked, it return 1, otherwise 0.
- low level write/erase using the block device calls are still possible.
  It is up to the user to check the device status ahead.

Signed-off-by: robert-hh <robert@hammelrath.com>
robert-hh added a commit to robert-hh/micropython that referenced this pull request May 24, 2024
Porting PR micropython#8814 of @iabdalkader to the mimxrt platform.
- When the board is mounted to a PC, local write access is blocked.
- Local write access will be re-enabled again if the disk is ejected.
- If the board is not connected to a PC on start-up, local write access
  is enabled.
- The status of the write access can be determined by bdev.ioctl(7, 0).
  If the device is mounted to a PAC and thus local write access is
  blocked, it return 1, otherwise 0.
- low level write/erase using the block device calls are still possible.
  It is up to the user to check the device status ahead.

Signed-off-by: robert-hh <robert@hammelrath.com>
robert-hh added a commit to robert-hh/micropython that referenced this pull request Jun 1, 2024
Porting PR micropython#8814 of @iabdalkader to the mimxrt platform.
- When the board is mounted to a PC, local write access is blocked.
- Local write access will be re-enabled again if the disk is ejected.
- If the board is not connected to a PC on start-up, local write access
  is enabled.
- The status of the write access can be determined by bdev.ioctl(7, 0).
  If the device is mounted to a PAC and thus local write access is
  blocked, it return 1, otherwise 0.
- low level write/erase using the block device calls are still possible.
  It is up to the user to check the device status ahead.

Signed-off-by: robert-hh <robert@hammelrath.com>
robert-hh added a commit to robert-hh/micropython that referenced this pull request Sep 4, 2024
Porting PR micropython#8814 of @iabdalkader to the mimxrt platform.
- When the board is mounted to a PC, local write access is blocked.
- Local write access will be re-enabled again if the disk is ejected.
- If the board is not connected to a PC on start-up, local write access
  is enabled.
- The status of the write access can be determined by bdev.ioctl(7, 0).
  If the device is mounted to a PAC and thus local write access is
  blocked, it return 1, otherwise 0.
- low level write/erase using the block device calls are still possible.
  It is up to the user to check the device status ahead.

Signed-off-by: robert-hh <robert@hammelrath.com>
robert-hh added a commit to robert-hh/micropython that referenced this pull request Oct 27, 2024
Porting PR micropython#8814 of @iabdalkader to the mimxrt platform.
- When the board is mounted to a PC, local write access is blocked.
- Local write access will be re-enabled again if the disk is ejected.
- If the board is not connected to a PC on start-up, local write access
  is enabled.
- The status of the write access can be determined by bdev.ioctl(7, 0).
  If the device is mounted to a PAC and thus local write access is
  blocked, it return 1, otherwise 0.
- low level write/erase using the block device calls are still possible.
  It is up to the user to check the device status ahead.

Signed-off-by: robert-hh <robert@hammelrath.com>
robert-hh added a commit to robert-hh/micropython that referenced this pull request Nov 12, 2024
Porting PR micropython#8814 of @iabdalkader to the mimxrt platform.
- When the board is mounted to a PC, local write access is blocked.
- Local write access will be re-enabled again if the disk is ejected.
- If the board is not connected to a PC on start-up, local write access
  is enabled.
- The status of the write access can be determined by bdev.ioctl(7, 0).
  If the device is mounted to a PAC and thus local write access is
  blocked, it return 1, otherwise 0.
- low level write/erase using the block device calls are still possible.
  It is up to the user to check the device status ahead.

Signed-off-by: robert-hh <robert@hammelrath.com>
robert-hh added a commit to robert-hh/micropython that referenced this pull request Jan 16, 2025
Porting PR micropython#8814 of @iabdalkader to the mimxrt platform.
- When the board is mounted to a PC, local write access is blocked.
- Local write access will be re-enabled again if the disk is ejected.
- If the board is not connected to a PC on start-up, local write access
  is enabled.
- The status of the write access can be determined by bdev.ioctl(7, 0).
  If the device is mounted to a PAC and thus local write access is
  blocked, it return 1, otherwise 0.
- low level write/erase using the block device calls are still possible.
  It is up to the user to check the device status ahead.

Signed-off-by: robert-hh <robert@hammelrath.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants