How to overwrite default cgroup cgconfig.conf using cgconfig.d? - linux

The default cgroup config file cgconfig.conf provided with the libcgroup conatains:
mount {
cpuset = /cgroup/cpuset;
cpu = /cgroup/cpu;
cpuacct = /cgroup/cpuacct;
memory = /cgroup/memory;
devices = /cgroup/devices;
freezer = /cgroup/freezer;
net_cls = /cgroup/net_cls;
blkio = /cgroup/blkio;
}
I want to use something like this:
mount {
cpuset = /cgroup/cpu_and_mem;
cpu = /cgroup/cpu_and_mem;
cpuacct = /cgroup/cpu_and_mem;
memory = /cgroup/cpu_and_mem;
}
group cpu_memory_high {
cpu {
cpu.shares = 800;
}
cpuset {
cpuset.cpus="0-6";
}
memory {
memory.limit_in_bytes = 5G;
}
}
group cpu_memory_low {
cpu {
cpu.share = 200;
}
cpuset {
cpuset.cpus="8"
}
memory {
memory.limit_in_bytes = 500M;
}
}
I don't want to overwrite cgconfig.conf, So I tried to use cgconfig.d with above settings in a new file abc.conf and placed it in cgconfig.d.
But these new settings didn't work for me.
Anyone have idea whats wrong with above config.

In order to work /etc/cgconfig.d/ directory you have to add:
$CGCONFIGPARSER_BIN -L /etc/cgconfig.d/
after:
$CGCONFIGPARSER_BIN -l $CONFIG_FILE
line in /etc/init.d/cgconfig file.
It works on Amazon Linux at least.

On Centos 7, it seems /etc/cgconfig.d was enabled by default, but it seems that is no longer the case on Centos 8. Here's how I fixed it:
Copy the default cgconfig unit file to cgconfigd.service:
sudo cp /usr/lib/systemd/system/cgconfig.service \
/etc/systemd/system/cgconfigd.service
Edit the file:
Change both occurrences of -l /etc/cgconfig.conf to -L /etc/cgconfig.d.
Under [Unit], add After=cgconfig.service
Enable and start the service:
sudo systemctl daemon-reload
sudo systemctl enable cgconfigd
sudo systemctl start cgconfigd

You have misunderstood how cgroups work. The mounts are arbitrary. Your group declarations create new directories in the mounts. There is never any need to combine subsystem directories and doing so will make it impossible to control tasks separately as they all use similar directory structures. It will more than likely cause cgroups to fail altogether.
The mounts you already have are fine, and the groups you set up will work as they are. You only need to reference the group name and the subsystem. Combining mounts will not make any difference.
See https://askubuntu.com/a/94743/170177

Related

Puppet: conditional restart of service

Is it possible to conditionally skip refresh events on a service resource? Or alternatively: Is it possible to prevent a service resource inside a class to be refreshed when the class is notified?
Context: I have a Puppet module containing the following manifest (simplified):
class foo(
Boolean pre_process_service = true,
Boolean auto_restart_service = true
) {
if $pre_process_service {
exec { 'process config':
... # details including a pretty complex command - should be hidden in my module
notify => Service['foo'],
}
}
service { 'foo':
ensure => 'running',
enable => true,
}
}
which might be used like so:
file { 'config':
... # copies config from somewhere
}
class { 'foo':
auto_restart_service => false,
subscribe => File['config'],
}
How can I avoid restarting the service when the user specifies auto_restart_service => false?
Note that the user of the module decides how to provide the configuration (copying files, checking out a Git repository,...) so I can't do that inside my module. Instead the class subscribes to the resource providing the configuration. As long as the user goes with the default of auto_restart_service = true everything works fine and even disabling the preprocessing of the configuration works correctly. However, when the user specifies auto_restart_service = false the service will still restart since the service resource is refreshed when the class is notified. Wrapping the service resource into an if block like I did with the exec resource doesn't work either since the service resource does multiple things:
It starts the service if it isn't running
It enables the service if it isn't enabled
It restarts the service if notified
I only want to conditionally prevent (3) from happening while always doing (1) and (2). Is there a way to do this?
I don't think there's a way to not refresh the service when you notify the class. However, you can try to conditionally override how Puppet should restart the service with the restart attribute of the service resource.
Something like this:
if $auto_restart_service {
# Let the provider handle the restart
$_attr = {}
} else {
# Let Puppet execute `true` instead of actually restarting the service
$_attr = { 'restart' => '/usr/bin/true' }
}
service { 'foo':
ensure => 'running',
enable => true,
* => $_attr,
}
The idea from tectux is really nice. I've enhanced the if conditions. I have decided to use script for custom fact.
modules/autofs/facts.d/autofs.sh
#!/bin/sh
DECISION=`test -f /usr/bin/docker && /usr/bin/docker ps -q |grep -q . && echo no`
if [ "x$DECISION" == "x" ] ; then
DECISION=yes
fi
echo '{'
echo ' "autofs": {'
echo " \"do_automatic_restart\": \"$DECISION\""
echo ' }'
echo '}'
So, the output of the script
# modules/autofs/facts.d/autofs.sh
{
"autofs": {
"do_automatic_restart": "yes"
}
}
Now we can use the custom fact
if $facts['autofs']['do_automatic_restart'] == "no" {
$_attr = { 'restart' => "logger puppet agent: automounter is NOT going to be RESTARTED due to active containers on a host" }
} else {
$_attr = {}
}

