ERROR: ld.so: object ‘/usr/lib/arm-linux-gnueabihf/libarmmem.so’ from /etc/ld.so.preload cannot be preloaded (cannot open shared object file): ignored.を解決したい

Raspberry Pi 3 Model B
OS: Raspbian Stretch lite April 2018

久しく触れていなかったRaspberry Pi 3に電気を点してRaspbianを起動したところ、いくつかのコマンドでERROR: ld.so: object ‘/usr/lib/arm-linux-gnueabihf/libarmmem.so’ from /etc/ld.so.preload cannot be preloaded (cannot open shared object file): ignored.というエラーメッセージがあらわれるようになっていたから慌てたものである。どうやら/etc/ld.so.preloadから呼び出される/usr/lib/arm-linux-gnueabihf/libarmmem.soが開けずこういう有り様になるようである。

$ lxc list
ERROR: ld.so: object '/usr/lib/arm-linux-gnueabihf/libarmmem.so' from /etc/ld.so.preload cannot be preloaded (cannot open shared object file): ignored.
(snip)

こういう場合はrpi-updateを実行することで解決へ導かれることがある模様であるから試みるとこうである。

$ sudo rpi-update
 *** Raspberry Pi firmware updater by Hexxeh, enhanced by AndrewS and Dom
(snip)
 *** If no errors appeared, your firmware was successfully updated to 328f413f7d2ec7855e25ff282d4354c57ce38860
 *** A reboot is needed to activate the new firmware

$ sudo reboot

再起動後に改めてコマンドを実行してみるとエラーメッセージはすっかり掻き消えてしまったからほんとうによかった。

参考:
ERROR: ld.so: object ‘/usr/lib/arm-linux-gnueabihf/libarmmem.so’ from /etc/ld.so.preload cannot be preloaded (cannot open shared object file): ignored.

Raspberry Pi 3でUbuntu MateをUSBブートさせる

Raspberry Pi 3 Model B
OS: Raspbian Stretch lite April 2018
OS: Ubuntu MATE 16.04.2

RaspbianであればUSBメモリに焼き付けるだけで素直にUSBブートしてくれるのであるが、Ubuntu MateをUSBブートさせるとなれば様々細工を施しておかねばならぬようである。まずはRaspberry Pi 3に搭載されているOne Time Programmable(OTP) メモリに対してUSBブートを許すビットをセットせねばならない。これは一旦セットしてしまうともはや元に戻すこと能わないから勢い慎重にならざるを得ない。セット前のOTPメモリの様子はこうである。

$ vcgencmd otp_dump | grep 17:
17:1020000a

/boot/config.txtの御仕舞いにprogram_usb_boot_mode=1を追記する。

$ echo program_usb_boot_mode=1 | sudo tee -a /boot/config.txt
program_usb_boot_mode=1

そうしたら再起動する。

$ sudo reboot

再起動後にあらためてOTPメモリの様子を窺い17番目の箇所が「3020000a」となっていたら宜しいようである。

$ vcgencmd otp_dump | grep 17:
17:3020000a

次はRaspbianとUbuntu Mateのイメージを準備する。圧縮された姿のままであるとこのあとに控える開始セクタの取り調べにちょっと困るので併せて解凍も済ませておく。

$ wget -c http://director.downloads.raspberrypi.org/raspbian_lite/images/raspbian_lite-2018-04-19/2018-04-18-raspbian-stretch-lite.zip
$ unzip 2018-04-18-raspbian-stretch.zip

$ wget -c https://ubuntu-mate.org/raspberry-pi/ubuntu-mate-16.04.2-desktop-armhf-raspberry-pi.img.xz
$ xz -dkv ubuntu-mate-16.04.2-desktop-armhf-raspberry-pi.img.xz

そうしたらまずはRaspbianを構成するそれぞれのパーティションがどのセクタから開始しているかを詳らかにする。これらが明らかになったらマウント用のディレクトリをこしらえてパーティション毎にループバックマウントする。

