Skip to content
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

Support removable device #29

Closed
pcercuei opened this issue Dec 8, 2019 · 17 comments
Closed

Support removable device #29

pcercuei opened this issue Dec 8, 2019 · 17 comments

Comments

@pcercuei
Copy link
Contributor

pcercuei commented Dec 8, 2019

I'm facing a problem and I'm not sure how to fix it.

I want uMTP-R to expose a micro-SD card, if it's plugged to my system. The mountpoint is a directory inside /media whose name is the label of the filesystem, so not a fixed one (but I may be able to change that if needed).

What I do right now, is have /media as a MTP volume. /media is a 64-kB tmpfs, since it only ever contains mountpoints and no actual data. It works fine on Linux, but Windows will refuse to copy since it detects that the drive is 64-kB.

Do you have an idea how I could make this setup work?

@jfdelnero
Copy link
Member

I think that we need to add the possibility to "connect" uMTP to udev or something else to detect the disks removal/insertion. Then uMTP can send an MTP removal/insertion event to the PC.

@jfdelnero
Copy link
Member

@pcercuei : This is now done on the trunk.

You can now mount/unmount a store in command line.

Once umtprd is running you can use the -cmd: option to send commands to the daemon.
Two command line examples with a store named "home folder" in the config file :

umtprd -cmd:mount:home\ folder
umtprd -cmd:unmount:home\ folder

Can you now easily use udev to execute these command lines when a media is inserted/ejected.

Please also note that there is now a new "notmounted" option in the config file to keep a store unmounted by default at startup. See the config file on the repository for the usage.

@pcercuei
Copy link
Contributor Author

Fantastic news! I'll test it ASAP.

@pcercuei
Copy link
Contributor Author

I can't get it to work properly...

My umtprd.conf contains:

storage "/media/sdcard"  "SD Card" "rw,notmounted"

I type:

sudo umtprd '-cmd:mount:SD Card'

I get:

[uMTPrd - 19:55:49 - Info] uMTP Responder
[uMTPrd - 19:55:49 - Info] Version: v1.3.5 compiled the Feb 13 2020@14:20:21
[uMTPrd - 19:55:49 - Info] (c) 2018 - 2020 Viveris Technologies
[uMTPrd - 19:55:49 - Info] Sending command : mount:SD Card
[uMTPrd - 19:55:49 - Error] send_message_queue : Couldn't send mount:SD Card !

@jfdelnero
Copy link
Member

Is umtprd running ? No particular message regarding the queue creation when the umtp daemon is started ?

@pcercuei
Copy link
Contributor Author

pcercuei commented Apr 28, 2020

Sorry for the delay. I had to had a UART to be able to debug MTP.

I get:

[uMTPrd - 00:09:38 - Error] msgqueue_handler_init : msgget error 89

Looks like I miss the system-V IPC in my kernel. I'll enable it and try again.

@twsmith85
Copy link

Hey guys, I've been testing this feature also. Everything seems to work for me with it as long as the device is connected to a host. I can plug and unplug the sd card without problem.

However, if I disconnect the device from a host and then add/remove sd card I see no log output from umtprd (DEBUG is enabled) and it seems to hang at that point. It will no longer reconnect to a host afterward.

I'm using functionfs for the setup and udev rules to trigger the mount/unmount commands. I'm still digging through the code to understand the cause of this.

By the way, thanks for this excellent bit of code and the continued support of it!

@twsmith85
Copy link

twsmith85 commented May 17, 2020

Adding a bit more info, it seems the process terminates and goes zombie in the above scenario.

Steps to recreate:

  1. Disconnect functioning gadget with umtrpd from host
  2. Remove sd card
  3. send umount command: RUN+="/usr/bin/umtprd -cmd:unmount:storage" ( not sure if this actually matters.)
[2020-05-17 19:40:32,417] [INFO] usb_cli   , Detected USB disconnect
[2020-05-17 19:40:32,421] [INFO] usb_cli   , Closing Serial
[2020-05-17 19:40:32,425] [INFO] usb_cli   , Opening Serial with pyserial version 3.4
[2020-05-17 19:40:32,451] [INFO] usb_cli   , Starting CLI on usb_cli
  335 root     /usr/bin/umtprd
  426 root     grep mtp
 ps | grep mtp
  335 root     /usr/bin/umtprd
  429 root     grep mtp
 ps | grep mtp
  335 root     /usr/bin/umtprd
  431 root     grep mtp
 mmc1: card 0001 removed

 May 17 19:40:43 reader kern.info kernel: mmc1: card 0001 removed
May 17 19:40:43 reader user.notice syslog: [uMTPrd - Info] uMTP Responder
May 17 19:40:43 reader user.notice syslog: [uMTPrd - Info] Version: v1.3.6 compiled the May 17 2020@11:11:59
May 17 19:40:43 reader user.notice syslog: [uMTPrd - Info] (c) 2018 - 2020 Viveris Technologies
May 17 19:40:43 reader user.notice syslog: [uMTPrd - Info] Sending command : unmount:storage
May 17 19:40:43 reader user.debug syslog: [uMTPrd - Debug] send_message_queue : current exec path : /usr/bin/umtprd
May 17 19:40:43 reader user.debug syslog: [uMTPrd - Debug] send_message_queue : msgqueue_id = 0
May 17 19:40:43 reader user.debug syslog: [uMTPrd - Debug] msgqueue_thread : New message received : unmount:storage
May 17 19:40:43 reader user.debug syslog: [uMTPrd - Debug] mtp_get_storage_index_by_name : storage
May 17 19:40:43 reader user.debug syslog: [uMTPrd - Debug] mtp_get_storage_index_by_name : /media/storage/storage1 -> 00000000
May 17 19:40:43 reader user.err syslog: failed to write super block

 ps | grep mtp
  335 root     [umtprd]
  441 root     grep mtp

