Ports ディレクトリのオーバーレイを利用する

Ports の OVERLAYS とは

最近の FreeBSD ports には、 OVERLAYS といって ports tree 全体とは別枠で管理している ports を 追加したり上書きしたりする仕組みが入っています。 OVERLAYS を使うと、ports tree 全体ではなく部分的な自分でメンテナンスしている分だけ管理するということが可能になります。 Ports に入っていないソフトウェアやバージョンについて、 オーバーレイツリーを作成して公開している人もいます。

ということで、ports の OVERLAYS の使い方をおさらいしてみたいと思います。

まず、公式の ports を git clone したものが /usr/local/poudriere/ports/trial にあるとします。 そうして、オーバーレイツリーを /usr/local/poudriere/ports/overlay_trial に置きます。 いかにも poudriere で作った ports tree ですが、あとで poudriere での使い方も説明するので使いまわしです。

trial には FreeBSD 公式の ports を置きまして、極力触りません。 ovelay_trial には x11-wm/hikari という port が入っています。 設定としては、開発が止まっている hikari を個人でメンテしているものの野良 port という感じです。

OVERLAYS の使い方: 素の Ports 篇

make コマンドがどのように ports の makefile 群を見つけるかですが、 ports の場合はローカルディレクトリの Makefile に次の行があります。

.include <bsd.port.mk>

この bsd.port.mk を ports ツリーの Mk ディレクトリを特定して見つければよいわけですが、*BSD では make は /usr/share/mk を見に行くようあらかじめプログラムされており、 FreeBSD ではここに bsd.port.mk が置かれています。 まずはこの bsd.port.mk を読み込んで、その bsd.port.mk の中で ports ツリーの位置を特定して ports の Mk/bsd.port.mk ほかの makefile を読み込むようになっています。

その ports ツリーの位置を特定する方法のひとつが、 ユーザーが指定する PORTSDIR make 変数です。

従いまして、オーバーレイツリー下の port ディレクトリで makeコマンドを使う場合、この PORTSDIR を指定してやります。

# make PORTSDIR=/usr/local/poudriere/ports/trial

次に、オーバーレイツリーを指定します。 これには OVERLAYS make 変数を使います。

# make OVERLAYS=/usr/local/poudriere/ports/overlay_trial

これらを組み合わせて、make config とか make extract などの ports のコマンドを実行するのは次のようになります。

# make OVERLAYS=/usr/local/poudriere/ports/overlay_trial PORTSDIR=/usr/local/poudriere/ports/trial config

# make OVERLAYS=/usr/local/poudriere/ports/overlay_trial PORTSDIR=/usr/local/poudriere/ports/trial DISTDIR=/usr/ports/distfiles extract

OVERLAYS の使い方: Poudriere 篇

Poudriere では対応しているコマンドでは -O (ラージオー)オプションでオーバーレイツリーが指定できますが、 任意のディレクトリが指定できるわけではなく、 poudriere の ports ディレクトリとして作成されたもの (poudriere ports -l で出力されるもの)しか指定できません。

そこで、オーバーレイツリーとして使えるように、 以下のコマンドで空の ports ツリーを poudriere で作成し、 あとから別途オーバーレイツリーの中身を入れていきます。 -F オプションが作成する ports ツリーを空のままにするものです。

# poudriere ports -cF -p overlay_trial

よく使う poudriere のコマンドでは、bulk と testport が -O オプションに対応しています。 options コマンドは対応していないので、 オーバーレイツリー下の port についてオプションの変更を行いたい場合は、 /usr/local/etc/poudriere.d 下に置く make.conf ファイル内で次のように指定します。

x11_wm_hikari_SET= OPT1 OPT2
x11_wm_hikari_UNSET= OPT3

poudriere のコマンドでは、次のようにオーバーレイツリーを指定します。

# poudriere bulk -j s15amd64 -p trial -O overlay_trial x11-wm/hikari

OVERLAYS が複数あったら?

OVERLAYS と S がついているように、OVERLAYS make 変数には複数のオーバーレイツリーが指定できます。