$ parted 2018-04-18-raspbian-stretch.img
(snip)
(parted) unit B
(parted) print
Model:  (file)
Disk /home/guro/local/tmp/2018-04-18-raspbian-stretch.img: 4953473024B
Sector size (logical/physical): 512B/512B
Partition Table: msdos

Number  Start      End          Size         Type     File system  Flags
 1      4194304B   49384447B    45190144B    primary  fat32        lba
 2      50331648B  4953473023B  4903141376B  primary  ext4

(parted) quit

$ sudo mkdir -p /mnt/raspbian/bootfs /mnt/raspbian/rootfs
$ sudo mount -t vfat -o loop,offset=4194304 2018-04-18-raspbian-stretch.img /mnt/raspbian/bootfs
$ sudo mount -t ext4 -o loop,offset=50331648 2018-04-18-raspbian-stretch.img /mnt/raspbian/rootfs

Ubuntu Mateのイメージファイルについても同じ要領でループバックマウントする。

$ parted ubuntu-mate-16.04.2-desktop-armhf-raspberry-pi.img
(snip)
(parted) unit B
(parted) print
(snip)
Number  Start      End          Size         Type     File system  Flags
 1      1048576B   67108863B    66060288B    primary  fat16        lba
 2      67108864B  4999610367B  4932501504B  primary  ext4

$ sudo mkdir -p /mnt/mate/bootfs /mnt/mate/rootfs
$ sudo mount -t vfat -o loop,offset=1048576 ubuntu-mate-16.04.2-desktop-armhf-raspberry-pi.img /mnt/mate/bootfs
$ sudo mount -t ext4 -o loop,offset=67108864 ubuntu-mate-16.04.2-desktop-armhf-raspberry-pi.img /mnt/mate/rootfs

そうしたらUSBブートに必要となるファイルをRaspbian側からUbuntu Mateの方へ複製する。

$ sudo cp -av /mnt/raspbian/rootfs/lib/modules/4.14.34* /mnt/mate/rootfs/lib/modules/
$ sudo cp -av /mnt/raspbian/rootfs/lib/firmware/brcm/brcmfmac43455-sdio.* /mnt/mate/rootfs/lib/firmware/brcm/

$ cd /mnt/raspbian/bootfs/
$ sudo cp -av bootcode.bin fixup.dat start.elf bcm2710-rpi-3-b-plus.dtb kernel.img kernel7.img bcm2710-rpi-* /mnt/mate/bootfs/

それからUbuntu Mateのcmdline.txtとfstabも書き換える。

$ sudo vi /mnt/mate/bootfs/cmdline.txt
dwc_otg.lpm_enable=0 console=serial0,115200 console=tty1 root=/dev/sda2 rootfstype=ext4 elevator=deadline fsck.repair=yes rootwait quiet splash plymouth.ignore-serial-consoles init=/usr/lib/raspi-config/init_resize.sh

$ sudo vi /mnt/mate/rootfs/etc/fstab
proc       /proc      proc    defaults          0       0
/dev/sda2  /          ext4    defaults,noatime  0       1
/dev/sda1  /boot/     vfat    defaults          0       2

これで下準備は終いであるからRaspbianとUbuntu MateのイメージをアンマウントしておいてUSBメモリにUbuntu MateのイメージをEtcherなどで焼き付けてやればRaspberry Pi 3でUSBブートできたのでよかった。

