Как установить ulimit -n из программы golang?
Моя цель состояла в том, чтобы установить ulimit -n из программы golang, чтобы мне не нужно было устанавливать ее глобально, а ограничить ее внутри программы.
Нашел системные вызовы 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
1 ответ
Работает как положено.
Мягкое ограничение - это значение, которое ядро устанавливает для соответствующего ресурса. Жесткий предел действует как верхний предел для мягкого предела: непривилегированный процесс может только установить для своего мягкого предела значение в диапазоне от 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.go
за linux/amd64
Вы не смогли за linux/386
, Были ошибки Go в Getrlimit
а также Setrlimit
для Linux 32-битные дистрибутивы. Эти ошибки были исправлены.
Использование Go 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}
$