Friday, March 9, 2018

使用LXC建立USB以及X-forward環境

使用LXC建立USB以及X forward環境

因為修課需要一些debian系的工具,不過我不想讓debian系的和Arch Linux混在一起,所以LXC看起來是一個不錯的解。

環境

  1. OS: Arch Linux (4.15.7-1-ARCH)
  2. LXC
  3. ubuntu on LXC

步驟

LXC準備

安裝 LXC

$ sudo pacman -Sy lxc arch-install-scripts debootstap

建立 Host Network (NAT bridge) (Arch Wiki寫得很好看Arch Wiki)

建立/etc/default/lxc-net(詳情見Arch Wiki)
USE_LXC_BRIDGE="true"
LXC_BRIDGE="lxcbr0"
LXC_ADDR="10.0.3.1"
LXC_NETMASK="255.255.255.0"
LXC_NETWORK="10.0.3.0/24"
LXC_DHCP_RANGE="10.0.3.2,10.0.3.254"
LXC_DHCP_MAX="253"
修改lxc template conf,在/etc/lxc/default.conf新增
lxc.net.0.type = veth
lxc.net.0.link = lxcbr0
lxc.net.0.flags = up
lxc.net.0.hwaddr = 00:16:3e:xx:xx:xx
安裝dnsmasq
$ sudo pacman -Sy dnsmasq
開啟以及設定開機啟動:
sudo systemctl start lxc-net
sudo systemctl enable lxc-net

建立container (ubuntu)

建previleged的container
$ sudo lxc-create -n UbuntuBuild -t /usr/share/lxc/templates/lxc-ubuntu [ -P lxc-location]  
修改container的網路(由於我要裝的軟體的license綁mac address,所以我需要修改一下mac address),修改lxc的路徑下的config file,若沒指定lxc的位置,預設是在/var/lib/lxc/CONTAINER_NAME/config,有指定路徑則在 /PATH/YOU/DEFINED/CONTAINER_NAME/config
## default values
... 
...
## network
lxc.net.0.type = veth
lxc.net.0.link = br0
lxc.net.0.flags = up
lxc.net.0.name = eth0
lxc.net.0.hwaddr = .... ## 自行修改mac address

LXC Xorg

修改container的config(同上位置)
## default values
...
...
# network
...
...
## for xorg
lxc.mount.entry = /dev/dri dev/dri none bind,optional,create=dir
lxc.mount.entry = /dev/snd dev/snd none bind,optional,create=dir
lxc.mount.entry = /tmp/.X11-unix tmp/.X11-unix none bind,optional,create=dir,ro
lxc.mount.entry = /dev/video0 dev/video0 none bind,optional,create=file

lxc.mount.entry = tmpfs tmp tmpfs defaults
基本上邏輯是把Xorg需要的device mount進來。
/dev/dri為direct rendering manager(DRM)的device file,
/dev/snd為音效的device file
/dev/video0為video device file
ubuntu on LXC中安裝X相關套件
$ sudo lxc-console -n UbuntuBuild [ -P /path]
進到ubuntu lxc
# sudo apt-get install xauth x11-apps
使用ssh -X進入LXC
# /usr/bin/xclock
應該要有windows跑出來
其他app可能會需要裝dbus
# sudo apt-get install dbus dbus-x11
其他部份可以看以連結How Do I Get X11 Applications Running in a LXC Container?

LXC USB

修改container的config(同上位置)
## usb
lxc.cgroup.devices.allow = c 189:* rwm

lxc.mount.entry = /dev/bus/usb/001 dev/bus/usb/001  none bind,optional,create=dir
lxc.mount.entry = /dev/bus/usb/002 dev/bus/usb/002  none bind,optional,create=dir
lxc.mount.entry = /dev/bus/usb/003 dev/bus/usb/003  none bind,optional,create=dir
lxc.mount.entry = /dev/bus/usb/004 dev/bus/usb/004  none bind,optional,create=dir
接下來我們來探究一下
lxc.cgroup.devices.allow = c 189:* rwm
這行的意思,首先
$ ls -al /dev/bus/usb/001
drwxr-xr-x 2 root root     80 Mar  8 23:06 .
drwxr-xr-x 6 root root    120 Mar  8 23:06 ..
crw-rw-r-- 1 root root 189, 0 Mar  8 23:06 001
crw-rw-r-- 1 root root 189, 1 Mar  8 23:06 002
你會發現189這個數字,這數字其實是major number,這些數字在Linux的文件中都有定義,請看https://github.com/torvalds/linux/blob/master/Documentation/admin-guide/devices.txt
逗號後為minor number,有於usb裝置多,所以在lxc.cgroup.devices.allow中用wildcard取代。底下部份就是把usb的device folder mount進LXC中。

LXC Serial Port設定

由於修課需要用到serial port,但是Serial Port的tty只有插上後才會出現,這對開機就需mount的lxc來說偏麻煩。這時有一個好用的指令出現了。

lxc-device

在使用lxc-device時仍須注意cgroup是否有允許該裝置。
例如Serial Port常用(USB serial converters)的major number為188。所以需要在config中新增
lxc.cgroup.devices.allow = c 188:* rwm
這樣開機後才有效果。接下來,在插入裝置後找到該裝置device名稱,例如
/dev/ttyUSB1。這時我們需要透過lxc-device把其接入中。
$ sudo lxc-device -n CONTAINER_NAME [-P path] add /dev/ttyUSB1
這樣這個裝置就會被加入LXC中了。

精選文章

使用Ardunio Atmega2560 連接 nRF24L01+

使用Ardunio Atmega2560 連接 nRF24L01+ 關於library 目前主流有 https://github.com/maniacbug/RF24 與 https://github.com/TMRh20/RF24 這兩個。 其中TMRh20大大做...