12

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

システムコール setrlimit が見つかり、同じものに対して 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)
}

得られた出力は次のとおりです。

george@george-Not-Specified ~/work/odesk/progium/trial $ ./getRlimit 
{4294963002032703 0}
Error Setting Rlimit  invalid argument
Rlimit Final {4294963002032703 999999}
george@george-Not-Specified ~/work/odesk/progium/trial $ sudo ./getRlimit 
[sudo] password for george: 
{4294963002032703 0}
Error Setting Rlimit  invalid argument 
Rlimit Final {4294963002032703 999999}
george@george-Not-Specified ~/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
george@george-Not-Specified ~/work/odesk/progium/trial $ 

そのため、rlimit を取得できましたが、制限の設定に失敗し、エラーが返されました。失敗しましたが、値を再度取得するとMAX値が変更されましたが、CUR値は同じままです。このエラーの原因はカーネルの問題ですか、それともプログラムが悪いのでしょうか? このような問題の詳細と対処方法はどこにありますか?

アップデート:

修正後に動作します。

george@george-Not-Specified ~/work/odesk/progium/trial $ go build getRlimit.go 
george@george-Not-Specified ~/work/odesk/progium/trial $ ./getRlimit 
{1024 4096}
Error Setting Rlimit  operation not permitted
Rlimit Final {1024 4096}
george@george-Not-Specified ~/work/odesk/progium/trial $ sudo ./getRlimit                                                                                               
[sudo] password for george: 
{1024 4096}
Rlimit Final {999999 999999}
george@george-Not-Specified ~/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
george@george-Not-Specified ~/work/odesk/progium/trial $ go version
go version devel +7c42cfa28e24 Tue Jul 30 14:22:14 2013 +1000 linux/386
4

1 に答える 1

31

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

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}

アップデート:

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

Godefaultブランチを使用して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}
$ 
于 2013-07-23T18:20:41.140 に答える