Skip to content

Commit a7ab2e6

Browse files
author
Richard Ray
committed
add support for root filesystem image transfer via uftp, and md5sum check
1 parent 3139353 commit a7ab2e6

File tree

10 files changed

+306
-7
lines changed

10 files changed

+306
-7
lines changed

uftp/README

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
Implementing UFTP in xCAT
2+
3+
When a node boots via xCAT in stateless mode, it first receives a kernel and
4+
an initial ramdisk from the management server. Inside the initial ramdisk is
5+
a script named xcatroot which is responsible for copying the node's root
6+
filesystem image from the management server with wget, uncompressing it into
7+
RAM, and switching to it. The URL of the root filesystem image is passed to
8+
xcatroot via a kernel boot parameter.
9+
10+
In order to support uftp, xcatroot needs to start uftpd, and then signal the
11+
management server that it is ready to receive the image file. The management
12+
server also needs to wait for some amount of time before starting the transfer,
13+
since there could be some variability in the hardware boot process, and the
14+
slowest node might not have started uftpd yet. In order to make sure the image
15+
transferred correctly, the md5 checksum is checked. If the md5 check fails, or
16+
the transfer times out, xcatroot falls back to wget.
17+
18+
To implement this, three kernel boot parameters were added, which are:
19+
20+
uftp
21+
uftpdelay
22+
md5sum
23+
24+
To use UFTP, set uftp=true. The uftpdelay parameter is for specifying the
25+
number of seconds to wait before the transfer starts, and defaults to 30 if
26+
not specified. The md5sum parameter should be set to the md5 checksum of the
27+
root filesystem image. These need to be set in the addkcmdline field in the
28+
osimage table in xCAT, so that nodeset will pick them up. The packimage
29+
command has been extended with some options to facilitate this:
30+
31+
packimage [-s| --sum] set md5sum=<md5 checksum of image>
32+
packimage [-u| --uftp] set uftp=true
33+
packimage [-d| --delay=<uftp delay in seconds> set uftpdelay=<uftp delay in seconds>
34+
35+
Note that if -s is omitted, and an md5sum exists in addkcmdline, the existing
36+
entry is removed because it would no longer be valid. Similarly, if -u is
37+
omitted and uftp=true exists in addkcmdline, it is removed.

uftp/uftp-4.9.3-1.ppc64le.rpm

139 KB
Binary file not shown.

uftp/uftp-4.9.3.tar.gz

235 KB
Binary file not shown.
205 KB
Binary file not shown.

uftp/uftp-listener

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
#!/bin/bash
2+
set -E
3+
LOGDIR=/var/log/xcat/
4+
LOGFILE=uftp_listener.log
5+
mkdir -p $LOGDIR
6+
7+
usage() {
8+
echo "usage: uftp-listener [ -i interface ] [ -s sleep time ]"
9+
exit 1
10+
}
11+
12+
debug() {
13+
[ "$DEBUG" ] && echo "$@"
14+
echo "$@" >> $LOGDIR/$LOGFILE
15+
}
16+
17+
while getopts ":i:s:hd" options
18+
do
19+
case ${options} in
20+
i ) INTERFACE=${OPTARG};;
21+
s ) SLEEP=${OPTARG};;
22+
d ) DEBUG=true;;
23+
h ) usage
24+
exit 1;;
25+
* ) usage
26+
exit 1;;
27+
esac
28+
done
29+
30+
# if INTERFACE is null, try to detect
31+
if [ -z "$INTERFACE" ]; then
32+
MAN_NET=$(/opt/xcat/bin/lsdef -t network management | grep net | sed 's/.*=//')
33+
INTERFACE=$(netstat -nr | grep $MAN_NET | awk '{print $8}')
34+
fi
35+
36+
if [ -z "$INTERFACE" ]; then
37+
debug "ERROR: detection of interface failed and none supplied with -i, aborting..."
38+
exit 1
39+
fi
40+
41+
ip link show $INTERFACE > /dev/null 2>&1
42+
RC=$?
43+
44+
if [ "$RC" != 0 ]; then
45+
debug "ERROR: invalid interface $INTERFACE"
46+
exit 1
47+
fi
48+
49+
# if no sleep time supplied, use the default of 30 seconds
50+
if [ -z "$SLEEP" ]; then
51+
SLEEP=30
52+
fi
53+
54+
UFTP=$(which uftp)
55+
if [ ! -x $UFTP ]; then
56+
debug "ERROR: uftp binary not found, exiting!"
57+
exit 1
58+
fi
59+
60+
# make sure 1045/tcp is not already in use
61+
nc -i 500ms -l -p 1045 2>&1 | grep "Address already in use" > /dev/null
62+
RC=$?
63+
if [ "$RC" = 0 ]; then
64+
debug "ERROR: 1045/tcp is already in use, sleeping 10 seconds and exiting"
65+
sleep 10
66+
exit 1
67+
fi
68+
69+
debug "listening for transfer request on 1045/tcp"
70+
while true
71+
do
72+
LINE=$(nc -l -p 1045 | grep -E "/install/.*/rootimg(\.sfs|\.cpio\.gz|\.cpio\.xz|\.tar.gz|\.tar\.xz|-statelite\.gz)")
73+
DATE=$(date --rfc-3339=ns)
74+
debug $DATE $LINE
75+
ROOTIMG=$(echo $LINE | sed 's/.*GET //' | sed 's+HTTP/1.1.*++')
76+
if [ ! -f $ROOTIMG ]
77+
then
78+
debug "$ROOTIMG: file not found"
79+
else
80+
debug "sleeping $SLEEP seconds"
81+
sleep $SLEEP # wait for additional nodes that might also want this image
82+
debug "copying $ROOTIMG"
83+
$UFTP -I $INTERFACE -R 500000 -B 104857600 -b 8800 -D /rootimg.cpio.gz $ROOTIMG
84+
fi
85+
done

