lsmem/chmem: Remove tools

lsmem/chmem moved to util-linux >= 2.30, remove them from s390-tools.

For kernels >= 4.13, the default memory zone for hotplug memory was
changed from zone MOVABLE to zone NORMAL. In order to keep using zone
MOVABLE for memory hotplug, either use the lsmem/chmem tools from
s390-tools version 2.1.0, or an updated version of the util-linux
version of lsmem/chmem that contains the following util-linux git
commits (included in util-linux 2.32):

60a7e9e94e49 "lsmem/chmem: add memory zone awareness"
0a4320f5e785 "tests/lsmem: update lsmem test with ZONES column"
afee3f204247 "lsmem/chmem: add memory zone awareness to bash-completion"

Signed-off-by: Gerald Schaefer <gerald.schaefer@de.ibm.com>
Signed-off-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
This commit is contained in:
Gerald Schaefer
2017-11-13 18:48:16 +01:00
committed by Michael Holzheu
parent c21e464856
commit 778292e771
7 changed files with 5 additions and 658 deletions

View File

@@ -3,6 +3,9 @@ Release history for s390-tools (MIT version)
* __v2.1.1 (2017-mm-dd)__
Removed tools:
- lsmem/chmem: Moved to util-linux >= 2.30
Changes of existing tools:
- lszcrypt: Add CEX6S exploitation

View File

@@ -131,8 +131,6 @@ Package contents
- znetconf: List and configure network devices for s390 network adapters.
- cio_ignore: Query and modify the contents of the CIO device driver
blacklist.
- lsmem: Display the online status of the available memory.
- chmem: Set hotplug memory online or offline.
- dasdstat: Configure and format the debugfs based DASD statistics data.
* zkey:

View File

@@ -4,9 +4,9 @@
include ../common.mak
SCRIPTS = lsdasd lstape chccwdev lszfcp cio_ignore znetconf dasdstat
USRSBIN_SCRIPTS = lsmem chmem lsluns
USRSBIN_SCRIPTS = lsluns
MANPAGES= lsdasd.8 lstape.8 chccwdev.8 lszfcp.8 lsluns.8 \
cio_ignore.8 znetconf.8 chmem.8 lsmem.8 dasdstat.8
cio_ignore.8 znetconf.8 dasdstat.8
SUB_DIRS = zcrypt scm chp css qeth

View File

