mirror of
https://github.com/XTXMarkets/ternfs.git
synced 2026-05-03 08:19:58 -05:00
Harmonize addr-passing, add shuckle beacon and test it in kmod
This commit is contained in:
+25
-17
@@ -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
@@ -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
@@ -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
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user