doushou7169 2013-07-23 17:37
浏览 301
已采纳

如何通过Golang程序设置ulimit -n?

My purspose was to set ulimit -n from within a golang program so that I do not have to set it globally but restrict it within the program.

Found systemcalls setrlimit and get rlimit for the same. (http://linux.die.net/man/2/setrlimit)

But when I tried a sample program for the same I was getting an error saying invalid argument while setting the value.

    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)
         }

The output obtained was :

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 $ 

So I was able to get the rlimit Setting the limit failed and returned an error. Even though it failed the MAX value got changed when I took the value again but CUR value remains the same. Can this error be due to some issue with my kernel or is it a bad program ? Where can I find more information and how to deal with an issue like this ?

Update :

Works after the fix has been made.

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
  • 写回答

1条回答 默认 最新

  • dongyou2279 2013-07-23 18:20
    关注

    It works as expected.

    setrlimit(2).

    The soft limit is the value that the kernel enforces for the corresponding resource. The hard limit acts as a ceiling for the soft limit: an unprivileged process may only set its soft limit to a value in the range from 0 up to the hard limit, and (irreversibly) lower its hard limit. A privileged process (under Linux: one with the CAP_SYS_RESOURCE capability) may make arbitrary changes to either limit value.

    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)
    }
    

    Output:

    $ 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:

    I successfully ran rlimit.go for linux/amd64, you failed for linux/386. There were a Go bugs in Getrlimit and Setrlimit for Linux 32-bit distributions. These bugs have been fixed.

    Using the Go default branch tip (to include the bug fixes), run the following, and update your question with the results.

    $ 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}
    $ 
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论

报告相同问题?

悬赏问题

  • ¥15 如何实验stm32主通道和互补通道独立输出
  • ¥30 这是哪个作者做的宝宝起名网站
  • ¥60 版本过低apk如何修改可以兼容新的安卓系统
  • ¥25 由IPR导致的DRIVER_POWER_STATE_FAILURE蓝屏
  • ¥50 有数据,怎么建立模型求影响全要素生产率的因素
  • ¥50 有数据,怎么用matlab求全要素生产率
  • ¥15 TI的insta-spin例程
  • ¥15 完成下列问题完成下列问题
  • ¥15 C#算法问题, 不知道怎么处理这个数据的转换
  • ¥15 YoloV5 第三方库的版本对照问题