Matt Jamison
2007-03-14 18:24:30 UTC
You are not alone :)
Here is a patch that I've been using for some time to address this problem. I
just ported it from 3.7.4 to 3.8.0 this morning, but it works in my limited
testing and has worked for some time with 3.7.4. I should note that we are
only using RHEL so I've not tested this on other distros, but I -think- this
method should work for any and all flavors. If not, perhaps this patch can
be tweaked accordingly and is still useful...
Basically, rather than shelling out to blkid to resolve swap labels to real
devices, I read and unpack the swap header from the device directly to get
the label.
Matt
Index: lib/SystemImager/Server.pm
===================================================================
--- lib/SystemImager/Server.pm (revision 51)
+++ lib/SystemImager/Server.pm (working copy)
@@ -1287,16 +1287,15 @@
# swap
if ( $xml_config->{fsinfo}->{$line}->{fs} eq "swap" ) {
- my $label = '';
- if ($mount_dev) {
- # add LABEL if necessary
- if ($mount_dev =~ /LABEL=(.*)/) {
- $label = "-L $1";
- }
- }
-
# create swap
- $cmd = "mkswap -v1 $label $real_dev || shellout";
+ $cmd = "mkswap -v1 $real_dev";
+
+ # add swap label if necessary
+ if( $mount_dev =~ /^LABEL=(.*)/ ){
+ $cmd .= " -L $1";
+ }
+ $cmd .= " || shellout";
+
print $out qq(logmsg "$cmd"\n);
print $out "$cmd\n";
Index: lib/SystemImager/Common.pm
===================================================================
--- lib/SystemImager/Common.pm (revision 51)
+++ lib/SystemImager/Common.pm (working copy)
@@ -12,6 +12,8 @@
use strict;
use vars qw($version_number $VERSION);
+use POSIX qw(sysconf _SC_PAGESIZE);
+
$version_number="SYSTEMIMAGER_VERSION_STRING";
$VERSION = $version_number;
@@ -26,6 +28,7 @@
# check_if_root
# detect_bootloader
# get_active_swaps_by_dev
+# get_swap_devs_by_label
# get_boot_flavors
# get_disk_label_type
# get_mounted_devs_by_mount_point_array
@@ -77,7 +80,38 @@
return %active_swaps_by_dev;
}
+# Usage:
+# my $swap_devs_by_label = get_swap_devs_by_label();
+sub get_swap_devs_by_label {
+ my $buf = "";
+ my %swaps;
+ my $page_size = POSIX::sysconf(_SC_PAGESIZE) || die "Error getting
sysconf _SC_PAGESIZE!";
+
+ open(SWAPS, '<', '/proc/swaps') || die "Could not open /proc/swaps for
read: $!";
+ my @swaps = <SWAPS>;
+ close SWAPS;
+ shift @swaps; # remove header...
+
+ for my $line ( @swaps ){
+ chomp $line;
+ my($dev) = (split(/\s+/, $line))[0];
+
+ open(SWAPDEV, '<', $dev) or die "Could not open $dev for read: $!";
+ my $bytes_read = sysread(SWAPDEV, $buf, $page_size, 0);
+ close SWAPDEV;
+
+ unless( $bytes_read == $page_size ){
+ die "sysread returned only $bytes_read reading $dev, _SC_PAGESIZE
= [$page_size]\n";
+ }
+
+ my $label = (unpack('a1024IIIA16A16I117I', $buf))[5]; # v1 swap
header structure found in swapheader.h from util-linux pkg
+ $swaps{$label} = $dev;
+ }
+
+ return wantarray ? %swaps : \%swaps;
+}
+
# Usage:
# %array = get_mounted_devs_by_mount_point_array();
# my %mounted_devs_by_mount_point = get_mounted_devs_by_mount_point_array();
@@ -1241,6 +1275,7 @@
my %mounted_devs_by_mount_point =
get_mounted_devs_by_mount_point_array();
my %active_swaps_by_dev = get_active_swaps_by_dev();
+ my %swap_devs_by_label = get_swap_devs_by_label();
# Read in fstab file and output fstab stanza. -BEF-
#
@@ -1296,11 +1331,14 @@
#
$real_dev = $mount_dev;
$mount_dev = "";
- } else {
- unless ($real_dev) {
- # Try to identify real_dev from the LABEL or UUID
value.
- chomp($real_dev = `blkid -t $mount_dev`);
- $real_dev =~ s/^(.*): .*$/$1/;
+ }
+
+ # if this swap device happens be setup in fstab via a label
(RHEL4 and clones),
+ # reslove that label to the actual device name here
+ if( $fs eq "swap" && $mount_dev =~ /^LABEL=(.*)/ ){
+ if( defined $1 && exists $swap_devs_by_label{$1} ){
+ $real_dev = $swap_devs_by_label{$1};
+ #print STDERR "DEBUG: swap label [$1] resolves to
device [$real_dev]\n";
}
}
Here is a patch that I've been using for some time to address this problem. I
just ported it from 3.7.4 to 3.8.0 this morning, but it works in my limited
testing and has worked for some time with 3.7.4. I should note that we are
only using RHEL so I've not tested this on other distros, but I -think- this
method should work for any and all flavors. If not, perhaps this patch can
be tweaked accordingly and is still useful...
Basically, rather than shelling out to blkid to resolve swap labels to real
devices, I read and unpack the swap header from the device directly to get
the label.
Matt
Index: lib/SystemImager/Server.pm
===================================================================
--- lib/SystemImager/Server.pm (revision 51)
+++ lib/SystemImager/Server.pm (working copy)
@@ -1287,16 +1287,15 @@
# swap
if ( $xml_config->{fsinfo}->{$line}->{fs} eq "swap" ) {
- my $label = '';
- if ($mount_dev) {
- # add LABEL if necessary
- if ($mount_dev =~ /LABEL=(.*)/) {
- $label = "-L $1";
- }
- }
-
# create swap
- $cmd = "mkswap -v1 $label $real_dev || shellout";
+ $cmd = "mkswap -v1 $real_dev";
+
+ # add swap label if necessary
+ if( $mount_dev =~ /^LABEL=(.*)/ ){
+ $cmd .= " -L $1";
+ }
+ $cmd .= " || shellout";
+
print $out qq(logmsg "$cmd"\n);
print $out "$cmd\n";
Index: lib/SystemImager/Common.pm
===================================================================
--- lib/SystemImager/Common.pm (revision 51)
+++ lib/SystemImager/Common.pm (working copy)
@@ -12,6 +12,8 @@
use strict;
use vars qw($version_number $VERSION);
+use POSIX qw(sysconf _SC_PAGESIZE);
+
$version_number="SYSTEMIMAGER_VERSION_STRING";
$VERSION = $version_number;
@@ -26,6 +28,7 @@
# check_if_root
# detect_bootloader
# get_active_swaps_by_dev
+# get_swap_devs_by_label
# get_boot_flavors
# get_disk_label_type
# get_mounted_devs_by_mount_point_array
@@ -77,7 +80,38 @@
return %active_swaps_by_dev;
}
+# Usage:
+# my $swap_devs_by_label = get_swap_devs_by_label();
+sub get_swap_devs_by_label {
+ my $buf = "";
+ my %swaps;
+ my $page_size = POSIX::sysconf(_SC_PAGESIZE) || die "Error getting
sysconf _SC_PAGESIZE!";
+
+ open(SWAPS, '<', '/proc/swaps') || die "Could not open /proc/swaps for
read: $!";
+ my @swaps = <SWAPS>;
+ close SWAPS;
+ shift @swaps; # remove header...
+
+ for my $line ( @swaps ){
+ chomp $line;
+ my($dev) = (split(/\s+/, $line))[0];
+
+ open(SWAPDEV, '<', $dev) or die "Could not open $dev for read: $!";
+ my $bytes_read = sysread(SWAPDEV, $buf, $page_size, 0);
+ close SWAPDEV;
+
+ unless( $bytes_read == $page_size ){
+ die "sysread returned only $bytes_read reading $dev, _SC_PAGESIZE
= [$page_size]\n";
+ }
+
+ my $label = (unpack('a1024IIIA16A16I117I', $buf))[5]; # v1 swap
header structure found in swapheader.h from util-linux pkg
+ $swaps{$label} = $dev;
+ }
+
+ return wantarray ? %swaps : \%swaps;
+}
+
# Usage:
# %array = get_mounted_devs_by_mount_point_array();
# my %mounted_devs_by_mount_point = get_mounted_devs_by_mount_point_array();
@@ -1241,6 +1275,7 @@
my %mounted_devs_by_mount_point =
get_mounted_devs_by_mount_point_array();
my %active_swaps_by_dev = get_active_swaps_by_dev();
+ my %swap_devs_by_label = get_swap_devs_by_label();
# Read in fstab file and output fstab stanza. -BEF-
#
@@ -1296,11 +1331,14 @@
#
$real_dev = $mount_dev;
$mount_dev = "";
- } else {
- unless ($real_dev) {
- # Try to identify real_dev from the LABEL or UUID
value.
- chomp($real_dev = `blkid -t $mount_dev`);
- $real_dev =~ s/^(.*): .*$/$1/;
+ }
+
+ # if this swap device happens be setup in fstab via a label
(RHEL4 and clones),
+ # reslove that label to the actual device name here
+ if( $fs eq "swap" && $mount_dev =~ /^LABEL=(.*)/ ){
+ if( defined $1 && exists $swap_devs_by_label{$1} ){
+ $real_dev = $swap_devs_by_label{$1};
+ #print STDERR "DEBUG: swap label [$1] resolves to
device [$real_dev]\n";
}
}
I've made a new SystemImager version 3.8.0 server (we have older versions
on other systems) and it worked more or less out of the box. However,
The Golden Client runs CentOS 4.4 (RHEL4 clone) and has this line in
LABEL=SWAP-hda2 swap swap defaults 0 0
However, when the si_getimage is done a .master script has been created
which doesn't format a swap partition in /dev/hda2, so when the cloned
client comes up it has no swap space :-(
It seems to me that there must still be a bug in SystemImager 3.8.0
regarding LABEL=SWAP-xxx partitions. However, Andrea claimed that
http://sourceforge.net/mailarchive/message.php?msg_id=36855405
I know the workaround of replacing LABEL=SWAP by /dev, but I'd like
to get the real, permanent solution working.
FYI, the generated .master script contains these sections which ought
logmsg "Creating partition ${DISK0}2."
START_MB=$END_OF_LAST_PRIMARY
END_MB=$(( $DISK_SIZE - 0 ))
logmsg "parted -s -- $DISK0 mkpart primary linux-swap $START_MB $END_MB ||
shellout" parted -s -- $DISK0 mkpart primary linux-swap $START_MB $END_MB
|| shellout END_OF_LAST_PRIMARY=$END_MB
....
### BEGIN swap and filesystem creation commands ###
logmsg "mke2fs -q -j ${DISK0}1 || shellout"
mke2fs -q -j ${DISK0}1 || shellout
logmsg "tune2fs -L / ${DISK0}1"
tune2fs -L / ${DISK0}1
logmsg "mkdir -p /a/ || shellout"
mkdir -p /a/ || shellout
logmsg "mount ${DISK0}1 /a/ -t ext3 -o defaults || shellout"
mount ${DISK0}1 /a/ -t ext3 -o defaults || shellout
### END swap and filesystem creation commands ###
<config>
<disk dev="/dev/hda" label_type="msdos" unit_of_measurement="MB">
<!--
This disk's output was brought to you by the partition tool
"sfdisk", and by the numbers 4 and 5 and the letter Q.
-->
<part num="1" size="8510" p_type="primary" p_name="-"
flags="boot" /> <part num="2" size="*" p_type="primary" p_name="-"
flags="swap" /> </disk>
<fsinfo line="10" comment="# This file is edited by fstab-sync - see
'man fstab-sync' for details" />
<fsinfo line="20" real_dev="/dev/hda1" mount_dev="LABEL=/" mp="/"
fs="ext3" options="defaults" dump="1" pass="1" />
<fsinfo line="30" real_dev="none" mp="/dev/pts" fs="devpts"
options="gid=5,mode=620" dump="0" pass="0" />
<fsinfo line="40" real_dev="none" mp="/dev/shm" fs="tmpfs"
options="defaults" dump="0" pass="0" />
<fsinfo line="50" real_dev="none" mp="/proc" fs="proc"
options="defaults" dump="0" pass="0" />
<fsinfo line="60" real_dev="none" mp="/sys" fs="sysfs"
options="defaults" dump="0" pass="0" />
<fsinfo line="70" mount_dev="LABEL=SWAP-hda2" mp="swap" fs="swap"
options="defaults" dump="0" pass="0" format="no" />
<fsinfo line="80" real_dev="/dev/hdc" mp="/media/cdrom" fs="auto"
options="pamconsole,fscontext=system_u:object_r:removable_t,exec,noauto,man
aged" dump="0" pass="0" format="no" />
<fsinfo line="90" real_dev="/dev/fd0" mp="/media/floppy" fs="auto"
options="pamconsole,fscontext=system_u:object_r:removable_t,exec,noauto,man
aged" dump="0" pass="0" format="no" />
<boel devstyle="udev"/>
</config>
Please Cc: your answers also to my E-mail because I received the list in
digested form with a multi-day delay. Also, the list archive is several
weeks behind (last message is from Feb. 22) and is therefore pretty useless
:-(
Thanks a lot,
Ole
on other systems) and it worked more or less out of the box. However,
The Golden Client runs CentOS 4.4 (RHEL4 clone) and has this line in
LABEL=SWAP-hda2 swap swap defaults 0 0
However, when the si_getimage is done a .master script has been created
which doesn't format a swap partition in /dev/hda2, so when the cloned
client comes up it has no swap space :-(
It seems to me that there must still be a bug in SystemImager 3.8.0
regarding LABEL=SWAP-xxx partitions. However, Andrea claimed that
http://sourceforge.net/mailarchive/message.php?msg_id=36855405
I know the workaround of replacing LABEL=SWAP by /dev, but I'd like
to get the real, permanent solution working.
FYI, the generated .master script contains these sections which ought
logmsg "Creating partition ${DISK0}2."
START_MB=$END_OF_LAST_PRIMARY
END_MB=$(( $DISK_SIZE - 0 ))
logmsg "parted -s -- $DISK0 mkpart primary linux-swap $START_MB $END_MB ||
shellout" parted -s -- $DISK0 mkpart primary linux-swap $START_MB $END_MB
|| shellout END_OF_LAST_PRIMARY=$END_MB
....
### BEGIN swap and filesystem creation commands ###
logmsg "mke2fs -q -j ${DISK0}1 || shellout"
mke2fs -q -j ${DISK0}1 || shellout
logmsg "tune2fs -L / ${DISK0}1"
tune2fs -L / ${DISK0}1
logmsg "mkdir -p /a/ || shellout"
mkdir -p /a/ || shellout
logmsg "mount ${DISK0}1 /a/ -t ext3 -o defaults || shellout"
mount ${DISK0}1 /a/ -t ext3 -o defaults || shellout
### END swap and filesystem creation commands ###
<config>
<disk dev="/dev/hda" label_type="msdos" unit_of_measurement="MB">
<!--
This disk's output was brought to you by the partition tool
"sfdisk", and by the numbers 4 and 5 and the letter Q.
-->
<part num="1" size="8510" p_type="primary" p_name="-"
flags="boot" /> <part num="2" size="*" p_type="primary" p_name="-"
flags="swap" /> </disk>
<fsinfo line="10" comment="# This file is edited by fstab-sync - see
'man fstab-sync' for details" />
<fsinfo line="20" real_dev="/dev/hda1" mount_dev="LABEL=/" mp="/"
fs="ext3" options="defaults" dump="1" pass="1" />
<fsinfo line="30" real_dev="none" mp="/dev/pts" fs="devpts"
options="gid=5,mode=620" dump="0" pass="0" />
<fsinfo line="40" real_dev="none" mp="/dev/shm" fs="tmpfs"
options="defaults" dump="0" pass="0" />
<fsinfo line="50" real_dev="none" mp="/proc" fs="proc"
options="defaults" dump="0" pass="0" />
<fsinfo line="60" real_dev="none" mp="/sys" fs="sysfs"
options="defaults" dump="0" pass="0" />
<fsinfo line="70" mount_dev="LABEL=SWAP-hda2" mp="swap" fs="swap"
options="defaults" dump="0" pass="0" format="no" />
<fsinfo line="80" real_dev="/dev/hdc" mp="/media/cdrom" fs="auto"
options="pamconsole,fscontext=system_u:object_r:removable_t,exec,noauto,man
aged" dump="0" pass="0" format="no" />
<fsinfo line="90" real_dev="/dev/fd0" mp="/media/floppy" fs="auto"
options="pamconsole,fscontext=system_u:object_r:removable_t,exec,noauto,man
aged" dump="0" pass="0" format="no" />
<boel devstyle="udev"/>
</config>
Please Cc: your answers also to my E-mail because I received the list in
digested form with a multi-day delay. Also, the list archive is several
weeks behind (last message is from Feb. 22) and is therefore pretty useless
:-(
Thanks a lot,
Ole