uftp/uftp-listener.service

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
[Unit]
2+
Description=UFTP listener
3+
Wants=basic.target
4+
After=basic.target network.target
5+
6+
[Service]
7+
Type=simple
8+
ExecStart=/bin/bash /opt/xcat/bin/uftp-listener
9+
KillMode=control-group
10+
11+
[Install]
12+
WantedBy=multi-user.target

uftp/uftp.spec

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
Name: uftp
2+
Version: 4.9.3
3+
Release: 1
4+
Summary: UFTP - Encrypted UDP based FTP with multicast
5+
6+
Group: FTP Server
7+
License: GPL
8+
URL: http://uftp-multicast.sourceforge.net
9+
Source0: http://sourceforge.net/projects/uftp-multicast/files/source-tar/uftp-4.9.3.tar.gz
10+
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
11+
12+
BuildRequires: openssl-devel
13+
14+
%description
15+
UFTP is an encrypted multicast file transfer program, designed to securely, reliably, and efficiently transfer files to multiple receivers simultaneously. This is useful for distributing large files to a large number of receivers, and is especially useful for data distribution over a satellite link (with two way communication), where the inherent delay makes any TCP based communication highly inefficient. The multicast encryption scheme is based on TLS with extensions to allow multiple receivers to share a common key. UFTP also has the capability to communicate over disjoint networks separated by one or more firewalls (NAT traversal) and without full end-to-end multicast capability (multicast tunneling) through the use of a UFTP proxy server. These proxies also provide scalability by aggregating responses from a group of receivers.
16+
17+
%prep
18+
%setup -q
19+
20+
%build
21+
make %{?_smp_mflags}
22+
23+
%install
24+
rm -rf $RPM_BUILD_ROOT
25+
make install DESTDIR=$RPM_BUILD_ROOT
26+
27+
%clean
28+
rm -rf $RPM_BUILD_ROOT
29+
30+
%files
31+
%defattr(-,root,root,-)
32+
/usr/bin/uftp
33+
/usr/sbin/uftpd
34+
/usr/sbin/uftpproxyd
35+
/usr/bin/uftp_keymgt
36+
/usr/share/man/man1/uftp.1.gz
37+
/usr/share/man/man1/uftp_keymgt.1.gz
38+
/usr/share/man/man1/uftpd.1.gz
39+
/usr/share/man/man1/uftpproxyd.1.gz
40+
41+
%changelog

xCAT-server/lib/xcat/plugins/packimage.pm

Lines changed: 76 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
-p Profile (compute,service)
1212
-a Architecture (ppc64,x86_64,etc)
1313
-m Method (default cpio)
14+
-s Compute MD5 checksum of image
15+
-u Use uftp for copying image
16+
-d uftp delay in seconds (default is 30)
1417
1518
=cut
1619

