Harmonize addr-passing, add shuckle beacon and test it in kmod

This commit is contained in:
Francesco Mazzoli
2023-11-14 11:13:45 +00:00
parent f3c81cd92b
commit 340e7f2f37
10 changed files with 395 additions and 152 deletions
+25 -17
View File
@@ -17,14 +17,10 @@ void usage(const char* binary) {
fprintf(stderr, " Same as '-log-level debug'.\n");
fprintf(stderr, " -shuckle host:port\n");
fprintf(stderr, " How to reach shuckle, default '%s'\n", defaultShuckleAddress.c_str());
fprintf(stderr, " -own-ip-1 ipv4 address\n");
fprintf(stderr, " How to advertise ourselves to shuckle.\n");
fprintf(stderr, " -port-1 port\n");
fprintf(stderr, " Port on which to listen on.\n");
fprintf(stderr, " -own-ip-2 ipv4 address\n");
fprintf(stderr, " How to advertise ourselves to shuckle (second address, optional).\n");
fprintf(stderr, " -port-2 port\n");
fprintf(stderr, " Port on which to listen on (second port).\n");
fprintf(stderr, " -addr-1 ipv4 ip:port\n");
fprintf(stderr, " The first address to bind ourselves too, we'll also advertise it to shuckle.\n");
fprintf(stderr, " -addr-2 ipv4 ip:port\n");
fprintf(stderr, " The second address to bind ourselves too, we'll also advertise it to shuckle. Optional.\n");
fprintf(stderr, " -log-file string\n");
fprintf(stderr, " If not provided, stdout.\n");
fprintf(stderr, " -shard-timeout-ms milliseconds\n");
@@ -61,6 +57,18 @@ static uint16_t parsePort(const std::string& arg) {
return port;
}
static std::pair<uint32_t, uint16_t> parseIpv4Addr(const char* binary, const std::string& arg) {
size_t colon = arg.find(':');
if (colon == std::string::npos) {
fprintf(stderr, "Invalid ipv4 ip:port address '%s'\n\n", arg.c_str());
usage(binary);
exit(2);
}
uint32_t ip = parseIpv4(binary, arg.substr(0, colon));
uint16_t port = parsePort(arg.substr(colon+1));
return {ip, port};
}
int main(int argc, char** argv) {
namespace fs = std::filesystem;
@@ -104,14 +112,14 @@ int main(int argc, char** argv) {
options.logFile = getNextArg();
} else if (arg == "-shuckle") {
shuckleAddress = getNextArg();
} else if (arg == "-own-ip-1") {
options.ipPorts[0].ip = parseIpv4(argv[0], getNextArg());
} else if (arg == "-port-1") {
options.ipPorts[0].port = parsePort(getNextArg());
} else if (arg == "-own-ip-2") {
options.ipPorts[1].ip = parseIpv4(argv[0], getNextArg());
} else if (arg == "-port-2") {
options.ipPorts[1].port = parsePort(getNextArg());
} else if (arg == "-addr-1") {
const auto [ip, port] = parseIpv4Addr(argv[0], getNextArg());
options.ipPorts[0].ip = ip;
options.ipPorts[0].port = port;
} else if (arg == "-addr-2") {
const auto [ip, port] = parseIpv4Addr(argv[0], getNextArg());
options.ipPorts[1].ip = ip;
options.ipPorts[1].port = port;
} else if (arg == "-syslog") {
options.syslog = true;
} else if (arg == "-shard-timeout-ms") {
@@ -157,7 +165,7 @@ int main(int argc, char** argv) {
}
if (options.ipPorts[0].ip == 0) {
fprintf(stderr, "Please provide -own-ip.\n\n");
fprintf(stderr, "Please provide -addr-1.\n\n");
usage(argv[0]);
exit(2);
}
+25 -17
View File
@@ -21,14 +21,10 @@ static void usage(const char* binary) {
fprintf(stderr, " Same as '-log-level debug'.\n");
fprintf(stderr, " -shuckle host:port\n");
fprintf(stderr, " How to reach shuckle, default '%s'\n", defaultShuckleAddress.c_str());
fprintf(stderr, " -own-ip-1 ipv4 address\n");
fprintf(stderr, " How to advertise ourselves to shuckle.\n");
fprintf(stderr, " -port-1 port\n");
fprintf(stderr, " Port on which to listen on.\n");
fprintf(stderr, " -own-ip-2 ipv4 address\n");
fprintf(stderr, " How to advertise ourselves to shuckle (second address, optional).\n");
fprintf(stderr, " -port-2 port\n");
fprintf(stderr, " Port on which to listen on (second port).\n");
fprintf(stderr, " -addr-1 ipv4 ip:port\n");
fprintf(stderr, " The first address to bind ourselves too, we'll also advertise it to shuckle.\n");
fprintf(stderr, " -addr-2 ipv4 ip:port\n");
fprintf(stderr, " The second address to bind ourselves too, we'll also advertise it to shuckle. Optional.\n");
fprintf(stderr, " -log-file string\n");
fprintf(stderr, " If not provided, stdout.\n");
fprintf(stderr, " -incoming-packet-drop [0, 1)\n");
@@ -86,6 +82,18 @@ static uint16_t parsePort(const std::string& arg) {
return port;
}
static std::pair<uint32_t, uint16_t> parseIpv4Addr(const char* binary, const std::string& arg) {
size_t colon = arg.find(':');
if (colon == std::string::npos) {
fprintf(stderr, "Invalid ipv4 ip:port address '%s'\n\n", arg.c_str());
usage(binary);
exit(2);
}
uint32_t ip = parseIpv4(binary, arg.substr(0, colon));
uint16_t port = parsePort(arg.substr(colon+1));
return {ip, port};
}
const std::unordered_map<std::string, uint64_t> durationUnitMap = {
{"ns", 1ull},
{"us", 1'000ull},
@@ -150,14 +158,14 @@ int main(int argc, char** argv) {
options.simulateOutgoingPacketDrop = parseProbability(getNextArg());
} else if (arg == "-shuckle") {
shuckleAddress = getNextArg();
} else if (arg == "-own-ip-1") {
options.ipPorts[0].ip = parseIpv4(argv[0], getNextArg());
} else if (arg == "-port-1") {
options.ipPorts[0].port = parsePort(getNextArg());
} else if (arg == "-own-ip-2") {
options.ipPorts[1].ip = parseIpv4(argv[0], getNextArg());
} else if (arg == "-port-2") {
options.ipPorts[1].port = parsePort(getNextArg());
} else if (arg == "-addr-1") {
const auto [ip, port] = parseIpv4Addr(argv[0], getNextArg());
options.ipPorts[0].ip = ip;
options.ipPorts[0].port = port;
} else if (arg == "-addr-2") {
const auto [ip, port] = parseIpv4Addr(argv[0], getNextArg());
options.ipPorts[1].ip = ip;
options.ipPorts[1].port = port;
} else if (arg == "-syslog") {
options.syslog = true;
} else if (arg == "-xmon") {
@@ -197,7 +205,7 @@ int main(int argc, char** argv) {
}
if (options.ipPorts[0].ip == 0) {
fprintf(stderr, "Please provide -own-ip-1.\n\n");
fprintf(stderr, "Please provide -addr-1.\n\n");
usage(argv[0]);
exit(2);
}
+18 -32
View File
@@ -874,10 +874,8 @@ func main() {
flag.Usage = usage
failureDomainStr := flag.String("failure-domain", "", "Failure domain")
futureCutoff := flag.Duration("future-cutoff", DEFAULT_FUTURE_CUTOFF, "")
ownIp1Str := flag.String("own-ip-1", "", "First IP that we'll bind to, and that we'll advertise to shuckle.")
port1 := flag.Uint("port-1", 0, "First port on which to run on. By default it will be picked automatically.")
ownIp2Str := flag.String("own-ip-2", "", "Second IP that we'll advertise to shuckle. If it is not provided, we will only bind to the first IP.")
port2 := flag.Uint("port-2", 0, "Port on which to run on. By default it will be picked automatically.")
addr1 := flag.String("addr-1", "", "First address to bind to, and that will be advertised to shuckle.")
addr2 := flag.String("addr-2", "", "Second address to bind to, and that will be advertised to shuckle. Optional.")
verbose := flag.Bool("verbose", false, "")
xmon := flag.String("xmon", "", "Xmon environment (empty, prod, qa)")
trace := flag.Bool("trace", false, "")
@@ -899,33 +897,23 @@ func main() {
os.Exit(2)
}
if *ownIp1Str == "" {
fmt.Fprintf(os.Stderr, "-own-ip-1 must be provided.\n\n")
if *addr1 == "" {
fmt.Fprintf(os.Stderr, "-addr-1 must be provided.\n\n")
usage()
os.Exit(2)
}
if *ownIp2Str == "" && *port2 != 0 {
fmt.Fprintf(os.Stderr, "You've provided -port-2, but no -own-ip-2. If you don't need the second route, provide neither. If you do, provide both.\n\n")
usage()
os.Exit(2)
ownIp1, port1, err := lib.ParseIPV4Addr(*addr1)
if err != nil {
panic(err)
}
parseIp := func(ipStr string) [4]byte {
parsedOwnIp := net.ParseIP(ipStr)
if parsedOwnIp == nil || parsedOwnIp.To4() == nil {
fmt.Fprintf(os.Stderr, "IP %v is not a valid ipv4 address. %v\n\n", ipStr, parsedOwnIp)
usage()
os.Exit(2)
}
var ownIp [4]byte
copy(ownIp[:], parsedOwnIp.To4())
return ownIp
}
ownIp1 := parseIp(*ownIp1Str)
var ownIp2 [4]byte
if *ownIp2Str != "" {
ownIp2 = parseIp(*ownIp2Str)
var port2 uint16
if *addr2 != "" {
ownIp2, port2, err = lib.ParseIPV4Addr(*addr2)
if err != nil {
panic(err)
}
}
var failureDomain [16]byte
@@ -995,10 +983,8 @@ func main() {
log.Info("Running block service with options:")
log.Info(" failureDomain = %v", *failureDomainStr)
log.Info(" futureCutoff = %v", *futureCutoff)
log.Info(" ownIp1 = '%v'", *ownIp1Str)
log.Info(" port1 = %v", *port1)
log.Info(" ownIp2 = %v", *ownIp2Str)
log.Info(" port2 = %v", *port2)
log.Info(" addr1 = '%v'", *addr1)
log.Info(" addr2 = '%v'", *addr2)
log.Info(" logLevel = %v", level)
log.Info(" logFile = '%v'", *logFile)
log.Info(" shuckleAddress = '%v'", *shuckleAddress)
@@ -1087,7 +1073,7 @@ func main() {
}
}
listener1, err := net.Listen("tcp4", fmt.Sprintf("%v:%v", net.IP(ownIp1[:]), *port1))
listener1, err := net.Listen("tcp4", fmt.Sprintf("%v:%v", net.IP(ownIp1[:]), port1))
if err != nil {
panic(err)
}
@@ -1098,8 +1084,8 @@ func main() {
var listener2 net.Listener
var actualPort2 uint16
if *ownIp2Str != "" {
listener2, err = net.Listen("tcp4", fmt.Sprintf("%v:%v", net.IP(ownIp2[:]), *port2))
if *addr2 != "" {
listener2, err = net.Listen("tcp4", fmt.Sprintf("%v:%v", net.IP(ownIp2[:]), port2))
if err != nil {
panic(err)
}
+18 -16
View File
@@ -30,7 +30,6 @@ func main() {
hddBlockServices := flag.Uint("hdd-block-services", 2, "Number of HDD block services per failure domain.")
flashBlockServices := flag.Uint("flash-block-services", 2, "Number of HDD block services per failure domain.")
profile := flag.Bool("profile", false, "Whether to run code (both Go and C++) with profiling.")
ownIp := flag.String("own-ip", "127.0.0.1", "What IP to advertise to shuckle for these services.")
shuckleBincodePort := flag.Uint("shuckle-bincode-port", 10001, "")
shuckleHttpPort := flag.Uint("shuckle-http-port", 10000, "")
startingPort := flag.Uint("start-port", 10002, "The services will be assigned port in this order, CDC, shard_000, ..., shard_255, bs_0, ..., bs_n. If 0, ports will be chosen randomly.")
@@ -124,14 +123,13 @@ func main() {
// Start shuckle
shuckleAddress := fmt.Sprintf("127.0.0.1:%v", *shuckleBincodePort)
procs.StartShuckle(log, &managedprocess.ShuckleOpts{
Exe: goExes.ShuckleExe,
BincodePort: uint16(*shuckleBincodePort),
HttpPort: uint16(*shuckleHttpPort),
LogLevel: level,
Dir: path.Join(*dataDir, "shuckle"),
Xmon: *xmon,
ScriptsJs: *shuckleScriptsJs,
OwnIp1: "127.0.0.1",
Exe: goExes.ShuckleExe,
HttpPort: uint16(*shuckleHttpPort),
LogLevel: level,
Dir: path.Join(*dataDir, "shuckle"),
Xmon: *xmon,
ScriptsJs: *shuckleScriptsJs,
Addr1: "127.0.0.1:10001",
})
// Start block services
@@ -151,13 +149,15 @@ func main() {
FailureDomain: fmt.Sprintf("%d", i),
LogLevel: level,
ShuckleAddress: fmt.Sprintf("127.0.0.1:%d", *shuckleBincodePort),
OwnIp1: "127.0.0.1",
OwnIp2: "127.0.0.1",
Profile: *profile,
Xmon: *xmon,
}
if *startingPort != 0 {
opts.Port1 = uint16(*startingPort) + 257 + uint16(i)
opts.Addr1 = fmt.Sprintf("127.0.0.1:%v", uint16(*startingPort)+257+uint16(i))
opts.Addr1 = fmt.Sprintf("127.0.0.1:%v", uint16(*startingPort)+257+uint16(i))
} else {
opts.Addr1 = "127.0.0.1:0"
opts.Addr2 = "127.0.0.1:0"
}
procs.StartBlockService(log, &opts)
}
@@ -177,12 +177,13 @@ func main() {
LogLevel: level,
Valgrind: *buildType == "valgrind",
ShuckleAddress: shuckleAddress,
OwnIp1: *ownIp,
Perf: *profile,
Xmon: *xmon,
}
if *startingPort != 0 {
opts.Port1 = uint16(*startingPort)
opts.Addr1 = fmt.Sprintf("127.0.0.1:%v", *startingPort)
} else {
opts.Addr1 = "127.0.0.1:0"
}
procs.StartCDC(log, *repoDir, &opts)
}
@@ -197,12 +198,13 @@ func main() {
Shid: shid,
Valgrind: *buildType == "valgrind",
ShuckleAddress: shuckleAddress,
OwnIp1: *ownIp,
Perf: *profile,
Xmon: *xmon,
}
if *startingPort != 0 {
opts.Port1 = uint16(*startingPort) + 1 + uint16(i)
opts.Addr1 = fmt.Sprintf("127.0.0.1:%v", uint16(*startingPort)+1+uint16(i))
} else {
opts.Addr1 = "127.0.0.1:0"
}
procs.StartShard(log, *repoDir, &opts)
}
+21 -25
View File
@@ -1976,7 +1976,8 @@ func initDb(dbFile string) (*sql.DB, error) {
func main() {
httpPort := flag.Uint("http-port", 10000, "Port on which to run the HTTP server")
bincodePort := flag.Uint("bincode-port", 10001, "Port on which to run the bincode server.")
addr1 := flag.String("addr-1", "", "First address to bind bincode server on.")
addr2 := flag.String("addr-2", "", "Second address to bind bincode server on (optional).")
logFile := flag.String("log-file", "", "File in which to write logs (or stdout)")
verbose := flag.Bool("verbose", false, "")
trace := flag.Bool("trace", false, "")
@@ -1989,31 +1990,27 @@ func main() {
mtu := flag.Uint64("mtu", 0, "")
stale := flag.Duration("stale", 3*time.Minute, "")
scriptsJs := flag.String("scripts-js", "", "")
ownIp1Str := flag.String("own-ip-1", "", "First IP that we'll bind to.")
ownIp2Str := flag.String("own-ip-2", "", "Second IP that we'll bind to. If it is not provided, we will only bind to the first IP.")
flag.Parse()
noRunawayArgs()
if *ownIp1Str == "" {
fmt.Fprintf(os.Stderr, "-own-ip-1 must be provided.\n")
if *addr1 == "" {
fmt.Fprintf(os.Stderr, "-addr-1 must be provided.\n")
os.Exit(2)
}
parseIp := func(ipStr string) [4]byte {
parsedOwnIp := net.ParseIP(ipStr)
if parsedOwnIp == nil || parsedOwnIp.To4() == nil {
fmt.Fprintf(os.Stderr, "IP %v is not a valid ipv4 address. %v\n", ipStr, parsedOwnIp)
os.Exit(2)
}
var ownIp [4]byte
copy(ownIp[:], parsedOwnIp.To4())
return ownIp
ownIp1, ownPort1, err := lib.ParseIPV4Addr(*addr1)
if err != nil {
panic(err)
}
ownIp1 := parseIp(*ownIp1Str)
var ownIp2 [4]byte
if *ownIp2Str != "" {
ownIp2 = parseIp(*ownIp2Str)
var ownPort2 uint16
if *addr2 != "" {
ownIp2, ownPort2, err = lib.ParseIPV4Addr(*addr2)
if err != nil {
panic(err)
}
}
logOut := os.Stdout
@@ -2040,9 +2037,8 @@ func main() {
}
log.Info("Running shuckle with options:")
log.Info(" bincodePort = %v", *bincodePort)
log.Info(" ownIp1 = %s", *ownIp1Str)
log.Info(" ownIp2 = %s", *ownIp2Str)
log.Info(" addr1 = %s", *addr1)
log.Info(" addr2 = %s", *addr2)
log.Info(" httpPort = %v", *httpPort)
log.Info(" logFile = '%v'", *logFile)
log.Info(" logLevel = %v", level)
@@ -2066,16 +2062,16 @@ func main() {
readSpanBufPool = lib.NewBufPool()
bincodeListener1, err := net.Listen("tcp", fmt.Sprintf("%v:%v", net.IP(ownIp1[:]), *bincodePort))
bincodeListener1, err := net.Listen("tcp", fmt.Sprintf("%v:%v", net.IP(ownIp1[:]), ownPort1))
if err != nil {
panic(err)
}
defer bincodeListener1.Close()
var bincodeListener2 net.Listener
if *ownIp2Str != "" {
if *addr2 != "" {
var err error
bincodeListener2, err = net.Listen("tcp", fmt.Sprintf("%v:%v", net.IP(ownIp2[:]), *bincodePort))
bincodeListener2, err = net.Listen("tcp", fmt.Sprintf("%v:%v", net.IP(ownIp2[:]), ownPort2))
if err != nil {
panic(err)
}
@@ -2096,9 +2092,9 @@ func main() {
config := &shuckleConfig{
ip1: ownIp1,
port1: uint16(*bincodePort),
port1: ownPort1,
ip2: ownIp2,
port2: uint16(*bincodePort),
port2: ownPort2,
blockServiceMinFreeBytes: *bsMinBytes,
}
state, err := newState(log, db, config)
+212
View File
@@ -0,0 +1,212 @@
package main
import (
"flag"
"fmt"
"io"
"log"
"net"
"os"
"strconv"
"xtx/eggsfs/lib"
"xtx/eggsfs/msgs"
)
func handleRequestParsed(log *lib.Logger, shuckleResp *msgs.ShuckleResp, req msgs.ShuckleRequest) (msgs.ShuckleResponse, error) {
var err error
var resp msgs.ShuckleResponse
switch req.(type) {
case *msgs.ShuckleReq:
resp = shuckleResp
default:
err = fmt.Errorf("bad req type %T", req)
}
return resp, err
}
func handleError(
log *lib.Logger,
conn *net.TCPConn,
err error,
) {
if err == io.EOF {
log.Debug("got EOF, terminating")
return
}
// we always raise an alert since this is almost always bad news in shuckle
log.RaiseAlertStack(1, "got unexpected error %v from %v", err, conn.RemoteAddr())
// attempt to say goodbye, ignore errors
if eggsErr, isEggsErr := err.(msgs.ErrCode); isEggsErr {
lib.WriteShuckleResponseError(log, conn, eggsErr)
} else {
lib.WriteShuckleResponseError(log, conn, msgs.INTERNAL_ERROR)
}
}
func handleRequest(log *lib.Logger, shuckleResp *msgs.ShuckleResp, conn *net.TCPConn) {
defer conn.Close()
req, err := lib.ReadShuckleRequest(log, conn)
if err != nil {
handleError(log, conn, err)
return
}
log.Debug("handling request %T from %s", req, conn.RemoteAddr())
resp, err := handleRequestParsed(log, shuckleResp, req)
if err != nil {
handleError(log, conn, err)
return
}
log.Debug("sending back response %T to %s", resp, conn.RemoteAddr())
if err := lib.WriteShuckleResponse(log, conn, resp); err != nil {
handleError(log, conn, err)
}
}
func noRunawayArgs() {
if flag.NArg() > 0 {
fmt.Fprintf(os.Stderr, "Unexpected extra arguments %v\n", flag.Args())
os.Exit(2)
}
}
func main() {
bincodePort := flag.Uint("bincode-port", 10001, "Port on which to run the bincode server.")
logFile := flag.String("log-file", "", "File in which to write logs (or stdout)")
verbose := flag.Bool("verbose", false, "")
trace := flag.Bool("trace", false, "")
xmon := flag.String("xmon", "", "Xmon environment (empty, prod, qa)")
syslog := flag.Bool("syslog", false, "")
ownIp1Str := flag.String("own-ip-1", "", "First IP that we'll bind to.")
ownIp2Str := flag.String("own-ip-2", "", "Second IP that we'll bind to. If it is not provided, we will only bind to the first IP.")
shuckleAddr1 := flag.String("shuckle-1", "", "First shuckle address to advertise")
shuckleAddr2 := flag.String("shuckle-2", "", "Second shuckle address to advertise")
flag.Parse()
noRunawayArgs()
if *ownIp1Str == "" {
fmt.Fprintf(os.Stderr, "-own-ip-1 must be provided.\n")
os.Exit(2)
}
parseIp := func(ipStr string) [4]byte {
parsedOwnIp := net.ParseIP(ipStr)
if parsedOwnIp == nil || parsedOwnIp.To4() == nil {
fmt.Fprintf(os.Stderr, "IP %v is not a valid ipv4 address. %v\n", ipStr, parsedOwnIp)
os.Exit(2)
}
var ownIp [4]byte
copy(ownIp[:], parsedOwnIp.To4())
return ownIp
}
ownIp1 := parseIp(*ownIp1Str)
var ownIp2 [4]byte
if *ownIp2Str != "" {
ownIp2 = parseIp(*ownIp2Str)
}
parseShuckleAddr := func(addrStr string) (ip [4]byte, port uint16) {
hostStr, portStr, err := net.SplitHostPort(addrStr)
if err != nil {
panic(err)
}
ipV := net.ParseIP(hostStr)
if ipV == nil || len(ipV) != 4 {
panic(fmt.Errorf("invalid ip address %q", hostStr))
}
copy(ip[:], ipV[:])
port64, err := strconv.ParseUint(portStr, 0, 16)
if err != nil {
panic(err)
}
port = uint16(port64)
return ip, port
}
if *shuckleAddr1 == "" {
panic(fmt.Errorf("-shuckle-1 needs to be provided"))
}
shuckleResp := &msgs.ShuckleResp{}
shuckleResp.Ip1, shuckleResp.Port1 = parseShuckleAddr(*shuckleAddr1)
if *shuckleAddr2 != "" {
shuckleResp.Ip2, shuckleResp.Port2 = parseShuckleAddr(*shuckleAddr2)
}
logOut := os.Stdout
if *logFile != "" {
var err error
logOut, err = os.OpenFile(*logFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644)
if err != nil {
log.Fatalf("could not open log file %v: %v", *logFile, err)
}
}
level := lib.INFO
if *verbose {
level = lib.DEBUG
}
if *trace {
level = lib.TRACE
}
log := lib.NewLogger(logOut, &lib.LoggerOptions{Level: level, Syslog: *syslog, Xmon: *xmon, AppInstance: "eggsshuckle", AppType: "restech_eggsfs.critical", PrintQuietAlerts: true})
log.Info("Running shuckle beacon with options:")
log.Info(" bincodePort = %v", *bincodePort)
log.Info(" ownIp1 = %s", *ownIp1Str)
log.Info(" ownIp2 = %s", *ownIp2Str)
log.Info(" logFile = '%v'", *logFile)
log.Info(" logLevel = %v", level)
bincodeListener1, err := net.Listen("tcp", fmt.Sprintf("%v:%v", net.IP(ownIp1[:]), *bincodePort))
if err != nil {
panic(err)
}
defer bincodeListener1.Close()
var bincodeListener2 net.Listener
if *ownIp2Str != "" {
var err error
bincodeListener2, err = net.Listen("tcp", fmt.Sprintf("%v:%v", net.IP(ownIp2[:]), *bincodePort))
if err != nil {
panic(err)
}
defer bincodeListener2.Close()
}
if bincodeListener2 == nil {
log.Info("running on %v", bincodeListener1.Addr())
} else {
log.Info("running on %v,%v", bincodeListener1.Addr(), bincodeListener2.Addr())
}
terminateChan := make(chan any)
startBincodeHandler := func(listener net.Listener) {
go func() {
defer func() { lib.HandleRecoverChan(log, terminateChan, recover()) }()
for {
conn, err := listener.Accept()
if err != nil {
terminateChan <- err
return
}
go func() {
defer func() { lib.HandleRecoverPanic(log, recover()) }()
handleRequest(log, shuckleResp, conn.(*net.TCPConn))
}()
}
}()
}
startBincodeHandler(bincodeListener1)
if bincodeListener2 != nil {
startBincodeHandler(bincodeListener2)
}
panic(<-terminateChan)
}
+7 -11
View File
@@ -569,11 +569,8 @@ func (bsv *blockServiceVictim) start(
LogLevel: log.Level(),
ShuckleAddress: fmt.Sprintf("127.0.0.1:%d", shucklePort),
FutureCutoff: &testBlockFutureCutoff,
OwnIp1: "127.0.0.1",
OwnIp2: "127.0.0.1",
Profile: profile,
Port1: port1,
Port2: port2,
Addr1: "127.0.0.1:0",
Addr2: "127.0.0.1:0",
})
}
@@ -875,11 +872,10 @@ func main() {
shuckleAddress := fmt.Sprintf("127.0.0.1:%v", shucklePort)
shuckleOpts := &managedprocess.ShuckleOpts{
Exe: goExes.ShuckleExe,
BincodePort: shucklePort,
LogLevel: level,
BlockserviceMinBytes: 10 << (10 * 3),
Dir: path.Join(*dataDir, "shuckle"),
OwnIp1: "127.0.0.1",
Addr1: fmt.Sprintf("127.0.0.1:%v", shucklePort),
}
if *blockServiceKiller {
shuckleOpts.Stale = time.Hour * 1000 // never, so that we stimulate the clients ability to fallback
@@ -950,8 +946,8 @@ func main() {
Valgrind: *buildType == "valgrind",
Perf: *profile,
ShuckleAddress: shuckleAddress,
OwnIp1: "127.0.0.1",
OwnIp2: "127.0.0.1",
Addr1: "127.0.0.1:0",
Addr2: "127.0.0.1:0",
}
if *buildType == "valgrind" {
// apparently 100ms is too little when running with valgrind
@@ -973,8 +969,8 @@ func main() {
IncomingPacketDrop: *incomingPacketDrop,
OutgoingPacketDrop: *outgoingPacketDrop,
ShuckleAddress: shuckleAddress,
OwnIp1: "127.0.0.1",
OwnIp2: "127.0.0.1",
Addr1: "127.0.0.1:0",
Addr2: "127.0.0.1:0",
TransientDeadlineInterval: &testTransientDeadlineInterval,
}
procs.StartShard(log, *repoDir, &shopts)
+29
View File
@@ -0,0 +1,29 @@
package lib
import (
"fmt"
"net"
"strconv"
)
func ParseIPV4Addr(addrStr string) (ip [4]byte, port uint16, err error) {
hostStr, portStr, err := net.SplitHostPort(addrStr)
if err != nil {
panic(err)
}
ipV := net.ParseIP(hostStr)
if ipV == nil || ipV.To4() == nil {
return ip, port, fmt.Errorf("invalid ip address %q", hostStr)
}
port64, err := strconv.ParseUint(portStr, 0, 16)
if err != nil {
return ip, port, err
}
copy(ip[:], ipV.To4()[:])
port = uint16(port64)
return ip, port, nil
}
+37 -34
View File
@@ -263,10 +263,8 @@ func (procs *ManagedProcesses) installSignalHandlers() {
type BlockServiceOpts struct {
Exe string
Path string
OwnIp1 string
Port1 uint16
OwnIp2 string
Port2 uint16
Addr1 string
Addr2 string
StorageClasses []msgs.StorageClass
FailureDomain string
FutureCutoff *time.Duration
@@ -288,12 +286,12 @@ func (procs *ManagedProcesses) StartBlockService(ll *lib.Logger, opts *BlockServ
createDataDir(opts.Path)
args := []string{
"-failure-domain", opts.FailureDomain,
"-own-ip-1", opts.OwnIp1,
"-port-1", fmt.Sprintf("%d", opts.Port1),
"-own-ip-2", opts.OwnIp2,
"-port-2", fmt.Sprintf("%d", opts.Port2),
"-addr-1", opts.Addr1,
"-log-file", path.Join(opts.Path, "log"),
}
if opts.Addr2 != "" {
args = append(args, "-addr-2", opts.Addr2)
}
if opts.FutureCutoff != nil {
args = append(args, "-future-cutoff", opts.FutureCutoff.String())
}
@@ -316,7 +314,7 @@ func (procs *ManagedProcesses) StartBlockService(ll *lib.Logger, opts *BlockServ
args = append(args, path.Join(opts.Path, fmt.Sprintf("%d", i)), storageClass.String())
}
return procs.Start(ll, &ManagedProcessArgs{
Name: fmt.Sprintf("block service (%v:%d & %v:%d)", opts.OwnIp1, opts.Port1, opts.OwnIp2, opts.Port2),
Name: fmt.Sprintf("block service (%s & %s)", opts.Addr1, opts.Addr2),
Exe: opts.Exe,
Args: args,
StdoutFile: path.Join(opts.Path, "stdout"),
@@ -386,25 +384,23 @@ type ShuckleOpts struct {
Exe string
Dir string
LogLevel lib.LogLevel
BincodePort uint16
HttpPort uint16
BlockserviceMinBytes uint64
Stale time.Duration
Xmon string
ScriptsJs string
OwnIp1 string
OwnIp2 string
Addr1 string
Addr2 string
}
func (procs *ManagedProcesses) StartShuckle(ll *lib.Logger, opts *ShuckleOpts) {
createDataDir(opts.Dir)
args := []string{
"-bincode-port", fmt.Sprintf("%d", opts.BincodePort),
"-http-port", fmt.Sprintf("%d", opts.HttpPort),
"-log-file", path.Join(opts.Dir, "log"),
"-bs-min-bytes", fmt.Sprintf("%d", opts.BlockserviceMinBytes),
"-data-dir", opts.Dir,
"-own-ip-1", opts.OwnIp1,
"-addr-1", opts.Addr1,
}
if opts.LogLevel == lib.DEBUG {
args = append(args, "-verbose")
@@ -421,8 +417,8 @@ func (procs *ManagedProcesses) StartShuckle(ll *lib.Logger, opts *ShuckleOpts) {
if opts.ScriptsJs != "" {
args = append(args, "-scripts-js", opts.ScriptsJs)
}
if opts.OwnIp2 != "" {
args = append(args, "-own-ip-2", opts.OwnIp2)
if opts.Addr2 != "" {
args = append(args, "-addr-2", opts.Addr2)
}
procs.Start(ll, &ManagedProcessArgs{
Name: "shuckle",
@@ -470,10 +466,8 @@ type ShardOpts struct {
IncomingPacketDrop float64
OutgoingPacketDrop float64
ShuckleAddress string
OwnIp1 string
Port1 uint16
OwnIp2 string
Port2 uint16
Addr1 string
Addr2 string
TransientDeadlineInterval *time.Duration
Xmon string
}
@@ -488,12 +482,10 @@ func (procs *ManagedProcesses) StartShard(ll *lib.Logger, repoDir string, opts *
"-incoming-packet-drop", fmt.Sprintf("%g", opts.IncomingPacketDrop),
"-outgoing-packet-drop", fmt.Sprintf("%g", opts.OutgoingPacketDrop),
"-shuckle", opts.ShuckleAddress,
"-own-ip-1", opts.OwnIp1,
"-port-1", fmt.Sprintf("%v", opts.Port1),
"-port-2", fmt.Sprintf("%v", opts.Port2),
"-addr-1", opts.Addr1,
}
if opts.OwnIp2 != "" {
args = append(args, "-own-ip-2", opts.OwnIp2)
if opts.Addr2 != "" {
args = append(args, "-addr-2", opts.Addr2)
}
if opts.TransientDeadlineInterval != nil {
args = append(args, "-transient-deadline-interval", fmt.Sprintf("%dns", opts.TransientDeadlineInterval.Nanoseconds()))
@@ -562,10 +554,8 @@ type CDCOpts struct {
Valgrind bool
Perf bool
ShuckleAddress string
OwnIp1 string
Port1 uint16
OwnIp2 string
Port2 uint16
Addr1 string
Addr2 string
ShardTimeout time.Duration
Xmon string
}
@@ -578,12 +568,10 @@ func (procs *ManagedProcesses) StartCDC(ll *lib.Logger, repoDir string, opts *CD
args := []string{
"-log-file", path.Join(opts.Dir, "log"),
"-shuckle", opts.ShuckleAddress,
"-own-ip-1", opts.OwnIp1,
"-port-1", fmt.Sprintf("%v", opts.Port1),
"-port-2", fmt.Sprintf("%v", opts.Port2),
"-addr-1", opts.Addr1,
}
if opts.OwnIp2 != "" {
args = append(args, "-own-ip-2", opts.OwnIp2)
if opts.Addr2 != "" {
args = append(args, "-addr-2", opts.Addr2)
}
if opts.ShardTimeout != 0 {
args = append(args, "-shard-timeout-ms", fmt.Sprintf("%v", opts.ShardTimeout.Milliseconds()))
@@ -641,6 +629,21 @@ func (procs *ManagedProcesses) StartCDC(ll *lib.Logger, repoDir string, opts *CD
procs.Start(ll, &mpArgs)
}
type ShuckleBeaconOpts struct {
Exe string
Dir string
LogLevel lib.LogLevel
Valgrind bool
Perf bool
ShuckleAddress string
OwnIp1 string
Port1 uint16
OwnIp2 string
Port2 uint16
ShardTimeout time.Duration
Xmon string
}
type BuildCppOpts struct {
Valgrind bool
Sanitize bool
+3
View File
@@ -101,3 +101,6 @@ timeout -s KILL 300 ssh -p 2222 -i image-key fmazzol@localhost "grep eggsfs /pro
# Rmmod
timeout -s KILL 300 ssh -p 2222 -i image-key fmazzol@localhost "sudo rmmod eggsfs"
# sudo sysctl fs.eggsfs.debug=1
# eggs/eggstests -kmod -filter 'direct' -short -binaries-dir eggs