Armadilloフォーラム

コンテナ起動後のUSB認識方法

uen2825

2023年4月19日 15時36分

お世話になっております。
A6Eを使用して開発しています。
コンテナ(a6e-gw-container)を起動し、後からUSBを接続し、USBに書込みを実行したいと思っています。
下記サイトから試したところUSBの認識は出来ました。
https://armadillo.atmark-techno.com/blog/15349/13918
起動しているコンテナ(a6e-gw-container)からUSBを認識させる方法を教えてください。
宜しくお願いいたします。

コメント

at_dominique.m…

2023年4月19日 16時42分

uen2825さん

お世話になっています、
アットマークテクノのマルティネです。

> コンテナ(a6e-gw-container)を起動し、後からUSBを接続し、USBに書込みを実行したいと思っています。
> 下記サイトから試したところUSBの認識は出来ました。
> https://armadillo.atmark-techno.com/blog/15349/13918
> 起動しているコンテナ(a6e-gw-container)からUSBを認識させる方法を教えてください。

ボリュームを shared で追加すると、後でマウントされたディレクトリをコンテナから見えます。

以下の例では alpine イメージを使っていますが、a6e-gw-container のコンフィグで似たような add_volumes コマンドを追加できればと思います。
同じく、手動でマウントしていますがブログのような udev によるマウントコマンドでもいいです。

armadillo:~# cat /etc/atmark/containers/alpine.conf
set_image docker.io/alpine
set_command sleep infinity
 
add_volumes /var/app/volumes/mnt:/mnt:shared
 
# コンテナの強制再起動
armadillo:~# podman_start alpine
alpine
3e055cf2030cb508e9e86f5d3e6876f825c9c1c20e33f791ff90035e9715dcac
armadillo:~# mkdir /var/app/volumes/mnt/usb
armadillo:~# mount /dev/sda1 /var/app/volumes/mnt/usb
armadillo:~# podman exec -ti alpine sh
/ # df /mnt/usb/
Filesystem           1K-blocks      Used Available Use% Mounted on
/dev/sda1               204800      3616    121856   3% /mnt/usb
/ # exit

分かりにくくてすみません、何か問題あったら聞いてください。

よろしくお願いします。

アットマークテクノ
マルティネ様
ご回答ありがとうございます。
仰る通りの手順で確認できました。
この手順をプログラムでできないでしょうか。
やりたいことはUSBを挿した時にデータをUSBに書き込み、USBを抜いてもいい状態にしたいと思っています。
ここでする質問でない内容でしたらご容赦ください。

at_dominique.m…

2023年4月28日 11時59分

uen2825さん

> この手順をプログラムでできないでしょうか。
> やりたいことはUSBを挿した時にデータをUSBに書き込み、USBを抜いてもいい状態にしたいと思っています。
> ここでする質問でない内容でしたらご容赦ください。

そうですね…方法はいくつかありますが、起動しているアプリケーション類によりますね。

シンプルな shell script 程度のアプリケーションでしたら、先週に紹介した udev ルールでマウントするから、コマンドを mount ではなく自分のスクリプトを動かしてしまえばそれだけでいいと思います。
コンテナを使わずにホストから mount && cp && umount もできますし、podman exec でコンテナと接触するもできます(mount && podman exec <container> <command> && umount

もう少し独立したアプリケーションでしたら、専用のマウントコンテナを作った方が楽かもしれません?

3月にリリースされた Armadillo Base OS 3.17.2-at.4 で podman_start に hotplug の対応を追加したので、
機能があれば以下のコンフィグで udev のイベントを待って用事に合わせたプログラムを動かせます:
※ ABOS のバージョンは /etc/atmark-release で確認できます

armadillo:~# cat /etc/atmark/containers/hotplug.conf
# sd でストレージ系のデバイスにアクセスを設定します
# /run/udev は例の pyudev に必要です、次のアップデート
# に add_hotplugs で自動的に追加することにします。
add_hotplugs sd
add_volumes /run/udev:/run/udev:ro
# マウントするに SYS_ADMIN を追加します
add_args --cap-add SYS_ADMIN
# スクリプトのあるボリュームの追加
add_volumes /var/app/volumes/udev:/app
# 自分のイメージです。alpine に py3-udev をインストールしたものです。
set_image udev
# 自分のスクリプトの実行
set_command python3 /app/monitor.py

で monitor.py の内容を以下にして:

import pyudev
context = pyudev.Context()
monitor = pyudev.Monitor.from_netlink(context)
monitor.filter_by(subsystem='block')
for action, device in monitor:
    if action != 'add':
        continue
    if device.properties.get('ID_FS_USAGE') != 'filesystem':
        continue
    print(f'added mountable {device.device_node}')

USB デバイスを差し込む際にメッセージが表示されますが、対応は自由にプログラムできます。
C の場合は https://man7.org/linux/man-pages/man3/udev_monitor_receive_device.3.html 等で似たような対応はできます。

これでどうでしょうか?

よろしくお願いします。

アットマークテクノ
マルティネス様
ご回答ありがとうございます。

> コンテナを使わずにホストから mount && cp && umount もできますし、podman exec でコンテナと接触するもできます(mount && podman exec && umount

podman execより
コンテナ内からumountしようとするとコマンドが見つからないと出てしまいます
/ # ummount /mnt/usb
/bin/sh: ummount: not found
対処方法があればご教授ください

何度も申し訳ございません。

> / # ummount /mnt/usb
> /bin/sh: ummount: not found

umountではなく、mが一つ多くはいってummountになっているようですが、
umountで試した結果not foundになったでしょうか?

大変失礼いたしました。
下記のようなエラーになってしまいます。

/ # umount /mnt/usb
umount: can't unmount /mnt/usb: Operation not permitted

宜しくお願いいたします。

at_dominique.m…

2023年5月10日 9時38分

uen2825さん

マルティネです。

> / # umount /mnt/usb
> umount: can't unmount /mnt/usb: Operation not permitted

umount はマウント同様に「CAP_SYS_ADMIN」の制限が必要ですので、/etc/atmark/containers/xxx.conf に「add_args --cap-add SYS_ADMIN」を追加しないとできません。(この linux の capability が大きすぎてすごく残念です…)

podman exec でコマンドを実行している様に見えますので、この問題をごまかすには podman exec の後に umount もできます。
例えば:
- ホスト側の udev rule で container_copy.sh を実行:
ACTION=="add", KERNEL=="sd*", SUBSYSTEM=="block", ENV{ID_FS_USAGE}=="filesystem", RUN+="/var/app/volumes/container_copy.sh %k"

- container_copy.sh の内容は以下のとおり

#!/bin/sh
# udev の %k はデバイス名になります、例えば sda1
mount "/dev/$1" /var/app/volumes/mnt/usb || exit
podman exec mycontainer cp -a ...
umount /var/app/volumes/mnt/usb

アットマークテクノ
マルティネス様

> umount はマウント同様に「CAP_SYS_ADMIN」の制限が必要ですので、/etc/atmark/containers/xxx.conf に「add_args --cap-add SYS_ADMIN」を追加しないとできません。(この linux の capability が大きすぎてすごく残念です…)

上記追加したところうまくいきました。
ありがとうございました。