# make OVERLAYS="/usr/local/poudriere/ports/overlay1 /usr/local/poudriere/ports/overlay2" make

のように書きます。 複数のオーバーレイツリーに同じ名称の port が含まれる場合にどちらが優先されるかは試していませんが、 bsd.port.mk の記述を読む限りは、後に書いた方(上記の場合は overlay2) が優先されるようです。

トイレにうんこが詰まったらどうするか

はじめに

トイレにうんこがつまるとは

前にトイレにうんこが詰まったと言ったら笑われたことがありますし、 私もトイレはうんこを流すものであって詰まるなんておかしいとは思うのですが、 詰まる時には詰まるのです。うんこが。トイレに。

私の家だけの話でもないらしく、 どこぞの大学の工学部の男子トイレには 「1本目をしたら2本目を出す前に流せ」とか 「詰まらせたら申し出でろ」とか 書かれていたりするという話を聞いたりしたことがあります。 大食いの男子が危険因子ということでしょうか。

とにかく、トイレにはうんこが詰まることがあるのです。

大前提として

トイレにうんこが詰まってしまったのを解消するのに基本かつ最強なのがラバーカップであることは世間で合意がとれていると思うのですが、 うんこが流れて行って奥の方で詰まっているのならともかく、便器の中にでーんとうんこが鎮座しているところにラバーカップを突っ込むのはちょっと抵抗があるよなという気持ちは分かってもらえると思います。

この話は、そういう場合でもちょろちょろとでも水が流れるようであれば、ラバーカップを便器につっこまなくても詰まりが解消できるかもしれないという話です。

完全には詰まらせるな

うんこが詰まる時はいきなり完全に詰まるのではなく、量が多いなとか、 流れが悪いな詰まりそうだなという段階を経ているものです。 そういう兆候を見逃さずに、そこでうんこをするのをいったんやめるようにしましょう。 下痢だったりするとそうも言っていられませんが、よっぽど多いのでなければ下痢便は流れるものです。 うんこをしながらこまめに流すようにしてください。 硬いうんこの場合は、しばらくのあいだなら押し戻して我慢することができるはずです。 くれぐれも、流れは悪いけどまだ流れているうちに、詰まり解消の行動に移るようにしてください。

さてやりましょう

準備するもの

  • バケツ
  • 40℃くらいのお湯の出る蛇口
  • 酵素入りの洗濯洗剤(なくてもよい)

お湯でたたかう

用意するものをみればわかる通り、うんこが詰まっているのを解消するためにすることは単純にお湯を流すだけです。 陶器の便器の場合、説明書にあまり高い温度のお湯を流すと便器が割れると書いてあります。 便器が割れて詰まっているものがトイレに流れ出したら本末転倒ですので、 お湯の温度は40℃程度にしてください。

洗剤は気休めというか、どれほどの効果があるのか実際には分からないのでなくてもよいと書きましたが、 入っている酵素は洗濯機でぐるぐる回す短い時間の間に、綿の繊維を多少ほぐす効果があるそうなので、 食物繊維を含むうんこも多少ほぐしてくれるのではないかと期待して入れます。 泡立てたらあふれてしまうので、入れる量はちょっとだけ、粉の洗剤ならバケツ一杯のお湯に小さじ半分とか4分の1くらい、濃縮液体洗剤なら一滴でよいでしょう。

はじめはちょろちょろとしか流れていかないと思いますので、 いきなり勢いよくバケツのお湯を便器にあけるのではなく、 便器の普段流れるレベルの高さにお湯のふちがとどまるように注意しながらお湯をいれてください。 そうして、お湯が流れたらまたお湯を汲んできて流します。 これを繰り返して、うんこをほぐして崩して流すのが目的です。 水でも良さそうな気がするのですが、経験上、水だと全然流れるようになりません。

経験上はバケツを20回か30回トイレに運べば流れますが、 中途半端に流れているところでやめるとまた詰まりますので、 バケツ一杯分を一気に入れたら、例のごごごごという音と共に一気に流れるようになるまでやりきってください。