@@ -1,334 +0,0 @@
#!/usr/bin/perl
#
# chmem - Tool to change memory hotplug status
#
# Copyright IBM Corp. 2010, 2017
#
# s390-tools is free software; you can redistribute it and/or modify
# it under the terms of the MIT license. See LICENSE for details.
#
use strict;
use warnings;
use Getopt::Long qw(:config no_ignore_case no_auto_abbrev);
use File::Basename;
my $script_name = fileparse($0);
my $online = 0;
my $offline = 0;
my $memdir = "/sys/devices/system/memory";
my $block_size = 0;
my $max_block_nr = 0;
my $devices = {};
my $dev_size;
my $blocks_per_dev = 0;
my $devs_per_block = 0;
my $ret = 0;
my @entries;
sub chmem_usage()
{
print <<HERE;
Usage: $script_name [OPTIONS] SIZE|RANGE
The $script_name command sets a particular size or range of memory online
or offline.
Specify SIZE as <size>[m|M|g|G]. With m or M, <size> specifies the memory
size in MB (1024 x 1024 bytes). With g or G, <size> specifies the memory size
in GB (1024 x 1024 x 1024 bytes). The default unit is MB.
Specify RANGE in the form 0x<start>-0x<end> as shown in the output of the
lsmem command. <start> is the hexadecimal address of the first byte and <end>
is the hexadecimal address of the last byte in the memory range.
SIZE and RANGE must be aligned to the Linux memory block size, as shown in
the output of the lsmem command.
OPTIONS
-e, --enable
Set the given RANGE or SIZE of memory online.
-d, --disable
Set the given RANGE or SIZE of memory offline.
-h, --help
Print a short help text, then exit.
-v, --version
Print the version number, then exit.
HERE
}
sub chmem_version()
{
print "$script_name: version %S390_TOOLS_VERSION%\n";
print "Copyright IBM Corp. 2010, 2017\n";
}
sub chmem_get_dev_size()
{
my ($device, $old_device, $block, $old_block) = (0, 0, 0, 0);
foreach (@entries) {
$_ =~ /memory(\d+)/;
$block = $1;
$device = `cat $_/phys_device`;
chomp($device);
if ($device > $old_device) {
$dev_size = int((($block - $old_block) * $block_size) /
($device - $old_device));
last;
}
$dev_size += $block_size;
$old_block = $block;
}
}
sub chmem_online($)
{
my $block = shift;
qx(echo online_movable > $memdir/memory$block/state 2>/dev/null);
if ($? >> 8 != 0) {
qx(echo online > $memdir/memory$block/state 2>/dev/null);
}
return $? >> 8;
}
sub chmem_offline($)
{
my $block = shift;
qx(echo offline > $memdir/memory$block/state 2>/dev/null);
return $? >> 8;;
}
sub chmem_read_attr($$$)
# parameters: state, device, block
{
my @attributes = qw(state phys_device);
foreach (0..1) {
$_[$_] = `cat $memdir/memory$_[2]/$attributes[$_]`;
chomp($_[$_]);
}
}
sub chmem_read_devices()
{
my $block = 0;
my $device = 0;
my $old_device = 0;
my $blocks = 0;
my $state;
foreach (@entries) {
$_ =~ /memory(\d+)/;
$block = $1;
chmem_read_attr($state, $device, $block);
if ($device != $old_device) {
$devices->{$old_device}->{'id'} = $old_device;
$devices->{$old_device}->{'blocks'} = $blocks;
$old_device = $device;
$blocks = 0;
}
if ($state eq "online") {
$blocks++;
}
}
$devices->{$old_device}->{'blocks'} = $blocks;
$devices->{$old_device}->{'id'} = $old_device;
}
sub chmem_dev_action($$)
{
my ($dev_id, $blocks) = @_;
my ($start_block, $end_block, $tmp_block, $max_blocks);
my $state;
my $i = 0;
my $count = 0;
if ($blocks_per_dev > 0) {
$start_block = $dev_id * $blocks_per_dev;
$end_block = $start_block + $blocks_per_dev - 1;
$max_blocks = $blocks_per_dev;
} else {
$start_block = int($dev_id / $devs_per_block);
$end_block = $start_block;
$max_blocks = 1;
}
if ($blocks > $max_blocks) {
$blocks = $max_blocks;
}
while ($count < $blocks && $i < $max_blocks) {
$tmp_block = $online ? $start_block + $i : $end_block - $i;
$state = `cat $memdir/memory$tmp_block/state`;
chomp($state);
if ($offline && $state eq "online") {
$count++ unless chmem_offline($tmp_block);
}
if ($online && $state eq "offline") {
$count++ unless chmem_online($tmp_block);
}
$i++;
}
return $count;
}
sub chmem_size($)
{
my $size = shift;
my ($blocks, $dev_blocks, $dev_id);
$blocks = int($size / $block_size);
if ($online) {
foreach my $device (sort {$b->{'blocks'} <=> $a->{'blocks'} ||
$a->{'id'} <=> $b->{'id'}}
values %{$devices}) {
$dev_blocks = $device->{'blocks'};
$dev_id = $device->{'id'};
if ($dev_blocks < $blocks_per_dev || $dev_blocks == 0) {
$blocks -= chmem_dev_action($dev_id, $blocks);
if ($blocks == 0) {
last;
}
}
}
if ($blocks > 0) {
printf(STDERR "chmem: Could only set %lu MB of memory ".
"online.\n", $size - $blocks * $block_size);
$ret = 1;
}
} else {
foreach my $device (sort {$a->{'blocks'} <=> $b->{'blocks'} ||
$b->{'id'} <=> $a->{'id'}}
values %{$devices}) {
$dev_blocks = $device->{'blocks'};
$dev_id = $device->{'id'};
if ($dev_blocks > 0) {
$blocks -= chmem_dev_action($dev_id, $blocks);
if ($blocks == 0) {
last;
}
}
}
if ($blocks > 0) {
printf(STDERR "chmem: Could only set %lu MB of memory ".
"offline.\n", $size - $blocks * $block_size);
$ret = 1;
}
}
}
sub chmem_range($$)
{
my ($start, $end) = @_;
my $block = 0;
my $state;
while ($start < $end && $block < $max_block_nr) {
$block = int($start / ($block_size << 20));
$state = `cat $memdir/memory$block/state`;
chomp($state);
if ($online && $state eq "offline") {
if (chmem_online($block)) {
printf(STDERR "chmem: Could not set ".
"0x%016x-0x%016x online\n", $start,
$start + ($block_size << 20) - 1);
$ret = 1;
}
}
if ($offline && $state eq "online") {
if (chmem_offline($block)) {
printf(STDERR "chmem: Could not set ".
"0x%016x-0x%016x offline\n", $start,
$start + ($block_size << 20) - 1);
$ret = 1;
}
}
$start += $block_size << 20;
}
}
sub chmem_check()
{
$block_size = `cat $memdir/block_size_bytes`;
chomp($block_size);
if ($block_size =~ /(?:0x)?([[:xdigit:]]+)/) {
$block_size = unpack("Q", pack("H16",
substr("0" x 16 . $1, -16)));
$block_size = $block_size >> 20;
} else {
die "chmem: Unknown block size format in sysfs.\n";
}
if ($online == 0 && $offline == 0) {
die "chmem: Please specify one of the options -e or -d.\n";
}
if ($online == 1 && $offline == 1) {
die "chmem: You cannot specify both options -e and -d.\n";
}
chmem_get_dev_size();
if ($dev_size >= $block_size) {
$blocks_per_dev = int($dev_size / $block_size);
} else {
$devs_per_block = int($block_size / $dev_size);
}
}
sub chmem_action()
{
my ($start, $end, $size, $unit);
if (!defined($ARGV[0])) {
die "chmem: Missing size or range.\n";
}
if ($ARGV[0] =~ /^0x([[:xdigit:]]+)-0x([[:xdigit:]]+)$/) {
$start = unpack("Q", pack("H16", substr("0" x 16 . $1, -16)));
$end = unpack("Q", pack("H16", substr("0" x 16 . $2, -16)));
if ($start % ($block_size << 20) ||
($end + 1) % ($block_size << 20)) {
die "chmem: Start address and (end address + 1) must ".
"be aligned to memory block size ($block_size MB).\n";
}
chmem_range($start, $end);
} else {
if ($ARGV[0] =~ m/^(\d+)([mg]?)$/i) {
$size = $1;
$unit = $2 || "";
if ($unit =~ /g/i) {
$size = $size << 10;
}
if ($size % $block_size) {
die "chmem: Size must be aligned to memory ".
"block size ($block_size MB).\n";
}
chmem_size($size);
} else {
printf(STDERR "chmem: Invalid size or range: %s\n",
$ARGV[0]);
exit 1;
}
}
}
# Main
unless (GetOptions('v|version' => sub {chmem_version(); exit 0;},
'h|help' => sub {chmem_usage(); exit 0;},
'e|enable' => \$online,
'd|disable' => \$offline)) {
die "Try '$script_name --help' for more information.\n";
};
@entries = (sort {length($a) <=> length($b) || $a cmp $b} <$memdir/memory*>);
if (@entries == 0) {
die "chmem: No memory hotplug interface in sysfs ($memdir).\n";
}
$entries[-1] =~ /memory(\d+)/;
$max_block_nr = $1;
chmem_read_devices();
chmem_check();
chmem_action();
exit $ret;

