Linux Kernel 5.11 をセルフビルドしたメモ

Linux Kernel 5.11 がリリースされました.

F2FSの圧縮周りもアップデートがあるようなので試してみたくなりました.ということでセルフビルドしたらこれまで出なかったエラーが出たのでメモしておきます.

Warning
Debian sid amd64の 5.10.0-3-amd64 環境でビルドしました.Linux 5.9はビルドしたことがあるけれど,Linux 5.10はビルドしたことのない環境です.

Linux 5.11 build時にエラー( BTF: .tmp_vmlinux.btf: pahole (pahole) is not available )

以下のようなエラーが発生しました.

$ make -j`nproc` bindeb-pkg
〜省略〜
BTF: .tmp_vmlinux.btf: pahole (pahole) is not available
Failed to generate BTF for vmlinux
Try to disable CONFIG_DEBUG_INFO_BTF
〜省略〜
$ grep CONFIG_DEBUG_INFO_BTF ./.config
CONFIG_DEBUG_INFO_BTF=y

CONFIG_DEBUG_INFO_BTF を無効にすることも可能ですが, dwarves パッケージでDWARF utilitiesを導入するとこで解決しました.

$ sudo apt install dwarves

その他,DKMSでのVirtualBox moduleのビルドも失敗しました.これはVirtualBoxの対応待ちかなと思います.

ということで,以下のような感じで大丈夫そうです.

Linux 5.11のビルド

必要なパッケージの導入
$ sudo apt install build-essential linux-source bc kmod cpio flex libncurses5-dev libelf-dev libssl-dev dwarves
ソースの入手,確認と展開
$ wget https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.11.tar.xz \
https://cdn.kernel.org/pub/linux/kernel/v5.x/linux-5.11.tar.sign (1)
$ unxz ./linux-5.11.tar.xz (2)
$ gpg --verify ./linux-5.11.tar.sign (3)
gpg: assuming signed data in './linux-5.11.tar'
gpg: Signature made Mon 15 Feb 2021 06:11:32 PM JST
gpg:                using RSA key 647F28654894E3BD457199BE38DBBDC86092693E
gpg: Good signature from "Greg Kroah-Hartman <gregkh@linuxfoundation.org>" [unknown]
gpg:                 aka "Greg Kroah-Hartman (Linux kernel stable release signing key) <greg@kroah.com>" [undefined]
gpg:                 aka "Greg Kroah-Hartman <gregkh@kernel.org>" [unknown]
gpg: WARNING: This key is not certified with a trusted signature!
gpg:          There is no indication that the signature belongs to the owner.
Primary key fingerprint: 647F 2865 4894 E3BD 4571  99BE 38DB BDC8 6092 693E
$ tar tvf ./linux-5.11.tar | lv (4)
$ tar xf ./linux-5.11.tar (5)
$ cd linux-5.11
  1. sourceと署名を入手
  2. 解凍
  3. 署名確認(署名はこちらで確認)
  4. アーカイブ確認
  5. アーカイブ展開
configファイルの用意とビルド
$ cp /boot/config-`uname -r` ./.config (1)
$ yes "" | make oldconfig (2)
$ tar xf ../linux_5.10.9-1.debian.tar.xz debian/certs/ (3)
$ time make -j`nproc` bindeb-pkg (4)
  :
dpkg-deb: building package 'linux-libc-dev' in '../linux-libc-dev_5.11.0-1_amd64.deb'.
dpkg-deb: building package 'linux-image-5.11.0' in '../linux-image-5.11.0_5.11.0-1_amd64.deb'.
dpkg-deb: building package 'linux-image-5.11.0-dbg' in '../linux-image-5.11.0-dbg_5.11.0-1_amd64.deb'.
 dpkg-genbuildinfo --build=binary
 dpkg-genchanges --build=binary >../linux-5.11.0_5.11.0-1_amd64.changes
dpkg-genchanges: info: binary-only upload (no source code included)
 dpkg-source --after-build .
dpkg-buildpackage: info: binary-only upload (no source included)
$ ls -1s ../linux*.deb (5)
  7932 ../linux-headers-5.11.0_5.11.0-1_amd64.deb
728724 ../linux-image-5.11.0-dbg_5.11.0-1_amd64.deb
 52136 ../linux-image-5.11.0_5.11.0-1_amd64.deb
  1124 ../linux-libc-dev_5.11.0-1_amd64.deb
$ sudo apt install ../linux-image-5.11.0_5.11.0-1_amd64.deb ../linux-libc-dev_5.11.0-1_amd64.deb ../linux-headers-5.11.0_5.11.0-1_amd64.deb (6)
  1. 現在のkernel configをコピーする
  2. 新しい設定を既定値で設定
  3. Debianのkernel sourceから証明書をコピー(若しくは CONFIG_SYSTEM_TRUSTED_KEYS="" する)
  4. cpu数を指定してビルド開始
  5. 出来上がったパッケージの確認
  6. 出来上がったパッケージを導入
Machine Owner Key(MOK)で署名する(セキュアブートを有効にしている場合にのみ必要な処理)
$ sudo sbsign --key ~/MOK.priv --cert ~/MOK.pem /boot/vmlinuz-5.11.0 --output vmlinuz-5.11.0 (1)
$ sudo mv ./vmlinuz-5.11.0 /boot/vmlinuz-5.11.0
$ find /lib/modules/5.11.0/updates/dkms/ -type f | xargs -n1 sudo ./scripts/sign-file sha256 ~/MOK.priv ~/MOK.der (2)
  1. kernelに署名
  2. DKMSで作成したmoduleに署名

このあたりの処理は自動化できると思うんだけど未確認.
MOKの作成や,セキュアブートについては以下のページが参考になる.

環境