時間を短縮したければ

便器の見えるところからはうんこが流れていったけれども、 まだ奥の方に少し詰まっているようで流れが悪いというところまで来たら、 時間を短縮するためにラバーカップを持ち出してもよいでしょう。

衛生的には、便器の中にうんこがみえていようがいなかろうが、あたりを飛び交う大腸菌とか変わらないと思いますが、 そこはまあ気分の問題で。

かたいうんこをなんとかしたいとき

たまに、こういうことをしてもにっちもさっちもいかない、あまりにも硬いうんこが出ることがあります。 詰まるのではなく、硬くて折れたりしないので流れていかないというものです。 これはもう、棒状の何かを突っ込んで力ずくで切り分けるしかないと思いますが、 そういうことはしたくないという場合には、お金がかかりますが水酸化ナトリウム(苛性ソーダ、商品だとピーピースルーKとか) を入れて放置すると崩れてくれることがあります。 それ以外の場合には、水酸化ナトリウムはつまったうんこにはあまり役に立ちません。

それでは

もしもあなたがトイレにうんこを詰まらせて検索して来ているのだとしたら、幸運を祈ります。

root で chown -R や rm -r を実行する時には -x オプションを追加しろ

新年早々 samba がこけまして、 samba に認証情報をあずけてあるユーザーが認証できなくなっって大弱りでした。 原因は fdescfs をマウントしてあるところに chown -R を実行してしまったことです。 最近のソフトウェアは、自分の領域の下の方の path に fdescfs をマウントしていることが多いので (samba とか)、うっかり root で chown や rm を実行してそいつを踏んでしまうと、 おもいもかけぬファイルの所有者を変更したり消してしまったりします。 それで samba が読み書きできなくなったディレクトリやファイルがあってこけてしまったのでした。

そういう事故を防ぐために、root で chown や rm を再帰的に実行する場合は、 mount 境界をまたがないようにすることが重要です。 それが -x オプションです。

というわけで、root で chown や rm を再帰的に実行する際には、

# chown -Rx ...

とか

# rm -rfx ...

とか

# rm -rdx ...

とか、忘れずに -x をつけましょう。今年の抱負です。

従来の方法で更新してきた FreeBSD システムを PKGBASE 方式に変換する

pkgbasify

実のところ、 必要な手順を lua script にしたものFreeBSD Foundation が公開しているので、 これを持ってきて動かせば済む話だったりします。

というわけで、

freebsd-update で更新してきた場合

こちらは公式にずっと従っているわけですから特別なことはなくて、pkgbasify の説明に書いてあるとおりにやればよいです。

makeworld で更新してきた場合

こちらも pkgbasify スクリプトは使えるのですが、ちょっとした準備がいります。

まず、make buildworld buildkernel してから installkernel installworld でシステムを更新します。 make delete-old delete-old-libs も実行しておいて、余計なファイルを消しておくべきでしょう。

make packages も行って pkgbase リポジトリを構築します。 これについては先日ざっと書いたので、 それを参考にしてください。httpd で取れるようにするところは書いていませんが、 まあ分かりますよね。

そうしたら、その pkgbase リポジトリを記述した pkg コマンドの設定ファイルを /etc/pkg に置きます。 これは、pkgbasify がパッケージリポジトリごとに pkg update を実行して、 リポジトリの情報を読み取る手順があるのですが、この時 pkg update が実行されるのが /etc/pkg 以下の *.conf ファイルに設定が書かれているリポジトリに対してだけだからです。 一般的に自分で記述したパッケージリポジトリの設定は /usr/local/etc/pkg/repos/ 以下に置くと思いますが、後で消してよいのでそれを /etc/pkg 下にコピーしてください。

以上を行ってから pkgbasify を実行します。 その時にいくつか引数を指定します。

# ./pkgbasify.lua --no-create-repo-conf --repo-name myrepo-base

