File: //opt/ndn-cgroups/cgroup_updater.pl
#!/usr/bin/env perl
use strict;
use warnings;
use feature 'say';
use Digest::MD5::File qw( file_md5_hex );
use File::Slurp;
use Getopt::Long;
use JSON;
my ($dryrun, $config_file, $limits_file, $force, $verbose) = (0);
my $cgset_bin = '/usr/bin/cgset';
my $cgget_bin = '/usr/bin/cgget';
GetOptions(
"d|dryrun" => \$dryrun,
"v|verbose" => \$verbose,
"h|help" => sub{ usage() },
"c|config=s" => \$config_file,
"l|limits=s" => \$limits_file,
"f|force" => \$force,
);
sub usage {
say << "EOS";
[About]
Script will update cgroup values for user cgroups
[Usage]
usage: $0 [--dryrun]
[Flags]
-d, --dryrun - dryrun, doesnt execute removal
-f, --force - force update
-h, --help - help! my hand is stuck in the toaster
-c, --config - config file other than default /opt/ndn-cgroups/config.json from servicectl
-l, --limits - limits file other than default /opt/ndn-cgroups/limits.json from servicectl
[Example]
Standard Usage:
$0
EOS
exit 1;
}
$config_file ||= '/opt/ndn-cgroups/config.json';
$limits_file ||= '/opt/ndn-cgroups/limits.json';
# Determine if the md5 from limits.json.md5 is different than the file limits.json
# if it is different we need to run updates on the cgroup values that currently exist
my $limits_md5_name = $limits_file . ".md5";
my $limits_md5;
my $need_update;
if (-e $limits_md5_name) {
$limits_md5 = File::Slurp::read_file($limits_md5_name);
}
my $limits = File::Slurp::read_file($limits_file);
my $json_limits = decode_json $limits;
my %limits = %$json_limits;
my $md5 = file_md5_hex( $limits_file );
if (!$force && ($md5 && $limits_md5) && $md5 eq $limits_md5) {
say "up to date";
exit 0;
}
#
my $config = File::Slurp::read_file($config_file);
my $json_config = decode_json $config;
my $root = $json_config->{'cgroup_root'};
my $parent_group = $json_config->{'customer_cgroups'};
my $cgroup_path = $root . $parent_group;
# find created cgroups
sub GetUserCgroupsPath {
my @path;
for my $limits (keys %limits) {
my $users_cmd = qq(find $cgroup_path/*/$limits/* -type d);
my $cgpath = `$users_cmd`;
foreach (split /\n/, $cgpath) {
$_ =~ s/\/sys\/fs\/cgroup\///;
push @path, $_;
}
}
return @path;
}
my @paths = GetUserCgroupsPath();
for my $user_cgroup_path (@paths) {
for my $limit_group (keys %limits) {
next unless $user_cgroup_path =~ qr/\b$limit_group\b/;
for my $control (keys %{$limits{$limit_group}}) {
for my $cgroup (keys %{$limits{$limit_group}{$control}}) {
my $value = $limits{$limit_group}{$control}{$cgroup};
say "$cgset_bin -r $control.$cgroup=$value $user_cgroup_path" if $verbose;
`$cgset_bin -r $control.$cgroup=$value $user_cgroup_path` unless $dryrun;
}
}
}
}
say "done";
File::Slurp::write_file($limits_md5_name, $md5);
exit 0;