View File

@@ -1,75 +0,0 @@
.\" Copyright 2017 IBM Corp.
.\" s390-tools is free software; you can redistribute it and/or modify
.\" it under the terms of the MIT license. See LICENSE for details.
.\"
.TH CHMEM 8 "Apr 2010" "s390-tools"
.
.
.SH NAME
chmem \- set memory online or offline.
.
.SH SYNOPSIS
.B chmem
.RB OPTIONS
.RB [SIZE|RANGE]
.
.
.SH DESCRIPTION
The chmem command sets a particular size or range of memory online or offline.
.
.IP "\(hy" 2
Specify SIZE as <size>[m|M|g|G]. With m or M, <size> specifies the memory
size in MB (1024 x 1024 bytes). With g or G, <size> specifies the memory size
in GB (1024 x 1024 x 1024 bytes). The default unit is MB.
.
.IP "\(hy" 2
Specify RANGE in the form 0x<start>-0x<end> as shown in the output of the
lsmem command. <start> is the hexadecimal address of the first byte and <end>
is the hexadecimal address of the last byte in the memory range.
.
.PP
SIZE and RANGE must be aligned to the Linux memory block size, as shown in
the output of the lsmem command.
Setting memory online can fail if the hypervisor does not have enough memory
left, for example because memory was overcommitted. Setting memory offline can
fail if Linux cannot free the memory. If only part of the requested memory can
be set online or offline, a message tells you how much memory was set online
or offline instead of the requested amount.
.
.
.SH OPTIONS
.TP
.BR \-h ", " \-\-help
Print a short help text, then exit.
.
.TP
.BR \-v ", " \-\-version
Print the version number, then exit.
.
.TP
.BR \-e ", " \-\-enable
Set the given RANGE or SIZE of memory online.
.
.TP
.BR \-d ", " \-\-disable
Set the given RANGE or SIZE of memory offline.
.
.
.SH EXAMPLES
.TP
.B chmem --enable 1024
This command requests 1024 MB of memory to be set online.
.
.TP
.B chmem -e 2g
This command requests 2 GB of memory to be set online.
.
.TP
.B chmem --disable 0x00000000e4000000-0x00000000f3ffffff
This command requests the memory range starting with 0x00000000e4000000
and ending with 0x00000000f3ffffff to be set offline.
.
.
.SH SEE ALSO
.BR lsmem (8)