--no-create-repo-confFreeBSD 公式のパッケージリポジトリの設定を書き出さないオプションです。 base、ports 含めていらないという場合に指定してください。 公式から入れることもあるんだよなあという場合は外してください。

--repo-name は公式のパッケージリポジトリの代わりに base のパッケージを取ってくるリポジトリ名を指定します。 ここでは myrepo-base としていますが、ご自分で設定した名称を指定してください。

実行中に何か問題があって --force オプションをつけてやり直す場合も、 上記オプションの指定を忘れないようにしてください。

pkgbasify の実行後に何を確認するか

pkgbasify の README にかかれているとおり、/etc/master.passwd と /etc/group が大切なのはそうなんですが、 *.pkgsave ファイルがあったら確認して不要になったら消すとか、 pkg which してどのパッケージにも所属していないファイルがないか探すとかいろいろある気はします。 正直よくわかりません。

FreeBSD で音楽再生中の音飛びをなくす

小ネタ。

FreeBSD で音楽を聞いていると、通常のプロセスの優先度だと音飛びが発生することがある。 root で renice して nice 値を下げてスケジューリングの優先度を上げてもあまり効果がなかったりすることが多い。

そこで優先度を上げるとよいのが realtime priority である。最大値(優先度最低)が 31 なので、

# rtprio 30 -$(pgrep progname)

みたいに実行する。こちらも数値が小さい方が優先度が高い。 基本は root のみが実行できるが、MAC で一般ユーザーも使えるように設定できて、/boot/loader.conf に

mac_priority_load="YES"

を追加して、realtime グループ (47) にユーザーを追加すると、そのユーザーも rtprio コマンドが使える。

逆に、あるプロセスに CPU が本当に idle 状態でないと動かないようにして、 ほかのプログラムの邪魔をさせたくない場合、idprio コマンドで idle priority を設定するとよい。 こちらの場合は idletime グループ (48) にユーザーを追加する。

2026-01-07 追記

idprio を poudriere bulk のような全体ではかなり CPU や I/O を食うジョブに設定すると、 むしろ GUI がまともに動かなくなって困ることがあった。 idprio の manpage に、idprio を使うとデッドロックが起きる可能性が高いと書いてあって、 どうやらそれみたい。 idprio を使う場合は、その配下のプロセスを含めても CPU やら メモリやら I/O やらのリソースをあまり食わない範囲で使うべきなようで、 poudriere bulk なんかは nice で通常のスケジューリング優先度を下げるべきなようである。

FreeBSD の PKGBASE サーバーを自分で用意する

はじめに

RELEASE インストールして、公式が提供してくれるのを、 freebsd-update と pkg で入れていればいいじゃんと煽られても頑なに stable を(最近は current も) 追いかけているし、poudriere で自分用の package repository をビルドしています。 こんにちは。

今回は、そんな私のような人向けに、FreeBSD 15.0-RELEASE からは PKGBASE という、 base のいろいろも pkg コマンドで扱う仕組みが入ったんですけれども、 それでも自分用の pkgbase repository をビルドして stable (とか current) 追っかけが続けられるんだろうか、もちろんできますよという話です。

今回の前提

これまで注ぎ足し注ぎ足しで面倒を見てきた stable の入った PC を前提にした話をすると長くなるので、 今回は FreeBSD 15.0-RELEASE とか stable/15 のスナップショットを pkgbase 方式でインストールしたシステムを前提とします。 buildworld 方式でやってきたシステムからの移行の話はちょっと待っていてください。

host と poudriere jail のソースを合わせる

poudriere jail は一番近い RELEASE を freebsd-update で入れているんだという場合は、 どこかに base のソースコードを置いて、それに対する操作に読み替えてください。

というわけで、poudriere jail のソースコードからビルドしたものを host にもインストールして、 両者のリビジョンを合わせます。あんまり意味はないけどそうしています。 ケチだから make buildworld の回数を減らしたいんですよ。

poudriere jail の作成

# poudriere jail -c -j s15amd64 -v stable/15 -m git+https

