Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

[インデックス 10466] ファイルの概要

このコミットは、Go言語のsyscallパッケージに、SUSv3 (Single UNIX Specification, Version 3) で定義されているRLIMIT (Resource Limit) およびRUSAGE (Resource Usage) 関連の定数を追加するものです。これにより、GoプログラムがUNIX系システムのリソース管理機能に、より標準的かつ包括的にアクセスできるようになります。

コミット

commit e2467f047b0d22b79aed86157064abfa5e205859
Author: Sébastien Paolacci <sebastien.paolacci@gmail.com>
Date:   Sat Nov 19 15:17:40 2011 +0900

    syscall: add SUSv3 RLIMIT/RUSAGE constants
    
    R=golang-dev, mikioh.mikioh, rsc
    CC=golang-dev
    https://golang.org/cl/5369092

GitHub上でのコミットページへのリンク

https://github.com/golang/go/commit/e2467f047b0d22b79aed86157064abfa5e205859

元コミット内容

syscall: add SUSv3 RLIMIT/RUSAGE constants

このコミットは、syscallパッケージにSUSv3で定義されているRLIMITおよびRUSAGE関連の定数を追加します。

変更の背景

Go言語のsyscallパッケージは、オペレーティングシステムが提供する低レベルのシステムコールへのインターフェースを提供します。プログラムがシステムのリソース使用量を制限したり、プロセスやその子プロセスのリソース使用状況を詳細に取得したりするためには、これらのシステムコールが提供する定数が必要不可欠です。

このコミットが行われた2011年当時、Go言語はまだ比較的新しい言語であり、syscallパッケージも継続的に機能拡張が行われていました。UNIX系システムにおけるリソース管理は、setrlimitgetrlimitgetrusageといったシステムコールを通じて行われますが、これらの関数が受け取る引数や返す構造体には、特定の定数(例えば、制限の種類を示すRLIMIT_CPUや、リソース使用量の対象を示すRUSAGE_SELFなど)が用いられます。

このコミットの背景には、Go言語がより幅広いシステムプログラミングのユースケースに対応し、UNIX標準(SUSv3)に準拠したリソース管理機能を提供する必要性があったと考えられます。これにより、GoプログラムからOSのリソース制限を設定したり、リソース使用状況を監視したりする際に、移植性と正確性が向上します。

前提知識の解説

SUSv3 (Single UNIX Specification, Version 3)

SUSv3は、UNIX系オペレーティングシステムの標準を定義する仕様です。IEEE Std 1003.1-2001 (POSIX.1) とOpen Group Base Specifications Issue 6を統合したもので、アプリケーションが異なるUNIX系システム間で移植可能であることを保証するためのAPI、ユーティリティ、およびデータフォーマットを規定しています。この標準に準拠することで、ソフトウェア開発者は特定のOSに依存しない、より汎用的なプログラムを作成できます。RLIMITRUSAGEに関する定数や構造体も、このSUSv3によって標準化されています。

RLIMIT (Resource Limit)

RLIMITは、プロセスが使用できるシステムリソースの最大値を設定するためのメカニズムです。UNIX系システムでは、setrlimit(2)およびgetrlimit(2)システムコールを通じて、以下の種類のリソースに制限を設けることができます。

  • RLIMIT_AS: プロセスのアドレス空間(仮想メモリ)の最大サイズ。
  • RLIMIT_CORE: コアダンプファイルの最大サイズ。
  • RLIMIT_CPU: プロセスが使用できるCPU時間の最大値(秒単位)。
  • RLIMIT_DATA: プロセスのデータセグメントの最大サイズ。
  • RLIMIT_FSIZE: プロセスが作成できるファイルの最大サイズ。
  • RLIMIT_NOFILE: プロセスが開くことができるファイルの最大数(ファイルディスクリプタの数)。
  • RLIMIT_STACK: プロセスのスタックセグメントの最大サイズ。

これらの制限は、ソフトリミット(rlim_cur)とハードリミット(rlim_max)の2種類があります。ソフトリミットはユーザーが自由に下げることができ、ハードリミット以下であれば上げることができます。ハードリミットは特権プロセス(通常はroot)のみが上げることができます。RLIM_INFINITYは、リソースに制限がないことを示す特別な値です。

RUSAGE (Resource Usage)

RUSAGEは、プロセスまたはその子プロセスが消費したシステムリソースに関する統計情報を取得するためのメカニズムです。getrusage(2)システムコールを通じて、以下の対象のリソース使用量を取得できます。

  • RUSAGE_SELF: 呼び出し元のプロセス自身のリソース使用量。
  • RUSAGE_CHILDREN: 呼び出し元のプロセスが終了を待った子プロセス(ゾンビプロセスを含む)のリソース使用量の合計。
  • RUSAGE_THREAD: 呼び出し元のスレッド自身のリソース使用量(Linuxなど一部のシステムでサポート)。

