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
Ulimit enforces the predefined limit of how much resources a user can use. The tool uses a certain configuration file as the core to assign the ulimit values. For more fine-tuned control, it’s better to edit the file. There are two types of limits that can be imposed: soft and hard limits.
Working with ulimit commands: 1 To display maximum users process or for showing maximum user process limit for the logged-in user. ulimit -u 2 For showing the maximum file size a user can have. ulimit -f 3 For showing maximum memory size for the current user. ulimit -m 4 For showing maximum memory size limit.
To change the ulimit, you have to declare which type of limit you’d like to define. Here’s a shortlist with all the available parameters you can change. Almost all of them define the maximum value of each of the parameters.
To check the ulimit value use the following command: 1. To display maximum users process or for showing maximum user process limit for the logged-in user. 2. For showing the maximum file size a user can have.
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}
$
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With