$ dpkg-query -W build-essential linux-source bc kmod cpio flex libncurses5-dev libelf-dev libssl-dev dwarves sbsign
tool
bc      1.07.1-2+b2
build-essential 12.9
cpio    2.13+dfsg-4
dwarves 1.20-1
flex    2.6.4-8
kmod    28-1
libelf-dev:amd64        0.183-1
libncurses5-dev:amd64   6.2+20201114-2
libssl-dev:amd64        1.1.1j-1
linux-source    5.10.13-1
sbsigntool      0.9.2-2
$ lsb_release -dr
Description:    Debian GNU/Linux bullseye/sid
Release:        unstable
$ uname -mr
5.10.0-3-amd64 x86_64
再起動後
$ uname -mr
5.11.0 x86_64

FirefoxとYoutube-dlでTVerの動画をダウンロードする

Tip
投稿時の2020-02-20時点のTVerと youtube-dl version 2021.02.10 では以下の手順は必要なく,youtube-dlで直接ダウンロードできるようになっています.
$ wget https://yt-dl.org/downloads/latest/youtube-dl
$ chmod u+x youtube-dl
$ ./youtube-dl $URL

先日TVerで見られる番組が見たくなりました.動画は再生途中で止まったりするのが嫌なので一旦ローカルにダウンロードしてから視聴することが多いです.

よく使うYoutube-DLではダウンロードできませんでした.

ERROR: Unsupported URL: https://tver.jp/episode/NNNNNNNN

siteのsourceを見るとbrightcoveを使っていて,brightcoveはyoutube-dlで対応しているようです.

ちなみにLinuxのChromiumで開くと推奨環境外と判定されて閲覧できません.Google ChromeやFirefoxだとそのまま,Chromimだとユーザーエージェントを変更することで閲覧できます.今回はFirefoxを利用しました.

推奨環境について
ご利用の環境はTVerの推奨環境ではございません。

推奨環境以外では、動画再生できないなど正常に動作しない場合がございます。
推奨環境でのご利用をお願い致します。

録画したいURLをFirefoxで開いて F12Ctrl + Shift + I 若しくは,メニューから「ウェブ開発」→「開発ツールを表示」で開発ツールを表示します.
Ctrl + f で検索ボックスを表示して data-account , data-video-id の値をメモします.

TVerDownload fx inspector

メモした値を以下のURLに埋め込みます.

後はこのURLを youtube-dl に渡してダウンロードできました.

環境
$ youtube-dl --version
2019.01.17
$ dpkg-query -W firefox
firefox 85.0.1-1
$ lsb_release -dr
Description:    Debian GNU/Linux bullseye/sid
Release:        unstable
$ uname -m
x86_64

TTY TwitterクライアントのTTYtterからOysttyerに乗り換え

TTYtterというPerl製でcliで動作するTwitter clientがあります.自作Twitter投稿scriptがアカウントをBANされてAPI keyが使えなくなった後これを使って自動投稿などをしていたのですが,Debian busterから無くなっています.
開発元を見るとOysttyerというものが変わりに存在するようなのでそちらに乗り換えました.

TTYtterからOysttyerに乗り換えるには認証鍵などを作り直す必要があるようです.
-oauthwizard オプションで認証ができるようです.
既定値では認証情報は ~/.oysttyerkey に保存されますが,複数のTwitterアカウントで利用したいので -key=認証情報格納ファイル オプションを付けて区別します.

Note
-keyf のパスに ~ を使うとエラーになるようです.今回は代わりに $HOME を使いました.
$ oysttyer -keyf=$HOME/.oysttyerkey_kagolug_ml -oauthwizard (1)
-- using SSL for default URLs.
trying to find cURL ... /usr/bin/curl
-- Streaming API disabled (no -dostream) (oysttyer will use REST API only)
-- no version check performed (use /vcheck, or -vcheck to check on startup)

+------------------------------------------------------------------------------+
|| WELCOME TO oysttyer: Authorize oysttyer by signing into Twitter with OAuth ||
+------------------------------------------------------------------------------+
Looks like you're starting oysttyer for the first time, and/or creating a
keyfile. Welcome to the most user-hostile, highly obfuscated, spaghetti code
infested and obscenely obscure Twitter client that's out there. You'll love it.

oysttyer generates a keyfile that contains credentials for you, including your
access tokens. This needs to be done JUST ONCE. You can take this keyfile with
you to other systems. If you revoke oysttyer's access, you must remove the
keyfile and start again with a new token. You need to do this once per account
you use with oysttyer; only one account token can be stored per keyfile. If you
have multiple accounts, use -keyf=... to specify different keyfiles. KEEP THESE
FILES SECRET.

** This wizard will overwrite ~/.oysttyerkey_kagolug_ml
Press RETURN/ENTER to continue or CTRL-C NOW! to abort.
(2)
Request from https://api.twitter.com/oauth/request_token ... SUCCEEDED!

1. Visit, in your browser, ALL ON ONE LINE,

https://api.twitter.com/oauth/authorize?oauth_token=lfqqTgAAAAAAixnPABABd7YG56I (3)

2. If you are not already signed in, fill in your username and password.

3. Verify that oysttyer is the requesting application, and that its permissions
are as you expect (read your timeline, see who you follow and follow new
people, update your profile, post tweets on your behalf and access your
direct messages). IF THIS IS NOT CORRECT, PRESS CTRL-C NOW!

4. Click Authorize app.

5. A PIN will appear. Enter it below.

Enter PIN> 0901765 (4)

Request from https://api.twitter.com/oauth/access_token ... SUCCEEDED!
Written keyfile /home/mk/.oysttyerkey_kagolug_ml