@jfdelnero
Copy link
Member

Thanks. I need to test this case (functionfs + drive removal while disconnected)

@pcercuei
Copy link
Contributor Author

I'm having the problem that on my OS the external media (e.g. SD cards) are mounted according to their name, so I can't know their mountpoint in advance to add them to the umtprd.conf...

@twsmith85
Copy link

Hey Paul, Not sure if you ever got this problem resolved in your last comment. But I used udev rules to automagically make symlinks in /dev based on the sys fs physical device address connecting. So for instance, a udev rule could be added to say every time a micro sd card is inserted create a /dev/usd symlink that points to it's block device, and a /dev/usd# symlink for each partition.

And those are the devices I referenced in the config file.

@twsmith85
Copy link

Hey guys,

I got some time to run some gdb today and this seems to be the cause of the crash I have seen:

Unplugging the gadget from the host causes umtprd to close the fs db
[uMTPrd - Debug] deinit_fs_db called

Removing the card now tries to use that db when unmount is sent. msgqueue.c -> msgqueue_thread() runs unmount which calls get_entry_by_storageid() which calls the following while db is null:

if(!entry_list)
   entry_list = db->entry_list;

A quick fix for me seems to be:

if(!entry_list && db)
	entry_list = db->entry_list;

After this small change its working great in my short period of testing.

If this looks like a valid solution, I opened a pull request #49 . Thanks!

@pcercuei
Copy link
Contributor Author

Hi @twsmith85, I don't understand how udev can help you - the storage entries in the umtprd.conf contain mount points, and not dev node paths...

@twsmith85
Copy link

twsmith85 commented Dec 21, 2020

Ah, right, I should have been clearer.

I'm on an embedded system using BuildRoot. Our udev rules handle both physical port identification and mounting. We are also using a single micro sd port for storage that will always be mounted to /media/storage/storage1 using the udev rules. Maybe this is not an option on your setup.

Here's the add section of that udev rule in case it helps give an idea on your system (Added Devpath filter with edit):

### Auto mount support for micro SD storage cards ###

# If not micro SD storage port, bail

DEVPATH!="/devices/platform/ahb/b0000000.sdio-host/mmc_host/mmc1/*", GOTO="end"

ACTION=="add", GOTO="add"

ACTION=="remove", GOTO="remove"

GOTO="end"


LABEL="add"

# Create disk symlink

ENV{DEVTYPE}=="disk", SYMLINK:="storage"

# Create mount disk directory

ENV{DEVTYPE}=="disk", RUN+="/bin/mkdir -p /media/storage"

# Mount partition-less sticks

ENV{DEVTYPE}=="disk", SUBSYSTEM=="block", ENV{ID_FS_TYPE}!="", ENV{ID_FS_TYPE}=="exfat", RUN+="/usr/sbin/mount.exfat /dev/storage /media/storage"

ENV{DEVTYPE}=="disk", SUBSYSTEM=="block", ENV{ID_FS_TYPE}!="", ENV{ID_FS_TYPE}=="ntfs", RUN+="/usr/sbin/mount.ntfs-3g /dev/storage /media/storage"

ENV{DEVTYPE}=="disk", SUBSYSTEM=="block", ENV{ID_FS_TYPE}!="", ENV{ID_FS_TYPE}!="exfat|ntfs", RUN+="/bin/mount /dev/storage /media/storage"

# Create partition symlink

ENV{DEVTYPE}=="partition",  SYMLINK:="storage%n"

# Create mount partition directory

ENV{DEVTYPE}=="partition", RUN+="/bin/mkdir -p /media/storage/storage%n"

# Mount target partition and notify MTP

ENV{DEVTYPE}=="partition", ENV{ID_FS_TYPE}!="", ENV{ID_FS_TYPE}=="exfat", RUN+="/usr/sbin/mount.exfat /dev/storage%n /media/storage/storage%n"

ENV{DEVTYPE}=="partition", ENV{ID_FS_TYPE}!="", ENV{ID_FS_TYPE}=="ntfs", RUN+="/usr/sbin/mount.ntfs-3g /dev/storage%n /media/storage/storage%n"

ENV{DEVTYPE}=="partition", ENV{ID_FS_TYPE}!="", ENV{ID_FS_TYPE}!="exfat|ntfs", RUN+="/bin/mount /dev/storage%n /media/storage/storage%n"

ENV{DEVTYPE}=="partition", RUN+="/usr/bin/umtprd -cmd:mount:storage"

GOTO="end"

@pcercuei
Copy link
Contributor Author

@twsmith85 my udev rule: https://github.com/OpenDingux/buildroot/blob/opendingux/board/opendingux/target_skeleton/etc/udev/rules.d/61-automount.rules

I mount removable devices according to their partition name. I guess I could symlink these into a /media/storage/storageX like you do, but that means I would need generic names in umtprd.conf for the removable storage devices and the MTP volumes. Ideally the MTP volumes would be named after the partition names.

@pcercuei
Copy link
Contributor Author

I've been working on adding a addstorage: command. The diff is actually tiny if the command itself uses the same syntax and line format as the conf file.

Adding a rmstorage: command would be a bit more tricky, the core (mtp.c) itself does not support storages being removed.

@jfdelnero
Copy link
Member

i will check this tomorrow but i think that storages can be removed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants