7

私の目的は、golangプログラム内からulimit -nを設定して、グローバルに設定する必要はなく、プログラム内で制限することでした。golangプログラムからulimit -nを設定するにはどうすればよいですか?

システムコールsetrlimitとget rlimitが見つかりました。 (http://linux.die.net/man/2/setrlimit

しかし、私は同じもののサンプルプログラムを試したときに、値を設定している間に無効な引数を言うエラーが発生していました。

package main 

    import (
     "fmt" 
     "syscall" 
    ) 

    func main() { 

     var rLimit syscall.Rlimit 

     err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rLimit) 

     if err != nil { 
       fmt.Println("Error Getting Rlimit ", err) 
     } 
     fmt.Println(rLimit) 

     rLimit.Max = 999999 
     rLimit.Cur = 999999 

     err = syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rLimit) 
     if err != nil { 
      fmt.Println("Error Setting Rlimit ", err) 
     } 
     err = syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rLimit) 

     if err != nil { 
      fmt.Println("Error Getting Rlimit ", err) 
     } 
     fmt.Println("Rlimit Final", rLimit) 
     } 

得られた出力がされた:

[email protected] ~/work/odesk/progium/trial $ ./getRlimit 
{4294963002032703 0} 
Error Setting Rlimit invalid argument 
Rlimit Final {4294963002032703 999999} 
[email protected] ~/work/odesk/progium/trial $ sudo ./getRlimit 
[sudo] password for george: 
{4294963002032703 0} 
Error Setting Rlimit invalid argument 
Rlimit Final {4294963002032703 999999} 
[email protected] ~/work/odesk/progium/trial $ uname -a 
Linux george-Not-Specified 3.5.0-17-generiC#28-Ubuntu SMP Tue Oct 9 19:32:08 UTC 2012 i686 i686 i686 GNU/Linux 
[email protected] ~/work/odesk/progium/trial $ 

だから私は上限を設定RLIMIT を得ることができたが失敗し、エラーを返しました。 値を取ったときにMAX値が変わったにもかかわらず、CUR値は同じままです。 このエラーは私のカーネルに何らかの問題があるか、それとも悪いプログラムなのでしょうか?より多くの情報と、このような問題に対処する方法はどこで見つけることができますか?

アップデート:修正が行われた後

作品。

[email protected] ~/work/odesk/progium/trial $ go build getRlimit.go 
[email protected] ~/work/odesk/progium/trial $ ./getRlimit 
{1024 4096} 
Error Setting Rlimit operation not permitted 
Rlimit Final {1024 4096} 
[email protected] ~/work/odesk/progium/trial $ sudo ./getRlimit                        
[sudo] password for george: 
{1024 4096} 
Rlimit Final {999999 999999} 
[email protected] ~/work/odesk/progium/trial $ uname -a 
Linux george-Not-Specified 3.5.0-17-generiC#28-Ubuntu SMP Tue Oct 9 19:32:08 UTC 2012 i686 i686 i686 GNU/Linux 
[email protected] ~/work/odesk/progium/trial $ go version 
go version devel +7c42cfa28e24 Tue Jul 30 14:22:14 2013 +1000 linux/386 

答えて

14

期待どおりに動作します。

setrlimit(2)です。

ソフトリミットは、対応するリソースのカーネルで適用される値です( )。特権のないプロセスでは、ソフトリミットは0からハード限界の範囲内の値 にのみ設定され、ハードリミットは(不可逆的に)ハードリミットを下回ることがあります。特権プロセス(Linuxでは、 CAP_SYS_RESOURCE機能を持つもの)は、 の制限値を任意に変更できます。

rlimit.go

package main 

import (
    "fmt" 
    "syscall" 
) 

func main() { 
    var rLimit syscall.Rlimit 
    err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rLimit) 
    if err != nil { 
     fmt.Println("Error Getting Rlimit ", err) 
    } 
    fmt.Println(rLimit) 
    rLimit.Max = 999999 
    rLimit.Cur = 999999 
    err = syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rLimit) 
    if err != nil { 
     fmt.Println("Error Setting Rlimit ", err) 
    } 
    err = syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rLimit) 
    if err != nil { 
     fmt.Println("Error Getting Rlimit ", err) 
    } 
    fmt.Println("Rlimit Final", rLimit) 
} 

出力:

$ uname -a 
Linux peterSO 3.8.0-26-generiC#38-Ubuntu SMP Mon Jun 17 21:43:33 UTC 2013 x86_64 x86_64 x86_64 GNU/Linux 
$ go build rlimit.go 
$ ./rlimit 
{1024 4096} 
Error Setting Rlimit operation not permitted 
Rlimit Final {1024 4096} 
$ sudo ./rlimit 
[sudo] password for peterSO: 
{1024 4096} 
Rlimit Final {999999 999999} 

UPDATE:

私は成功しlinux/amd64ためrlimit.goを走ったが、あなたはlinux/386に失敗しました。 Linuxの32ビット版ディストリビューションでは、GoバグがGetrlimitSetrlimitにありました。これらのバグは修正されました。

defaultブランチtip(バグ修正を含めるために)を使用して、以下を実行し、質問を結果に更新します。

$ uname -a 
Linux peterSO 3.8.0-26-generiC#38-Ubuntu SMP Mon Jun 17 21:46:08 UTC 2013 i686 i686 i686 GNU/Linux 
$ go version 
go version devel +ba52f6399462 Thu Jul 25 09:56:06 2013 -0400 linux/386 
$ ulimit -Sn 
1024 
$ ulimit -Hn 
4096 
$ go build rlimit.go 
$ ./rlimit 
{1024 4096} 
Error Setting Rlimit operation not permitted 
Rlimit Final {1024 4096} 
$ sudo ./rlimit 
[sudo] password for peterSO: 
{1024 4096} 
Rlimit Final {999999 999999} 
$ 
+0

なぜ私のケースでは機能しないのでしょうか? –

+0

@GeorgeThomas PeterSOが指摘したように、スーパーユーザー特権でアプリケーションを実行していますか? – elithrar

+0

私は両方の方法を試みたが、それは同じだった。 –