Now, restart oysttyer to use this keyfile.
(To choose between multiple keyfiles other than the default .oysttyerkey,
tell oysttyer where the key is using -keyf=... .)
  1. 認証ファイルを指定して認証処理実行
  2. Enterで続行
  3. URLをコピーしてウェブブラウザにて認証したいTwitterアカウントで許可する
  4. ウェブブラウザに表示されるPINを入力してEnter

これで認証情報が指定ファイルに格納されます.

TTYtterではScript中から以下のようにして投稿を行っていました.

ttytter -keyf=/home/mk/.ttytterkey-kagolug_ml -location -lat=31.5775639 -long=130.6667937 -status="$MESSAGE"

Oysttyerのユーザガイドのコマンドラインオプションを確認するとそのまま使えそうです.

コマンドと認証鍵ファイルを変更するだけで動作しました.

$ oysttyer -keyf=/home/mk/.oysttyerkey_kagolug_ml -location -lat=31.5775639 -long=130.6667937 -status="投稿テスト📮"
-- using SSL for default URLs.
trying to find cURL ... /usr/bin/curl
test-login SUCCEEDED!
post attempt -- using lat/long: (31.5775639, 130.6667937)
SUCCEEDED!

Scriptも同様にコマンドと鍵ファイルを書き換えました.これでbuster以降でも大丈夫なはずです :)

環境
$ dpkg-query -W oysttyer chromium
chromium        88.0.4324.146-1~deb10u1
oysttyer        2.10.0-1
$ lsb_release -dr
Description:    Debian GNU/Linux 10 (buster)
Release:        10
$ uname -m
x86_64

小さな静的htmlのKanban boardのNullboardを少し試す

静的htmlでローカルで完結するBanban board の Nullboard を知ったので少し試してみました.

ローカルにcloneして開くか, https://nullboard.io/preview にアクセスして試せます.

はじめはマニュアルやTipsの書かれたボードが表示されます.右上のメニューから「Add new board…​」を選んで新しいボードを作ってみます.

nullboard01

ボードが出来たら次はボードタイトルの右のメニューから「+List」でリストを追加出来ます.

nullboard02

リストのメニューから「+Note」でノートを追加したり,リストの移動が出来ます.移動はドラッグ&ドロップでも可能です.

nullboard03

日本語や絵文字も大丈夫です.

nullboard04

右上のメニューからデータのエクスポート,インポートが可能です.

どうやってローカルでデータを保存しているんだろうと思ったら,Local Storageで実現しているようです.

Nullboardの機能では手動でデータエクスポート,インポートが可能ですが自動でできるといいなと思ってデータの場所を探してみました.chromiumでは ` ~/.config/chromium/Profile\ 1/Local\ Storage/leveldb/000485.ldb` というファイルの中にNullboardに書いたデータがありました.

恐らくLevelDBというもののようです.自動バックアップするようにすると安心そうです.

Kanbanbordは色々ありますがNullboardはオフラインでローカルのみでも動作するのが面白いです.ただ,データの保管場所がLocalStorageなのでデータが消えてしまうのが怖いのでコマ目にバックアップを取ったほうが安心そうです.

環境
$ dpkg-query -W chromium firefox
chromium        88.0.4324.146-1
firefox 85.0.1-1
$ lsb_release -dr
Description:    Debian GNU/Linux bullseye/sid
Release:        unstable
$ uname -m
x86_64

軽量TwitterフロントエンドのNitterをセルフホスト

NitterというTwitterのフロントエンドがあります.最近はTwitterが重くてなにか検索しようと思っても待ち長かったり画像読み込み失敗したりといったこともよくあります(PCのスペックと回線が細いせいも大きいですが).軽量ブラウザを使ったりもしてみましたがそうすると見た目や使い勝手がいまいち.

そして現在そういった軽量ブラウザは利用もできなくなりました.

This browser is no longer supported.
Please switch to a supported browser to continue using twitter.com. You can see a list of supported browsers in our Help Center.

そこで Nitter を試してみたところ軽くていい感じです.

現在ログイン機能はないので,投稿や非公開Tweetや非公開リストなどは使えませんが,イベントのハッシュタグを追ったり,過去のtweetを検索といったことをするのに便利です.

RSS形式での出力にも対応しています.

軽量で便利なのでロカールマシンでNitterを動かして外にURLを共有するときは https://nitter.net/ を利用していました.

という話を以前オープンソースカンファレンス2020福岡内の鹿児島らぐのコマで発表しました.

しかし,最近は https://nitter.net/ がTwitterの制限に掛かって利用できないことが多くなってきました.なので自分のVPS上にホストしてみました.

Note
同じ手順で Raspberry Pi OS buster armhf や Debian sid(nimはDebinaパッケージのもの利用)でも動作しました.

Nitterのインストール環境の用意

Nitterが依存している Redislibsass を導入しておきます.

$ sudo apt install redis-server libsass-dev

Nitterを専用アカウントで動かしたいので nitter ユーザ,グループを作ってそのユーザで操作します.

$ sudo groupadd nitter (1)
$ sudo useradd -m -g nitter nitter (2)
$ sudo -iu nitter (3)
  1. nitter グループを作成
  2. nitter ユーザを作成
  3. nitter ユーザのシェルを開く

nimの用意

Nitterはnim-langで出来ています.Nitterのコンパイルにはnim 1.2.0以上が必要ですが,Debian busterのパッケージ版のnimは 0.19.4 でコンパイル出来ません.buster-backports も 1.0.4-1~bpo10+1 と対応していません.(bullseyeは1.4.2)

$ nimble build -d:release
  Verifying dependencies for nitter@0.1.0
       Tip: 2 messages have been suppressed, use --verbose to show them.
     Error: Unsatisfied dependency: nim (>= 1.2.0)
$ dpkg-query -W nim
nim     0.19.4-1

