Postfix 3.10が Linuxカーネル7系でビルドできなかった話

Gentoo Linuxで Postfix 3.10.8をビルドしたところ、Postfix側のOS判定が Linux 7.xを知らず configure相当の段階で失敗したため、原因と最小パッチを整理した。

Postfix 3.10が Linuxカーネル7系でビルドできなかった話

Gentoo Linuxで mail-mta/postfix-3.10.8 をビルドしようとしたところ、カーネルが 7.0.2-gentoo-dist の環境で configure相当の処理が止まった。

make -f Makefile.in MAKELEVEL= Makefiles
ATTENTION:
ATTENTION: Unknown system type: Linux 7.0.2-gentoo-dist
ATTENTION:
make: *** [Makefile.in:33: Makefiles] Error 1

Postfix本体が壊れているというより、ビルドスクリプト側のプラットフォーム判定が将来の Linuxカーネルメジャーバージョンを想定していなかった、という種類の問題だった。

原因

Postfixの makedefs では、Linuxカーネルのメジャーバージョンをパターンで判定している。Postfix 3.10.8では該当箇所が次のようになっていた。

Linux.[3456].*)
    SYSTYPE=LINUX$RELEASE_MAJOR
    ...

つまり Linux 3.xから6.xまでは知っているが、7.xは知らない。カーネルが 7.0.2-gentoo-dist になるとこの条件にマッチせず、Unknown system type としてビルドが止まる。

makedefs だけ直しても足りなかった

最初は makedefs の判定を広げれば済むと思ったが、それだけではまだ失敗した。makedefs を通過すると今度はコンパイラに -DLINUX7 が渡されるようになり、src/util/sys_defs.h 側が LINUX7 を知らないため unsupported platform で止まる。

結果として、少なくとも次の2箇所を直す必要があった。

パッチ1: makedefs

--- a/makedefs
+++ b/makedefs
@@ -639,7 +639,7 @@
 		: ${SHLIB_ENV="LD_LIBRARY_PATH=`pwd`/lib"}
 		: ${PLUGIN_LD="${CC-gcc} -shared"}
 		;;
-    Linux.[3456].*)
+    Linux.[3-9].*)
 		SYSTYPE=LINUX$RELEASE_MAJOR

パッチ2: src/util/sys_defs.h

--- a/src/util/sys_defs.h
+++ b/src/util/sys_defs.h
@@ -763,7 +763,8 @@
   * LINUX.
   */
 #if defined(LINUX2) || defined(LINUX3) || defined(LINUX4) || defined(LINUX5) \
-	|| defined(LINUX6)
+	|| defined(LINUX6) \
+	|| defined(LINUX7)
 #define SUPPORTED

この2枚を適用することで、手元の mail-mta/postfix-3.10.8 は Linux 7.0.2環境でビルドできた。

Gentooでの一時回避

正式なパッチが ebuild側に入るまでは、ローカルの Portageパッチとして持つのが扱いやすい。たとえば次のようなファイルを用意する。

/etc/portage/patches/mail-mta/postfix-3.10.8/linux-7.patch

中身は上記2つの差分をまとめたものにする。Portageは対応するパッケージのビルド時に、このディレクトリに置いたパッチを適用してくれる。

この方法はあくまでローカル回避策。Postfix 3.10系や Gentoo ebuild側で正式対応が入ったら、ローカルパッチは外しておくほうがよい。

もう少し根本的な話

Postfix 3.11.1では makedefs 側の判定が Linux.[34567].* に広がっているようだが、この方式だと Linux 8.xが来た時に同じ話が繰り返される。sys_defs.h 側も含めて、カーネルのメジャーバージョンをリテラルに足していく設計になっているためだ。

実際の互換性確認が必要なのは当然としても、少なくとも「既知の古い Linuxだけ許可する」形よりは、「Linux 3以降を同系統として扱い、例外があれば個別に落とす」形のほうが保守しやすいように見える。

そもそも、ビルド時に実行している環境の uname だけを見てOS種別や対応可否を決めるやり方自体も、クロスビルドやコンテナ化されたビルド環境が珍しくない今ではだいぶ危うい前提になっている。

今回の件は、アプリケーションの機能そのものではなく、ビルド時のOS判定が未来のバージョン番号に弱かった例として覚えておくとよさそうだ。

関連記事

当社代表のデスクトップ(※)を常時ライブ配信中

※ライブ配信専用PC

OSSの検証や自社用ツールの開発といった公開できる作業に限り、 ライブ配信専用PC上で行っています。常時配信ですのでいつでもお気軽にチャットメッセージ(公開)を残していって下さい。