Commit 60e7adb8 authored by Mike Hibler's avatar Mike Hibler

Partial support for disk-zeroing on experiment termination.

I did the "back half" support.  If the 'mustwipe' field is non-zero
in the reserved table entry for a node then its disk must be zeroed.
How the zeroing is done, depends on the value of the mustwipe field.
Right now, '1' means pass the '-z' option to frisbee to have it zero
all non-allocated blocks.  The value '2' is reserved for enabling a
"full wipe" pass of the disk before running frisbee, which Keith Sklower
(DETER) wanted to be able to do.  Note that 1 and 2 are effectively the
same, if we are loading a full-disk image; i.e. all non-allocated blocks
from the new image are zeroed.  But if the disk were being loaded with
a single-partition image, then "frisbee -z" would only wipe unused
blocks in that partition.

The reload_daemon has been modified to extract the mustwipe info and
invoke os_load accordingly.   os_load now takes a "-z <type>" option
to enable the zeroing by setting a value in the current_reloads table.
tmcd will read and return that info to its caller in the "loadinfo" command.
Finally, the rc.frisbee script that runs in the frisbee MFS extracts the
loadinfo info and crafts the frisbee startup command.

What still needs to be done is the "front end," how the user specifies
the value and how it winds up in the DB reserved table.  This will probably
involve addition of state to the experiments table as this will likely be
a per-experiment setting.
parent ea6e552a
......@@ -50,6 +50,7 @@ my @nodes;
my @freed_nodes=();
my @dynanodes=();
my $error = 0;
my %mustzero=();
$| = 1; # Turn off line buffering on output
......@@ -110,34 +111,20 @@ if (@ARGV) {
if ($n =~ /^([-\w]+)$/) { $n = $1; }
else { die("*** $0:\n Bad node name: $n.\n"); }
# Shark hack
if ($n =~ /(sh\d+)/ ) {
# It's a shark - do the whole shelf if its not done already.
my $shelf = $1;
if ( ! (join(",", @nodes) =~ /,$shelf-\d,/)) {
# Shelf hasn't been done yet...
foreach my $n ( 1 .. 8 ) {
push(@nodes, "$shelf-$n");
}
}
# End shark hack
} else {
# its not a shark - just add it in...
push(@nodes, $n);
# if -x was specified, remove any
# mapping to a node which has a phys_nodeid of $n.
if ($freeDependantVirtuals) {
my $result =
DBQueryFatal("SELECT r.node_id FROM reserved AS r ".
"LEFT JOIN nodes AS n ".
"ON r.node_id=n.node_id ".
"WHERE n.phys_nodeid='$n' AND ".
"r.eid='$eid' AND r.pid='$pid'");
while (my ($dependantVirtual) = $result->fetchrow_array()) {
if (defined $dependantVirtual && $dependantVirtual ne $n) {
push(@nodes, $dependantVirtual);
}
push(@nodes, $n);
# if -x was specified, remove any
# mapping to a node which has a phys_nodeid of $n.
if ($freeDependantVirtuals) {
my $result =
DBQueryFatal("SELECT r.node_id FROM reserved AS r ".
"LEFT JOIN nodes AS n ".
"ON r.node_id=n.node_id ".
"WHERE n.phys_nodeid='$n' AND ".
"r.eid='$eid' AND r.pid='$pid'");
while (my ($dependantVirtual) = $result->fetchrow_array()) {
if (defined $dependantVirtual && $dependantVirtual ne $n) {
push(@nodes, $dependantVirtual);
}
}
}
......@@ -183,6 +170,16 @@ foreach my $n (@nodes) {
next;
}
#
# Remember if the node's disk must be zeroed
#
my $rowref = $result->fetchrow_hashref();
if ($rowref->{'mustwipe'}) {
$mustzero{$n} = $rowref->{'mustwipe'};
} else {
$mustzero{$n} = 0;
}
if ( $moveToOldReserved ) {
# Move to holding reservation. Node is not free, but is no longer
# owned by the pid/eid, so cannot be mucked with.
......@@ -251,6 +248,7 @@ foreach my $n (@freed_nodes) {
if ($isvirt || !$imageable) {
# VIRTNODE HACK: Virtual nodes are special. Do not clean or reload.
$mustclean = 0;
$mustzero{$n} = 0;
}
elsif (defined($clean)) {
# If def_boot_osid set, then $clean is defined. Otherwise not set
......@@ -354,9 +352,10 @@ foreach my $n (@freed_nodes) {
DBQueryFatal("select node_id,image_id from scheduled_reloads " .
"where node_id='$n'");
# XXX force reload hack!
if ( !$TESTMODE && ((!$isvirt && $imageable) || $result->numrows() ||
TBNodeType($n) eq "garcia")) { # XXX Garcia hack
if (!$TESTMODE &&
((!$isvirt && $imageable) || # XXX force reload hack!
$result->numrows() || $mustzero{$n} ||
TBNodeType($n) eq "garcia")) { # XXX Garcia hack
print "Moving $n to $reloadpid/$pendingeid.\n";
DBQueryWarn("update reserved set pid='$reloadpid',eid='$pendingeid',".
......
......@@ -67,6 +67,7 @@ CREATE TABLE comments (
CREATE TABLE current_reloads (
node_id varchar(32) NOT NULL default '',
image_id varchar(45) NOT NULL default '',
mustwipe tinyint(4) NOT NULL default '0',
PRIMARY KEY (node_id)
) TYPE=MyISAM;
......@@ -1490,6 +1491,7 @@ CREATE TABLE reserved (
old_eid varchar(32) NOT NULL default '',
cnet_vlan int(11) default NULL,
inner_elab_role enum('boss','ops','node') default NULL,
mustwipe tinyint(4) NOT NULL default '0',
PRIMARY KEY (node_id),
UNIQUE KEY vname (pid,eid,vname),
KEY old_pid (old_pid,old_eid)
......
......@@ -2518,3 +2518,12 @@ last_net_act,last_cpu_act,last_ext_act);
alter table users add wikiname tinytext;
alter table groups add wikiname tinytext;
1.321: DB support for disk wipe-age. If 'mustwipe' is set in the reserved
table entry for a node, then when nfree'd, the disk must be reloaded
and all free blocks zeroed to prevent information leakage.
alter table reserved add mustwipe tinyint(4) NOT NULL default '0';
alter table current_reloads add mustwipe \
tinyint(4) NOT NULL default '0';
#!/usr/bin/perl -wT
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2004 University of Utah and the Flux Group.
# Copyright (c) 2000-2005 University of Utah and the Flux Group.
# All rights reserved.
#
# Osload library. Basically the backend to the osload script, but also used
......@@ -54,6 +54,7 @@ sub osload ($$) {
my @nodes = ();
my $noreboot = 0;
my $asyncmode = 0;
my $zerofree = 0;
# Locals
my %retries = ();
......@@ -84,6 +85,9 @@ sub osload ($$) {
if (defined($args->{'asyncmode'})) {
$asyncmode = $args->{'asyncmode'};
}
if (defined($args->{'zerofree'})) {
$zerofree = $args->{'zerofree'};
}
#
# Figure out who called us. Root and admin types can do whatever they
......@@ -197,6 +201,7 @@ sub osload ($$) {
"*** osload ($node): No filename associated with $imageid!\n";
goto failednode;
}
if (! -R $imagepath) {
if ($ELABINELAB) {
#
......@@ -210,6 +215,12 @@ sub osload ($$) {
"Frisbee Launcher ($imageid) failed!\n";
goto failednode;
}
if (! -R $imagepath) {
print STDERR
"*** osload ($node): ".
"Frisbee Launcher get not fetch $imagepath ($imageid)!\n";
goto failednode;
}
}
else {
print STDERR
......@@ -324,6 +335,7 @@ sub osload ($$) {
$reload_mode = "UISP";
$reload_func = \&SetupReloadUISP;
$reboot_required = 0; # We don't reboot motes to reload them
$zerofree = 0; # and we don't zero "the disk"
} else {
$reload_mode = "Frisbee";
$reload_func = \&SetupReloadFrisbee;
......@@ -339,13 +351,14 @@ sub osload ($$) {
'func' => $reload_func,
'imageid' => $imageid,
'osid' => $defosid,
'reboot' => $reboot_required
'reboot' => $reboot_required,
'zerofree'=> $zerofree
};
print "Setting up reload for $node (mode: $reload_mode)\n";
if (!$TESTMODE) {
if (&$reload_func($node, $imageid,$defosid) < 0) {
if (&$reload_func($node, $imageid, $defosid, $zerofree) < 0) {
print STDERR
"*** osload ($node): Could not set up reload. Skipping.\n";
goto failednode;
......@@ -465,7 +478,7 @@ sub osload ($$) {
# Possible race with reboot?
if (&{$reload_info->{'func'}}($node, $reload_info->{'imageid'},
$reload_info->{'osid'}) < 0) {
$reload_info->{'osid'}, $reload_info->{'zerofree'}) < 0) {
print(STDERR
"*** osload ($node): ".
"Could not set up reload. Skipping.\n");
......@@ -529,7 +542,32 @@ sub WaitTillReloadDone($$$@)
sleep(5);
foreach my $node (@nodes) {
if (! $done{$node}) {
my $maxwait = $maxwaits{$reload_info->{$node}{'imageid'}};
my $maxwait;
#
# If we have to zero fill free space, then the
# wait time has to be proportional to the disk
# size. In other words, a really, really, really
# long time. Lets assume 20MB/sec to blast zeros,
# so 50 seconds/GB. What the heck, lets call it
# 1GB/minute. Did I mention how this would take
# a really long time?
#
if ($reload_info->{$node}{'zerofree'}) {
my $disksize;
my $query_result =
DBQueryWarn("select HD from node_types,nodes ".
"where nodes.type=node_types.type".
" and node_id='$node'");
if ($query_result && $query_result->numrows) {
($disksize) = $query_result->fetchrow_array();
}
$disksize = 20
if (!$disksize);
$maxwait = ($disksize * 60);
} else {
$maxwait = $maxwaits{$reload_info->{$node}{'imageid'}};
}
my $query_result =
DBQueryWarn("select * from current_reloads ".
......@@ -604,9 +642,9 @@ sub WaitTillReloadDone($$$@)
}
# Setup a reload.
sub SetupReloadFrisbee($$$)
sub SetupReloadFrisbee($$$$)
{
my ($node, $imageid, $osid_notused) = @_;
my ($node, $imageid, $osid_notused, $zerofree) = @_;
my $osid = $FRISBEEOSID;
#
......@@ -628,7 +666,8 @@ sub SetupReloadFrisbee($$$)
#
$query_result =
DBQueryWarn("replace into current_reloads ".
"(node_id, image_id) values ('$node', '$imageid')");
"(node_id, image_id, mustwipe) values ".
"('$node', '$imageid', $zerofree)");
return -1
if (!$query_result);
......@@ -650,9 +689,9 @@ sub SetupReloadFrisbee($$$)
# this differs from a Frisbee reload in one key way - it does the reload
# right here in this code, rather than setting up a reload for later.
#
sub SetupReloadUISP($$$)
sub SetupReloadUISP($$$$)
{
my ($node, $imageid, $osid) = @_;
my ($node, $imageid, $osid, $zerofree_unused) = @_;
#
# Get the path to the image
......
#!/usr/bin/perl -wT
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2004 University of Utah and the Flux Group.
# Copyright (c) 2000-2005 University of Utah and the Flux Group.
# All rights reserved.
#
use English;
......@@ -24,14 +24,19 @@ sub usage()
"Use -w to wait for the nodes to finish booting.\n".
"Use -r to supress rebooting nodes - you'll need to to it yourself\n".
"Use -e to reload all the nodes in an experiment.\n" .
"Use -l to get a list of images you are permitted to load.\n");
"Use -l to get a list of images you are permitted to load.\n".
"Use -z <style> to zero all unallocated blocks on the disk\n".
" style==0: don't zero (same as not using -z)\n".
" style==1: let frisbee do the zeroing\n".
" style==2: zero disk before running frisbee\n");
exit(-1);
}
my $optlist = "swldi:e:p:m:r";
my $optlist = "swldi:e:p:m:rz:";
my $waitmode = 1;
my $listonly = 0;
my $debug = 0;
my $noreboot = 0;
my $zerofree = 0;
my @nodes = ();
my $imagepid;
my $imagename;
......@@ -81,6 +86,8 @@ $waitmode = 2
if (defined($options{"w"}));
$noreboot = 1
if (defined($options{"r"}));
$zerofree = $options{"z"}
if (defined($options{"z"}));
#
# Figure out which nodes. Choice of nodes on command line, or all nodes in an
......@@ -223,6 +230,7 @@ my %failednodes = ();
$osloadargs{'debug'} = $debug;
$osloadargs{'waitmode'} = $waitmode;
$osloadargs{'noreboot'} = $noreboot;
$osloadargs{'zerofree'} = $zerofree;
$osloadargs{'nodelist'} = [ @nodes ];
# No imageid means to load the default image.
$osloadargs{'imageid'} = $imageid
......
......@@ -64,8 +64,8 @@ my $reboot = "$TB/bin/node_reboot";
my $tbrsync = "$TB/bin/tbrsync";
my $logfile = "$TB/log/reloadlog";
my $debug = 0;
my $retry_time = 15; # in minutes
my $warn_time = 30; # in minutes
my $retry_time = 20; # in minutes
my $warn_time = $retry_time * 2; # in minutes
my %retried = ();
my %warned = ();
my %failed = ();
......@@ -131,10 +131,14 @@ while (1) {
# First, look for nodes that have been in the reloading experiment for
# longer than $retry_time, and try rebooting them
#
# XXX we count on mustwipe having the value 0, 1, 2 to represent
# ever slower forms of wipeage. For retry_time of 20 minutes that
# yields waits of 20, 40 and 60 minutes.
#
$query_result =
DBQueryWarn("select node_id from reserved where pid='$RELOADPID' " .
"and eid='$RELOADEID' and " .
"(CURRENT_TIMESTAMP - INTERVAL $retry_time MINUTE) ".
DBQueryWarn("select node_id,mustwipe from reserved " .
"where pid='$RELOADPID' and eid='$RELOADEID' and " .
"(CURRENT_TIMESTAMP - INTERVAL $retry_time * (mustwipe + 1) MINUTE)".
" > rsrv_time");
if (! $query_result) {
......@@ -142,7 +146,7 @@ while (1) {
next;
}
while (($node) = $query_result->fetchrow){
while (($node, $mustwipe) = $query_result->fetchrow) {
$idle=0;
#
# If this was a node that failed os_load, then instead of rebooting,
......@@ -150,7 +154,7 @@ while (1) {
#
if ($failed{$node}) {
print "$node failed an earlier os_load. Trying again\n";
push(@retry_list, $node);
push(@retry_list, [$node, $mustwipe]);
delete $failed{$node};
# Skip any reboots.
$retried{$node} = $time;
......@@ -187,22 +191,25 @@ while (1) {
# Next, we do the same thing for nodes in the reloading experiment for
# longer than $warn_time, and warn the admins.
#
# XXX again, we scale by the value of mustwipe.
#
$query_result =
DBQueryWarn("select node_id from reserved where pid='$RELOADPID' " .
"and eid='$RELOADEID' and " .
"(CURRENT_TIMESTAMP - INTERVAL $warn_time MINUTE) > ".
" rsrv_time");
DBQueryWarn("select node_id,mustwipe from reserved " .
"where pid='$RELOADPID' and eid='$RELOADEID' and " .
"(CURRENT_TIMESTAMP - INTERVAL $warn_time * (mustwipe + 1) MINUTE)".
" > rsrv_time");
if (! $query_result) {
print "DB Error. Waiting a bit.\n";
next;
}
while (($node) = $query_result->fetchrow){
while (($node, $mustwipe) = $query_result->fetchrow) {
$idle=0;
if (!$warned{$node}) {
my $toolong = $warn_time * ($mustwipe + 1);
notify("Node $node has been in $RELOADPID/$RELOADEID for " .
"more than $warn_time minutes");
"more than $toolong minutes");
}
$warned{$node} = $time;
}
......@@ -227,7 +234,8 @@ while (1) {
my $CLASSCLAUSE = "(n.class='pc' or n.class='pct')";
$query_result =
DBQueryWarn("select a.node_id,b.pid,b.eid from reserved as b ".
DBQueryWarn("select a.node_id,b.pid,b.eid,b.mustwipe ".
"from reserved as b ".
"left join nodes as a on a.node_id=b.node_id ".
"left join last_reservation as l on l.node_id=a.node_id ".
"left join node_types as n on n.type=a.type where ".
......@@ -249,18 +257,19 @@ while (1) {
# Grab all the nodes that match
my @pending_list = @retry_list;
while (%hrow = $query_result->fetchhash()) {
while (%hrow = $query_result->fetchhash()) {
$node = $hrow{'node_id'};
$pid = $hrow{'pid'};
$eid = $hrow{'eid'};
$mustwipe = $hrow{'mustwipe'};
if ($pid eq $RELOADPID && $eid eq $PENDINGEID) {
push(@pending_list,$node);
push(@pending_list, [$node,$mustwipe]);
} else {
push(@other_list,$node);
push(@other_list, [$node,$mustwipe]);
}
}
my $nodes = join(" ", (@pending_list, @other_list));
my $nodes = join(" ", map { $_->[0] } @pending_list, @other_list);
print "Trying to reload $nodes at ".`date`;
#
......@@ -273,7 +282,9 @@ while (1) {
#
my %images = ();
my %imagenodes = ();
foreach $node (@pending_list) {
foreach $ref (@pending_list) {
($node, $mustwipe) = @{$ref};
$query_result =
DBQueryWarn("select image_id from scheduled_reloads " .
"where node_id='$node'");
......@@ -297,15 +308,26 @@ while (1) {
}
# XXX End Garcia Hack
#
# We need to divide up nodes not only by the image they are
# to load (imageid) but also by if and how the disk should be
# zeroed (mustzero). So we really have a hash of hashes each
# of which is an array of nodes. However, my perl skilz are
# not up to that so just combine the imageid and mustwipe into
# a single hash key ('/' is illegal in both, so we use it as
# the separator).
#
my $idid = "$imageid/$mustwipe";
$images{$node} = $imageid;
if (defined(@{$imagenodes{$imageid}})) {
push(@{$imagenodes{$imageid}},$node);
if (defined(@{$imagenodes{$idid}})) {
push(@{$imagenodes{$idid}},$node);
} else {
$imagenodes{$imageid} = [$node];
$imagenodes{$idid} = [$node];
}
if ($debug) {
print "$node => $images{$node} == $imageid (".
join(",",@{$imagenodes{$imageid}}).")\n";
print "$node ($mustwipe) => $images{$node} == $imageid (".
join(",",@{$imagenodes{$idid}}).")\n";
}
}
......@@ -315,17 +337,19 @@ while (1) {
# We change the reservation EID over and fire up an os_load
# directly.
#
my $cond = join(" or ",map("node_id='$_'",@pending_list));
my $cond = "node_id in (" .
join(",", map("'$_->[0]'", @pending_list)) . ")";
if (! DBQueryWarn("update reserved set ".
"rsrv_time=now(),eid='$RELOADEID' ".
"where $cond")) {
print "Could not update EID for ".join(" ",@pending_list).
". Waiting a bit.\n";
print "Could not update EID for " .
join(" ", map("$_->[0]", @pending_list)) .
". Waiting a bit.\n";
next;
} else {
print "Pending nodes moved to $RELOADEID at ".`date`;
foreach my $n (@pending_list) {
foreach my $n (map("$_->[0]", @pending_list)) {
TBSetNodeHistory($n, TB_NODEHISTORY_OP_MOVE, $UID,
$RELOADPID, $RELOADEID);
}
......@@ -335,11 +359,13 @@ while (1) {
# Now run an os_load for each image
foreach $imageid (keys %imagenodes) {
foreach my $idid (keys %imagenodes) {
my $nodelist = join(" ",@{$imagenodes{$imageid}});
my $nodelist = join(" ",@{$imagenodes{$idid}});
my $os_load_flags = "";
($imageid, $mustzero) = split("/", $idid);
# XXX Garcia Hack - gross..
# We special-case garcia loading for now until the subnode->node
# dependancies are worked out inside os_load.
......@@ -351,7 +377,7 @@ while (1) {
if (system("$tbrsync upload $gimagepath $nodelist") == 0) {
if (system("$reboot $nodelist") == 0) {
# rsync and reboot succeeded, so free 'em up.
foreach my $gnode (@{$imagenodes{$imageid}}) {
foreach my $gnode (@{$imagenodes{$idid}}) {
freefromreloading($gnode);
}
print "garcia reload done at ".`date`;
......@@ -380,7 +406,14 @@ while (1) {
# the node's type
#
if ($imageid) {
$os_load_flags .= " -m $imageid ";
$os_load_flags .= " -m $imageid";
}
#
# Handle optional zeroing of the disk
#
if ($mustzero) {
$os_load_flags .= " -z $mustzero";
}
print "Running '$os_load $os_load_flags $nodelist' at ".`date`;
......@@ -396,7 +429,7 @@ while (1) {
# Record the failure list. If we get to the 15 minute
# retry, call os_load again instead of rebooting.
foreach my $node (@{$imagenodes{$imageid}}) {
foreach my $node (@{$imagenodes{$idid}}) {
$failed{$node} = $time;
}
}
......@@ -407,6 +440,8 @@ while (1) {
}
if (@other_list > 0 ) {
my $nodes = join(" ", map { $_->[0] } @other_list);
#
# Call sched_reload with the "force" option, which says that if
# sched_reload cannot reserve the node (cause someone just got it)
......@@ -417,11 +452,11 @@ while (1) {
# default, and sched_reload will pick that up from the database
# in the absence of a -i option.
#
if (system("$sched_reload -f @other_list")) {
if (system("$sched_reload -f $nodes")) {
#
# Could not get it. Wait and go around again.
#
print "$sched_reload failed on @other_list. Waiting a bit.\n";
print "$sched_reload failed on $nodes. Waiting a bit.\n";
next;
}
......
#!/bin/sh
#
# EMULAB-COPYRIGHT
# Copyright (c) 2000-2004 University of Utah and the Flux Group.
# Copyright (c) 2000-2005 University of Utah and the Flux Group.
# All rights reserved.
#
# Optional flag argument says "do not reboot"
......@@ -49,6 +49,8 @@ PARTITION=${PARTITION:-'0'}
PARTOS=`echo $LOADINFO | awk -F= '{ printf $4 }' | awk -F' ' '{ print $1 }'`
DISK=`echo $LOADINFO | awk -F= '{ printf $5 }' | awk -F' ' '{ print $1 }'`
DISK=${DISK:-'ad0'}
ZFILL=`echo $LOADINFO | awk -F= '{ printf $6 }' | awk -F' ' '{ print $1 }'`
ZFILL=${ZFILL:-'0'}
if [ "$PARTITION" != "0" ]; then
SLICE="-s $PARTITION"
......@@ -121,11 +123,20 @@ if [ x"$ADDRESS" != x ]; then
MCASTIF=""
fi
MCASTADDR="-m $MCAST -p $PORT"
#
# ZFILL==1: use frisbee
# ZFILL==2: separate disk-wipe pass (not yet implemented)
#
if [ "$ZFILL" != "0" ]; then
ZFILL="-z"
else
ZFILL=""
fi
echo "Running $BINDIR/frisbee $LOADIP $MEMARGS $SLICE $MCASTIF $MCASTADDR /dev/$DISK at `date`"
echo "Running $BINDIR/frisbee $LOADIP $MEMARGS $ZFILL $SLICE $MCASTIF $MCASTADDR /dev/$DISK at `date`"
$BINDIR/tmcc state RELOADING
$BINDIR/frisbee $LOADIP $MEMARGS $SLICE $MCASTIF $MCASTADDR /dev/$DISK
$BINDIR/frisbee $LOADIP $MEMARGS $ZFILL $SLICE $MCASTIF $MCASTADDR /dev/$DISK
case $? in
0)
echo "Frisbee run finished"
......
......@@ -3259,17 +3259,17 @@ COMMAND_PROTOTYPE(doloadinfo)
char buf[MYBUFSIZE];
char *bufp = buf, *ebufp = &buf[sizeof(buf)];
char *disktype;
int disknum;
int disknum, zfill;
/*
* Get the address the node should contact to load its image
*/
res = mydb_query("select load_address,loadpart,OS,frisbee_pid "
res = mydb_query("select load_address,loadpart,OS,frisbee_pid,mustwipe "
" from current_reloads as r "
"left join images as i on i.imageid = r.image_id "
"left join os_info as o on i.default_osid = o.osid "
"where node_id='%s'",
4, reqp->nodeid);
5, reqp->nodeid);
if (!res) {
error("doloadinfo: %s: DB Error getting loading address!\n",
......@@ -3302,6 +3302,14 @@ COMMAND_PROTOTYPE(doloadinfo)
bufp += OUTPUT(bufp, ebufp - bufp,
"ADDR=%s PART=%s PARTOS=%s", row[0], row[1], row[2]);
/*
* Remember zero-fill free space indicator
*/
zfill = 0;
if (row[4] && row[4][0])
zfill = atoi(row[4]);
mysql_free_result(res);
/*
......@@ -3326,9 +3334,10 @@ COMMAND_PROTOTYPE(doloadinfo)
if (row[1] && row[1][0])
disknum = atoi(row[1]);
}
OUTPUT(bufp, ebufp - bufp, " DISK=%s%d\n", disktype, disknum);
OUTPUT(bufp, ebufp - bufp, " DISK=%s%d ZFILL=%d\n",
disktype, disknum, zfill);
mysql_free_result(res);
client_writeback(sock, buf, strlen(buf), tcp);
if (verbose)
info("doloadinfo: %s", buf);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment