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
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 65 additions and 20 deletions

View File

@ -34,7 +34,7 @@ impl NetworkTopology {
}
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;
}
}
@ -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)
.args(args)
.output()
.expect(launch_err_msg);
if ignore_err {
return true;
}
if !output.status.success() {
eprintln!(
"{} command failed with exit code: {}",
@ -83,6 +93,7 @@ fn insert_iptables_rule(my_partition: usize) -> bool {
],
"Failed to add iptables rule",
"iptables",
false,
)
}
@ -92,6 +103,7 @@ fn flush_iptables_rule() {
&["-F", "-t", "mangle"],
"Failed to flush iptables",
"iptables flush",
true,
);
}
@ -104,6 +116,7 @@ fn insert_tc_root(interface: &str) -> bool {
],
"Failed to add root qdisc",
"tc add root qdisc",
false,
)
}
@ -116,30 +129,33 @@ fn delete_tc_root(interface: &str) {
],
"Failed to delete root qdisc",
"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>
run(
"tc",
&[
"qdisc", "add", "dev", interface, "parent", class, "handle", tos, "netem", filter,
],
"Failed to add tc child",
"tc add child",
)
run("tc", &args, "Failed to add tc child", "tc add child", false)
}
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>
run(
"tc",
&[
"qdisc", "delete", "dev", interface, "parent", class, "handle", tos, "netem", filter,
],
&args,
"Failed to 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",
"tc add filter",
false,
)
}
@ -166,6 +183,7 @@ fn delete_tos_filter(interface: &str, class: &str, tos: &str) {
],
"Failed to delete tos 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) {
@ -216,12 +234,13 @@ fn shape_network(matches: &ArgMatches) {
topology.interconnects.iter().for_each(|i| {
if i.b as usize == my_partition {
let handle = (i.a + 1).to_string();
let tos_string = i.a.to_string();
let class = format!("1:{}", i.a);
if !insert_tc_netem(
interface.as_str(),
class.as_str(),
tos_string.as_str(),
handle.as_str(),
i.config.as_str(),
) {
flush_iptables_rule();
@ -229,12 +248,12 @@ fn shape_network(matches: &ArgMatches) {
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();
delete_tc_netem(
interface.as_str(),
class.as_str(),
tos_string.as_str(),
handle.as_str(),
i.config.as_str(),
);
delete_tc_root(interface.as_str());
@ -265,13 +284,14 @@ fn cleanup_network(matches: &ArgMatches) {
topology.interconnects.iter().for_each(|i| {
if i.b as usize == my_partition {
let handle = (i.a + 1).to_string();
let tos_string = i.a.to_string();
let class = format!("1:{}", i.a);
delete_tos_filter(interface.as_str(), class.as_str(), tos_string.as_str());
delete_tc_netem(
interface.as_str(),
class.as_str(),
tos_string.as_str(),
handle.as_str(),
i.config.as_str(),
);
}

View File

@ -80,6 +80,7 @@ BINS=(
solana-keygen
solana-ledger-tool
solana-log-analyzer
solana-net-shaper
solana-archiver
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