取得できる情報には、ユーザーCPU時間、システムCPU時間、最大常駐セットサイズ、ページフォルトの回数、シグナル受信回数、コンテキストスイッチの回数などが含まれます。これらの情報は、プログラムのパフォーマンス分析やリソース消費の監視に役立ちます。

技術的詳細

このコミットは、Go言語のsyscallパッケージが、各OS(FreeBSD, Linux)およびアーキテクチャ(386, amd64)固有のシステムコール定数を正しく認識し、Goプログラムから利用できるようにするためのものです。

具体的には、以下のファイルが変更されています。

  • src/pkg/syscall/mkerrors.sh: このシェルスクリプトは、C言語のヘッダファイルからGo言語の定数定義を自動生成するために使用されます。このコミットでは、sys/resource.hヘッダファイルがインクルードされるように変更され、RLIMIT_およびRUSAGE_関連の定数が抽出対象に追加されています。これにより、Goのsyscallパッケージがこれらの定数を自動的に取り込むことができるようになります。
  • src/pkg/syscall/zerrors_*.go: これらのファイルは、mkerrors.shスクリプトによって自動生成される、OSおよびアーキテクチャ固有のエラーコードやその他の定数定義を含むGoのソースファイルです。このコミットでは、RLIMIT_AS, RLIMIT_CORE, RLIMIT_CPU, RLIMIT_DATA, RLIMIT_FSIZE, RLIMIT_NOFILE, RLIMIT_STACK, RLIM_INFINITYといったRLIMIT関連の定数と、RUSAGE_CHILDREN, RUSAGE_SELF, RUSAGE_THREADといったRUSAGE関連の定数が追加されています。これらの定数には、対応するOSのC言語ヘッダファイルで定義されている実際の数値が割り当てられます。
  • src/pkg/syscall/zsysnum_*.go: これらのファイルは、OSおよびアーキテクチャ固有のシステムコール番号を定義するGoのソースファイルです。このコミットでは、FreeBSDおよびLinuxのzsysnumファイルに、新しいシステムコール(例: SYS_CAP_NEW, SYS_PDFORK, SYS_PRLIMIT64など)が追加されています。これは、RLIMIT/RUSAGE関連の機能と直接関係しない場合もありますが、mkerrors.shスクリプトがシステムコール番号も同時に更新するプロセスの一部として含まれている可能性があります。特にLinuxではPRLIMIT64システムコールが追加されており、これはsetrlimit/getrlimitの64ビット版であり、より大きなリソース制限を扱うために重要です。
  • src/pkg/syscall/ztypes_linux_*.go: これらのファイルは、OSおよびアーキテクチャ固有の型定義を含むGoのソースファイルです。IFLA_MAXの値が更新されています。これはネットワークインターフェース関連の定数であり、直接RLIMIT/RUSAGEとは関係ありませんが、mkerrors.shスクリプトが広範囲の定数を更新する際に変更された可能性があります。

この変更により、Goプログラムはsyscall.RLIMIT_CPUsyscall.RUSAGE_SELFといった定数を使用して、OSのリソース管理機能にアクセスできるようになります。例えば、syscall.Setrlimit関数やsyscall.Getrusage関数を呼び出す際に、これらの定数を引数として渡すことが可能になります。

コアとなるコードの変更箇所