とりあえずnimの公式サイトのバイナリを利用してコンパイルすることにします.

$ wget https://nim-lang.org/download/nim-1.4.2-linux_x64.tar.xz \
https://nim-lang.org/download/nim-1.4.2-linux_x64.tar.xz.sha256 (1)
$ sha256sum -c ./nim-1.4.2-linux_x64.tar.xz.sha256 (2)
nim-1.4.2-linux_x64.tar.xz: OK
$ tar tvf nim-1.4.2-linux_x64.tar.xz | lv (3)
$ tar xvf nim-1.4.2-linux_x64.tar.xz (4)
  1. nimのバイナリをダウンロード
  2. hash確認
  3. アーカイブ確認
  4. アーカイブ展開

Nitterのコンパイル

Nitterのsourceをcloneしてさっきダウンロードして展開したnimでコンパイルします.

$ git clone https://github.com/zedeus/nitter
$ cd nitter
$ PATH=~/nim-1.4.2/bin:$PATH nimble build -d:release
$ PATH=~/nim-1.4.2/bin:$PATH nimble scss
$ mkdir ./tmp

Redis が起動しているのを確認して nitter を起動してみます.この状態で 8080 ポートにアクセスして Nitter が利用できるのを確認します.ポート番号などは nitter.conf で変更できます.

$ ps -ef|grep -i redis (1)
redis    11786     1  0 Feb11 ?        00:15:28 /usr/bin/redis-server 127.0.0.1:6379
$ ./nitter & (2)
$ w3m http://localhost:8080/ (3)
$ kill %1 (4)
$ exit (5)
  1. Redisが動いているのを確認
  2. Nitterを起動
  3. Nitterの動作を確認
  4. Nitterを終了
  5. nitter アカウントから抜ける

Nitterの起動設定

次にNitterに起動設定を行います.Systemd環境なので以下のようなサービスファイルを用意しました.

/etc/systemd/system/nitter.service
[Unit]
Description=Nitter (An alternative Twitter front-end)
After=syslog.target
After=network.target

[Service]
Type=simple

# set user and group
User=nitter
Group=nitter

# configure location
WorkingDirectory=/home/nitter/nitter
ExecStart=/home/nitter/nitter/nitter

Restart=always
RestartSec=15

[Install]
WantedBy=multi-user.target

サービスを有効にしてNitterを起動します.

$ sudo systemctl enable --now nitter.service
$ systemctl status nitter
● nitter.service - Nitter (An alternative Twitter front-end)
   Loaded: loaded (/etc/systemd/system/nitter.service; enabled; vendor preset: enabled)
   Active: active (running) since Wed 2021-02-17 01:13:07 JST; 34s ago
 Main PID: 19702 (nitter)
    Tasks: 1 (limit: 4696)
   Memory: 3.6M
   CGroup: /system.slice/nitter.service
           └─19702 /home/nitter/nitter/nitter
$ w3m http://localhost:8080/

外に公開せず,ローカルで動作させる場合はここまでの手順でOKです.

ドメインとSSL証明書の用意

※この手順はローカルで動かす場合は必要ありません.

今回はサブドメインを用意しました.DNSを設定して nitter.matoken.org を用意しました.設定ミスしたときにリカバリしやすいようにTTlを短く設定してうまく行ったらいつもの長さにします.

証明書はcertbotを使いLet’s encryptで作成しました.

$ sudo certbot certonly -d nitter.matoken.org

apache httpdの用意

※この手順はローカルで動かす場合は必要ありません.

Nitterをそのまま外に公開するのはセキュリティ的に良くないということで,apache httpdでhttpdの処理をしてNitterの8080に転送するようにしました.

Nitter用のapache httpd設定ファイルを用意します.

/etc/apache2/sites-available/nitter.matoken.org.conf
<VirtualHost *:80>
        ServerName nitter.matoken.org
        Redirect permanent / https://nitter.matoken.org/
</VirtualHost>
<IfModule mod_ssl.c>
<VirtualHost *:443>
        ServerName nitter.matoken.org
        ServerAdmin webmaster@matoken.org

        <Proxy *>
                Order deny,allow
                Allow from all
        </Proxy>

        ProxyPreserveHost On
        ProxyPass / http://127.0.0.1:8080/ nocanon
        ProxyPassReverse / http://127.0.0.1:8080/
        AllowEncodedSlashes On

        ErrorLog ${APACHE_LOG_DIR}/error.nitter.matoken.org.log
        CustomLog ${APACHE_LOG_DIR}/access.nitter.matoken.org.log combined

        SSLCertificateFile /etc/letsencrypt/live/nitter.matoken.org/fullchain.pem
        SSLCertificateKeyFile /etc/letsencrypt/live/nitter.matoken.org/privkey.pem

</VirtualHost>
</IfModule>

設定を有効にしてテスト後反映します.

$ sudo a2ensite nitter.matoken.org.conf (1)
$ sudo apache2ctl configtest (2)
$ sudo systemctl reload apache2 (3)
  1. 設定ファイルを有効にする
  2. 設定ファイルのテスト
  3. apache httpdの設定反映

この状態で http://nitter.matoken.org/ 及び https://nitter.matoken.org/ にアクセスしてみて Nitter が利用できたらOKです.

とりあえず一般公開しておきますが,今の https://nitter.net みたいにアクセス制限がしょっちゅうかかるようになったら制限するかもしれません.

環境