RHEL: cgroup change of group failed

When I run the following command, I get cgroup change of group failed:
cgexec --sticky -g *:/throttle some_task
Cgroup throttle is defined in cgconfig.conf, which looks like this:
# Configuration file generated by cgsnapshot
mount {
cpuset = /cgroup/cpuset;
cpu = /cgroup/cpu;
cpuacct = /cgroup/cpuacct;
memory = /cgroup/memory;
devices = /cgroup/devices;
freezer = /cgroup/freezer;
net_cls = /cgroup/net_cls;
blkio = /cgroup/blkio;
}
group throttle {
cpu {
cpu.rt_period_us="1000000";
cpu.rt_runtime_us="0";
cpu.cfs_period_us="1000000";
cpu.cfs_quota_us="500000";
cpu.shares="1024";
}
}
group throttle {
memory {
memory.memsw.failcnt="0";
memory.limit_in_bytes="1073741824";
memory.memsw.max_usage_in_bytes="0";
memory.move_charge_at_immigrate="0";
memory.swappiness="60";
memory.use_hierarchy="0";
memory.failcnt="0";
memory.soft_limit_in_bytes="134217728";
memory.memsw.limit_in_bytes="1073741824";
memory.max_usage_in_bytes="0";
}
}
group throttle {
blkio {
blkio.throttle.write_iops_device="8:0 10";
blkio.throttle.read_iops_device="8:0 10";
blkio.throttle.write_bps_device="";
blkio.throttle.read_bps_device="";
blkio.weight="500";
blkio.weight_device="";
}
}
I have searched far and wide and haven't a clue how to start trouble shooting this. This seems to be commonly associated with incorrect permissions. However, I don't define permissions (the documentation for cgroups says that this is optional). I'm running the process as root.
Figured it out. For some reason, cgexec on my system is not liking the wildcard (*) for the controller. When I listed controllers by name, it worked:
cgexec --sticky -g "cpu,memory,blkio":/throttle some_task
The manpage for cgexec on my system lists *:<group_name> as valid syntax, however, so I'm not sure what exactly is going on. Either way, it's working correctly when the controllers are specified.

How to script stap (systemtap) to see if some process has called specific kernel function?

Using stap, I can write *.stp file to
Either track a process's action like:
probe process("mytest").begin
{
printf("Caught mytest process")
}
Or to track if a kernel function is called by any process:
probe kernel.function("do_exit").call #all processes
{
printf("called kernel/exit.c: do_exit\n")
}
But my requirement is: to track the kernel function call from specific process names, like tracking "sys_open" called by "mytest" processes.
How to write this .stp statement/function?
Thanks!
I found a way to do that: use a variable indicating the program name
global prog_name = "mytest";
probe kernel.function("do_exit").call
{
if(execname() == progname){
printf("called kernel/exit.c: do_exit\n");
}
}

Spark/Gradle -- Getting IP Address in build.gradle to use for starting master and workers