$ sudo umount /mnt/raspbian/* /mnt/mate/*

参考:
HOW TO BOOT FROM A USB MASS STORAGE DEVICE ON A RASPBERRY PI 3
RPI vcgencmd usage
Ubuntu-Mate fails to boot on Raspberry-Pi 3 via USB

motionのオプションについて

Raspberry Pi 3 Model B
OS: Raspbian Stretch lite March 2018
Logicool HD Webcam C270

motionには大変多くのオプションが用意されているのでちょっと戸惑う。調べたものを備忘録として記載し折に触れて参照するものである。なお設定確認のために頻回の起動と停止を繰り返すと突如機嫌を損ねることがあった。また設定ファイルのコメントに書いてあるデフォルト値と実際の設定値が異なることが屡々あったけれどもそういう事もあろうとおもう。

オプション 内容
daemon デーモンとして起動するかどうかをonかoffで指定。デフォルトではoff。
setup_mode motionをセットアップモードで起動。ライブストーリムの動画は変化があったピクセルが黒白や青で表示されてるようになり、何も知らぬ人が見れば故障したと思う。ライブストリームを見ながらノイズレベルの調整をしたり斑点状ノイズの除去の様子を確認しながら、動体を検知したと認める閾値を自ら定める場合に使うようである。
v4l2_palette カラーフォーマットと言われるものを指定。デフォルトは17でこれはYUV420を示している。ウェブカメラがサポートしていないフォーマットを指定していてもmotionが勝手に対応フォーマットを探して選択してくれるのでまことにゆき届いているとおもう。なおログを確認してみるとC270はYUYVかMJPGをサポートしている事がわかるので8か15を選択すればよいようである。
input 1つ以上の入力を持つキャプチャカードの数を記載するようである。USBカメラを接続しているなら-1を選択する。デフォルトも-1。
power_line_frequency 電源周波数に併せて指定する設定であるが通常はデフォルトのままでよいようである。電源周波数に繊細なウェブカメラで画像が安定しない場合に試すのが良さそうである。
rotate 画像の回転角度を0、90、180、270度から選択。デフォルトは0。0度以外を選択すると回転させる手数がかかるためかCPUの負荷がいくらか大きくなるようである。此れ以外の角度を指定すると「rotate_init: Config option “rotate” not a multiple of 90:」という風にエラーメッセージが記録され0度を指定したものとして扱われた。
90度回転させたようす
width 画像の横幅をpixelで指定。デフォルトは352と設定ファイルのコメントには書いてあるけれども設定値は320であった。8の倍数でなければ「vid_v4lx_start: config image width (~) is not modulo 8」という具合にエラーが記録される上、motionが起動しなかった。C270は720pをサポートしているので1280を指定したがheightを240のままにしていたところ、形が歪に過ぎるのか「v4l2_do_set_pix_format: Adjusting resolution from 1280×240 to 544×288.」という具合に解像度が勝手に調節されるようである。
height 画像の縦幅をpixelで指定。デフォルトは288と設定ファイルのコメントには書いてあるけれども設定値は240であった。やはり8の倍数でなければならない。720pをサポートするC270だから720を指定すると大変大きく画面に写し出すことができた。

framerate 動体を検知した時に画像をキャプチャするフレームレートの最大値を指定するようである。取りうる値は2~100で、100を指定すると実質的に上限を撤廃することと同様という。設定ファイルのコメントではデフォルト100との記載であったが設定値は2であった。数値を大きくすればCPUの負荷も上がるということである。C270ではwidth x heightが1280×720の場合は高々5fps程度であったけれども640×320にすると14fps前後までキャプチャできたので解像度も影響するような情勢である。
auto_brightness 輝度を自動で設定するか否かを決める。選択肢はonかoffである。C270ではonにするとログに「v4l2_set_control: setting control “Brightness” to 253 (ret -1 Input/output error)」といった具合のメッセージがひっきりなしにあらわれるから懸命に輝度をセットしようとしているフシがあるけれども恐らく効果がないようである。
brightness 輝度を0~255で指定。デフォルトは0で、これはmotion側で輝度をセットしないということである。なおC270では0以外の数値をセットしても「v4l2_set_control: setting control “brightness” to 2 (ret -1 Input/output error)」のようなメッセージがログに記録されるばかりで写し出される映像の様子に特段の変化は無いようであった。contrast(コントラスト)やsaturation(彩度)、hue(色相)についても同様であった。
threshold 閾値である。この数値を超えると動体を検知したとみなす。変化があったピクセルの数を閾値として指定する。デフォルトは1500。ノイズの処理が関係しているようなので単純に現フレームと一つ前のフレームを比較して変化があったピクセル数がカウントされるというわけではないようである。
pre_capture 動体検知が始まる前の画像をどれだけバッファしておくか指定する。取扱説明書を見ると0~100秒で指定するように見えるけれども、作成された動画をコマ送りにして確認してみるとどうもフレーム数ではないかという疑いがある。デフォルトは0。0は一つもバッファしないのと同じことである。あまり大きな数値を指定するとフレームがスキップされたり動画の滑らかさが失われるため0~5程度に収めておくのがよいとあるけれども0~5秒という意味合いであれば指定する値はframerateの数値だけ乗ずるのがよさそうである。
post_capture 動体の検知が完了してから何フレーム余分にキャプチャするか指定する。デフォルトは0。1~5秒程度になるようフレーム数を設定するのがおすすめであるという。
event_gap この設定は要すれば動体検知が収まってからevent_gap秒以内にまた動体を検知したらそれは一つの動画にまとめられるというようなことであると思う。event_gap秒を超えればそれは別イベントとして捉えられ記録動画も新たに別ファイルとして生成されるような風情であった。デフォルトは60。
max_movie_time 動画の最大記録秒数を指定。デフォルトは0でこれは上限を設けないことを意味する。無闇に1などを設定すると1秒の細切れ動画が山ほどできあがるので本当に不毛であった。
output_pictures 動体を検知した際、画像をどういう具合に出力するか指定。on、off、first、bestから選択できる。onは動体を検知した際の画像を全部出力する。offはまったく画像を出力しない。firstは動体を検知した一番最初のフレームのみ保存する。bestは動体検知イベント中でもっともピクセル数に変化が見られた場面を出力する。デフォルトではonだから放って置くとどんどんストレージを占拠してゆくおそれがある。
output_debug_pictures 変化が見られたピクセルがどこであったのかを黒白青赤で示す画像を出力する。上は通常の出力画像、下がこの設定で出力される画像。元の画像がわかっているとデバッグ画像もなんとなく意味を持って見えてくるようになるので妙なものである。

quality 画質の設定。デフォルトは75。1~100の間から指定する。100はほとんど圧縮がかからないので画質はよいけれどもファイルサイズが大きく、数値が小さくなると圧縮が強くなってゆき画質も劣化してゆく。なお1はこういう有様であった。目を細めて遠くから見るとちょっと画質が上がったように錯覚するので妙なものである。

picture_type 出力する画像のフォーマットを指定。jpegとppmから選択する。デフォルトはjpeg。ppm(portable pixmap format)はファイルサイズが大きいのでストレージの膨らみ具合には気を使う必要がある模様である。
ffmpeg_output_movies 動体を検知した際に動画を作成するか否かをonかoffで指定。デフォルトではoffとの記載であったが設定ファイルはonであった。
ffmpeg_bps 動画のビットレートを指定する。0から9999999の間で指定し、デフォルトは400000。ffmpeg_variable_bitrateが有効になっている場合はこの設定は無視されるという。
ffmpeg_variable_bitrate 可変ビットレートで動画をエンコードするよう設定する。0~100で指定し、デフォルトは0。0は可変ビットレートでのエンコードを無効にする。数値が大きいほど画質は高くなってゆく。
locate_motion_mode 検知した動体は此の箇所であるぞと表明する枠を表示する設定。on、off、previewから選択し、デフォルトではoff。previewでは画像にのみ枠を表示し、動画には表示しない。枠が表示されると途端に近未来的な風情がして好きである。

locate_motion_style 検知した動体は此れであるぞと示す枠のスタイルを設定。box、redbox、cross、redcrossから選択し、デフォルトではbox。boxは白枠、redboxは赤枠、crossは白十字、redcrossは赤十字である。locate_motion_modeが有効でないと意味をなさない。crossを選択するとこういう具合である。

text_right 画面の右下に表示する文字列を設定。変換指定子の一覧を参考にしつつ装飾してゆくとよさそうである。デフォルトでは%Y-%m-%d\n%T-%qである。それぞれ年-月-日、改行、時刻-フレーム番号、を示している。文字列を表示させない為にはtext_rightとだけ記述すればよかった。日本語を含むとSegmentation faultが発生してMotionが起動しない。
text_left 画面の左下に表示する文字列を設定。text_rightとおおむね同じことであるが設定していないと文字列は表示されない点が異なる。やはり日本語を含むといけない。使用できない変換指定子があったのでこれはmotionのバージョンによる問題であるかもしれない。

text_changes 変化のあったピクセル数を画面の右上に表示する。

text_double テキストのサイズを通常の二倍に拡大するならonにする。デフォルトではoff。もともとが大変細かい文字なので大きく表示されるのはまことにありがたい。

target_dir 画像と動画を保存するディレクトリを指定。指定しないとカレントディレクトリになる。デフォルトでは/var/lib/motionが記載されていた。
picture_filename 画像ファイルの名前を指定。デフォルトではイベント番号-年月日時刻-フレーム番号となる。
movie_filename 動画フィアルの名前を指定。デフォルトではイベント番号-年月日時刻となる。
stream_port ライブストリームの待受ポート番号。デフォルトでは8081が指定されていた。
stream_quality ライブストリームの画質。デフォルトは50。1~100の間から選択し、数値が大きくなるほど画質はよくなる。
stream_motion 動きのないうちはフレームレートを1にし、動体を検知したらフレームレートを増すようにする設定。フレームレートはstream_maxrateで指定した値まで増す。ネットワーク帯域の無駄遣いが許されない環境では帯域の節約に貢献するとおもう。

stream_localhost ライブストリームへのアクセスをローカルホストからのみに制限する。デフォルトではon。誰もが見られるようにするならoffを指定する。
stream_auth_method ライブストリームへのアクセスに認証を必要とする設定。0は無効、1はBasic認証、2はDigest認証。デフォルトでは無効。特段の理由がなければ認証を要するように誂えるのがよさそうである。
stream_authentication 認証に使うユーザ名とパスワードを指定。ユーザ名:パスワード といった形式で記載する。
stream_preview_scale Motionのウェブ設定画面に表示するライブストリーム映像の大きさを指定する。単位は取扱説明書に記載されていないけれどもHTMLソースにあるimgタグのwidth属性を見ると%単位であったのでそういうことであろう。デフォルトでは25なので1/4サイズで表示される。

webcontrol_port ブラウザからMotionの設定を可能にするならポート番号を記載してwebcontrol_authenticationもセットする。デフォルトは0で無効ということであるがすでに8080とセットされていた。
webcontrol_localhost Motion設定画面へのアクセスをlocalhostのみに制限するならon。デフォルトでonになっていた。制限を外すならoffにする。
webcontrol_authentication ウェブ設定画面へのアクセスに認証を要するようにする設定。ユーザ名:パスワード のフォーマットで記載する。stream_auth_methodのときと違いメソッドはBasic認証のみであるようである。ウェブ設定画面を有効にするのであれば絶対に設定すべきであるという風情で取扱説明書に記載がある。

if you are enabling the webcontrol feature of Motion, you really really really … should enable security authentications. No. Seriously. You really should.

ここまでの設定を組み合わせて概ね満足行く形の動体検知がこなされるようになった。

参考:
Motion

Raspbianにmotionを導入してブラウザからウェブカメラの映像を見る

Raspberry Pi 3 Model B
OS: Raspbian Stretch lite March 2018
Logicool HD Webcam C270

Raspberry Pi 3 Model BにHD Webcam C270を接続すれば忽ち認識されるし、uvcvideoモジュールも併せてロードされるから面倒と向かい合うことなく使えそうな様子である。

$ lsusb
Bus 001 Device 004: ID 046d:0825 Logitech, Inc. Webcam C270

$ lsmod | grep uvc
uvcvideo               90112  0

motionパッケージのインストールには夥しい数のライブラリに加えてffmpegも併せてインストールされるので自前で用意したffmpegがあるならばちょっと注意を要すると思う。

$ sudo apt install motion

ひとまず設定ファイルにあるstream_localhostをoffに変更する。これがonのままであるとlocalhostからしかライブストリームの様子を観察できない。

$ sudo vi /etc/motion/motion.conf
#stream_localhost on
stream_localhost off

そうしてmotionを起動したら、motionが稼働するマシンのIPアドレスの8081番ポートへブラウザでアクセスするとこういう具合である。

$ sudo motion
[0:motion] [NTC] [ALL] conf_load: Processing thread 0 - config file /etc/motion/motion.conf
[0:motion] [NTC] [ALL] motion_startup: Motion 4.0 Started
[0:motion] [NTC] [ALL] motion_startup: Logging to file (/var/log/motion/motion.log)

なお、セットアップモードという言葉に惹かれて-sオプションをつけて起動すると出力された映像はこういう有様であった。何がなんだか一寸わからない。ドキュメントをみると変化のあった画素を黒白や青で表現するように読み取れる。動体検知の設定をする際のノイズ除去や閾値の決定をするにあたって役立つような風情である。

参考:
HD Webcam C270
Linux UVC driver and tools
Motion

RaspbianにLXDを導入する

Raspberry Pi 3 Model B
OS: Raspbian Stretch lite March 2018

RaspbianではaptコマンドでLXDパッケージを導入することができないようであるからSnappyというパッケージマネージャで以ってインストールするのがよいようである。先んじてaptコマンドでlxcとsnapdパッケージをインストールしておく。

$ sudo apt install lxc snapd
$ sudo snap install lxd

$ snap list
Name  Version    Rev   Tracking  Developer  Notes
lxd   3.0.0      6661  stable    canonical  devmode

lxdコマンドは/snap/binへ配置されるようであるからパスを通すぞと息巻いていたらすでに開通済みであり拍子抜けしたものである。どうやら/etc/profile.d/apps-bin-path.shがこの役割を担っているようであった。

$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/games:/usr/games:/snap/bin

$ cat /etc/profile.d/apps-bin-path.sh
# Expand the $PATH to include /snap/bin which is what snappy applications
# use
PATH=$PATH:/snap/bin

然し乍らsudoで実行する際には/etc/sudoersにあるsecure_pathの影響が及ぶからこのままでは「sudo: lxd: コマンドが見つかりません」と出て終いである。そうであるからsecure_pathにも/snap/binを追加する。

$ sudo visudo
#Defaults       secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
Defaults        secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/snap/bin"

そうしたらsudo lxd initで初期設定をおこなう。クラスタリングモードで実行するか否かやストレージなどに関する様々な問いかけがあるけれどもひとまずはすべてデフォルトのまま通した。

$ sudo lxd init
Would you like to use LXD clustering? (yes/no) [default=no]:
(snip)

なんらかコンテナの操作をしようとするとこうである。パーミッションの設定がソケットファイルへの接続を許してくれない模様である。パーミッションを確認するとrootユーザとlxdグループにだけ読み書きを許すような情勢である。

$ lxc list
If this is your first time running LXD on this machine, you should also run: lxd init
To start your first container, try: lxc launch ubuntu:16.04
Error: Get http://unix.socket/1.0: dial unix /var/snap/lxd/common/lxd/unix.socket: connect: permission denied

$ sudo ls -l /var/snap/lxd/common/lxd/unix.socket
srw-rw---- 1 root lxd 0  4月 11 21:50 /var/snap/lxd/common/lxd/unix.socket

このままではユーザpiがたいへん困るのでlxdグループに追加するとよい。なお続けざまにコンテナを操作しようとしても同じエラーメッセージを頂戴したので一旦ログアウトして再度ログインするとよさそうである。

$ sudo gpasswd -a pi lxd
ユーザ pi をグループ lxd に追加

これでコンテナの操作がほしいままになった。

参考:
Linux Containers – LXD – オンラインでの試用