$ git -C ~nitter/nitter log -1
commit f392b6ca37e66c7c759aa98db23e0bdc62b39c3d (HEAD -> master, origin/master, origin/HEAD)
Author: Lukas Winkler <github@lw1.at>
Date:   Sun Feb 14 12:49:09 2021 +0100

    run optipng -o 9 on all images (#337)
$ dpkg-query -W apache2 redis* libsass-dev certbot
apache2 2.4.38-3+deb10u4
certbot 0.31.0-1+deb10u1
libsass-dev:amd64       3.5.5-4
redis-server    5:5.0.3-4+deb10u2
redis-tools     5:5.0.3-4+deb10u2
$ lsb_release -dr
Description:    Debian GNU/Linux 10 (buster)
Release:        10
$ uname -m
x86_64

AndroidスマートフォンをLinuxデスクトップのスピーカーにしてビデオ会議中に離席しても話に付いていけるようにする

以下の記事で「AudioRelay」というアプリを知りました.

ちょっと飲み物を取ってくるとかいうときなどに便利そう.
しかしこれはWindowsからAndroidへ転送するもので他の環境では動作しません.Linuxでも動作するものを探してみました.

「SoundWire」

SoundWireはWindow若しくはLinux x64_64(64bit)/x86(32bit),Raspberry Pi OSからAndroidへオーディオを転送してくれるようです.

バイナリが配布されているので対応するそれを入手して展開,実行してAndroidアプリから接続すればオーディオが転送されます.デスクトップファイルやアイコンも同梱されているので必要に応じて登録すると便利そうです.

$ tar tvf SoundWire_Server_linux64.tar.gz (1)
drwxrwxrwx Georgie/None      0 2020-01-26 21:22 SoundWireServer/
-rwxrwxrwx Georgie/None   2913 2020-01-16 09:00 SoundWireServer/INSTALL.txt
-rwxrwxrwx Georgie/None   1393 2020-01-16 08:46 SoundWireServer/license.txt
-rwxrwxrwx Georgie/None   2235 2014-09-16 09:08 SoundWireServer/opus_license.txt
-rwxrwxrwx Georgie/None   1583 2014-09-16 09:09 SoundWireServer/readerwriterqueue_license.txt
-rwxrwxrwx Georgie/None   6915 2020-01-26 21:22 SoundWireServer/README.txt
-rwxrwxrwx Georgie/None    448 2019-12-31 11:00 SoundWireServer/SoundWire-Server.desktop
-rwxrwxrwx Georgie/None 1611672 2020-01-16 11:55 SoundWireServer/SoundWireServer
-rwxrwxrwx Georgie/None  237351 2012-11-22 17:28 SoundWireServer/sw-icon.xpm
$ tar xf SoundWire_Server_linux64.tar.gz (2)
$ clamscan SoundWireServer/SoundWireServer (3)
$ ha512sum SoundWireServer/SoundWireServer
a0c1da0afad9e94aef82e19b2555ccf33494ec56fdbd6193a838beae31cec58ca75cae1949f520db84c6793bab13c9c3283b519416bebb1c54bbd66b5c489676  SoundWireServer/SoundWireServer
$ SoundWireServer/SoundWireServer (4)
  1. アーカイブの確認
  2. アーカイブの展開
  3. 念の為手動でもウィルス確認
  4. 実行

ソースは公開されていないようです.

ファイアウォールを利用している場合は,UDP:59010, 59011 を開放する必要があるようです.(起動オプションや環境変数でカスタマイズ可能)
その他, -nogui オプションでX無しでも動作します.

SoundWire PC

SoundWire Android

「WifiAudio」

「WifiAudio」はWindows若しくはLinux x86_64(64bit)からAndroidへオーディオを転送してくれるようです.

PC側は以下のページでバイナリが配布されているのですが,ダウンロードするにはフォーラムに登録が必要のようです.登録には氏名,メールアドレス,生年月日などを求められます.

$ clamscan ./wifiaudio_linux (1)
$ sha512sum ./wifiaudio_linux
6c78f47066ad550b988468c74e9bd56e099393a61a11ffffeda31fc181c60cbd5209763e80da9000d6453fef5cc829b9329b26d46993cc3f00c0bb76ffc81864  ./wifiaudio_linux
$ chmod u+x ./wifiaudio_linux (2)
$ ./wifiaudio_linux (3)
  1. 念の為手動でもウィルス確認
  2. 実行権付与
  3. 実行
$ lsof -i | grep wifiaudio
wifiaudio 1818239 matoken   12u  IPv4 15191466      0t0  UDP *:32000

利用ポートを確認すると UDP:32000 のようなのでファイアウォールを利用している場合は開放しておきます.

WiFiAudio PC
WiFiAudio Android

「ffmpegとVLC」

クローズドソースのものしか見当たらないなということで例によってffmpegで試してみます.
アプリケーションの音声をキャプチャしてmp3形式でスマートフォンのipアドレスに配信します.

$ pactl list short sources (1)
0       alsa_output.pci-0000_00_1b.0.analog-stereo.monitor      module-alsa-card.c      s16le 2ch 44100Hz       RUNNING
1       alsa_input.pci-0000_00_1b.0.analog-stereo       module-alsa-card.c      s16le 2ch 48000Hz       RUNNING
2       alsa_input.pci-0000_00_1b.0.analog-stereo.echo-cancel   module-echo-cancel.c    float32le 1ch 32000Hz   RUNNING
3       alsa_output.pci-0000_00_1b.0.analog-stereo.echo-cancel.monitor  module-echo-cancel.c    float32le 1ch 32000Hz   RUNNING
4       alsa_input.hw_Loopback_1_0      module-alsa-source.c    s16le 1ch 16000Hz       RUNNING
$ ffmpeg -f pulse -i alsa_output.pci-0000_00_1b.0.analog-stereo.monitor -ac 2 -acodec libmp3lame -f rtp rtp://10.42.0.90:1234/ (2)
  1. PulseAudioのデバイスを確認
  2. ffmpegでAndroidのIPに対してmp3形式で配信

この状態でVLC等で rtp://@:1234 を再生するとLinuxDesktopの音が流れてきます.

ffmpegのオプションについてはこのあたりを.

AndroidでmDNSが使えればいいのですが,使えなさそうなのでIPアドレスを確認するのがちょっとめんどうですね.固定IPにしたりマルチキャスト配信してしまってもいいかもしれません.

とりあえずはarpでごまかしてみました.

#!/bin/bash

MONITOR=`pactl list short sources | grep analog-stereo.monitor | cut -f2 -d'    '`
PHONE_MAC=18:d6:1c:00:00:00
PHONE_IP=`arp -i wlp3s0 | grep ${PHONE_MAC} | cut -f1 -d' '`
PORT=1234

ffmpeg -f pulse -i ${MONITOR} -acodec libmp3lame -ar 22050 -f rtp rtp://${PHONE_IP}:${PORT}/

VLC Android

「ffmpegとicecast2」

Wi-Fiの届く自宅内であればこれまでのものでいいですが,長丁場でご飯買いにコンビニまで行ってこようというような時には使えません.

外のサーバーに投げてストリーミングしてみます.今回はicecast2を利用しています.

$ ffmpeg -f pulse -i alsa_output.platform-snd_aloop.0.analog-stereo.monitor -loglevel 31 -stats -f adts -content_type audio/aac icecast://$USER:PASS@example.com:8000/stream

Androidでicecast2のurlを開くとLinuxデスクトップの音が聞こえてきます :)
ffmpegの部分をOBS StudioにするとGUIなのでとっつきやすいかもしれませんね.