という感じで stable のソースコードを取ってきて poudriere jail をビルドします。 最初に必要な poudriere とか git はどうしましょう問題はありますが、 そこは仕方がないので FreeBSD 公式のパッケージをインストールして使います。

せっかくだから poudriere jail も pkgbase 方式で用意したら? と思うかもしれませんが、 そうするとソースコードが無くて kernel module が作れません。やめた方がよいです。 そもそも pkgbase のリポジトリも作れません。

kernel のビルド

poudriere jail -c で buildworld が実行されますので、終わったら /usr/local/poudriere/jails/s15amd64/usr/src に移動します。 generic kernel ではなく、自分用の設定でビルドした kernel を使いたい場合は、 sys/amd64/conf/MYKERNCONF とか、なんか kernel configuration file を作成します。 Aarch64 とか他のアーキテクチャについては適宜読み替えてください。

で、

# make KERNCONF=MYKERNCONF buildkernel

とやって kernel をビルドします。generic kernel で良い場合は KERNCONF の指定は不要です。

注意ですが、このあと installkernel、installworld はしないように気をつけてください。

pkgbase の作成

pkgbase のリポジトリを置くディレクトリを作成します。 私は /usr/local/poudriere/data/pkgbase としましたが、この辺はお好きなように。

次にいよいよ base パッケージを作成します。/usr/local/poudriere/jails/s15amd64/usr/src で

# make REPODIR=/usr/local/poudriere/data/pkgbase KERNCONF=MYKERNCONF packages

とやって、終わるまでしばらく待ちます。

リポジトリに署名しておきたい場合は、タイプ ecdsa の秘密鍵が /usr/local/etc/pkg/keys/myrepo.key にあるとして、

# make REPODIR=/usr/local/poudriere/data/pkgbase KERNCONF=MYKERNCONF PKG_REPO_SIGNING_KEY=ecdsa:/usr/local/etc/pkg/keys/myrepo.key packages

とします。

どうやって myrepo.key (と myrepo.pub)を作ればいいのと半べそをかいている人に教えてあげますが、 pkg-key(8) に書いてあって、次のようにすればよいです。

# pkg key --create -t ecdsa /usr/local/etc/pkg/keys/myrepo.key > /usr/local/etc/pkg/keys/myrepo.pub

pkg 向けに repository を定義する

/etc/pkg/FreeBSD.conf を参考にします。

ローカルの場合は httpd が何かのトラブルで動かない場合もインストールできるように file: で指定します。 リモートの場合は http:https: ですね。そう、http サーバーを設定すれば、他の PC にも同じものがインストールできるのです。

ローカルはこんな感じ:

myrepo-base: {
  url: "file:///usr/local/poudriere/data/pkgbase/FreeBSD:15:amd64/latest",
  mirror_type: "none",
  signature_type: "none",
  enabled: yes,
  priority: 10
}

リモートで署名してある場合はこんな感じ:

myrepo-base: {
  url: "https://pkg.example.jp/base/FreeBSD:15:amd64/latest",
  mirror_type: "none",
  signature_type: "pubkey",
  pubkey: "/usr/local/etc/pkg/keys/myrepo.pub",
  enabled: yes,
  priority: 10
}

さあアップデートしてみよう

# pkg upgrade -r myrepo-base 

で新しい base のパッケージがインストールされるはずです。 kernel が新しくなっているか、再起動する前に

# pkg info -a | grep kernel

とかやって確認しておきましょう。

もうひとつ

これまで make buildworld buildkernel; make installkernel installworld でやってきたのを、 PKGBASE 方式に移行できないのかと思うのはもっともなことですが、実はそれもできます。 それについてはまた後日。

FreeBSD でも GPU に計算させて遊ぶ(FFTライブラリ篇)

CUDA ではありません

FreeBSD でも Linux エミュレーションで頑張ったら CUDA を使えるよという話は FreeBSD forum になんか記事があったのでそっちを見てください。

FreeBSD でも GPU で計算

