LinuxでAndroidSDKの更新をするとき、/tmpの容量不足で失敗する事への対処方法

最近のLinuxディストリビューションは/tmpに物理メモリを割り当てていることがあるようですが、例えば当方が使用しているFedora26は、標準で物理メモリの半分をtmpfsとして/tmpにマウントしているようです。

当方のPCは物理メモリが8Gしか無いので、/tmpは4Gしか使えないことになります。これで、AndroidSDKの更新(特にNDKの更新)をすると、/tmpを使い切ってしまい、「ディスクの空きが足りない」的な英語のエラーメッセージと共に失敗します。この現象の対策をしてみます。

対策

/tmpへのtmpfsのマウントはsystemdがやっているのですが、下手にsystemdのユニットをいじって起動不能になるのは面倒なので、systemdには手を出さないことにします。

javaの一時ファイル用ディレクトリを変更する

というわけで、javaの挙動を変えていきます。java実行環境はシステムプロパティ「java.io.tmpdir」を一時ファイル記憶場所とするので、-Dオプションでこのプロパティを変えてしまえば、任意のディレクトリを一時ファイル記憶場所にできます。

java "-Djava.io.tmpdir=/path/to/tmp" -jar hogehoge.jar

では、どうやってAndroidStudioやsdkmanagerにこのオプションを与えるかですが、まず、AndroidStudioはシェルスクリプトpath/to/AndroidStudio/bin/studio.shを、sdkmanagerはシェルスクリプトpath/to/AndroidSDK/tools/bin/sdkmanagerをそれぞれ実行することで起動しています。これらスクリプトjavaコマンドを起動しているのですが、オプションを与えるためにこれらスクリプトを書き換えてしまうと、逆に/tmpを使いたいときに、また戻さないといけなくなります。

そこで、環境変数「_JAVA_OPTIONS」を使います。例えば、AndroidStudioを起動する場合はこうします。

export _JAVA_OPTIONS="-Djava.io.tmpdir=/path/to/tmp"
#studio.shを含むディレクトリへのパスは通してあるものとします。
studio.sh

スクリプトで自動化

毎度ディレクトリを作ったり、環境変数をexportしたりするのは面倒なのでスクリプト化します。

  • ロックファイルをロック(無ければ作成)
  • 一時ファイルディレクトリを作成
  • 環境変数を設定
  • AndroidStudioを起動
  • 一時ファイルディレクトリを削除
  • ロックファイルをアンロック

この一連の操作を実行するスクリプトを作成します。

ロックファイルは$HOME/.as_lockとし、一時ファイルディレクトリを$HOME/.as_java_tmpとします。PowerShell Core向けスクリプトを作成します。(えっ!bash?だれですかそれ?)

AndroidStudioWithTemporaryDirectoryOnDisk.ps1

#!/usr/bin/pwsh -F

Set-Location $env:HOME
try{
	if(Test-Path AndroidStudioWithTemporaryDirectoryOnDisk_Error_Log.txt){
		Remove-Item AndroidStudioWithTemporaryDirectoryOnDisk_Error_Log.txt
	}
	[System.IO.FileStream]$lock_file = New-Object System.IO.FileStream (".as_lock", [System.IO.FileMode]::Create)
	$lock_file.Lock(0, 1)
	if(!(Test-Path .as_java_tmp)){
		New-Item .as_java_tmp -ItemType Directory
	}
	if(!((Get-Item .as_java_tmp -Force).PSIsContainer)){
		throw "./.as_java_tmp is not directory"
	}
	Set-Item env:_JAVA_OPTIONS -value ($env:_JAVA_OPTIONS + " -Djava.io.tmpdir=" + $env:HOME + "/.as_java_tmp")
	studio.sh
	Remove-Item .as_java_tmp -Force -Recurse
	$lock_file.Unlock(0, 1)
}
catch{
	Write-Host $Error | Out-File AndroidStudioWithTemporaryDirectoryOnDisk_Error_Log.txt
}

このスクリプトを$HOME/.local/binなどPATHの通った場所に置き、実行権を与えておけば、いつでも簡単に$HOME/.as_java_tmpを一時ファイルディレクトリにしてAndroidStudioを開始できます。

マウス操作だけで開けるようにする

どうせなら、アプリケーションメニューやデスクトップ上のアイコンから上記スクリプトを実行できると楽なので、.desktopファイルを作っていきます。

アプリケーションメニューのプログラミングカテゴリにあるAndroidStudioの項目をデスクトップに追加し、テキストエディタで開きます。項目が無い場合、AndroidStudioでTools->Create Desktop Entryを選択して作成できます。開いたらこれを改造します。

#!/usr/bin/env xdg-open
[Desktop Entry]
Version=1.0
Type=Application
Name=Android Studio With Disk Temporary Directory
Icon=/opt/AndroidStudio/bin/studio.png
Exec=AndroidStudioWithTemporaryDirectoryOnDisk.ps1
Comment=The Drive to Develop
Categories=Development;IDE;
Terminal=false
StartupWMClass=jetbrains-studio

Nameをそれっぽい名前にし、Execを先程のスクリプトにします。IconはAndroidStudioのインストール先によって異なるので違うかもしれません。

適当に名前を付けて(ここではjetbrains-studio-disk-tmp.desktop)デスクトップに保存します。これを/usr/local/share/applicationsか$HOME/.local/share/applicationsに入れておけばアプリケーションメニューにも追加されます。