帯域が気になる場合はビットレートを落とすといいと思います.このままだと128kbps程ですが, -ar 22050 として 64kbps, -ar 11025 をつけると32kbpsになります.
32kbpsはちょっと音が悪い感じなので,64kbps以上は欲しいかな?

icecast2などはこのあたりでも

ちなみに,VPSなどのサウンドカードのない計算機の場合以下のようにダミーデバイスを読み込むことで同じことが出来て便利です.
帯域が細かったりPCのスペックが足りないけど音声だけでも聞きたいといったときなどに使えます.

$ sudo modprobe -v snd-dummy
insmod /lib/modules/4.19.0-14-amd64/kernel/sound/drivers/snd-dummy.ko

終わりに

SoundWireとWifiAudioではLinuxではSoundWireの方がいいかなという感じです.しかしffmpeg+VLCでいいのではという感じも.
PC側の操作ですが,ボリュームは反映されず音量0でも配信されますが,ミュートすると聞こえなくなるので注意が必要です.
再生デバイスに迷った場合は pavucontrol などで Recordicg タブでプルダウンメニューからデバイスを順番に試していくといいと思います.音は出るけどノイズが多い場合はスピーカーからの音を拾っているマイクデバイスを選んで要る可能性があります.

そして現在自宅のWi-Fiは去年の台風時に壊れてNotePCをAPにしていて部屋を出ると電波が届かず実際は家の中ではどれも使えないという問題が.家を出て少し行くとmobile回線使えるんですけどね…….

環境

PC環境
$ SoundWireServer/SoundWireServer -nogui
    :
SoundWire Server v3.0
    :

$ dpkg-query -W ffmpeg lsof
ffmpeg  7:4.3.1-8
lsof    4.93.2+dfsg-1.1
$ lsb_release -dr
Description:    Debian GNU/Linux bullseye/sid
Release:        unstable
$ uname -m
x86_64
Android環境
SoundWire (free)
Version 3.0
WiFiAudio
Version 2.0
VLC
Version 3.3.4
本体
Rakuten mini(C330)
Android
9(セキュリティ アップデート:2020年12月5日)

Git学習ゲームの「Oh My Git!」

git game01

先週あったFOSDEM 2021のライトニングトーク(といっても1コマ20分)で知ったのですが,「Oh My Git!」というGit学習ゲームがあるそうです.

マルチプラットホームでWindows/macOS/Linux版が用意されています.バイナリはitch.ioで入手できます.

Note
itch.ioについてはこのあたりを.

ゲーミングプラットホームのitch – Speaker Deck

お題が出てきて,それにあった操作のカードを切ってgitの操作をしていきます.実際のコマンド内容も表示され,リポジトリも実際にローカルマシンに作られます.

git game02

ツリーがグラフィックで表現されてわかりやすいしキーボードに慣れていない人でもカードで操作だし入門に良さそうな感じです.後はローカライズされると勧めやすくなるかな.

Google Chrome/Chromium/Braveの履歴のタイムスタンプ形式を調べて1日分の履歴を手に入れる

たまに以前ウェブで見た情報が欲しくなることがあります.履歴に残っていればいいけど消えてしまっているかも.ウェブブラウザのアクセス履歴のタイトルとURLだけでもテキストファイルに残しておくと便利かもしれません.

履歴はHistoryファイルをsqlite3で叩くと取れるのですが,タイムスタンプがよくあるUNIX timeでもなくとても大きな値です.

$ sqlite3 ~/.config/chromium/Default/History "SELECT \"[\" || group_concat(json_object('timestamp', last_visit_time, title, url)) || \"]\" FROM urls;" | jq . | grep timestamp | sort
 -n | tail -1
    "timestamp": 13256542361632384,
UNIX timeの例
$ date +%s
1612703645

検索するとこのようなページを見つけました.

This timestamp format is used in web browsers such as Apple Safari (WebKit), Google Chrome and Opera (Chromium/Blink). It’s a 64-bit value for microseconds since Jan 1, 1601 00:00 UTC. One microsecond is one-millionth of a second.

このTimestampはUTC 1601-01-01からのマイクロセカンド秒らしいです.試してみます.

