

{"id":1338,"date":"2014-06-19T11:23:51","date_gmt":"2014-06-19T09:23:51","guid":{"rendered":"http:\/\/fabsk.eu\/blog\/?p=1338"},"modified":"2015-07-11T13:55:33","modified_gmt":"2015-07-11T11:55:33","slug":"1338","status":"publish","type":"post","link":"https:\/\/fabsk.eu\/blog\/2014\/06\/19\/1338\/","title":{"rendered":"cgroups script for the current session"},"content":{"rendered":"<p>In Linux, <a href=\"https:\/\/en.wikipedia.org\/wiki\/Cgroups\">cgroups<\/a> (a kernel feature) allows to limit the resources (cpu, memory\u2026) accessible to a group of processes. I have written a little bash script that will either:<\/p>\n<ul>\n<li><strong>create some groups<\/strong> for the current user session and assign some restrictions. No need to be root or to modify a global configuration file. Call it when your desktop session starts (for example by putting an entry in \u00ab~\/.kde\/Autostart\u00bb). Edit the script to create your own groups.<\/li>\n<li><strong>start a process<\/strong> in one of theses groups<\/li>\n<\/ul>\n<p>The main reason was that I encountered a bug with Firefox and Google+, with triggered infinite memory allocation, which freezes my machine for a few minutes (because of the trashing). I hope that it will allow me to kill the process\/close the tabs if it happens again.<br \/>\n<!--more--><\/p>\n<p>I only tested it in Ubuntu 14.04, so it may require some adaptations for other Linux systems. When a user logs in, a cgroup group is created for the user session, and only the configuration at the session level (<em>\/sys\/fs\/cgroup\/*\/user\/USER_ID.user\/SESSION_ID.session<\/em>) can be modified by the user. So this script will create sub-groups under this session level.<\/p>\n<p>Here is the script: <a href=\"http:\/\/fabsk.eu\/blog\/wp-content\/uploads\/2014\/06\/mycgroup.sh_.txt\">mycgroup.sh <\/a>(please rename it after download). Some usage examples:<\/p>\n<pre># create the groups\r\nmycgroup init\r\n# run in the groups \"darktable\" the command \"darktable\"\r\nmycgroup run darktable darktable<\/pre>\n<p>Content of the script (edit it and define your own groups):<\/p>\n<pre lang=\"bash\">#!\/bin\/bash\r\n\r\n# Create a group\r\n# param:\r\n# - type(s) (cpu, memory)\r\n# - group path\r\nfunction mycg_create {\r\n\u00a0\u00a0\u00a0 GRP=$(id -g -n)\r\n\u00a0\u00a0\u00a0 cgcreate -t $USER:$GRP -a $USER:$GRP -g \"$1\":\"$2\"\r\n}\r\n\r\n# Format a group path for the current session of the current user\r\n# param: group name\r\nfunction mycg_path {\r\n\u00a0\u00a0\u00a0 echo -n user\/$UID.user\/\"$XDG_SESSION_ID\".session\/\"$1\"\r\n}\r\n\r\n# Initialize my groups\r\nfunction mycg_init {\r\n\u00a0\u00a0\u00a0 echo Init cgroups: $(mycg_path)\r\n\u00a0\u00a0\u00a0 DARKTABLE=$(mycg_path darktable)\r\n\u00a0\u00a0\u00a0 mycg_create \"cpu,memory\" \"$DARKTABLE\"\r\n\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0 # Limit a bit the memory for darktables\r\n\u00a0\u00a0\u00a0 echo $((1500*1024*1024)) &gt; \/sys\/fs\/cgroup\/memory\/\"$DARKTABLE\"\/memory.limit_in_bytes\r\n\u00a0\u00a0\u00a0 echo 900 &gt; \/sys\/fs\/cgroup\/cpu\/\"$DARKTABLE\"\/cpu.shares\r\n\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0 # A group for Firefox\r\n\u00a0\u00a0\u00a0 GOOGLEFOX=$(mycg_path googlefox)\r\n\u00a0\u00a0\u00a0 mycg_create \"cpu,memory\" \"$GOOGLEFOX\"\r\n\u00a0\u00a0 \u00a0\r\n\u00a0\u00a0\u00a0 echo $((800*1024*1024)) &gt; \/sys\/fs\/cgroup\/memory\/\"$GOOGLEFOX\"\/memory.limit_in_bytes\r\n\u00a0\u00a0\u00a0 echo 500 &gt; \/sys\/fs\/cgroup\/cpu\/\"$GOOGLEFOX\"\/cpu.shares\r\n}\r\n\r\nif [ \"$1\" == \"init\" ]\r\nthen\r\n\u00a0\u00a0\u00a0 mycg_init\r\nelif [ \"$1\" == \"run\" ]\r\nthen\r\n\u00a0\u00a0\u00a0 shift\r\n\u00a0\u00a0\u00a0 if [ \"$#\" -lt 2 ]\r\n\u00a0\u00a0\u00a0 then\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 echo \"Error: not enough args\"\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 echo \"mygroup exec PROFILE_NAME COMMAND\"\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0 exit 1\r\n\u00a0\u00a0\u00a0 fi\r\n\u00a0\u00a0\u00a0 CG_GRP=\"$1\"\r\n\u00a0\u00a0\u00a0 shift \r\n\u00a0\u00a0\u00a0 echo \"Execute: group=$CG_GRP, command=$@\"\r\n\u00a0\u00a0\u00a0 CG_PATH=$(mycg_path \"$CG_GRP\")\r\n\u00a0\u00a0\u00a0 cgexec -g memory,cpu:\"$CG_PATH\" \"$@\"\r\nelse\r\n\u00a0\u00a0\u00a0 echo \"Unknown command: $1\"\r\n\u00a0\u00a0\u00a0 exit 2\r\nfi\r\n\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>In Linux, cgroups (a kernel feature) allows to limit the resources (cpu, memory\u2026) accessible to a group of processes. I have written a little bash script that will either: create some groups for the current user session and assign some restrictions. No need to be root or to modify a global configuration file. Call it [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[6,19],"tags":[],"class_list":["post-1338","post","type-post","status-publish","format-standard","hentry","category-informatique","category-linux","\"lang=\"en"],"_links":{"self":[{"href":"https:\/\/fabsk.eu\/blog\/wp-json\/wp\/v2\/posts\/1338","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/fabsk.eu\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/fabsk.eu\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/fabsk.eu\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/fabsk.eu\/blog\/wp-json\/wp\/v2\/comments?post=1338"}],"version-history":[{"count":14,"href":"https:\/\/fabsk.eu\/blog\/wp-json\/wp\/v2\/posts\/1338\/revisions"}],"predecessor-version":[{"id":1451,"href":"https:\/\/fabsk.eu\/blog\/wp-json\/wp\/v2\/posts\/1338\/revisions\/1451"}],"wp:attachment":[{"href":"https:\/\/fabsk.eu\/blog\/wp-json\/wp\/v2\/media?parent=1338"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/fabsk.eu\/blog\/wp-json\/wp\/v2\/categories?post=1338"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/fabsk.eu\/blog\/wp-json\/wp\/v2\/tags?post=1338"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}