View File

@@ -1,172 +0,0 @@
#!/usr/bin/perl
#
# lsmem - Tool to show memory hotplug status
#
# Copyright IBM Corp. 2010, 2017
#
# s390-tools is free software; you can redistribute it and/or modify
# it under the terms of the MIT license. See LICENSE for details.
#
use strict;
use warnings;
use Getopt::Long qw(:config no_ignore_case no_auto_abbrev);
use File::Basename;
my $script_name = fileparse($0);
my $memdir = "/sys/devices/system/memory";
my $block_size = 0;
my $list_all = 0;
my $dev_size = 0;
my @entries;
sub lsmem_read_attr($$$$)
# parameters: state, rem, device, block_nr
{
my @attributes = qw(state removable phys_device);
foreach (0..2) {
$_[$_] = `cat $memdir/memory$_[3]/$attributes[$_]`;
chomp($_[$_]);
}
}
sub lsmem_get_dev_size()
{
my ($device, $old_device, $block, $old_block) = (0, 0, 0, 0);
foreach (@entries) {
$_ =~ /memory(\d+)/;
$block = $1;
$device = `cat $_/phys_device`;
chomp($device);
if ($device > $old_device) {
$dev_size = int((($block - $old_block) * $block_size) /
($device - $old_device));
last;
}
$dev_size += $block_size;
$old_block = $block;
}
}
sub lsmem_list()
{
my $block = 0;
my ($start, $end, $size) = (0, 0, 0);
my ($state, $next_state) = (0, 0);
my ($rem, $next_rem) = (0, 0);
my ($device, $next_device, $end_dev) = (0, 0, 0);
my ($mem_online, $mem_offline) = (0, 0);
my $mem_hole;
$block_size = `cat $memdir/block_size_bytes`;
chomp($block_size);
if ($block_size =~ /(?:0x)?([[:xdigit:]]+)/) {
$block_size = unpack("Q", pack("H16",
substr("0" x 16 . $1, -16)));
$block_size = $block_size >> 20;
} else {
die "lsmem: Unknown block size format in sysfs.\n";
}
lsmem_get_dev_size();
# Start with $mem_hole = 1 to initialize $start, $state, $rem, $device
$mem_hole = 1;
print <<HERE;
Address Range Size (MB) State Removable Device
===============================================================================
HERE
foreach (@entries) {
$_ =~ /memory(\d+)/;
$block = $1;
if ($mem_hole) {
lsmem_read_attr($state, $rem, $device, $block);
$start = ($block) * ($block_size << 20);
$mem_hole = 0;
}
# check next block or memory hole
$block++;
if (-d "$memdir/memory".$block) {
lsmem_read_attr($next_state, $next_rem, $next_device,
$block);
} else {
$mem_hole = 1
}
if ($state ne $next_state || $rem != $next_rem || $list_all ||
$mem_hole) {
$end = ($block) * ($block_size << 20) - 1;
$size = ($end - $start + 1) >> 20;
if ($state eq "going-offline") {
$state = "on->off";
}
printf("0x%016x-0x%016x %10lu %-7s ", $start, $end,
$size, $state);
if ($state eq "online") {
printf(" %-9s ", $rem ? "yes" : "no");
$mem_online += $size;
} else {
printf(" %-9s ", "-");
$mem_offline += $size;
}
$end_dev = ($end / $dev_size) >> 20;
if ($device == $end_dev) {
printf("%d\n", $device);
} else {
printf("%d-%d\n", $device, $end_dev);
}
$state = $next_state;
$rem = $next_rem;
$device = $end_dev + 1;
$start = $end + 1;
}
}
printf("\n");
printf("Memory device size : %lu MB\n", $dev_size);
printf("Memory block size : %lu MB\n", $block_size);
printf("Total online memory : %lu MB\n", $mem_online);
printf("Total offline memory: %lu MB\n", $mem_offline);
}
sub lsmem_usage()
{
print <<HERE;
Usage: $script_name [OPTIONS]
The $script_name command lists the ranges of available memory with their online
status. The listed memory blocks correspond to the memory block representation
in sysfs. The command also shows the memory block size, the device size, and
the amount of memory in online and offline state.
OPTIONS
-a, --all
List each individual memory block, instead of combining memory blocks
with similar attributes.
-h, --help
Print a short help text, then exit.
-v, --version
Print the version number, then exit.
HERE
}
sub lsmem_version()
{
print "$script_name: version %S390_TOOLS_VERSION%\n";
print "Copyright IBM Corp. 2010, 2017\n";
}
# Main
unless (GetOptions('v|version' => sub {lsmem_version(); exit 0;},
'h|help' => sub {lsmem_usage(); exit 0;},
'a|all' => \$list_all)) {
die "Try '$script_name --help' for more information.\n";
};
@entries = (sort {length($a) <=> length($b) || $a cmp $b} <$memdir/memory*>);
if (@entries == 0) {
die "lsmem: No memory hotplug interface in sysfs ($memdir).\n";
}
lsmem_list();