まずはUNIX timeの1601-01-01からの秒数に10^6を掛けてUNIX timeとの差を求めます.(GNU coreutilsのdateって1970-01-01より前の時間も計算できるんだ!)

UTC 1601-01-01のUNIX time?に10^6
$ echo "$( date --utc --date 1601-01-01 +%s ) * 10^6" | bc
-11644473600000000

Chrome時間とUNIX timeの差を引いてUNIX timeに変換します.

$ echo "( 13256542361632384 -11644473600000000 ) / 1000000" | bc
1612068761

UNIX timeを人間が読めるように変換

$ date --date="@1612068761"
Sun 31 Jan 2021 01:52:41 PM JST

1行にまとめる

$ date --date="@`echo "(13256542361632384/10^6-11644473600)"|bc`"
Sun 31 Jan 2021 01:52:41 PM JST

逆に今の時間をChromeのtimestampに変換

$ echo "(`date +%s`+11644473600)*10^6" | bc
13257218080000000

1日前のChrome時間

$ echo "(`date -d '1day ago' +%s`+11644473600)*10^6" | bc
13257336413000000

chrometime

ということで1日分Chrome/ChromiumのHistoryはこんな感じで取得できそうです.

$ sqlite3 /tmp/History "SELECT \"[\" || group_concat(json_object('timestamp', last_visit_time, title, url)) || \"]\" FROM urls WHERE last_visit_time >= $(((`date -d '1 day ago' +%s` +11644473600)*1000000));"
Note
該当プロファイルを利用中の場合このようなエラーになります.
Error: database is locked
ブラウザを終了するか,Historyファイルを適当な場所にコピーしてそちらを使います.
$ cp /home/matoken/.config/google-chrome/Default/History /tmp/

History ファイルは既定値ではこの辺にあります.

Chromium
~/.config/chromium/Default/History
Google Chrome
~/.config/google-chrome/Default/History
Brave Brouser
/.config/BraveSoftware/Brave-Browser/Default/History

既定値以外の場合はこんな感じで検索? ~/.config 以外にもできるけどその場合はパスがわかっていると思います.

$ find ~/.config/chromium/ ~/.config/google-chrome/ ~/.config/BraveSoftware/Brave-Browser -name History -print

Operaは買収されてから使っていないのですが,古いプロファイルを見るとこの辺のようです.現在は変わっている可能性があります.

Opera
~/.config/opera/History

Safariは環境がないので未確認ですがArchiveBoxのscriptを見ると既定値は恐らくこのあたりです.

Safari
~/Library/Safari/History.db
環境
$ dpkg-query -W bc google-chrome-stable chromium brave-browser coreutils sqlite3
bc      1.07.1-2+b2
brave-browser   1.19.92
chromium        88.0.4324.146-1
coreutils       8.32-4+b1
google-chrome-stable    88.0.4324.150-1
sqlite3 3.34.1-1
$ lsb_release -dr
Description:    Debian GNU/Linux bullseye/sid
Release:        unstable
$ uname -m
x86_64

The Great SuspenderでサスペンドしていたURLをjsonで出力する

ということで削除されちゃったんですね.
自分は先月怪しいという話を聞いて削除していました.その時タブが消えてしまい悲しかったのですがこんな感じで復旧させました.
タイムスタンプとタイトル,URLをjsonで出力します.

$ sqlite3 ~/.config/google-chrome/Default/History "SELECT \"[\" || group_concat(json_object('timestamp', last_visit_time, title, url)) || \"]\" FROM urls WHERE url LIKE '%bkeccnjlkjkiokjodocebajanakg%';" | jq . | sed -e 's/chrome-extension:\/\/klbibkeccnjlkjkiokjodocebajanakg\/suspended.html.*&uri=//'

何をやっているかというと, ~/.config/google-chrome/Default/History がGoogle Chromeのsqlite3形式の履歴ファイルなので,この中からThe Great Suspenderのurlの含まれているurlを引っ張り出して整形しています.

Chromiumの場合は ~/.config/chromium/Default/History
Braveは ~/.config/BraveSoftware/Brave-Browser/Default/History でした.

Default以外のprofileは名前いろいろなのでfindとかで探すといいでしょう.

$ find ~/.config/chromium/ ~/.config/google-chrome/ ~/.config/BraveSoftware/Brave-Browser -name History

ここで紹介したのはLinuxでの場合ですが,パスを変えると他のOSでもいけるはずです.

環境1
$ dpkg-query -W jq sqlite3 chromium google-chrome-stable
chromium
google-chrome-stable    69.0.3497.100-1
jq      1.6-2.1ubuntu1
sqlite3 3.34.0-1
$ lsb_release -dr
Description:    Ubuntu Hirsute Hippo (development branch)
Release:        21.04
$ uname -m
x86_64
環境2
$ dpkg-query -W jq sqlite3 chrome brave-browser google-chrome-stable
brave-browser   1.19.90
google-chrome-stable    88.0.4324.146-1
jq      1.6-2.1
sqlite3 3.34.1-1
$ lsb_release -dr
Description:    Debian GNU/Linux bullseye/sid
Release:        unstable
$ uname -m
x86_64

drivetempでハードディスクの温度を確認する

先日Debian sid amd64環境でapt upgradeしたときにhddtempのNEWSがあることに気づきました.

$ zcat /usr/share/doc/hddtemp/NEWS.Debian.gz
hddtemp (0.3-beta15-54) unstable; urgency=medium

  hddtemp has been dead upstream for many years and is therefore in a minimal
  maintenance mode. It will be shipped in the Debian Bullseye release, but
  will not be present in the Debian Bookworm release.

  Nowadays the 'drivetemp' kernel module is a better alternative. It uses the
  Linux Hardware Monitoring kernel API (hwmon), so the temperature is returned
  the same way and using the same tools as other sensors.

  Loading this module is as easy as creating a file in the /etc/modules-load.d
  directory:

    echo drivetemp > /etc/modules-load.d/drivetemp.conf

 -- Aurelien Jarno <aurel32@debian.org>  Tue, 02 Feb 2021 20:27:44 +0100

