Commit efdd2de0 authored by Leigh B Stoller's avatar Leigh B Stoller
Browse files

Merge branch 'master' into current

parents 7e7631b1 36ab421d
/*
* Copyright (c) 2000-2010 University of Utah and the Flux Group.
*
*
* {{{EMULAB-LICENSE
*
*
* This file is part of the Emulab network testbed software.
*
*
* This file is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
*
* This file is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
*
* You should have received a copy of the GNU Affero General Public License
* along with this file. If not, see <http://www.gnu.org/licenses/>.
*
*
* }}}
*/
......@@ -107,7 +107,7 @@ static unsigned long scoredebugcount = 0;
#define SDEBUG(a) a
#endif
#else
#define SDEBUG(a)
#define SDEBUG(a)
#endif
#define MIN(a,b) (((a) < (b))? (a) : (b))
......@@ -353,7 +353,7 @@ float find_link_resolutions(resolution_vector &resolutions, pvertex pv,
}
info.switches.push_front(*switch_it);
resolutions.push_back(info);
total_weight += LINK_RESOLVE_INTRASWITCH;
SDEBUG(cerr << " intraswitch " << first << " and " << second
<< endl);
......@@ -486,7 +486,7 @@ float find_link_resolutions(resolution_vector &resolutions, pvertex pv,
}
}
}
return total_weight;
}
......@@ -509,7 +509,7 @@ inline float resolution_cost(tb_link_info::linkType res_type) {
// These shouldn't be passed in: fall through to below and die
break;
}
cerr << "*** Internal error: Should not be here. (resolution_cost)" << endl;
exit(EXIT_FATAL);
}
......@@ -582,7 +582,7 @@ void resolve_link(vvertex vv, pvertex pv, tb_vnode *vnode, tb_pnode *pnode,
if (dest_pv == pv) {
SDEBUG(cerr << " trivial link" << endl);
if (allow_trivial_links && vlink->allow_trivial) {
vlink->link_info.type_used = tb_link_info::LINK_TRIVIAL;
/*
......@@ -609,11 +609,11 @@ void resolve_link(vvertex vv, pvertex pv, tb_vnode *vnode, tb_pnode *pnode,
resolution_vector resolutions;
float total_weight = find_link_resolutions(resolutions, pv, dest_pv,
vlink,pnode,dest_pnode,flipped);
int n_resolutions = resolutions.size();
//int resolution_index = n_resolutions - 1;
int resolution_index = n_resolutions;
/*
* check for no link
*/
......@@ -723,7 +723,7 @@ void resolve_links(vvertex vv, pvertex pv, tb_vnode *vnode, tb_pnode *pnode,
SDEBUG(cerr << " seen before - skipping" << endl);
continue;
} else {
seen_links.insert(vlink);
seen_links.insert(vlink);
resolve_link(vv,pv,vnode,pnode,deterministic,*vedge_it);
}
}
......@@ -795,7 +795,7 @@ void unscore_link_info(vedge ve,tb_pnode *src_pnode,tb_pnode *dst_pnode, tb_vnod
SDEBUG(cerr << " interswitch link" << endl);
src_pnode->nontrivial_bw_used -= vlink->delay_info.bandwidth;
dst_pnode->nontrivial_bw_used -= vlink->delay_info.bandwidth;
#ifndef INTERSWITCH_LENGTH
SSUB(SCORE_INTERSWITCH_LINK);
#endif
......@@ -834,7 +834,7 @@ void unscore_link_info(vedge ve,tb_pnode *src_pnode,tb_pnode *dst_pnode, tb_vnod
dst_pnode->nontrivial_bw_used -= vlink->delay_info.bandwidth;
SSUB(SCORE_INTRASWITCH_LINK);
unscore_link(vlink->link_info.plinks.front(),ve,src_pnode,dst_pnode);
unscore_link(vlink->link_info.plinks.back(),ve,src_pnode,dst_pnode);
vlink->link_info.plinks.clear();
......@@ -924,7 +924,7 @@ void remove_node(vvertex vv)
assert(pnode != NULL);
/*
/*
* Find the type on the pnode that this vnode is associated with
*/
tb_pnode::types_map::iterator mit = pnode->types.find(vnode->type);
......@@ -941,7 +941,7 @@ void remove_node(vvertex vv)
} else {
tr = mit->second;
}
/*
* Clean up the pnode's state
......@@ -963,7 +963,7 @@ void remove_node(vvertex vv)
if (vnode->vclass != NULL) {
double score_delta = vnode->vclass->unassign_node(vnode->type);
SDEBUG(cerr << " vclass unassign " << score_delta << endl);
if (score_delta <= -1) {
violated--;
vinfo.vclass--;
......@@ -1037,26 +1037,26 @@ void remove_node(vvertex vv)
if (! dest_vnode->assigned) {
continue;
}
// Find the pnode on the ther end of the link, and unscore it!
pvertex dest_pv = dest_vnode->assignment;
tb_pnode *dest_pnode = get(pvertex_pmap,dest_pv);
unscore_link_info(*vedge_it,pnode,dest_pnode,vnode,dest_vnode);
// If the other end was connected before, it's not now
if (!vlink->no_connection) {
SDEBUG(cerr << " link now in violation.\n";)
mark_vlink_unassigned(vlink);
}
}
#ifdef PENALIZE_UNUSED_INTERFACES
// Keep track of the number of interfaces that the pnode is using
SSUB((pnode->total_interfaces - pnode->used_interfaces) * SCORE_UNUSED_INTERFACE);
pnode->used_interfaces = 0;
#endif
/*
* Adjust scores for the pnode
*/
......@@ -1070,9 +1070,15 @@ void remove_node(vvertex vv)
SADD(SCORE_PNODE * (powf(1+ tr->get_current_load() * 1.0/tr->get_max_load(),2)));
}
if (strategy_pack) {
// Inverse of strategy_balance
SSUB(SCORE_PNODE * (powf(((tr->get_max_load() - (tr->get_current_load()+1)) * 1.0)/tr->get_max_load(),0.5)));
SADD(SCORE_PNODE * (powf((tr->get_max_load() - tr->get_current_load()) * 1.0/tr->get_max_load(),0.5)));
// Inverse of strategy_balance - note that we have to make sure to not let
// the number drop below zero (which might happen if allow_overload is set)
int leftover_slots = tr->get_max_load() - tr->get_current_load();
int prev_leftover_slots = tr->get_max_load() - (tr->get_current_load()+1);
if (prev_leftover_slots < 0) { prev_leftover_slots = 0; }
if (leftover_slots < 0) { leftover_slots = 0; }
SSUB(SCORE_PNODE * (powf((prev_leftover_slots * 1.0)/tr->get_max_load(),0.5)));
SADD(SCORE_PNODE * (powf((leftover_slots * 1.0)/tr->get_max_load(),0.5)));
}
if (pnode->total_load == 0) {
// If the pnode is now free, we need to do some cleanup
......@@ -1114,7 +1120,7 @@ void remove_node(vvertex vv)
SADD(SCORE_UNASSIGNED);
vinfo.unassigned++;
violated++;
/*
* Scoring for features and desires
......@@ -1136,7 +1142,7 @@ void score_link_info(vedge ve, tb_pnode *src_pnode, tb_pnode *dst_pnode, tb_vnod
{
tb_vlink *vlink = get(vedge_pmap,ve);
tb_pnode *the_switch;
// If this link is to be adjusted to the native speed of the interface, go
// ahead and do that now - we use the minimum of the two endpoint interfaces
// Note! Not currently supported on trivial links! (it's illegal for
......@@ -1151,7 +1157,7 @@ void score_link_info(vedge ve, tb_pnode *src_pnode, tb_pnode *dst_pnode, tb_vnod
vlink->delay_info.bandwidth =
min(front_plink->delay_info.bandwidth, back_plink->delay_info.bandwidth);
}
switch (vlink->link_info.type_used) {
case tb_link_info::LINK_DIRECT:
SADD(SCORE_DIRECT_LINK);
......@@ -1231,7 +1237,7 @@ void score_link_info(vedge ve, tb_pnode *src_pnode, tb_pnode *dst_pnode, tb_vnod
new_over_bw = 0;
}
SDEBUG(cerr << " new trivial bandwidth over by " << new_over_bw << endl);
if (new_over_bw) {
// Count how many multiples of the maximum bandwidth we're at
int new_multiple = src_pnode->trivial_bw_used / src_pnode->trivial_bw;
......@@ -1322,7 +1328,7 @@ int add_node(vvertex vv,pvertex pv, bool deterministic, bool is_fixed, bool skip
cerr << *pnode;
#endif
SDEBUG(cerr << " vnode type = " << vnode->type << endl);
/*
* Handle types - first, check to see if the node is capable of taking on the
* vnode's type. If it can with a static type, just do the bookkeeping for
......@@ -1414,7 +1420,7 @@ int add_node(vvertex vv,pvertex pv, bool deterministic, bool is_fixed, bool skip
#ifdef PENALIZE_UNUSED_INTERFACES
pnode->used_interfaces = 0;
#endif
/*
* Record the node's assignment. Need to do this now so that 'loopback' links
* work below.
......@@ -1426,7 +1432,7 @@ int add_node(vvertex vv,pvertex pv, bool deterministic, bool is_fixed, bool skip
if (!skip_links) {
resolve_links(vv,pv,vnode,pnode,deterministic);
}
int old_load = tr->get_current_load();
int old_total_load = pnode->total_load;
......@@ -1459,7 +1465,7 @@ int add_node(vvertex vv,pvertex pv, bool deterministic, bool is_fixed, bool skip
// ptypes
tb_pnode::types_list::iterator lit = pnode->type_list.begin();
while (lit != pnode->type_list.end()) {
int new_violations =
int new_violations =
(*lit)->get_ptype()->add_users((*lit)->get_max_load());
if (new_violations) {
SADD(SCORE_MAX_TYPES * new_violations);
......@@ -1475,8 +1481,14 @@ int add_node(vvertex vv,pvertex pv, bool deterministic, bool is_fixed, bool skip
SADD(SCORE_PNODE * (powf(1 + ((tr->get_current_load()) * 1.0)/tr->get_max_load(),2)));
}
if (strategy_pack) {
SSUB(SCORE_PNODE * (powf(((tr->get_max_load() - (tr->get_current_load()-1)) * 1.0)/tr->get_max_load(),0.5)));
SADD(SCORE_PNODE * (powf(((tr->get_max_load() - tr->get_current_load()) * 1.0)/tr->get_max_load(),0.5)));
/* Note comment above about not letting drop below zero */
int leftover_slots = tr->get_max_load() - tr->get_current_load();
int prev_leftover_slots = tr->get_max_load() - (tr->get_current_load()-1);
if (prev_leftover_slots < 0) { prev_leftover_slots = 0; }
if (leftover_slots < 0) { leftover_slots = 0; }
SSUB(SCORE_PNODE * (powf((prev_leftover_slots * 1.0)/tr->get_max_load(),0.5)));
SADD(SCORE_PNODE * (powf((leftover_slots * 1.0)/tr->get_max_load(),0.5)));
}
// node no longer unassigned
......@@ -1518,7 +1530,7 @@ int add_node(vvertex vv,pvertex pv, bool deterministic, bool is_fixed, bool skip
pclass_set(vnode,pnode);
}
}
return 0;
}
......@@ -1564,7 +1576,7 @@ bool find_best_link(pvertex pv,pvertex switch_pv,tb_vlink *vlink,
// Whether we check the 'source' or 'destination' on the vlink against
// the phyisical link's source interface depends on whether the
// interface order in the in the pedge matches the interface order in
// interface order in the in the pedge matches the interface order in
// the vlink
bool plink_order_reversed;
tb_vnode *src_vnode = get(vvertex_pmap,vlink->src);
......@@ -1643,7 +1655,7 @@ bool find_best_link(pvertex pv,pvertex switch_pv,tb_vlink *vlink,
if (vlink->emulated) {
// For emulated links, we need to do bin packing. Right now, we use the
// first-fit approximation; there may be a better one
// Skip any links that already have non-emulated links assigned to them
if (plink->nonemulated > 0) {
continue;
......@@ -1710,7 +1722,7 @@ int find_interswitch_path(pvertex src_pv,pvertex dest_pv,
sedge current_se;
svertex current_sv = dest_sv;
switch_pred_map &preds = *switch_preds[src_sv];
if (preds[dest_sv] == dest_sv) {
// unreachable
return 0;
......@@ -1738,7 +1750,7 @@ void score_link(pedge pe,vedge ve,tb_pnode *src_pnode, tb_pnode *dst_pnode)
cerr << *plink;
cerr << *vlink;
#endif
if (plink->is_type == tb_plink::PLINK_NORMAL) {
// need to account for three things here, the possiblity of a new plink
// the user of a new emulated link, and a possible violation.
......@@ -1824,7 +1836,7 @@ void score_link(pedge pe,vedge ve,tb_pnode *src_pnode, tb_pnode *dst_pnode)
} else {
new_over_bw = 0;
}
if (new_over_bw) {
// Count how many multiples of the maximum bandwidth we're at
int num_violations =
......@@ -1949,7 +1961,7 @@ void unscore_link(pedge pe,vedge ve, tb_pnode *src_pnode, tb_pnode *dst_pnode)
}
}
#endif
// bandwidth check
if (plink->is_type != tb_plink::PLINK_LAN) {
#ifdef PENALIZE_BANDWIDTH
......@@ -2010,7 +2022,7 @@ score_and_violations score_fds(tb_vnode *vnode, tb_pnode *pnode, bool add) {
switch (fdit.membership()) {
case tb_featuredesire_set_iterator::BOTH:
/*
* On both
* On both
*/
// note: Right now, global features cannot be
// desires, so there is no code path for them here
......@@ -2050,7 +2062,7 @@ score_and_violations score_fds(tb_vnode *vnode, tb_pnode *pnode, bool add) {
* On the pnode, but not the vnode
*/
// What we do here depends on what kind o feature it is
if (fdit->is_local()) {
if (fdit->is_local()) {
// Do nothing for local features that are not matched -
// they are free to waste
} else if (fdit->is_global()) {
......@@ -2083,4 +2095,3 @@ score_and_violations score_fds(tb_vnode *vnode, tb_pnode *pnode, bool add) {
// endl;
return score_and_violations(score_delta,violations_delta);
}
#
# Copyright (c) 2000-2015 University of Utah and the Flux Group.
# Copyright (c) 2000-2016 University of Utah and the Flux Group.
#
# {{{EMULAB-LICENSE
#
......@@ -42,6 +42,12 @@ WITH_RANGEMAP = 0
WITH_MBR = 1
WITH_GPT = 1
#
# Support disk erase (e.g., TRIM) operations
# (incomplete as of 1/2016)
#
WITH_ERASE = 0
#
# Support encrypted and signed-checksumed images.
# Requires openssl libraries.
......
/*
* Copyright (c) 2016 University of Utah and the Flux Group.
*
* {{{EMULAB-LICENSE
*
* This file is part of the Emulab network testbed software.
*
* This file is free software: you can redistribute it and/or modify it
* under the terms of the GNU Affero General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at
* your option) any later version.
*
* This file is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
* License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this file. If not, see <http://www.gnu.org/licenses/>.
*
* }}}
*/
/*
* Support for disk erase operations (e.g., TRIM).
*/
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#ifdef __FreeBSD__
#include <sys/disk.h>
#endif
#define SECSIZE 512
#define SECALIGN(p) (void *)(((uintptr_t)(p) + (SECSIZE-1)) & ~(SECSIZE-1))
#define ISSECALIGNED(p) (((uintptr_t)(p) & (SECSIZE-1)) == 0)
#define ERASEMINSIZE 4096
#define ZEROSIZE (256*1024)
static off_t ebsize = -1;
static off_t erased = 0;
static off_t zeroed = 0;
static int zeroit(int fd, off_t offset, off_t count);
off_t
erasebsize(void)
{
if (ebsize < 0) {
#ifdef DIOCGDELETE
/* XXX this seems to be the minimum */
ebsize = ERASEMINSIZE;
#else
ebsize = 0;
#endif
}
return ebsize;
}
#ifdef DIOCGDELETE
int
erasedata(int fd, off_t offset, off_t ecount, int zeroonfail)
{
off_t args[2];
off_t toff, tend, tcnt;
off_t bsize = erasebsize();
if (bsize == 0) {
if (zeroonfail)
return zeroit(fd, offset, ecount);
return -1;
}
/*
* Check alignment/length, erase as much as we can.
*/
assert(ISSECALIGNED(toff));
assert(ISSECALIGNED(ecount));
toff = offset;
tend = offset + ecount;
if ((toff % bsize) != 0)
toff = ((toff + bsize-1) / bsize) * bsize;
if ((tend % bsize) != 0)
tend = (tend / bsize) * bsize;
tcnt = tend - toff;
#if 0
fprintf(stderr, "Would erase [%ld-%ld]\n", toff, tend-1);
if (toff > offset || tcnt != ecount) {
fprintf(stderr, "Would zero ");
if (toff > offset)
fprintf(stderr, "[%ld-%ld] ", offset, toff-1);
toff += tcnt;
if (toff < offset+ecount)
fprintf(stderr, "[%ld-%ld] ", toff, offset+ecount-1);
fprintf(stderr, "\n");
}
return 0;
#endif
args[0] = toff;
args[1] = tcnt;
if (ioctl(fd, DIOCGDELETE, args) < 0) {
fprintf(stderr,
"DIOCGDELETE of [%lld-%lld] failed (%d)\n",
(long long)args[0],
(long long)args[0]+args[1]-1, errno);
if (zeroonfail)
return zeroit(fd, offset, ecount);
return -1;
}
/*
* Take care of leading and trailing blocks we could not erase.
*/
if (toff > offset || tcnt != ecount) {
/* XXX zero the excess */
if (toff > offset && zeroit(fd, offset, toff-offset))
return -1;
toff += tcnt;
if (toff < offset+ecount &&
zeroit(fd, toff, offset+ecount-toff))
return -1;
}
return 0;
}
#else
int
erasedata(int fd, off_t offset, off_t ecount, int zeroonfail)
{
return -1;
}
#endif
static int
zeroit(int fd, off_t offset, off_t count)
{
char *buf, *_buf;
size_t bsize, wsize;
int err = 0;
if (lseek(fd, offset, SEEK_SET) < 0) {
perror("lseek to write zeros");
return -1;
}
if (count < bsize)
bsize = count;
else
bsize = ZEROSIZE;
_buf = malloc(bsize + SECSIZE);
if (_buf == NULL) {
fprintf(stderr, "Could not allocated zero buffer\n");
return -1;
}
buf = SECALIGN(_buf);
memset(buf, 0, bsize);
while (count > 0) {
if (count < bsize)
wsize = count;
else
wsize = bsize;
if (write(fd, buf, wsize) != wsize) {
fprintf(stderr, "Could not write zeros\n");
err = -1;
goto done;
}
count -= wsize;
}
done:
free(_buf);
return err;
}
/*
* Copyright (c) 2000-2015 University of Utah and the Flux Group.
* Copyright (c) 2000-2016 University of Utah and the Flux Group.
*
* {{{EMULAB-LICENSE
*
......@@ -113,6 +113,7 @@ static int dostype = -1;
static int slice = 0;
static int debug = 0;
static int outfd;
static int doerase = 0;
static int dofill = 0;
static int nothreads = 0;
static int rdycount;
......@@ -570,6 +571,7 @@ usage(void)
" -s slice Output to DOS slice (DOS numbering 1-4)\n"
" NOTE: Must specify a raw disk device.\n"
" -D DOS-ptype Set the DOS partition type in slice mode.\n"
" -E Erase (TRIM) free blocks where possible.\n"
" -z Write zeros to free blocks.\n"
" -p pattern Write 32 bit pattern to free blocks.\n"
" NOTE: Use -z/-p to avoid seeking.\n"
......@@ -599,7 +601,7 @@ main(int argc, char *argv[])
#ifdef NOTHREADS
nothreads = 1;
#endif
while ((ch = getopt(argc, argv, "vdhs:zp:oOnFD:W:Cr:Na:ck:eu:fIM:")) != -1)
while ((ch = getopt(argc, argv, "vdhs:Ezp:oOnFD:W:Cr:Na:ck:eu:fIM:")) != -1)
switch(ch) {
#ifdef FAKEFRISBEE
case 'F':
......@@ -634,6 +636,14 @@ main(int argc, char *argv[])
dostype = (int)strtoul(optarg, NULL, 0);
break;
#ifdef WITH_ERASE
case 'E':
doerase++;
break;
#else
fprintf(stderr, "Erase not supported\n");
exit(1);
#endif
case 'p':
fillpat = strtoul(optarg, NULL, 0);
case 'z':
......
#
# Copyright (c) 2000-2015 University of Utah and the Flux Group.
# Copyright (c) 2000-2016 University of Utah and the Flux Group.
#
# {{{EMULAB-LICENSE
#
......@@ -54,14 +54,17 @@ include $(TESTBED_SRCDIR)/GNUmakerules
CFLAGS = -O -g $(LDSTATIC) $(PARTFLAGS)
zapdisk: zapdisk.o disksize.o $(PARTLIBS)
$(CC) $(CFLAGS) zapdisk.o disksize.o $(PARTLIBS) -o zapdisk
zapdisk: zapdisk.o disksize.o erase.o $(PARTLIBS)
$(CC) $(CFLAGS) zapdisk.o disksize.o erase.o $(PARTLIBS) -o zapdisk
cp zapdisk zapdisk.debug
strip zapdisk
disksize.o: $(IZSRCDIR)/disksize.c
$(CC) -c $(CFLAGS) -o disksize.o $<
erase.o: $(IZSRCDIR)/erase.c
$(CC) -c $(CFLAGS) -o erase.o $<
$(PARTLIBS):
@$(MAKE) -C $(OBJDIR)/os/imagezip partlibs
......
/*
* Copyright (c) 2005-2015 University of Utah and the Flux Group.
* Copyright (c) 2005-2016 University of Utah and the Flux Group.
*
* {{{EMULAB-LICENSE
*
......@@ -55,6 +55,7 @@ static int verbose = 0;
static int pnum = 0;
static int bootblocks = 0;
static int superblocks = 0;
static int erase = 0;