View File

@@ -1,73 +0,0 @@
.\" Copyright 2017 IBM Corp.
.\" s390-tools is free software; you can redistribute it and/or modify
.\" it under the terms of the MIT license. See LICENSE for details.
.\"
.TH LSMEM 8 "Apr 2010" s390\-tools
.
.
.SH NAME
lsmem \- list the ranges of available memory with their online status.
.
.
.SH SYNOPSIS
.B lsmem
.RB [OPTIONS]
.
.
.SH DESCRIPTION
The lsmem command lists the ranges of available memory with their online
status. The listed memory blocks correspond to the memory block representation
in sysfs. The command also shows the memory block size, the device size, and
the amount of memory in online and offline state.
.
.SS "Column description"
.
.TP 4
Address Range
Start and end address of the memory range.
.
.TP 4
Size
Size of the memory range in MB (1024 x 1024 bytes).
.
.TP 4
State
Indication of the online status of the memory range. State on->off means
that the address range is in transition from online to offline.
.
.TP 4
Removable
"yes" if the memory range can be set offline, "no" if it cannot be set offline.
A dash ("\-") means that the range is already offline.
.
.TP 4
Device
Device number or numbers that correspond to the memory range.
Each device represents a memory unit for the hypervisor in control of the
memory. The hypervisor cannot reuse a memory unit unless the corresponding
memory range is completely offline. For best memory utilization, each device
should either be completely online or completely offline.
The chmem command with the size parameter automatically chooses the best suited
device or devices when setting memory online or offline. The device size depends
on the hypervisor and on the amount of total online and offline memory.
.
.
.SH OPTIONS
.TP
.BR \-a ", " \-\-all
List each individual memory block, instead of combining memory blocks with
similar attributes.
.
.TP
.BR \-h ", " \-\-help
Print a short help text, then exit.
.
.TP
.BR \-v ", " \-\-version
Print the version number, then exit.
.
.
.SH SEE ALSO
.BR chmem (8)