z80oolong さんはインスタンス qiitadon.com のユーザーです。アカウントさえ持っていればフォローしたり会話したりできます。 もしお持ちでないなら こちら からサインアップできます。

z80oolong @z80oolong@qiitadon.com

# Linuxbrew において ARM 系アーキテクチャで brew install が異常終了する問題を回避する

## 概要

ARM 系アーキテクチャにおいて、 Linuxbrew を用いて各種パッケージをビルドする場合に、 brew install コマンドを起動すると、以下のようなエラーメッセージを出力して異常終了する場合があります。

*** Error in `gcc-4.9': double free or corruption (top): 0x000b6a30 ***

そこで、ディレクトリ $HOMEBREW_PREFIX/bin 以下に、 gcc コンパイラに渡すオプションのうち、 -march=native 等を除去するためのラッパースクリプトを導入することにより、前述のような brew install コマンドが異常終了する問題を回避することが可能となりました。

## 詳細

詳細については、以下の記事を御覧下さい。

[1]:z80oolong.qrunch.io/entries/fj

## Firefox ESR のダウングレード

そして以下のようにして、パッケージ ```firefox-esr_45.9.0esr-1~deb8
1_armhf.deb``` をインストールします。

$ sudo gdebi ./firefox-esr_45.9.0esr-1~deb8
1_armhf.deb

## Firefox ESR の動作確認

最後に、以下のようにして、バージョン 45.9 にダウングレードした Firefox を起動して、 Firefox が正常に動作するか確認します。

$ firefox &

上記のダウングレードにより、 Firefox の画面が正常に表示されれば、 Firefox ESR が問題無く動作する事が判ります。

## ダウングレードの準備

本稿では、 Firefox ESR のバージョンを 45.9 にダウングレードする手法について述べます。

まず最初に、ディレクトリ /var/cache/apt/archives において、ファイル ```firefox-esr_45.9.0esr-1~deb8
1_armhf.deb``` が存在する事を確認し、このファイルを適当なディレクトリに以下のようにコピーします。

$ cp /var/cache/apt/archives/firefox-esr_45.9.0esr-1~deb8
1_armhf.deb .

次に、任意の .deb ファイルをインストールするためのソフトウェアである gdebi を以下のようにインストールします。

$ sudo apt-get install gdebi

# Debian noroot 環境において Firefox の動作に関する問題とその回避策について

## 概要

Debian noroot 環境において Firefox ESR を導入した場合、最新の Firefox を起動すると、 Firefox の画面が何も表示されない障害が発生することがあります。

これは、 Firefox の起動時に共有メモリに関するディレクトリ /dev/shm を参照した時に、 /dev/shm が一般ユーザに対してアクセス権限が適切に与えられない状態にある事が原因であると考えられます。

また、 Firefox が共有メモリを Debian 環境内の標準ライブラリ関数 shmat 等を介して操作していない事も原因として考えられます。

この問題は、旧版の Firefox のうち、共有メモリを Debian 環境内の標準ライブラリ関数 shmat 等を介して操作しているバージョンにダウングレードする事によって回避する事が出来ます。

ここでは、 Firefox ESR のダウングレードによって Firefox の問題を回避する手法について述べます。

## 追記 (2018/07/01)

link2symlink 機能を実装した proot において、内部ファイル ".l2s.*" を外部から削除した場合、ハードリンクの動作に不具合が発生する問題について、以下の通りの手法で不具合が解決致しました。

即ち、 Termux の開発コミュニティによる proot のソースコードに、システムコール getdents(2) をフックするコードを追加することにより、内部ファイル ".l2s.*" が proot の子プロセスから不可視化されて、当該問題が解決しました。

システムコール getdents(2) をフックするコードの追加については、 GnuRoot の開発コミュニティによる proot のコードを参考にしました。

なお、問題を修正した proot は、[proot-termux-build の最新の安定版][1]から入手できます。

[1]:github.com/z80oolong/proot-ter

## 結論

[pelya 氏][1]による libandroid-shmem.so と異なり、 [termux の開発コミュニティ][2]による libandroid-shmem.so は、関数 shmget(2) の第一引数 key に IPC_PRIVATE 以外の値を指定出来るために、 [termux の開発コミュニティ][2]による libandroid-shmem.so の導入によって Qt の共有メモリ関連のライブラリ関数を用いたソフトウェア等が Debian noroot 環境 で正常に動作し、また、他の共有メモリを使用したソフトウェアについても動作のパフォーマンスが向上したことが判りました。

[1]:github.com/pelya
[2]:termux.com/

(続き)
この動的ファイルを使用するには、まず最初に生成された動的ライブラリを Debian noroot 環境のルートディレクトリにインストールします。

# install -v -m 0755 libandroid-shmem-termux.so /

次に、 Debian noroot 環境の初期化ファイルである /proot.sh において、環境変数 LD_PRELOAD が定義されている行を以下のように修正します。

# LD_PRELOAD="... /libandroid-shmem.so ..."
LD_PRELOAD="... /libandroid-shmem-termux.so ..." # /libandroid-shmem.so を /libandroid-shmem-termux.so に修正。

初期化ファイル /proot.sh の修正後は、 Debian noroot 環境を再起動して設定を有効にします。

(続き)
そして、入手したソースコードが置かれているディレクトリに、以下のようにして、差分ファイル libandroid-shmem-termux-0.2_1-fix.diff を適用して通常通りに make コマンドによってコンパイルすると、動的ライブラリ libandroid-shmem-termux.so が生成されます。

$ patch -p1 < /path/to/diff/libandroid-shmem-termux-0.2_1-fix.diff
(ここに、 /path/to/diff は、 libandroid-shmem-termux-0.2_1-fix.diff が置かれているディレクトリのパス名)
$ make ... (オプションを適宜設定すること。)

## 差分ファイルの適用とソースコードのコンパイル

まず、 [termux の開発コミュニティ][2]による libandroid-shmem.so の github 版若しくは v0.2 版を以下の URL から入手し、 tarball の場合は適当なディレクトリに展開します。

- github.com/termux/libandroid-s
- github.com/termux/libandroid-s

次に、[termux の開発コミュニティ][2]による libandroid-shmem.so を Debian noroot 環境に再移植するための差分ファイルを以下の URL より入手します。

- gist.githubusercontent.com/z80

[2]:termux.com/

(続き)
しかし、 [pelya 氏][1]による
libandroid-shmem.so では、 Qt の共有メモリ関係のライブラリ関数を用いたソフトウエアが正常に動作しなかったり、その他の共有メモリを使用したソフトウェアの動作のパフォーマンスがあまり良くないという問題があります。

ここで、 Debian noroot 環境において、 [pelya 氏][1]による libandroid-shmem.so に代えて、 [termux の開発コミュニティ][2]によって改良された libandroid-shmem.so を導入することにより、Qt の共有メモリ関係のライブラリ関数を用いたソフトウエアの正常な動作や、その他の共有メモリを使用したソフトウェアの動作のパフォーマンスの向上を図ることが出来るようになりました。

[1]:github.com/pelya
[2]:termux.com/

# Termux 開発コミュニティによる libandroid-shmem.so を Debian noroot 環境に導入する

## はじめに

Debian noroot とは、 Android OS 上において root 権限を取ることなく Debian 環境を構築するためのアプリケーションです。

CPU の性能とメモリ容量が潤沢にある Android 端末であれば、 Debian noroot の導入によって Android 端末上で非常に軽快な Debian 環境を実現することができます。

[pelya 氏][1]によって作成された Debian noroot 環境には、共有メモリ関連の標準 C ライブラリ関数を /dev/ashmem によってエミュレートする Debian noroot 環境のための動的ライブラリである libandroid-shmem.so が導入されています。

[1]:github.com/pelya

この場合、ハードリンク元及びハードリンク先のファイルにアクセスしようとすると、Permission Denied のシステムコールエラーを発生して proot 環境下においてこれらのファイルの読み書きが完全に不可能となる場合があります。

この場合、問題となったファイルを削除するには、一旦 proot を link2symlink 機能を無効にして再起動する必要がありますので、ご注意下さい。

また、この問題の解決については、現在調査中ですのでどうか御了承下さい。

## ファイル .l2s.*, .l2s.*.0002 についての問題点

ここで、 proot 環境下において、ファイル .l2s.* 等は、一般ユーザの権限で書き込みや削除を行うことが可能であるため、これらのファイルをハードリンク元等のファイルより削除する操作を行った場合、実体を保持するファイルである .l2s.*.0002 等の場合は、ハードリンク元等のファイルの実体が失われることとなり、また、中間的なシンボリックリンクである .l2s.* の場合は、ハードリンク元の参照先を失うこととなります。

なお、この操作は、ハードリンクを作成したファイルを含むディレクトリを rm -rf コマンドで削除しようとした場合等に発生します。

2. 2回目以降に、ハードリンク元となるファイルからハードリンク先となるファイルにハードリンクを張る時、以下の処理が行われる。

- ハードリンク元となるファイルの実体のファイル名である .l2s.*.0002 の末尾の .0002 の数字を .0003 にインクリメントする。
- ハードリンク元となるファイルの実体のファイル .l2s.*.0003 に向けて、中間的なシンボリックリンク .l2s.* を張り直す。
- 中間的なシンボリックリンク .l2s.* に向けて、ハードリンク先となるファイル名にシンボリックリンクを張る。

3. proot による chroot 環境下においては、 1. 及び 2. で示された過程で作成されたシンボリックリンクが擬似的にハードリンクとして扱われる。

上記の事から判るように、ハードリンク元及びハードリンク先のファイルは、中間的なシンボリックリンク .l2s.* を経由して実体となるファイル .l2s.*.0003 を参照している事が判ります。

1. 1回目に、ハードリンク元となるファイルからハードリンク先となるファイルにハードリンクを張る時、以下の処理が行われる。

- ハードリンク元となるファイルの実体のファイル名が .l2s.*.0002 で始まるファイル名に変更される。
- ハードリンク元となるファイルの実体のファイル .l2s.*.0002 に向けて、中間的なシンボリックリンク .l2s.* を張る。
- 中間的なシンボリックリンク .l2s.* に向けて、ハードリンク元及びハードリンク先となるファイル名にシンボリックリンクを張る。

## proot の link2symlink 機能の動作原理

ここで、 Qiita の投稿 "[Debian noroot 環境において link2symlink 機能を実装した proot を導入する][1]" における "[proot の動作確認][2]" の章で述べた proot の link2symlink 機能の動作原理について下記に再掲します。

0. link2symlink 機能を実装した proot の子プロセスよりシステムコール link(2) が実行されると、 proot によってこれがフックされ、以下の処理が行われる。

[1]:qiita.com/z80oolong/items/20a1
[2]:qiita.com/z80oolong/items/20a1

# link2symlink 機能を実装した proot についての注意点

## 概要

termux の開発コミュニティによる link2symlink 機能を実装した proot について、下記のようにファイル foo から foo1 にハードリンクを張ると、 proot の内部で、 .l2s. で始まるファイルが作成されます。

$ cd ./test
$ ln foo foo1
$ ls -a
.l2s.foo0000.0002 .l2s.foo0000 foo foo1
...

これらのファイルは、ファイル foo, foo1 から張られる中間のシンボリックリンク及び foo, foo1 の実体となるファイルです。

これらのファイルは、一般ユーザから書き込みや削除が可能であり、これらのファイルをファイル foo, foo1 より先に削除した場合、 foo, foo1 のアクセスに著しい障害が発生する可能性があるので注意が必要です。

## Debian noroot 環境の再起動

/startx.sh を変更した後、 Debian noroot 環境を再起動すると、 ratpoison が使用出来るようになります。

## 設定の変更

パッケージ ratpoison をインストールした後は、以下のように、Debian noroot 環境の起動スクリプトである /startx.sh において、  xfce-session コマンドを起動している行を ratpoison コマンドを起動するように書き換えます。

...(略)...

sleep 1
#dbus-launch --exit-with-session sh -c 'xfce4-session ; setsid sh -c "cd /proc/ ; for f in [0-9]* ; do [ \$f = \$\$ ] || kill -9 \$f ; done"' &
dbus-launch --exit-with-session sh -c 'ratpoison ; setsid sh -c "cd /proc/ ; for f in [0-9]* ; do [ \$f = \$\$ ] || kill -9 \$f ; done"' & wait

## ratpoison の導入

軽量のタイル型ウィンドウマネージャ ratpoison は、コマンドライン上から apt-get コマンドを用いて、以下のようにして導入することが出来ます。

$ sudo apt-get install ratpoison