Login
Log in using an SSO provider:
Fedora Account System
Red Hat Associate
Red Hat Customer
Login using a Red Hat Bugzilla account
Forgot Password
Create an Account
Red Hat Bugzilla – Attachment 463954 Details for
Bug 631561
[6.1 FEAT] Implement lsmem and chmem
Home
New
Search
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh90 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
[?]
This site requires JavaScript to be enabled to function correctly, please enable it.
s390-tools-rhel6-lsmem-chmem.patch
s390-tools-rhel6-lsmem-chmem.patch (text/plain), 18.48 KB, created by
IBM Bug Proxy
on 2010-12-01 11:51:00 UTC
(
hide
)
Description:
s390-tools-rhel6-lsmem-chmem.patch
Filename:
MIME Type:
Creator:
IBM Bug Proxy
Created:
2010-12-01 11:51:00 UTC
Size:
18.48 KB
patch
obsolete
>Summary: lsmem/chmem: Tools to manage memory hotplug. >Description: With lsmem, you can display the online status of all available > memory. With chmem, you can set memory online or offline. >--- > README | 2 > zconf/Makefile | 17 ++ > zconf/chmem | 325 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ > zconf/chmem.8 | 71 ++++++++++++ > zconf/lsmem | 158 +++++++++++++++++++++++++++ > zconf/lsmem.8 | 69 ++++++++++++ > 6 files changed, 639 insertions(+), 3 deletions(-) > >--- a/README >+++ b/README >@@ -112,6 +112,8 @@ s390-tools (1.8.2) > 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. > > * dumpconf: > Allows to configure the dump device used for system dump in case a kernel >--- a/zconf/Makefile >+++ b/zconf/Makefile >@@ -5,14 +5,16 @@ include ../common.mak > > SCRIPTS = lsdasd lstape lscss chccwdev lsqeth lszfcp lschp chchp lszcrypt \ > chzcrypt lsluns cio_ignore znetconf >+USRSBIN_SCRIPTS = lsmem chmem > MANPAGES= lsdasd.8 lstape.8 lscss.8 chccwdev.8 lsqeth.8 lszfcp.8 lschp.8 \ >- chchp.8 lszcrypt.8 chzcrypt.8 lsluns.8 cio_ignore.8 znetconf.8 >+ chchp.8 lszcrypt.8 chzcrypt.8 lsluns.8 cio_ignore.8 znetconf.8 \ >+ chmem.8 lsmem.8 > > all: > > clean: > >-install: install-scripts install-manpages >+install: install-scripts install-manpages install-usrsbin-scripts > $(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 lsznet.raw $(TOOLS_LIBDIR) > $(INSTALL) -g $(GROUP) -o $(OWNER) -m 755 znetcontrolunits \ > $(TOOLS_LIBDIR) >@@ -26,6 +28,15 @@ install-scripts: $(SCRIPTS) > chmod 755 $(BINDIR)/$$i; \ > done > >+install-usrsbin-scripts: $(USRSBIN_SCRIPTS) >+ @for i in $^; do \ >+ cat $$i | \ >+ sed -e 's+%S390_TOOLS_VERSION%+$(S390_TOOLS_RELEASE)+' \ >+ >$(USRSBINDIR)/$$i; \ >+ chown $(OWNER).$(GROUP) $(USRSBINDIR)/$$i; \ >+ chmod 755 $(USRSBINDIR)/$$i; \ >+ done >+ > install-manpages: $(MANPAGES) > @if [ ! -d $(MANDIR) ]; then \ > mkdir -p $(MANDIR)/man8; \ >@@ -38,4 +49,4 @@ install-manpages: $(MANPAGES) > install -o $(OWNER) -g $(GROUP) -m 644 $$i $(MANDIR)/man8; \ > done > >-.PHONY: all install clean install-scripts install-manpages >+.PHONY: all install clean install-scripts install-manpages install-usrsbin-scripts >--- /dev/null >+++ b/zconf/chmem >@@ -0,0 +1,325 @@ >+#!/usr/bin/perl >+############################################################################### >+# chmem - script to show memory hotplug status. >+# >+# Copyright IBM Corp. 2010 >+# Author(s): Gerald Schaefer <gerald.schaefer@de.ibm.com> >+############################################################################### >+ >+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 $total_blocks = 0; >+my $devices = {}; >+my $dev_size; >+my $blocks_per_dev = 0; >+my $devs_per_block = 0; >+my $ret = 0; >+ >+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\n"; >+} >+ >+sub chmem_get_dev_size() >+{ >+ my $i = 0; >+ my $device = 0; >+ my $old_device = 0; >+ >+ while (-d "$memdir/memory$i") { >+ $device = `cat $memdir/memory$i/phys_device`; >+ chomp($device); >+ if ($device > $old_device) { >+ $dev_size = int($dev_size / ($device - $old_device)); >+ last; >+ } >+ $dev_size += $block_size; >+ $i++; >+ } >+} >+ >+sub chmem_online($) >+{ >+ my $block = shift; >+ >+ 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 $i = 0; >+ my $device = 0; >+ my $old_device = 0; >+ my $blocks = 0; >+ my $state; >+ >+ while (-d "$memdir/memory$i") { >+ chmem_read_attr($state, $device, $i); >+ 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++; >+ } >+ $i++; >+ } >+ $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 < $total_blocks - 1) { >+ $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() >+{ >+ unless (-d $memdir) { >+ die "chmem: No memory hotplug interface in sysfs ($memdir).\n"; >+ } >+ $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"; >+ } >+ >+ while (-d "$memdir/memory$total_blocks") { >+ $total_blocks++; >+ } >+ 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"; >+}; >+ >+chmem_read_devices(); >+chmem_check(); >+chmem_action(); >+exit $ret; >--- /dev/null >+++ b/zconf/chmem.8 >@@ -0,0 +1,71 @@ >+.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) >--- /dev/null >+++ b/zconf/lsmem >@@ -0,0 +1,158 @@ >+#!/usr/bin/perl >+############################################################################### >+# lsmem - script to show memory hotplug status. >+# >+# Copyright IBM Corp. 2010 >+# Author(s): Gerald Schaefer <gerald.schaefer@de.ibm.com> >+############################################################################### >+ >+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; >+ >+ >+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 $i = 0; >+ my ($device, $old_device) = (0, 0); >+ >+ while (-d "$memdir/memory$i") { >+ $device = `cat $memdir/memory$i/phys_device`; >+ chomp($device); >+ if ($device > $old_device) { >+ $dev_size = int($dev_size / ($device - $old_device)); >+ last; >+ } >+ $dev_size += $block_size; >+ $i++; >+ } >+} >+ >+sub lsmem_list() >+{ >+ my $i = 0; >+ my ($start, $end, $size) = (0, 0, 0); >+ my ($state, $old_state) = (0, 0); >+ my ($rem, $old_rem) = (0, 0); >+ my ($device, $old_device) = (0, 0); >+ my ($mem_online, $mem_offline) = (0, 0); >+ my ($last_block, $end_dev) = (0, 0); >+ >+ if (-d "$memdir/memory0") { >+ lsmem_read_attr($old_state, $old_rem, $old_device, 0); >+ } else { >+ die "lsmem: No memory hotplug interface in sysfs ($memdir).\n"; >+ } >+ >+ $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(); >+ >+ print <<HERE; >+Address Range Size (MB) State Removable Device >+=============================================================================== >+HERE >+ while (-d "$memdir/memory$i") { >+ $i++; >+ if (-d "$memdir/memory$i") { >+ lsmem_read_attr($state, $rem, $device, $i); >+ } else { >+ $last_block = 1; >+ } >+ if ($state ne $old_state || $rem != $old_rem || $list_all || >+ $last_block) { >+ $end = $i * ($block_size << 20) - 1; >+ $size = ($end - $start + 1) >> 20; >+ if ($old_state eq "going-offline") { >+ $old_state = "on->off"; >+ } >+ printf("0x%016x-0x%016x %10lu %-7s ", $start, $end, >+ $size, $old_state); >+ if ($old_state eq "online") { >+ printf(" %-9s ", $old_rem ? "yes" : "no"); >+ $mem_online += $size; >+ } else { >+ printf(" %-9s ", "-"); >+ $mem_offline += $size; >+ } >+ $end_dev = ($end / $dev_size) >> 20; >+ if ($old_device == $end_dev) { >+ printf("%d\n", $old_device); >+ } else { >+ printf("%d-%d\n", $old_device, $end_dev); >+ } >+ $old_state = $state; >+ $old_rem = $rem; >+ $old_device = $device; >+ $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\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"; >+}; >+ >+lsmem_list(); >--- /dev/null >+++ b/zconf/lsmem.8 >@@ -0,0 +1,69 @@ >+.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)
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Actions:
View
Attachments on
bug 631561
: 463954