[インデックス 15400] ファイルの概要
このコミットは、Go言語のsyscall
パッケージにNetBSDオペレーティングシステム向けのif_announce
メッセージのサポートを追加するものです。これにより、GoプログラムがNetBSDシステム上でネットワークインターフェースの到着(追加)や出発(削除)といったイベントを検知し、それに対応できるようになります。
コミット
- コミットハッシュ:
d41dede2803d36db138a0f3220dcd9ebf4749a25
- Author: Mikio Hara mikioh.mikioh@gmail.com
- Date: Sun Feb 24 12:06:24 2013 +0900
GitHub上でのコミットページへのリンク
https://github.com/golang/go/commit/d41dede2803d36db138a0f3220dcd9ebf4749a25
元コミット内容
syscall: add if_announce support for netbsd
Update #4866.
R=golang-dev, bradfitz, dave
CC=golang-dev
https://golang.org/cl/7382052
変更の背景
この変更の背景には、NetBSDシステムにおけるネットワークインターフェースの動的な管理があります。NetBSDのようなUNIX系OSでは、ネットワークインターフェース(例: イーサネットカード、Wi-Fiアダプタ、仮想インターフェースなど)がシステムに接続されたり、取り外されたりする際に、そのイベントをアプリケーションに通知するメカニズムが存在します。if_announce
メッセージはそのような通知メカニズムの一つです。
Go言語のsyscall
パッケージは、Goプログラムから基盤となるオペレーティングシステムのシステムコールやデータ構造にアクセスするためのインターフェースを提供します。ネットワーク関連のアプリケーション、特にネットワークインターフェースの状態変化に反応する必要があるデーモンやサービスをNetBSD上でGoで記述する場合、if_announce
メッセージを処理する機能が不可欠となります。
このコミットは、Goのsyscall
パッケージがNetBSDのif_announce
メッセージを認識し、Goの型として表現できるようにすることで、Go開発者がNetBSDのネットワークインターフェースイベントをより容易に扱えるようにすることを目的としています。コミットメッセージにあるUpdate #4866
は、おそらくGoプロジェクトの内部トラッカーにおける特定の課題や機能リクエストに対応するものであると考えられます。
前提知識の解説
Go言語のsyscall
パッケージ
Go言語のsyscall
パッケージは、Goプログラムがオペレーティングシステム(OS)の低レベルな機能にアクセスするためのインターフェースを提供します。これには、ファイル操作、プロセス管理、ネットワーク通信など、OSが提供するシステムコールやデータ構造のラッパーが含まれます。syscall
パッケージは、OS固有の定数、構造体、関数などを定義しており、クロスプラットフォームなGoプログラムでは通常直接使用されませんが、OS固有の機能やパフォーマンスが要求される場合には不可欠です。
NetBSD
NetBSDは、オープンソースのUNIX系オペレーティングシステムであり、その設計の移植性の高さで知られています。非常に多くのハードウェアアーキテクチャで動作し、組み込みシステムからサーバーまで幅広い用途で利用されています。ネットワークスタックはBSD系の伝統を受け継いでおり、ネットワークインターフェースの管理やルーティングに関する独自のメカニズムを持っています。
if_announce
メッセージ
NetBSDを含む一部のBSD系OSでは、ネットワークインターフェースの追加(到着)や削除(出発)といったイベントが発生した際に、カーネルがユーザー空間のプロセスに通知するためのメッセージを生成します。これがif_announce
メッセージです。これらのメッセージは、通常、ルーティングソケット(PF_ROUTE
)を通じてアプリケーションに配信されます。アプリケーションはこれらのメッセージを監視することで、ネットワークインターフェースの動的な変化を検知し、それに応じて動作を変更することができます。
struct if_announcemsghdr
if_announce
メッセージのヘッダ部分を定義するC言語の構造体です。この構造体には、メッセージの長さ、バージョン、タイプ、関連するインターフェースのインデックス、インターフェース名、そしてイベントの種類(到着か出発か)などの情報が含まれます。Goのsyscall
パッケージでは、C言語の構造体をGoの構造体としてマッピングし、Goプログラムからアクセスできるようにします。
IFAN_ARRIVAL
とIFAN_DEPARTURE
これらはif_announce
メッセージ内でイベントの種類を示す定数です。
IFAN_ARRIVAL
: ネットワークインターフェースがシステムに「到着」した(追加された)ことを示します。IFAN_DEPARTURE
: ネットワークインターフェースがシステムから「出発」した(削除された)ことを示します。
これらの定数を使用することで、Goプログラムは受信したif_announce
メッセージがどの種類のイベントを通知しているのかを判別できます。
zerrors_netbsd_*.go
と ztypes_netbsd_*.go
Goのsyscall
パッケージには、OS固有の定数や型定義を自動生成するメカニズムがあります。zerrors_netbsd_*.go
ファイルはNetBSD固有のエラーコードやその他の定数を定義し、ztypes_netbsd_*.go
ファイルはNetBSD固有のC言語の構造体をGoの構造体として定義します。これらのファイルは、異なるアーキテクチャ(例: 386
, amd64
, arm
)ごとに生成されるため、ファイル名にアーキテクチャ名が含まれています。このコミットでは、if_announce
に関連する新しい定数と型がこれらのファイルに追加されています。
技術的詳細
このコミットは、Goのsyscall
パッケージがNetBSDのif_announce
メッセージを適切に処理できるようにするための、低レベルな型と定数の追加に焦点を当てています。
-
types_netbsd.go
の変更:SizeofIfAnnounceMsghdr
という新しい定数が追加されました。これはC言語のstruct if_announcemsghdr
のサイズをGo側で参照するためのものです。C.sizeof_struct_if_announcemsghdr
を使用して、Cのヘッダファイルから実際のサイズを取得します。IfAnnounceMsghdr
という新しいGoの型が追加されました。これはC言語のstruct if_announcemsghdr
に対応するGoの構造体であり、C.struct_if_announcemsghdr
をラップしています。これにより、Goプログラム内でif_announce
メッセージのヘッダをGoの型として扱うことができるようになります。
-
zerrors_netbsd_*.go
の変更:IFAN_ARRIVAL
とIFAN_DEPARTURE
という2つの新しい定数が追加されました。これらはif_announce
メッセージが示すイベントの種類(到着または出発)を表す値です。これらの定数は、NetBSDのシステムヘッダファイルで定義されている対応するC言語の定数と同じ値を持つように設定されます。これにより、Goプログラムは受信したメッセージのWhat
フィールドをこれらの定数と比較することで、イベントの種類を判別できます。
-
ztypes_netbsd_*.go
の変更:SizeofIfAnnounceMsghdr
定数の具体的な値が、各アーキテクチャ(386
,amd64
,arm
)のztypes_netbsd_*.go
ファイルにハードコードされました。これは、C.sizeof_struct_if_announcemsghdr
がビルド時に解決された実際のサイズです。IfAnnounceMsghdr
構造体のGo言語での具体的な定義が、各アーキテクチャのztypes_netbsd_*.go
ファイルに追加されました。この構造体は、Msglen
,Version
,Type
,Index
,Name
,What
といったフィールドを持ち、それぞれがNetBSDのstruct if_announcemsghdr
の対応するフィールドにマッピングされます。Name
フィールドはインターフェース名を格納するための固定サイズの配列であり、What
フィールドはイベントの種類(IFAN_ARRIVAL
またはIFAN_DEPARTURE
)を示します。
これらの変更により、Goのsyscall
パッケージはNetBSDのif_announce
メッセージをGoの型として表現し、その内容をGoプログラムから直接アクセスできるようになります。これにより、Goで書かれたネットワークアプリケーションがNetBSDシステム上でインターフェースの動的な変化に反応する機能を実現するための基盤が提供されます。
コアとなるコードの変更箇所
src/pkg/syscall/types_netbsd.go
--- a/src/pkg/syscall/types_netbsd.go
+++ b/src/pkg/syscall/types_netbsd.go
@@ -171,11 +171,12 @@ type FdSet C.fd_set
// Routing and interface messages
const (
- SizeofIfMsghdr = C.sizeof_struct_if_msghdr
- SizeofIfData = C.sizeof_struct_if_data
- SizeofIfaMsghdr = C.sizeof_struct_ifa_msghdr
- SizeofRtMsghdr = C.sizeof_struct_rt_msghdr
- SizeofRtMetrics = C.sizeof_struct_rt_metrics
+ SizeofIfMsghdr = C.sizeof_struct_if_msghdr
+ SizeofIfData = C.sizeof_struct_if_data
+ SizeofIfaMsghdr = C.sizeof_struct_ifa_msghdr
+ SizeofIfAnnounceMsghdr = C.sizeof_struct_if_announcemsghdr
+ SizeofRtMsghdr = C.sizeof_struct_rt_msghdr
+ SizeofRtMetrics = C.sizeof_struct_rt_metrics
)
type IfMsghdr C.struct_if_msghdr
@@ -184,6 +185,8 @@ type IfData C.struct_if_data
type IfaMsghdr C.struct_ifa_msghdr
+type IfAnnounceMsghdr C.struct_if_announcemsghdr
+
type RtMsghdr C.struct_rt_msghdr
type RtMetrics C.struct_rt_metrics
src/pkg/syscall/zerrors_netbsd_386.go
, src/pkg/syscall/zerrors_netbsd_amd64.go
, src/pkg/syscall/zerrors_netbsd_arm.go
(各アーキテクチャで同様の変更)
--- a/src/pkg/syscall/zerrors_netbsd_386.go
+++ b/src/pkg/syscall/zerrors_netbsd_386.go
@@ -572,6 +572,8 @@ const (
ICANON = 0x100
ICRNL = 0x100
IEXTEN = 0x400
+ IFAN_ARRIVAL = 0x0
+ IFAN_DEPARTURE = 0x1
IFA_ROUTE = 0x1
IFF_ALLMULTI = 0x200
IFF_BROADCAST = 0x2
src/pkg/syscall/ztypes_netbsd_386.go
, src/pkg/syscall/ztypes_netbsd_amd64.go
, src/pkg/syscall/ztypes_netbsd_arm.go
(各アーキテクチャで同様の変更)
--- a/src/pkg/syscall/ztypes_netbsd_386.go
+++ b/src/pkg/syscall/ztypes_netbsd_386.go
@@ -219,11 +219,12 @@ type FdSet struct {
}
const (
- SizeofIfMsghdr = 0x98
- SizeofIfData = 0x84
- SizeofIfaMsghdr = 0x18
- SizeofRtMsghdr = 0x78
- SizeofRtMetrics = 0x50
+ SizeofIfMsghdr = 0x98
+ SizeofIfData = 0x84
+ SizeofIfaMsghdr = 0x18
+ SizeofIfAnnounceMsghdr = 0x18
+ SizeofRtMsghdr = 0x78
+ SizeofRtMetrics = 0x50
)
type IfMsghdr struct {
@@ -272,6 +273,15 @@ type IfaMsghdr struct {
Pad_cgo_0 [6]byte
}
+type IfAnnounceMsghdr struct {
+ Msglen uint16
+ Version uint8
+ Type uint8
+ Index uint16
+ Name [16]int8
+ What uint16
+}
+
type RtMsghdr struct {
Msglen uint16
Version uint8
コアとなるコードの解説
src/pkg/syscall/types_netbsd.go
SizeofIfAnnounceMsghdr = C.sizeof_struct_if_announcemsghdr
:C.sizeof_struct_if_announcemsghdr
は、C言語のヘッダファイルからstruct if_announcemsghdr
のサイズを取得するためのGoのCgo機能です。この行は、Goプログラムがこの構造体のメモリサイズを正確に知るために必要です。これは、ルーティングソケットから読み取ったバイト列をGoの構造体にキャストする際に重要になります。
type IfAnnounceMsghdr C.struct_if_announcemsghdr
:- この行は、C言語の
struct if_announcemsghdr
をGoのIfAnnounceMsghdr
型としてエイリアス(別名)を定義しています。これにより、Goプログラム内でC言語の構造体を直接参照する代わりに、Goの型システムに統合された形で扱うことができます。これは、Goのsyscall
パッケージがC言語のシステムコールインターフェースをGoの慣用的な方法でラップするための一般的なパターンです。
- この行は、C言語の
src/pkg/syscall/zerrors_netbsd_*.go
IFAN_ARRIVAL = 0x0
IFAN_DEPARTURE = 0x1
- これらの行は、NetBSDの
if_announce
メッセージで使われるイベントタイプを示す定数をGoに導入しています。IFAN_ARRIVAL
はインターフェースの追加、IFAN_DEPARTURE
はインターフェースの削除を意味します。これらの定数は、GoプログラムがIfAnnounceMsghdr
構造体のWhat
フィールドの値を解釈するために使用されます。値はNetBSDのシステムヘッダで定義されているものと一致します。
- これらの行は、NetBSDの
src/pkg/syscall/ztypes_netbsd_*.go
SizeofIfAnnounceMsghdr = 0x18
(例: 386, armの場合。amd64も同様)types_netbsd.go
で定義されたSizeofIfAnnounceMsghdr
の具体的な値が、各アーキテクチャのztypes_netbsd_*.go
ファイルにハードコードされています。これは、ビルド時にCgoが解決した実際のサイズです。この値は、Goプログラムがルーティングソケットから読み取るメッセージのバイト数を正確に把握するために使用されます。
type IfAnnounceMsghdr struct { ... }
:- この構造体は、NetBSDの
struct if_announcemsghdr
のGo言語での具体的な表現です。各フィールドはC言語の構造体の対応するフィールドにマッピングされます。Msglen uint16
: メッセージ全体の長さ。Version uint8
: メッセージのバージョン。Type uint8
: メッセージのタイプ(例:RTM_IFANNOUNCE
)。Index uint16
: イベントが発生したネットワークインターフェースのインデックス。Name [16]int8
: ネットワークインターフェースの名前(例: "em0", "lo0")。Goでは固定サイズの配列として表現されます。What uint16
: イベントの種類(IFAN_ARRIVAL
またはIFAN_DEPARTURE
)。
- この構造体は、NetBSDの
これらの変更により、Goのsyscall
パッケージはNetBSDのif_announce
メッセージをGoの型として表現し、その内容をGoプログラムから直接アクセスできるようになります。これにより、Goで書かれたネットワークアプリケーションがNetBSDシステム上でインターフェースの動的な変化に反応する機能を実現するための基盤が提供されます。
関連リンク
- Go CL 7382052: https://golang.org/cl/7382052
参考にした情報源リンク
- Go issue 4866: 残念ながら、公式の
golang/go
GitHubリポジトリでは、このコミットメッセージに記載されている#4866
という特定のIssueを見つけることができませんでした。これは、内部のトラッキングシステムで使われていた番号であるか、あるいはGoLandのIssueトラッカー(GO-4859など)のように、Go関連の別のプロジェクトのIssueを参照している可能性があります。 - NetBSD
if_announcemsghdr
(一般的な情報源): NetBSDのシステムプログラミングに関するドキュメントや、BSD系のネットワークスタックに関する一般的な情報源が参考になります。例えば、NetBSDのソースコードやmanページ(rtm_ifannounce(4)
など)が該当します。