このコミットのコアとなる変更は、主に以下のファイル群における定数の追加です。

  1. src/pkg/syscall/mkerrors.sh:

    • #include <sys/resource.h> の追加。
    • RLIMIT_ および RUSAGE_ 関連の定数を抽出対象とする正規表現の追加。
      --- a/src/pkg/syscall/mkerrors.sh
      +++ b/src/pkg/syscall/mkerrors.sh
      @@ -118,6 +118,7 @@ includes='\
       #include <errno.h>
       #include <sys/signal.h>
       #include <signal.h>
      +#include <sys/resource.h>
       '
      
       ccflags="$@"
      @@ -169,6 +170,8 @@ ccflags="$@"
       		$2 ~ /^TIOC/ ||
       		$2 ~ /^(IFF|IFT|NET_RT|RTM|RTF|RTV|RTA|RTAX)_/ ||
       		$2 ~ /^BIOC/ ||
      +\t\t$2 ~ /^RUSAGE_(SELF|CHILDREN|THREAD)/ ||
      +\t\t$2 ~ /^RLIMIT_(AS|CORE|CPU|DATA|FSIZE|NOFILE|STACK)|RLIM_INFINITY/ ||
       		$2 !~ /^(BPF_TIMEVAL)$/ &&
       		$2 ~ /^(BPF|DLT)_/ ||
       		$2 !~ "WMESGLEN" &&
      
  2. src/pkg/syscall/zerrors_freebsd_386.go, src/pkg/syscall/zerrors_freebsd_amd64.go, src/pkg/syscall/zerrors_linux_386.go, src/pkg/syscall/zerrors_linux_amd64.go:

    • 各OSおよびアーキテクチャに対応するRLIMIT_およびRUSAGE_定数の追加。値はOSによって異なる場合があります。
      // 例: src/pkg/syscall/zerrors_freebsd_386.go
      const (
      	// ... 既存の定数 ...
      	RLIMIT_AS                         = 0xa
      	RLIMIT_CORE                       = 0x4
      	RLIMIT_CPU                        = 0x0
      	RLIMIT_DATA                       = 0x2
      	RLIMIT_FSIZE                      = 0x1
      	RLIMIT_NOFILE                     = 0x8
      	RLIMIT_STACK                      = 0x3
      	RLIM_INFINITY                     = 0x7fffffffffffffff // FreeBSDの場合
      	// ...
      	RUSAGE_CHILDREN                   = -0x1
      	RUSAGE_SELF                       = 0x0
      	RUSAGE_THREAD                     = 0x1
      	// ...
      )
      
      Linuxの場合、RLIM_INFINITY-0x1となります。
  3. src/pkg/syscall/zsysnum_linux_386.go, src/pkg/syscall/zsysnum_linux_amd64.go:

    • Linux固有の新しいシステムコール番号の追加。特にSYS_PRLIMIT64RLIMIT関連の機能と密接に関連します。
      --- a/src/pkg/syscall/zsysnum_linux_386.go
      +++ b/src/pkg/syscall/zsysnum_linux_386.go
      @@ -342,4 +342,10 @@ const (
       	SYS_FANOTIFY_INIT          = 338
       	SYS_FANOTIFY_MARK          = 339
       	SYS_PRLIMIT64              = 340
      +\tSYS_NAME_TO_HANDLE_AT      = 341
      +\tSYS_OPEN_BY_HANDLE_AT      = 342
      +\tSYS_CLOCK_ADJTIME          = 343
      +\tSYS_SYNCFS                 = 344
      +\tSYS_SENDMMSG               = 345
      +\tSYS_SETNS                  = 346
       )
      

コアとなるコードの解説

このコミットの主要な目的は、Go言語のsyscallパッケージが、UNIX系OSのリソース管理機能(RLIMITRUSAGE)をGoプログラムから利用できるようにすることです。

  • mkerrors.shの変更: このスクリプトは、GoのsyscallパッケージがOS固有の定数を自動的に取り込むための重要なツールです。sys/resource.hのインクルードと、RLIMIT_およびRUSAGE_定数に対する正規表現の追加により、これらの定数がGoのコードベースに自動的に組み込まれるようになります。これにより、手動での定数定義の保守が不要になり、OSの変更に追従しやすくなります。
  • zerrors_*.goファイルの更新: これらのファイルは、mkerrors.shによって生成されるGoのソースコードであり、OS固有の定数(エラーコード、フラグ、そして今回のRLIMIT/RUSAGE定数など)を定義します。これらのファイルにRLIMIT_AS, RLIMIT_CPU, RLIM_INFINITY, RUSAGE_SELF, RUSAGE_CHILDRENなどの定数が追加されたことで、Goプログラムはこれらのシンボリックな定数名を使って、対応するシステムコール(setrlimit, getrlimit, getrusageなど)を呼び出すことができるようになります。これにより、マジックナンバー(直接的な数値)を使う必要がなくなり、コードの可読性と保守性が向上します。
  • zsysnum_*.goファイルの更新: これらのファイルはシステムコール番号を定義します。LinuxにおけるSYS_PRLIMIT64の追加は特に重要です。これは、従来のsetrlimit/getrlimitが32ビットの制限しか扱えなかったのに対し、64ビットの制限を扱えるようにする新しいシステムコールです。これにより、Goプログラムはより大きなファイルサイズやメモリ制限を設定できるようになります。

これらの変更により、Go開発者は、OSのリソース制限をプログラムから動的に設定したり、プロセスのリソース使用状況を詳細に監視したりする、より堅牢なシステムツールやアプリケーションを開発できるようになります。例えば、メモリリークの監視、CPU使用率の制限、開けるファイル数の制御などがGo言語で容易に実現できるようになります。

関連リンク

参考にした情報源リンク