hddtempは対応しているストレージの温度を取得できます.

$ sudo hddtemp /dev/sda
/dev/sda: Seagate BarraCuda SSD ZA0100MC0100 2    : 41°C

しかしこのNEWSによると hddtemp はもう上流でメンテナンスされていないのでDebianの次期バージョンの Bullseye には入るけどその次の Bookworm からは除かれる予定のようです.

そして drivetemp というカーネルモジュールが代替になるとのこと.

てことで少し試してみました.

drivetempについてはkernelのドキュメントを確認します.

例 1. zcat /usr/share/doc/linux-doc-5.10/Documentation/hwmon/drivetemp.rst.gz | rst2html | w3m -T text/html

Kernel driver drivetemp

References

ANS T13/1699-D Information technology – AT Attachment 8 – ATA/ATAPI Command Set
(ATA8-ACS)

ANS Project T10/BSR INCITS 513 Information technology – SCSI Primary Commands –
4 (SPC-4)

ANS Project INCITS 557 Information technology – SCSI / ATA Translation – 5
(SAT-5)

Description

This driver supports reporting the temperature of disk and solid state drives
with temperature sensors.

If supported, it uses the ATA SCT Command Transport feature to read the current
drive temperature and, if available, temperature limits as well as historic
minimum and maximum temperatures. If SCT Command Transport is not supported,
the driver uses SMART attributes to read the drive temperature.

Usage Note

Reading the drive temperature may reset the spin down timer on some drives.
This has been observed with WD120EFAX drives, but may be seen with other drives
as well. The same behavior is observed if the ‘hdtemp’ or ‘smartd’ tools are
used to access the drive. With the WD120EFAX drive, reading the drive
temperature using the drivetemp driver is still possible after it
transitioned to standby mode, and reading the drive temperature in this mode
will not cause the drive to change its mode (meaning the drive will not spin
up). It is unknown if other drives experience similar behavior.

A known workaround for WD120EFAX drives is to read the drive temperature at
intervals larger than twice the spin-down time. Otherwise affected drives will
never spin down.

Sysfs entries

Only the temp1_input attribute is always available. Other attributes are
available only if reported by the drive. All temperatures are reported in
milli-degrees Celsius.

┌─────────────┬───────────────────────────────────────────────────────────────┐
│temp1_input │Current drive temperature │
├─────────────┼───────────────────────────────────────────────────────────────┤
│temp1_lcrit │Minimum temperature limit. Operating the device below this │
│ │temperature may cause physical damage to the device. │
├─────────────┼───────────────────────────────────────────────────────────────┤
│temp1_min │Minimum recommended continuous operating limit │
├─────────────┼───────────────────────────────────────────────────────────────┤
│temp1_max │Maximum recommended continuous operating temperature │
├─────────────┼───────────────────────────────────────────────────────────────┤
│temp1_crit │Maximum temperature limit. Operating the device above this │
│ │temperature may cause physical damage to the device. │
├─────────────┼───────────────────────────────────────────────────────────────┤
│temp1_lowest │Minimum temperature seen this power cycle │
├─────────────┼───────────────────────────────────────────────────────────────┤
│temp1_highest│Maximum temperature seen this power cycle │
└─────────────┴───────────────────────────────────────────────────────────────┘

drivetempを読み込むとSysfs で temp1_input として出てくるようです.

現在のセンサーの一覧を取得します.
$ find /sys/ -name "temp1_input" > /tmp/before.list 2>/dev/null
$ cat /tmp/before.list
/sys/devices/platform/thinkpad_hwmon/hwmon/hwmon3/temp1_input
/sys/devices/platform/coretemp.0/hwmon/hwmon4/temp1_input
/sys/devices/virtual/thermal/thermal_zone0/hwmon0/temp1_input
drivetemp モジュールの読み込み
$ sudo modprobe -v drivetemp
insmod /lib/modules/5.10.0-3-amd64/kernel/drivers/hwmon/drivetemp.ko
Note
永続化したい場合は
$ echo drivetemp | sudo tee /etc/modules-load.d/drivetemp.conf
増えたセンサを確認
$ find /sys/ -name "temp1_input" 2>/dev/null | diff -u /tmp/before.list -
--- /tmp/before.list    2021-02-05 01:45:58.691517588 +0900
+++ -   2021-02-05 01:46:00.178371154 +0900
@@ -1,3 +1,4 @@
 /sys/devices/platform/thinkpad_hwmon/hwmon/hwmon3/temp1_input
 /sys/devices/platform/coretemp.0/hwmon/hwmon4/temp1_input
+/sys/devices/pci0000:00/0000:00:1f.2/ata1/host0/target0:0:0/0:0:0:0/hwmon/hwmon6/temp1_input
 /sys/devices/virtual/thermal/thermal_zone0/hwmon0/temp1_input
温度を確認
$ cat /sys/devices/pci0000:00/0000:00:1f.2/ata1/host0/target0:0:0/0:0:0:0/hwmon/hwmon6/temp1_input
44000
$ sudo hddtemp /dev/sda
/dev/sda: Seagate BarraCuda SSD ZA0100MC0100 2    : 44°C

hddtemp と同じ結果が取得できました.同じなので drivetemp の値は摂氏のようですね :)

とりあえず温度は取得できましたがデバイスから温度を取得したりデーモンなどは使えないのでそのへんは少し考えないといけなさそうです.