plabdist.in 3.16 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
#!/usr/bin/perl -w

#
# EMULAB-COPYRIGHT
# Copyright (c) 2003 University of Utah and the Flux Group.
# All rights reserved.
#

#
# Script for sync-ing out the netbed_files directory to planetlab nodes
#
# NOTE: This script currently requires YOUR keys, because it logs in as utah1
# on the planetlab nodes
#

use lib '@prefix@/lib';
use libdb;

my $INSTALL_ETCDIR = '@prefix@/etc';
my $ROOTBALL       = '@PLAB_ROOTBALL@';

#
# Username that we'll use to ssh into planetlab nodes
#
my $PLAB_USER = "utah1";

#
# Directory to sync with the plab nodes
#
my $LOCAL_SYNC_DIR  = "$INSTALL_ETCDIR/plab/netbed_files";
my $REMOTE_SYNC_DIR = "netbed_files";

#
# Maximum number of children to run at once - we'll keep this low, since it
# consumes bandwidth on boss
#
my $max_children = 4;

#
# Die unless the rootball exists - this serves two purposes:
# 1) It reminds you to install the rootball
# 2) It prevents you from accidentally running this in a devel tree
#
# We try opening it, so that a symlink pointing to a non-existant file will
# fail.
#
if (!open(ROOTBALL,"<$LOCAL_SYNC_DIR/www/$ROOTBALL")) {
    die "Unable to open $LOCAL_SYNC_DIR/www/$ROOTBALL: $!";
}
close ROOTBALL;

#
# Set up rsync to use ssh - we don't use sshtb, because we need to be able to
# control the username, and it would automatically pick emulabman. Also, we
# have to do the ssh argument differently from normal, because of the way rsync
# 'helpfully' parses them for us - spaces and quotes are a no-no.
#
$ENV{'RSYNC_RSH'} = "ssh -q -oBatchMode=yes -oStrictHostKeyChecking=no " .
		    "-l $PLAB_USER";

my $RSYNC = "/usr/local/bin/rsync";

63
if (!(($> == 0) || TBAdmin())) {
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
    die "Sorry, only admins can use this script!\n";
}

if (@ARGV) {
    die "Usage: $0\n";
}

#
# Get a list of planetlab nodes that are up
#
my $query_result = DBQueryFatal("SELECT n.node_id FROM nodes as n " .
            "LEFT JOIN node_status AS s ON n.node_id=s.node_id " .
	    "LEFT JOIN reserved AS r ON n.node_id = r.node_id " .
	    "WHERE n.type=\"pcplabphys\" AND s.status=\"up\" AND " .
		"!(r.pid=\"" . NODEDEAD_PID .
		    "\" AND r.eid=\"" . NODEDEAD_EID .  "\")");
my @nodes = ();
while (my ($node) = $query_result->fetchrow()) {
    push @nodes, $node;
}

#
# Run up to $max_children rsyncs at a time
#
my $current_children = 0;
my @failed = ();
while (@nodes || $current_children) {
    if (($current_children < $max_children) && @nodes) {
	#
	# If we have room for another child, start one up
	#
        my $node = pop @nodes;
        if (my $pid = fork()) {
            $current_children++;
            $children{$pid} = $node;
        } else {
            print "rsync-ing with $node ...\n";
            exec "$RSYNC -aLz $LOCAL_SYNC_DIR/ ${node}:$REMOTE_SYNC_DIR/";
        }
    } else {
	#
	# Wait for a child to die, and see if it failed
	#
        my $childpid = wait();
        if ($childpid < 0) {
            die "Bad return value from wait(): $childpid\n";
        }
        if ($children{$childpid}) {
            $current_children--;
            if ($?) {
                push @failed, $children{$childpid};
            }
        }
    }
}

if (@failed) {
    print "Some nodes failed: \n";
    print map {"$_\n"} @failed;
}

exit scalar @failed;