I understand at a basic level the various moving parts of build.gradle build scripts but am having trouble tying it all together.
In Apache Spark standalone mode, just trying to start a master and worker on the same box from build.gradle. (Later will extend with call with $SPARK_HOME/sbin/start-slaves with the proper argument for masterIP.)
Question: How can I assign my IP address to a variable in Groovy/build.gradle so I can pass it to a command in an Exec task? We want this to run on a couple different development machines.
We have a (I think fairly standard) /etc/hosts config with the FQDN and hostname assigned to 127.0.1.1. The driver gets around this OK but starting master and slaves with hostnames is not an option, I need the ip address.
I am trying:
task getMasterIP (type: Exec){
// declare script scope variable using no def or
executable "hostname"
args += "-I"
// need results of hostname call assigned to script scope variable
sparkMasterIP = <resultsOfHostnameCall>
}
// added this because startSlave stops if Master is already running
task startSlaveOnly(dependsOn:'getMasterIP', type: Exec){
executable "/usr/local/spark/sbin/start-slave.sh"
args += "spark://$sparkMasterIP:7077"
doLast {
println "enslaved"
}
}
// now make startSlave call startSlaveOnly after the initial startMaster
task startSlave(dependsOn:'startMaster', type: Exec) {
finalizedBy 'startSlaveOnly'
}
When I try something like suggested in the docs for Exec for Groovy calls:
task getMasterIP (type: Exec){
// declare script scope variable using no def or
sparkMasterIP = executable "hostname"
args += "-I"
}
I get a warning that executable is not recognized.
The " for a little more background on what I am thinking" section, not the main question.
Googling "build.gradle script scope variables" and looking at the first two results, in the basic docs I only see one type of variable and ext properties to be used.
16.4. Declaring variables -- There are two kinds of variables that can be declared in a build script: local variables and extra properties.
But in this other Gradle doc Appendix B. Potential Traps I am seeing two kinds of variables scopes aside from the ext properties:
For Gradle users it is important to understand how Groovy deals with
script variables. Groovy has two types of script variables. One with a
local scope and one with a script-wide scope.
With this example usage:
String localScope1 = 'localScope1'
def localScope2 = 'localScope2'
scriptScope = 'scriptScope'
I am assuming I should be using script-scope variables with no "def" or type declaration.
To fetch local IPs:
// Return all IPv4 addresses
def getLocalIPv4() {
def ip4s = []
NetworkInterface.getNetworkInterfaces()
.findAll { it.isUp() && !it.isLoopback() && !it.isVirtual() }
.each {
it.getInetAddresses()
.findAll { !it.isLoopbackAddress() && it instanceof Inet4Address }
.each { ip4s << it.getHostAddress() }
}
return ip4s
}
// Optionally, return all IPv6 addresses
def getLocalIPv6() {
def ip6s = []
NetworkInterface.getNetworkInterfaces()
.findAll { it.isUp() && !it.isLoopback() && !it.isVirtual() }
.each {
it.getInetAddresses()
.findAll { !it.isLoopbackAddress() && it instanceof Inet6Address }
.each { ip6s << it.getHostAddress() }
}
return ip6s
}
task printIP() doLast {
println getLocalIPv4()
println getLocalIPv6()
}
The two functions above return a list of IPv4 or IPv6 addresses respectively. You might notice that I'm skipping all localhosts, interfaces that are not up, all loopbacks and virtual interfaces. If you want to use the first IPv4 address, you can use it elsewhere as:
getLocalIPv4()[0]
or in your case:
args += "spark://"+ getLocalIPv4()[0] + ":7077"
I found this post that appears to be a more straightforward way of doing this but it limited to Linux platforms, hostname -I doesn't work in Windows and maybe not all Linux distros?
getting hostname
assigning it to variable
using in a build.gradle
task
Here's the task I built as a result, the accepted answer is much better and more universal, this is just for another way of looking at it
task getMasterIP{
doLast {
new ByteArrayOutputStream().withStream { os ->
def result = exec {
executable = 'hostname'
args += '-I'
}
ext.ipAddress = os.toString()
}
}
}
RaGe's answer does a better job of looking at all interfaces on all platforms

Puppet; Call another .pp

So I am using the https://forge.puppetlabs.com/pdxcat/nrpe module to try to figure out automation of NRPE across hosts.
One of the available usages is
nrpe::command {
'check_users':
ensure => present,
command => 'check_users -w 5 -c 10';
}
Is there anyway to make a "group" of these commands and have them called on specific nodes?
For example:
you have 5 different nrpe:command each defining a different check, and then call those specific checks?
I am basically trying to figure out if I could group certain checks/commands together instead of setting up a ton of text in the main sites.pp file. This would also allow for customized templates/configurations across numerous nodes.
Thanks!
EDIT:
This is the command and what it's supposed to do when called on with the 'check_users' portion. If I could have a class with a set of "nrpe:command" and just call on that class THROUGH the module, it should work. Sorry, though. Still new at puppet. Thanks again.
define nrpe::command (
$command,
$ensure = present,
$include_dir = $nrpe::params::nrpe_include_dir,
$libdir = $nrpe::params::libdir,
$package_name = $nrpe::params::nrpe_packages,
$service_name = $nrpe::params::nrpe_service,
$file_group = $nrpe::params::nrpe_files_group,
) {
file { "${include_dir}/${title}.cfg":
ensure => $ensure,
content => template('nrpe/command.cfg.erb'),
owner => root,
group => $file_group,
mode => '0644',
require => Package[$package_name],
notify => Service[$service_name],
}
}
What version are you talking about? In puppet latest versions, inheritance is deprecated, then you shouldn't use it.
The easiest way would be to use "baselines".
Assuming you are using a manifests directory (manifest = $confdir/manifests inside your puppet.conf), simply create a $confdir/manifests/minimal.pp (or $confdir/manifests/nrpe_config.pp or whatever class name you want to use) with the content below:
class minimal {
nrpe::command { 'check_users':
ensure => present,
command => 'check_users -w 5 -c 10',
}
}
Then just call this class inside your node definitions (let's say in $confdir/manifests/my_node.pp) :
node 'my_node.foo.bar' {
include minimal
}

Resources