С этой темой я корячился давно и долго, и вот после UP7 в LMDE всё заработало по-человечески.
Использовался
вот этот чудесный гайд.
Для работы по протоколу MTP используется библиотека
libmtp
, и похоже, в последнем релизе Debian её таки починили.
Чтобы примонтировать устройство по протоколу MTP, можно пользоваться кучей способов:
mtpfs
,
jmtpfs
,
gvfs-mtp
,
go-mtpfs
.
Вот последний и интересен. Разрабатывался (и поддерживается в момент написания статьи) разработчиком Android, быстр и, в последних версиях, лишён багов с отваливанием устройства. Ну, будем думать, что из-за фикса непосредственно в
libmtp
.
Перво-наперво, нужно разрешить не-root пользователям доступ к файловым системам, смонтированным от лица root. Для этого открываем
/etc/fuse.conf
и раскомментируем опцию
user_allow_other
.
Дальше нужно поставить сам go-mtpfs.
Для этого понадобятся git и компилятор Go, а дальше дело занимает пару минут.
Итак:
sudo apt-get install libmtp-dev git golang # готовим build environment
mkdir /tmp/go # здесь будем собирать
export GOPATH=/tmp/go
go get github.com/hanwen/go-mtpfs # забираем проект go-mtpfs с гитхаба; при этом происходит сборка при помощи Go
sudo mv /tmp/go/bin/go-mtpfs ~/bin/go-mtpfs # готово, перемещаем бинарник туда, куда нам удобно
sudo chmod a+x ~/bin/go-mtpfs # не забываем выдать бинарнику права на запуск
Собрали. Можем монтировать:
go-mtpfs /media/mtp
и размонтировать:
fusermount -u /media/mtp
Кроме того, добавим правила udev, чтобы при подключении устройства через USB оно автоматически монтировалось. Создаём файлик
/etc/udev/rules.d/99-android.rules
с вот таким содержанием:
# /etc/udev/rules.d/
# Google Nexus 7
SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", ATTR{idProduct}=="4e40", MODE="0666" # Bootloader
SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", ATTR{idProduct}=="d001", MODE="0666" # Recovery
SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", ATTR{idProduct}=="4e43", MODE="0666" # PTP media, USB debug off
SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", ATTR{idProduct}=="4e44", MODE="0666" # PTP media, USB debug on
SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", ATTR{idProduct}=="4e41", MODE="0666" # MTP media, USB debug off
SUBSYSTEM=="usb", ATTR{idVendor}=="18d1", ATTR{idProduct}=="4e42", MODE="0666" # MTP media, USB debug on
# Google Nexus 7 MTP mode under JB 4.1 : automatic mount & umount when plugged (USB debug on & off)
ENV{ID_MODEL}=="Nexus", ENV{ID_MODEL_ID}=="4e41", ACTION=="add", RUN+="/usr/bin/sudo -b -u dbz /home/dbz/bin/go-mtpfs -allow-other=true /media/mtp"
ENV{ID_MODEL}=="Nexus", ENV{ID_MODEL_ID}=="4e42", ACTION=="add", RUN+="/usr/bin/sudo -b -u dbz /home/dbz/bin/go-mtpfs -allow-other=true /media/mtp"
ENV{ID_MODEL}=="Nexus", ENV{ID_MODEL_ID}=="4e41", ACTION=="remove", RUN+="/bin/umount /media/mtp"
ENV{ID_MODEL}=="Nexus", ENV{ID_MODEL_ID}=="4e42", ACTION=="remove", RUN+="/bin/umount /media/mtp"
# Google Nexus 7 MTP mode under JB 4.2+ : automatic mount & umount when plugged (USB debug on & off)
ENV{ID_MODEL}=="Nexus_7", ENV{ID_MODEL_ID}=="4e41", ACTION=="add", RUN+="/usr/bin/sudo -b -u dbz /home/dbz/bin/go-mtpfs -allow-other=true /media/mtp"
ENV{ID_MODEL}=="Nexus_7", ENV{ID_MODEL_ID}=="4e42", ACTION=="add", RUN+="/usr/bin/sudo -b -u dbz /home/dbz/bin/go-mtpfs -allow-other=true /media/mtp"
ENV{ID_MODEL}=="Nexus_7", ENV{ID_MODEL_ID}=="4e41", ACTION=="remove", RUN+="/bin/umount /media/mtp"
ENV{ID_MODEL}=="Nexus_7", ENV{ID_MODEL_ID}=="4e42", ACTION=="remove", RUN+="/bin/umount /media/mtp"
Здесь используется монтирование через sudo, т.к. почему-то без него монтировать не хочет. Копаться почему так мне не хотелось. Опция
-b
используется для запуска монтирования в бекграунде, т.к. udev очень нетерпим к долгим операциям. Пробовал вот такую команду:
ENV{ID_MODEL}=="Nexus_7", ENV{ID_MODEL_ID}=="4e42", ACTION=="add", RUN+="/home/dbz/bin/go-mtpfs -allow-other=true /media/mtp &"
т.е. монтировать без sudo и отправлять процесс в бекграунд при помощи & - не сработало...
В правилах udev нужно прописывать абсолютные пути.
Также видим, что наряду с
fusermount -u
можно размонтировать обычным
umount
.
Т.к. после UP7 система, наконец-то, научилась монтировать устройства при помощи
gvfs-mtp
, при подключении устройства увидим 2 точки монтирования: одна та, что мы только что задали; другая - будет называться
Nexus_7
или как-нибудь похоже, и будет представлять собой путь вида
mtp://...
Всё бы ничего, но раз уж нам две шары ни к чему (всё прекрасно работает через go-mtpfs), можем удалить правила для gvfs-mtp. Кроме того, они, похоже, мешают перемонтировать устройство вручную при помощи go-mtpfs, если кабель не отключали/включали, а перемонтировать по какой-то причине было нужно.
Идём в
/lib/udev/rules.d/69-libmtp.rules
и комментируем следующие строки:
# Google Inc (for Asus) Nexus 7 (MTP)
#ATTR{idVendor}=="18d1", ATTR{idProduct}=="4e41", SYMLINK+="libmtp-%k", MODE="660", GROUP="audio", ENV{ID_MTP_DEVICE}="1", ENV{ID_MEDIA_PLAYER}="1"
# Google Inc (for Asus) Nexus 7 (MTP+ADB)
#ATTR{idVendor}=="18d1", ATTR{idProduct}=="4e42", SYMLINK+="libmtp-%k", MODE="660", GROUP="audio", ENV{ID_MTP_DEVICE}="1", ENV{ID_MEDIA_PLAYER}="1"
На этом всё. И чтобы наши правила вступили в силу:
sudo service udev restart
Выключаем/включаем кабель и вуаля - шара в
/media/mtp
. Разумеется, папку перед выполнением всех описанных операций надо создать :)
Закачка у меня происходит на скорости около 8 МБ/с.
Падений не наблюдается.
Есть ещё один нюанс. Если попытаться в файловом браузере отмонтировать шару, то получим сообщение, что мы не рут и сделать этого не можем.
Чтобы разрешить размонтирование, рекомендуют добавить правило в
/etc/fstab
:
DeviceFs(Nexus\0407) /media/mtp fuse.DeviceFs(Nexus\0407) allow_other,rw,user,noauto 0 0
Я не смог заставить эту опцию заработать. Кроме того, архитектура MTP такова, что как только вы скопировали файл, можно вытаскивать кабель, не боясь что-либо потерять или испортить файловую систему устройства.
Зато я добавил два удобненьких алиаса в
~/.bashrc
:
alias mtpmount='go-mtpfs /media/mtp'
alias mtpumount='fusermount -u /media/mtp'