LXDのコンテナ内でゲームパッドを使用する


LXDのコンテナでゲームパッドを使用できるようにしてみます。


環境

マシン : Raspberry Pi 5 8G

OS : Raspberry Pi OS(64-bit)

LXD : 5.0.2

ゲームパッド : ロジクール ゲームパッド F310

F310ゲームパッド - コンソールスタイル - ロジクールゲーミング


ゲームパッドの動作の確認は




jstest-gtkで行うことにします。

GitHub - Grumbel/jstest-gtk


最初にLXDのコンテナでGUIアプリを起動するを参考にコンテナ内でGUIアプリを使用できるようにしておきます。

インスタンス名はc1で話を進めます。




c1インスタンスに入り、inputグループのgidを調べてます。

$ lxc exec c1 bash
# less /etc/group | grep input
input:x:995:ubuntu

※# はコメントではなく、rootアカウントで操作している意味になります


c1インスタンス内でのinputグループのgidは995でした。

inputのgidは後ほど使用しますので記録しておきます。


c1インスタンスから抜け、USB接続したゲームパッドをコンテナ内で使用できるようにします。

# exit
$ lsusb
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 002: ID 046d:c216 Logitech, Inc. F310 Gamepad [DirectInput Mode]
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 002: ID 046d:c548 Logitech, Inc. Logi Bolt Receiver
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hjub

lsusbを実行することで、ゲームパッドはBus 003のDevice 002として接続されていることがわかりました。


上の出力内容の太字で示した箇所の値を用いて、c1インスタンスにデバイスの追加を行います。

$ lxc config device add c1 pad unix-hotplug vendorid=046d productid=05c4

太字の箇所の前四文字がUnixデバイスのベンダーID(vendorid)になりまして、後ろ四文字がUnixデバイスの製品ID(productid)になります。

デバイスを追加する時は、typeをunix-hotplugにします。

タイプ: unix-hotplug - LXD ドキュメント


コンテナ内でゲームパッドを使用する時はもう一つデバイスを追加する必要があります。

$ lxc config device add c1 js0 unix-char path=/dev/input/js0 source=/dev/input/js0 gid=995

末尾のgidには、インスタンス内で調べたinputグループのgidを指定します。

タイプ: unix-char - LXD ドキュメント


c1インスタンスの設定状況を確認しておきます。

$ lxc config show c1
architecture: aarch64
config:
  environment.DISPLAY: :0
  image.architecture: arm64
  image.description: ubuntu 24.04 LTS arm64 (release) (20240523.1)
  image.label: release
  image.os: ubuntu
  image.release: noble
  image.serial: "20240523.1"
  image.type: squashfs
  image.version: "24.04"
  raw.idmap: both 1000 1000
  volatile.base_image: c66a955225db160b6d094acc0ad1528afe1ca1727c814440625df75a64c80e44
  volatile.cloud-init.instance-id: d7edc386-1cd4-49cc-ad48-c556e6056f1e
  volatile.eth0.host_name: veth1b3b633e
  volatile.eth0.hwaddr: 00:16:3e:65:48:7b
  volatile.idmap.base: "0"
  volatile.idmap.current: '[{"Isuid":true,"Isgid":false,"Hostid":165536,"Nsid":0,"Maprange":1000},{"Isuid":true,"Isgid":true,"Hostid":1000,"Nsid":1000,"Maprange":1},{"Isuid":true,"Isgid":false,"Hostid":166537,"Nsid":1001,"Maprange":9999000},{"Isuid":false,"Isgid":true,"Hostid":165536,"Nsid":0,"Maprange":1000},{"Isuid":true,"Isgid":true,"Hostid":1000,"Nsid":1000,"Maprange":1},{"Isuid":false,"Isgid":true,"Hostid":166537,"Nsid":1001,"Maprange":9999000}]'
  volatile.idmap.next: '[{"Isuid":true,"Isgid":false,"Hostid":165536,"Nsid":0,"Maprange":1000},{"Isuid":true,"Isgid":true,"Hostid":1000,"Nsid":1000,"Maprange":1},{"Isuid":true,"Isgid":false,"Hostid":166537,"Nsid":1001,"Maprange":9999000},{"Isuid":false,"Isgid":true,"Hostid":165536,"Nsid":0,"Maprange":1000},{"Isuid":true,"Isgid":true,"Hostid":1000,"Nsid":1000,"Maprange":1},{"Isuid":false,"Isgid":true,"Hostid":166537,"Nsid":1001,"Maprange":9999000}]'
  volatile.last_state.idmap: '[]'
  volatile.last_state.power: RUNNING
  volatile.uuid: f6f0caa4-61ba-45d7-a208-223d803bbab1
devices:
  js0:
    gid: "995"
    path: /dev/input/js0
    source: /dev/input/js0
    type: unix-char
  mygpu:
    gid: "44"
    type: gpu
  pad:
    productid: 05c4
    type: unix-hotplug
    vendorid: 046d
  x11:
    path: /tmp/.X11-unix/X0
    source: /tmp/.X11-unix/X0
    type: disk
ephemeral: false
profiles:
- default
stateful: false
description: ""

コンテナとの比較用として、/dev/input/以下も見ておきます。

$ ls -l /dev/input/
合計 0
drwxr-xr-x  2 root root     140  ** ** **:** by-id
drwxr-xr-x  2 root root     200  ** ** **:** by-path
crw-rw----  1 root input 13, 64  ** ** **:** event0
crw-rw----  1 root input 13, 65  ** ** **:** event1
crw-rw----  1 root input 13, 66  ** ** **:** event2
crw-rw----  1 root input 13, 67  ** ** **:** event3
crw-rw----  1 root input 13, 68  ** ** **:** event4
crw-rw----  1 root input 13, 69  ** ** **:** event5
crw-rw----  1 root input 13, 70  ** ** **:** event6
crw-rw----+ 1 root input 13, 71  ** ** **:** event7
crw-rw----+ 1 root input 13,  0  ** ** **:** js0
crw-rw----  1 root input 13, 63  ** ** **:** mice
crw-rw----  1 root input 13, 32  ** ** **:** mouse0

ゲームパッド(js0)のパーミッションの末尾に + があります。

この + はACL(Access Control Lists⁠)⁠」によるパーミッションの設定が行われていることを意味するそうです。

第627回 コンテナの中でもWindowsのゲームを! | gihyo.jp

アクセス制御リスト - Wikipedia




c1インスタンスを再起動して、c1インスタンスに入り、jstest-gtkでゲームパッドが使用出来る事を確認してみます。


$ lxc restart c1
$ lxc exec c1
# sudo gpasswd -a ubuntu input
# sudo apt update
# sudo apt install jstest-gtk
# jstest-gtk

を実行して、


ゲームパッドが認識されている事を確認しましょう。


最後にインスタンスへ追加したデバイスの内容を確認しておきます。

# lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 001 Device 003: ID 046d:c548 Logitech, Inc. Logi Bolt Receiver
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 003 Device 002: ID 046d:c216 Logitech, Inc. F310 Gamepad [DirectInput Mode]
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
# ls -l /dev/input/
total 0
crw-rw---- 1 root input 13, 0 ** ** **:** js0
マインクラフト用ビジュアルエディタを開発しています。
詳しくはinunosinsi/mcws_blockly - githubをご覧ください。