[インデックス 17358] ファイルの概要
このコミットは、Go言語のsyscallパッケージがLinux/ARMアーキテクチャ向けのシステムコール番号を生成する際に使用する、Linuxカーネルのunistd.hヘッダーファイルへのURLが古くなっていた問題を修正するものです。具体的には、src/pkg/syscall/mkall.shスクリプト内で参照されているURLが更新されました。
コミット
commit 4a7a72b8c1146cd84a869f61a77331a6de89b962
Author: Rémy Oudompheng <oudomphe@phare.normalesup.org>
Date: Thu Aug 22 00:59:48 2013 +0200
syscall: fix stale URL for linux/arm unistd.h
R=golang-dev, bradfitz
CC=golang-dev
https://golang.org/cl/13105047
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/4a7a72b8c1146cd84a869f61a77331a6de89b962
元コミット内容
syscall: fix stale URL for linux/arm unistd.h
変更の背景
Go言語のsyscallパッケージは、オペレーティングシステム(OS)の低レベルな機能にアクセスするためのインターフェースを提供します。これには、システムコール(OSカーネルが提供するサービスをプログラムが利用するためのメカニズム)の呼び出しが含まれます。Goのクロスコンパイル能力をサポートするため、異なるOSやアーキテクチャ向けのシステムコール定義を正確に把握する必要があります。
src/pkg/syscall/mkall.shスクリプトは、Goのsyscallパッケージが利用するシステムコール番号や定数などを生成するための重要なツールです。このスクリプトは、Linuxカーネルのソースコードから直接情報を取得するためにcurlコマンドを使用していました。
しかし、LinuxカーネルのGitリポジトリのホスティング方法や、ヘッダーファイルの配置構造が時間とともに変化しました。特に、git.kernel.orgのWebインターフェースが従来のgitwebからcgitに移行し、さらにユーザー空間API(User-space API, UAPI)のヘッダーファイルがinclude/asm/からinclude/uapi/asm/に移動するという大きな変更がありました。
このコミットが行われた2013年頃は、Linuxカーネルのバージョンが3.x系に移行し、uapiディレクトリの導入が進んでいた時期です。古いURLは、これらの変更に対応しておらず、もはや正しいunistd.hファイルを取得できなくなっていました。その結果、GoのsyscallパッケージがLinux/ARM向けにビルドされる際に、誤った、あるいは古いシステムコール定義に基づいてしまう可能性がありました。この「stale URL(古くなったURL)」の問題を解決することが、このコミットの直接的な背景です。
前提知識の解説
1. システムコール (System Call)
システムコールは、ユーザー空間で動作するプログラムが、カーネル空間で動作するOSカーネルの機能(ファイルI/O、メモリ管理、プロセス管理など)を利用するための唯一の手段です。各システムコールには一意の番号(システムコール番号)が割り当てられており、プログラムはこの番号と引数を使ってカーネルに処理を要求します。
2. unistd.h
unistd.hは、POSIX標準で定義されているUNIX系システムコールや定数、データ型などを宣言するヘッダーファイルです。Linuxカーネルにおいては、各アーキテクチャ(x86, ARMなど)固有のシステムコール番号の定義がarch/<architecture>/include/asm/unistd.h(またはarch/<architecture>/include/uapi/asm/unistd.h)に記述されています。Goのsyscallパッケージは、これらの定義を読み込んで、Goプログラムからシステムコールを呼び出せるようにするためのバインディングを生成します。
3. mkall.shスクリプトとmksysnum_linux.pl
mkall.shは、Goのsyscallパッケージのビルドプロセスの一部として実行されるシェルスクリプトです。このスクリプトは、様々なOSとアーキテクチャの組み合わせ(例: linux_arm)に対して、システムコール関連のファイルを生成します。
その中で、mksysnumという変数が定義されており、これはLinuxカーネルのunistd.hからシステムコール番号を抽出するためのコマンドを保持しています。このコマンドはcurlを使ってunistd.hの内容をダウンロードし、それをmksysnum_linux.plというPerlスクリプトにパイプで渡します。mksysnum_linux.plは、ダウンロードしたヘッダーファイルから必要なシステムコール番号の情報をパースして、Goのソースコードとして出力します。
4. git.kernel.orgとcgit
git.kernel.orgは、Linuxカーネルの公式Gitリポジトリをホストしているウェブサイトです。
gitweb: 以前使用されていたGitリポジトリのWebインターフェースです。URLの形式が?p=...;a=blob_plain;f=...のようになっていました。cgit:gitwebに代わって導入された、よりモダンで高速なGitリポジトリのWebインターフェースです。URLの形式が/cgit/.../plain/...のようになります。この移行により、古いgitweb形式のURLは機能しなくなりました。
5. uapiディレクトリ
Linuxカーネルのソースツリーにおいて、include/uapi/ディレクトリは、ユーザー空間アプリケーションが利用するためのAPIヘッダーファイルを格納するために導入されました。これは、カーネル内部でのみ使用されるヘッダーファイルと、ユーザー空間に公開されるべきヘッダーファイルを明確に分離することを目的としています。これにより、カーネル内部の変更がユーザー空間のABI(Application Binary Interface)に意図せず影響を与えることを防ぎ、安定したAPIを提供できるようになりました。unistd.hのようなシステムコール定義は、ユーザー空間から利用されるため、このuapiディレクトリに移動されました。
技術的詳細
このコミットの技術的詳細は、主にLinuxカーネルのWebホスティングとヘッダーファイル構造の進化に起因するURLの変更に集約されます。
古いURLの構造と問題点
変更前のmksysnumコマンドで使用されていたURLは以下の通りです。
http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob_plain;f=arch/arm/include/asm/unistd.h;hb=HEAD
このURLは、git.kernel.orgのgitwebインターフェースの形式に従っています。
?p=linux/kernel/git/torvalds/linux-2.6.git:linux-2.6.gitというリポジトリを指定しています。これは、Linuxカーネルのバージョン2.6系のリポジトリを指している可能性がありますが、実際にはlinux.gitがメインのリポジトリです。a=blob_plain: 生のファイル内容を取得するためのアクションです。f=arch/arm/include/asm/unistd.h: 取得したいファイルのパスです。hb=HEAD: 最新のコミット(HEAD)のファイルを取得することを意味します。
このURLの問題点は以下の2点です。
gitwebからcgitへの移行:git.kernel.orgがgitwebからcgitに移行したため、この形式のURLはもはや有効ではありませんでした。curlでアクセスしても、期待するunistd.hの内容ではなく、エラーページやリダイレクト後の異なるコンテンツが返される可能性がありました。uapiディレクトリの導入: Linuxカーネルのヘッダーファイル構造が変更され、ユーザー空間API向けのヘッダーがarch/arm/include/asm/unistd.hからarch/arm/include/uapi/asm/unistd.hに移動しました。古いパスでは、最新かつ正しいシステムコール定義を取得できませんでした。
新しいURLの構造と解決策
変更後のmksysnumコマンドで使用されているURLは以下の通りです。
http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/plain/arch/arm/include/uapi/asm/unistd.h
このURLは、git.kernel.orgのcgitインターフェースの形式に従っています。
/cgit/linux/kernel/git/torvalds/linux.git:cgitインターフェースを通じてlinux.gitというメインのカーネルリポジトリを指定しています。/plain/: 生のファイル内容を直接取得するためのパスセグメントです。arch/arm/include/uapi/asm/unistd.h: 新しいuapiディレクトリ内の正しいunistd.hファイルのパスを指定しています。
この新しいURLは、git.kernel.orgの現在のホスティング環境とLinuxカーネルのヘッダーファイル構造の両方に適合しており、GoのビルドプロセスがLinux/ARM向けの正確なシステムコール定義を取得できるようになりました。
mkall.shスクリプトの役割
mkall.shスクリプトは、Goのsyscallパッケージが様々なプラットフォームで正しく機能するために不可欠です。このスクリプトは、各プラットフォーム(例: linux_arm)に対して、以下のステップを実行します(関連部分のみ抜粋):
mksysnumコマンドを実行して、OSのシステムコール番号定義を取得します。このコマンドは、curlでカーネルのunistd.hをダウンロードし、mksysnum_linux.plでパースします。mksyscallコマンドを実行して、システムコール呼び出しのGoコードを生成します。mktypesコマンドを実行して、Cgoを使ってGoの型定義を生成します。
このコミットは、ステップ1のmksysnumコマンドが依存する外部リソース(Linuxカーネルのunistd.h)へのアクセス方法を修正することで、Goのsyscallパッケージのビルドの堅牢性と正確性を向上させています。
コアとなるコードの変更箇所
変更はsrc/pkg/syscall/mkall.shファイル内の1行のみです。
--- a/src/pkg/syscall/mkall.sh
+++ b/src/pkg/syscall/mkall.sh
@@ -157,7 +157,7 @@ linux_amd64)
linux_arm)
mkerrors="$mkerrors"
mksyscall="./mksyscall.pl -l32 -arm"
- mksysnum="curl -s 'http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob_plain;f=arch/arm/include/asm/unistd.h;hb=HEAD' | ./mksysnum_linux.pl"
+ mksysnum="curl -s 'http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/plain/arch/arm/include/uapi/asm/unistd.h' | ./mksysnum_linux.pl"
mktypes="GOARCH=$GOARCH go tool cgo -godefs"
;;
netbsd_386)
具体的には、linux_arm)ケース内のmksysnum変数の値が変更されています。
コアとなるコードの解説
変更された行は、linux_armアーキテクチャ向けのシステムコール番号を生成するためのmksysnumコマンドを定義しています。
-
変更前:
mksysnum="curl -s 'http://git.kernel.org/?p=linux/kernel/git/torvalds/linux-2.6.git;a=blob_plain;f=arch/arm/include/asm/unistd.h;hb=HEAD' | ./mksysnum_linux.pl"この行は、git.kernel.orgの古いgitwebインターフェースを使用して、linux-2.6.gitリポジトリからarch/arm/include/asm/unistd.hファイルの生のコンテンツをダウンロードし、それをmksysnum_linux.plスクリプトにパイプで渡していました。 -
変更後:
mksysnum="curl -s 'http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/plain/arch/arm/include/uapi/asm/unistd.h' | ./mksysnum_linux.pl"この行は、git.kernel.orgの新しいcgitインターフェースを使用し、メインのlinux.gitリポジトリからarch/arm/include/uapi/asm/unistd.hファイルの生のコンテンツをダウンロードするように変更されました。ダウンロードされたコンテンツは、引き続きmksysnum_linux.plスクリプトによって処理されます。
この変更により、Goのビルドシステムは、Linuxカーネルの最新かつ正しいシステムコール定義を確実に取得できるようになり、Linux/ARM環境でのGoプログラムのシステムコール呼び出しの正確性と互換性が保証されます。
関連リンク
- Go言語の
syscallパッケージ: Go言語の公式ドキュメントやソースコードを参照することで、syscallパッケージの機能と利用方法について深く理解できます。 - Linuxカーネルのソースコード:
git.kernel.orgでLinuxカーネルのソースコードを直接参照することで、unistd.hやuapiディレクトリの構造、システムコール定義の進化について学ぶことができます。 - LinuxカーネルのUAPIに関するドキュメント: Linuxカーネルのドキュメントやメーリングリストのアーカイブには、
uapiディレクトリ導入の背景や目的に関する詳細な情報が含まれています。
参考にした情報源リンク
- Go言語の公式ドキュメント
- LinuxカーネルのGitリポジトリ (git.kernel.org)
- Linuxカーネルのcgitインターフェース
- LinuxカーネルのUAPIに関する情報 (例: LWN.netの記事など)
- GoのChange List 13105047 (コミットメッセージに記載されているGoのコードレビューシステムへのリンク)
- Linuxカーネルの
unistd.hの歴史 (GitHub上のLinuxカーネルミラーでファイルの履歴を追う) - Linuxカーネルの
uapiディレクトリ導入に関する議論 (LWN.netの記事など、uapi導入の背景を解説している情報源) - Gitwebとcgitの違いに関する情報 (Gitのドキュメントなど)
- Goの
mkall.shスクリプトのソースコード (GitHub上のGoリポジトリ) - Goの
mksysnum_linux.plスクリプトのソースコード (GitHub上のGoリポジトリ)