Script to run net-shaper on remote nodes (#6938)

* Script to run net-shaper on remote nodes

* fixes
This commit is contained in:
Pankaj Garg
2019-11-13 20:31:44 -08:00
committed by GitHub
parent 4fc767b3f6
commit c96b8c8d68
3 changed files with 65 additions and 20 deletions

View File

@ -34,7 +34,7 @@ impl NetworkTopology {
} }
for x in self.interconnects.iter() { for x in self.interconnects.iter() {
if x.a as usize >= self.partitions.len() || x.b as usize >= self.partitions.len() { if x.a as usize > self.partitions.len() || x.b as usize > self.partitions.len() {
return false; return false;
} }
} }
@ -43,12 +43,22 @@ impl NetworkTopology {
} }
} }
fn run(cmd: &str, args: &[&str], launch_err_msg: &str, status_err_msg: &str) -> bool { fn run(
cmd: &str,
args: &[&str],
launch_err_msg: &str,
status_err_msg: &str,
ignore_err: bool,
) -> bool {
let output = std::process::Command::new(cmd) let output = std::process::Command::new(cmd)
.args(args) .args(args)
.output() .output()
.expect(launch_err_msg); .expect(launch_err_msg);
if ignore_err {
return true;
}
if !output.status.success() { if !output.status.success() {
eprintln!( eprintln!(
"{} command failed with exit code: {}", "{} command failed with exit code: {}",
@ -83,6 +93,7 @@ fn insert_iptables_rule(my_partition: usize) -> bool {
], ],
"Failed to add iptables rule", "Failed to add iptables rule",
"iptables", "iptables",
false,
) )
} }
@ -92,6 +103,7 @@ fn flush_iptables_rule() {
&["-F", "-t", "mangle"], &["-F", "-t", "mangle"],
"Failed to flush iptables", "Failed to flush iptables",
"iptables flush", "iptables flush",
true,
); );
} }
@ -104,6 +116,7 @@ fn insert_tc_root(interface: &str) -> bool {
], ],
"Failed to add root qdisc", "Failed to add root qdisc",
"tc add root qdisc", "tc add root qdisc",
false,
) )
} }
@ -116,30 +129,33 @@ fn delete_tc_root(interface: &str) {
], ],
"Failed to delete root qdisc", "Failed to delete root qdisc",
"tc qdisc delete root", "tc qdisc delete root",
true,
); );
} }
fn insert_tc_netem(interface: &str, class: &str, tos: &str, filter: &str) -> bool { fn insert_tc_netem(interface: &str, class: &str, handle: &str, filter: &str) -> bool {
let mut filters: Vec<&str> = filter.split(' ').collect();
let mut args = vec![
"qdisc", "add", "dev", interface, "parent", class, "handle", handle, "netem",
];
args.append(&mut filters);
// tc qdisc add dev <if> parent 1:<i.a> handle <i.a>: netem <filters> // tc qdisc add dev <if> parent 1:<i.a> handle <i.a>: netem <filters>
run( run("tc", &args, "Failed to add tc child", "tc add child", false)
"tc",
&[
"qdisc", "add", "dev", interface, "parent", class, "handle", tos, "netem", filter,
],
"Failed to add tc child",
"tc add child",
)
} }
fn delete_tc_netem(interface: &str, class: &str, tos: &str, filter: &str) { fn delete_tc_netem(interface: &str, class: &str, handle: &str, filter: &str) {
let mut filters: Vec<&str> = filter.split(' ').collect();
let mut args = vec![
"qdisc", "delete", "dev", interface, "parent", class, "handle", handle, "netem",
];
args.append(&mut filters);
// tc qdisc delete dev <if> parent 1:<i.a> handle <i.a>: netem <filters> // tc qdisc delete dev <if> parent 1:<i.a> handle <i.a>: netem <filters>
run( run(
"tc", "tc",
&[ &args,
"qdisc", "delete", "dev", interface, "parent", class, "handle", tos, "netem", filter,
],
"Failed to delete child qdisc", "Failed to delete child qdisc",
"tc delete child qdisc", "tc delete child qdisc",
true,
); );
} }
@ -153,6 +169,7 @@ fn insert_tos_filter(interface: &str, class: &str, tos: &str) -> bool {
], ],
"Failed to add tos filter", "Failed to add tos filter",
"tc add filter", "tc add filter",
false,
) )
} }
@ -166,6 +183,7 @@ fn delete_tos_filter(interface: &str, class: &str, tos: &str) {
], ],
"Failed to delete tos filter", "Failed to delete tos filter",
"tc delete filter", "tc delete filter",
true,
); );
} }
@ -180,7 +198,7 @@ fn identify_my_partition(partitions: &[u8], index: u64, size: u64) -> usize {
} }
} }
my_partition my_partition + 1
} }
fn shape_network(matches: &ArgMatches) { fn shape_network(matches: &ArgMatches) {
@ -216,12 +234,13 @@ fn shape_network(matches: &ArgMatches) {
topology.interconnects.iter().for_each(|i| { topology.interconnects.iter().for_each(|i| {
if i.b as usize == my_partition { if i.b as usize == my_partition {
let handle = (i.a + 1).to_string();
let tos_string = i.a.to_string(); let tos_string = i.a.to_string();
let class = format!("1:{}", i.a); let class = format!("1:{}", i.a);
if !insert_tc_netem( if !insert_tc_netem(
interface.as_str(), interface.as_str(),
class.as_str(), class.as_str(),
tos_string.as_str(), handle.as_str(),
i.config.as_str(), i.config.as_str(),
) { ) {
flush_iptables_rule(); flush_iptables_rule();
@ -229,12 +248,12 @@ fn shape_network(matches: &ArgMatches) {
return; return;
} }
if !insert_tos_filter(interface.as_str(), tos_string.as_str(), class.as_str()) { if !insert_tos_filter(interface.as_str(), class.as_str(), tos_string.as_str()) {
flush_iptables_rule(); flush_iptables_rule();
delete_tc_netem( delete_tc_netem(
interface.as_str(), interface.as_str(),
class.as_str(), class.as_str(),
tos_string.as_str(), handle.as_str(),
i.config.as_str(), i.config.as_str(),
); );
delete_tc_root(interface.as_str()); delete_tc_root(interface.as_str());
@ -265,13 +284,14 @@ fn cleanup_network(matches: &ArgMatches) {
topology.interconnects.iter().for_each(|i| { topology.interconnects.iter().for_each(|i| {
if i.b as usize == my_partition { if i.b as usize == my_partition {
let handle = (i.a + 1).to_string();
let tos_string = i.a.to_string(); let tos_string = i.a.to_string();
let class = format!("1:{}", i.a); let class = format!("1:{}", i.a);
delete_tos_filter(interface.as_str(), class.as_str(), tos_string.as_str()); delete_tos_filter(interface.as_str(), class.as_str(), tos_string.as_str());
delete_tc_netem( delete_tc_netem(
interface.as_str(), interface.as_str(),
class.as_str(), class.as_str(),
tos_string.as_str(), handle.as_str(),
i.config.as_str(), i.config.as_str(),
); );
} }

View File

@ -80,6 +80,7 @@ BINS=(
solana-keygen solana-keygen
solana-ledger-tool solana-ledger-tool
solana-log-analyzer solana-log-analyzer
solana-net-shaper
solana-archiver solana-archiver
solana-validator solana-validator
) )

24
scripts/net-shaper.sh Executable file
View File

@ -0,0 +1,24 @@
#!/usr/bin/env bash
#
# Start/Stop network shaper
#
set -e
[[ $(uname) == Linux ]] || exit 0
cd "$(dirname "$0")"
sudo=
if sudo true; then
sudo="sudo -n"
fi
set -x
iface="$(ifconfig | grep mtu | grep -iv loopback | grep -i running | awk 'BEGIN { FS = ":" } ; {print $1}')"
if [[ "$1" = cleanup ]]; then
$sudo ~solana/.cargo/bin/solana-net-shaper cleanup -f "$2" -s "$3" -p "$4" -i "$iface"
else
$sudo ~solana/.cargo/bin/solana-net-shaper shape -f "$2" -s "$3" -p "$4" -i "$iface"
fi