世の中、GPU(というよりは CUDA)で計算をいろいろやらせてとかうるせえなあ、しょせん私が使っているのは FreeBSD でと言いたいところだけど、 FreeBSD でも GPU が使える以上は GPU に計算してもらうことだってできるはず。

というわけで、AMD GPU なら FreeBSD でも cloverOpenCL 遊びができますよという話。 NVidiaGPU については知らないけど、そっちをサポートしている OpenCL の実装がなかったっけ?

いきなり OpenCL をがりがりと書くのもなんなので、まずは既存のライブラリを使って FFT 計算をやってもらおう。 Ports/packages には clFFT が入っているからそれを使えばいいよね。 比較のために、CPU で計算する FFTW も使ってみよう。

ソースコード

というわけで、サンプルコードをここ https://github.com/oikumene/fft_example においた。 bench-* というプログラムに指定した画像ファイルをグレースケールに変換して FFT をかけるだけ。 一般的には GPU での計算は float でやるみたいだけど、なんかの科学技術計算ができたらいいなと思っているので double でやってみた。 FFTW 版は、1スレッドと6スレッドの2回計算している。 preparation がそれぞれのライブラリ用のデータ構造に画像のデータをコピーする処理にかかっている時間で、 execution が FFT の実行時間。clFFT 版はGPUからデータを取ってくるところも execution に入れている。 FFT の結果としてどういう情報を保存すればよいのか分からないので実部だけを保存するようにしてみたが、なんかおかしい。 逆フーリエ変換はうまくいくので、画像を保存する時のデータの取り出し方がたぶんなんかまずいんだけど。

実行結果

FFTW版。Motorola g13 のカメラで撮影した画像を処理したもの。 6スレッドあると計算時間が 1/3 くらいになるみたい。

% ./bin/bench-fftw img/IMG_20250227_200104.jpg 
FFTW(double) image (nthread = 1): img/IMG_20250227_200104.jpg
preparation: 0.00387s; execution: 0.19646s; total: 0.20033s
FFTW(double) image (nthread = 6): img/IMG_20250227_200104.jpg
preparation: 0.01027s; execution: 0.06586s; total: 0.07613s

なんだけど、clFFT 版はエラーになる。どうやら画像が大きすぎるよう。

% ./bin/bench-clfft img/IMG_20250227_200104.jpg
clFFT image: img/IMG_20250227_200104.jpg
Platform: Clover
Device: AMD Radeon RX 580 Series (radeonsi, polaris10, LLVM 19.1.7, DRM 3.49, 14.3-STABLE)
preparation: 0.19309s; execution: 0.00000s; total: 0.19309s
Executing clFFT on img/IMG_20250227_200104.jpg failed.

もう少し小さい画像ということで、WX321J のカメラで撮った画像を処理してみた。 まず FFTW 版。 準備にかかる時間があまり変わらなくて、計算時間が縮まったので6スレッドでもトータルの時間はあまり変わらない。

% ./bin/bench-fftw img/J0010126.jpg 
FFTW(double) image (nthread = 1): img/J0010126.jpg
preparation: 0.00359s; execution: 0.00525s; total: 0.00885s
FFTW(double) image (nthread = 6): img/J0010126.jpg
preparation: 0.00505s; execution: 0.00175s; total: 0.00680s

clFFT 版。今度は計算できた。float にすれば必要なメモリ量が半分になるのでもう少し大きな画像でもいけるはず。 だが、Radeon RX580 くらいだと、CPU (Xeon のなんか) の一スレッドと同じくらいの計算時間で (データ転送の時間があるので、計算時間そのものは短いとは思うが)、 準備の時間がだいぶかかってしまって、あまり GPU で計算するメリットがないかもしれない。

% ./bin/bench-clfft img/J0010126.jpg          
clFFT image: img/J0010126.jpg
Platform: Clover
Device: AMD Radeon RX 580 Series (radeonsi, polaris10, LLVM 19.1.7, DRM 3.49, 14.3-STABLE)
preparation: 4.24376s; execution: 0.00579s; total: 4.24955s