@@ -82,7 +85,7 @@ sub process_request {
8285
@ARGV = @{$args};
8386
}
8487
if (scalar(@ARGV) == 0) {
85-
$callback->({ info => ["Usage:\n packimage [-m| --method=cpio|tar] [-c| --compress=gzip|pigz|xz] <imagename>\n packimage [-h| --help]\n packimage [-v| --version]"] });
88+
$callback->({ info => ["Usage:\n packimage [-m| --method=cpio|tar] [-c| --compress=gzip|pigz|xz] <imagename>\n packimage [-h| --help]\n packimage [-v| --version]\n packimage [-s| --sum]\n packimage [-u| --uftp]\n packimage [-d| --delay=<uftp delay in seconds>"] });
8689
return 0;
8790
}
8891

@@ -97,10 +100,17 @@ sub process_request {
97100
my $destdir;
98101
my $imagename;
99102
my $dotorrent;
103+
my $domd5sum;
104+
my $douftp;
105+
my $uftpdelay;
106+
my $default_uftpdelay=30;
107+
my $addkcmdline;
100108
my $provmethod;
101109
my $help;
102110
my $version;
103111
my $lock;
112+
my $newaddkcmdline;
113+
my $linuximagetab;
104114

105115
GetOptions(
106116
"profile|p=s" => \$profile,
@@ -109,6 +119,9 @@ sub process_request {
109119
"method|m=s" => \$method,
110120
"compress|c=s" => \$compress,
111121
"tracker=s" => \$dotorrent,
122+
"sum|s" => \$domd5sum,
123+
"uftp|u" => \$douftp,
124+
"delay|d=s" => \$uftpdelay,
112125
"help|h" => \$help,
113126
"version|v" => \$version
114127
);
@@ -122,7 +135,7 @@ sub process_request {
122135
return 0;
123136
}
124137
if ($help) {
125-
$callback->({ info => ["Usage:\n packimage [-m| --method=cpio|tar] [-c| --compress=gzip|pigz|xz] <imagename>\n packimage [-h| --help]\n packimage [-v| --version]"] });
138+
$callback->({ info => ["Usage:\n packimage [-m| --method=cpio|tar] [-c| --compress=gzip|pigz|xz] <imagename>\n packimage [-h| --help]\n packimage [-v| --version]\n packimage [-s| --sum]\n packimage [-u| --uftp]\n packimage [-d| --delay=<uftp delay in seconds>"] });
126139
return 0;
127140
}
128141

@@ -146,7 +159,7 @@ sub process_request {
146159
$callback->({ error => ["The osimage table cannot be opened."], errorcode => [1] });
147160
return 1;
148161
}
149-
my $linuximagetab = xCAT::Table->new('linuximage', -create => 1);
162+
$linuximagetab = xCAT::Table->new('linuximage', -create => 1);
150163
unless ($linuximagetab) {
151164
$callback->({ error => ["The linuximage table cannot be opened."], errorcode => [1] });
152165
return 1;
@@ -156,7 +169,7 @@ sub process_request {
156169
$callback->({ error => ["Cannot find image \'$imagename\' from the osimage table."], errorcode => [1] });
157170
return 1;
158171
}
159-
(my $ref1) = $linuximagetab->getAttribs({ imagename => $imagename }, 'exlist', 'rootimgdir');
172+
(my $ref1) = $linuximagetab->getAttribs({ imagename => $imagename }, 'exlist', 'rootimgdir', 'addkcmdline');
160173
unless ($ref1) {
161174
$callback->({ error => ["Cannot find $imagename from the linuximage table."], errorcode => [1] });
162175
return 1;
@@ -178,8 +191,9 @@ sub process_request {
178191
return 1;
179192
}
180193

181-
$exlistloc = $ref1->{'exlist'};
182-
$destdir = $ref1->{'rootimgdir'};
194+
$exlistloc = $ref1->{'exlist'};
195+
$destdir = $ref1->{'rootimgdir'};
196+
$addkcmdline = $ref1->{'addkcmdline'};
183197
} else {
184198
$provmethod = "netboot";
185199
unless ($osver) {
@@ -537,6 +551,62 @@ sub process_request {
537551
system("rm -rf $xcat_packimg_tmpfile");
538552
return 1;
539553
}
554+
$newaddkcmdline = $addkcmdline;
555+
if ($domd5sum) { # if true, pass md5sum of root image as a boot parameter
556+
my $md5 = Digest::MD5->new;
557+
open(my $iorootimg, '<', "$destdir/rootimg.$suffix");
558+
binmode($iorootimg);
559+
$md5->addfile($iorootimg);
560+
my $md5sum = $md5->hexdigest;
561+
if ($addkcmdline =~ m/md5sum/) {
562+
$newaddkcmdline =~ s/md5sum=\w{32}/md5sum=$md5sum/;
563+
} else {
564+
$newaddkcmdline = $newaddkcmdline . " md5sum=" . $md5sum;
565+
}
566+
$linuximagetab->setAttribs({imagename => $imagename}, {addkcmdline => $newaddkcmdline});
567+
} else { # -s was not given, so remove any pre-existing md5sum since it will be invalid
568+
if ($newaddkcmdline =~ m/md5sum/) {
569+
$newaddkcmdline =~ s/ md5sum=\w{32}//;
570+
$newaddkcmdline =~ s/^md5sum=\w{32} //;
571+
$newaddkcmdline =~ s/^md5sum=\w{32}//;
572+
$linuximagetab->setAttribs({imagename => $imagename}, {addkcmdline => $newaddkcmdline});
573+
}
574+
}
575+
576+
if ($douftp) { # if true, pass uftp=true as a boot parameter
577+
if (!($newaddkcmdline =~ m/uftp=true/)) {
578+
$newaddkcmdline = $newaddkcmdline . " uftp=true";
579+
$linuximagetab->setAttribs({imagename => $imagename}, {addkcmdline => $newaddkcmdline});
580+
}
581+
} else { # -u was not given, so remove any pre-existing uftp boot parameters
582+
if ($newaddkcmdline =~ m/uftp=true/) {
583+
$newaddkcmdline =~ s/ uftp=true//;
584+
$newaddkcmdline =~ s/^uftp=true //;
585+
$newaddkcmdline =~ s/^uftp=true//;
586+
}
587+
if ($newaddkcmdline =~ m/uftpdelay=\d*/) {
588+
$newaddkcmdline =~ s/ uftpdelay=\d*//;
589+
$newaddkcmdline =~ s/^uftpdelay=\d* //;
590+
$newaddkcmdline =~ s/^uftpdelay=\d*//;
591+
}
592+
$linuximagetab->setAttribs({imagename => $imagename}, {addkcmdline => $newaddkcmdline});
593+
}
594+
595+
if (($uftpdelay) && ($douftp)) { # if true, pass uftpdelay as a boot parameter
596+
if ($newaddkcmdline =~ m/uftpdelay/) { # if there is a pre-existing uftpdelay, replace
597+
$newaddkcmdline =~ s/uftpdelay=\d*/uftpdelay=$uftpdelay/;
598+
} else { # otherwise, add supplied value
599+
$newaddkcmdline = $newaddkcmdline . " uftpdelay=$uftpdelay";
600+
}
601+
$linuximagetab->setAttribs({imagename => $imagename}, {addkcmdline => $newaddkcmdline});
602+
} elsif ($douftp) { # no uftpdelay was given, so use the default of $default_uftpdelay
603+
if ($newaddkcmdline =~ m/uftpdelay/) { # if there is a pre-existing uftpdelay, replace
604+
$newaddkcmdline =~ s/uftpdelay=\d*/uftpdelay=$default_uftpdelay/;
605+
} else { # otherwise, add default value
606+
$newaddkcmdline = $newaddkcmdline . " uftpdelay=$default_uftpdelay";
607+
}
608+
$linuximagetab->setAttribs({imagename => $imagename}, {addkcmdline => $newaddkcmdline});
609+
}
540610

541611
if ($method =~ /cpio/) {
542612
chmod 0644, "$destdir/rootimg.$suffix";

xCAT-server/share/xcat/netboot/rh/dracut_033/install.netboot

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
echo $drivers
33
dracut_install wget tar cpio gzip modprobe touch echo cut wc xz
44
dracut_install grep ifconfig hostname awk egrep grep dirname expr
5-
dracut_install mount.nfs
5+
dracut_install mount.nfs md5sum uftpd
66
dracut_install parted mke2fs bc mkswap swapon chmod
77
inst "$moddir/xcat-updateflag" "/tmp/updateflag"
88
inst "$moddir/xcatroot" "/sbin/xcatroot"

0 commit comments

Comments
 (0)