func clientFunc() int { socketfname := getSocketFilename() // client client, err := rpc.Dial("unix", socketfname) if err != nil { err = tryRunServer() if err != nil { fmt.Printf("%s\n", err.String()) return 1 } waitForAFile(socketfname) client, err = rpc.Dial("unix", socketfname) if err != nil { fmt.Printf("%s\n", err.String()) return 1 } } defer client.Close() if flag.NArg() > 0 { switch flag.Arg(0) { case "autocomplete": Cmd_AutoComplete(client) case "close": Cmd_Close(client) case "status": Cmd_Status(client) case "drop-cache": Cmd_DropCache(client) } } return 0 }
func SendHeartbeat(masterAddress string) { var args sfs.HeartbeatArgs var ret sfs.HeartbeatReturn master, err := rpc.Dial("tcp", masterAddress+":1338") if err != nil { log.Fatal("chunk: dialing:", err) } host, _ := os.Hostname() _, iparray, _ := net.LookupHost(host) tcpAddr, _ := net.ResolveTCPAddr(iparray[0] + ":1337") args.ChunkServerIP = *tcpAddr args.ChunkServerID = chunkServerID for { args.Capacity = capacity addedChunkSlice := make([]sfs.ChunkInfo, addedChunks.Len()) for i := 0; i < addedChunks.Len(); i++ { addedChunkSlice[i] = addedChunks.At(i).(sfs.ChunkInfo) } args.AddedChunks = addedChunkSlice err = master.Call("Master.BeatHeart", &args, &ret) if err != nil { log.Fatal("chunk: heartbeat error: ", err) } addedChunks.Resize(0, 0) time.Sleep(sfs.HEARTBEAT_WAIT) } return }
func (t *Server) ReplicateChunk(args *sfs.ReplicateChunkArgs, ret *sfs.ReplicateChunkReturn) os.Error { if args.Servers == nil { log.Printf("chunk: replication call: nil address.") return nil } log.Printf("replication request for site %s and chunk %d\n", args.Servers[0].String(), args.ChunkID) for i := 0; i < len(args.Servers); i++ { replicationHost, err := rpc.Dial("tcp", args.Servers[i].String()) if err != nil { log.Println("chunk: replication call:", err) continue } var readArgs sfs.ReadArgs var readRet sfs.ReadReturn readArgs.ChunkID = args.ChunkID err = replicationHost.Call("Server.Read", &readArgs, &readRet) if err != nil { log.Println("chunk: replication call:", err) continue } chunkTable[args.ChunkID] = readRet.Data break } return nil }
func Init(masterAddress string, loggingFlag bool) { var args sfs.ChunkBirthArgs var ret sfs.ChunkBirthReturn requestLoad = 0 loadArray = make([]int, 3) for i := 0; i < 3; i++ { loadArray[i] = 0 } loadArrayIndex = 0 logging = loggingFlag capacity = CHUNK_TABLE_SIZE args.Capacity = capacity host, _ := os.Hostname() _, iparray, _ := net.LookupHost(host) tcpAddr, _ = net.ResolveTCPAddr(iparray[0] + ":1337") args.ChunkServerIP = *tcpAddr log.Println("Chunk: Server addr: ", args.ChunkServerIP) if logging { err := os.Mkdir("log", 0777) if err != nil { log.Println(err.String()) logging = false } err = logger.Init("log/chunk-log-"+host+".txt", "../logger/") if err != nil { log.Println(err.String()) logging = false } } logger.QuickInit() go sigHandler() master, err := rpc.Dial("tcp", masterAddress+":1338") if master != nil { defer master.Close() } if err != nil { log.Fatal("chunk dial error:", err) } err = master.Call("Master.BirthChunk", &args, &ret) if err != nil { log.Fatal("chunk call error: ", err) } chunkServerID = ret.ChunkServerID tmpS := new(Server) tmpRet := new(sfs.ReplicateChunkReturn) if ret.ChunksToGet != nil { for cnt := 0; cnt < len(ret.ChunksToGet); cnt++ { tmpS.ReplicateChunk(&(ret.ChunksToGet[cnt]), tmpRet) } } }
/* delete */ func Delete(filename string) int { _, present := openFiles[filename] if !present { // log.Println("Client: filename does not exist ", filename); // return FAIL } else { var dummy file openFiles[filename] = &dummy, false } client, err := rpc.Dial("tcp", master+":1338") //IP needs to be changed to Master's IP defer client.Close() if err != nil { log.Println("Client: Dial Error", err) return FAIL } else { fileArgs := new(sfs.DeleteArgs) fileInfo := new(sfs.DeleteReturn) fileArgs.Name = filename err := client.Call("Master.DeleteFile", &fileArgs, &fileInfo) if err != nil || !fileInfo.Status { log.Println("Client: Delete fail ", fileInfo.Status, err) return FAIL } } return WIN }
func dialServer(address string) (*rpc.Client, os.Error) { server, err := rpc.Dial("tcp", address) if err != nil { log.Println("Client: Dial Error to", address, err.String()) } return server, err }
func Open(filename string, flag int) int { client, err := rpc.Dial("tcp", master+":1338") //IP needs to be changed to Master's IP if err != nil { log.Printf("Client: Error", err.String()) os.Exit(1) return FAIL } else { fileInfo := new(sfs.OpenReturn) fileArgs := new(sfs.OpenArgs) fileArgs.Name = filename // fileArgs.Size = 0; err := client.Call("Master.ReadOpen", &fileArgs, &fileInfo) if err != nil { log.Fatal("Client: Open fail ", err) } if fileInfo.New { log.Printf("Client: New file!\n") } else { log.Printf("Client: Old file!\n") } fd++ var nextFile file nextFile.size = fileInfo.Size nextFile.filePtr = 0 nextFile.name = filename nextFile.chunkInfo = new(vector.Vector) for i := 0; i < cap(fileInfo.Chunk); i++ { nextFile.chunkInfo.Push(fileInfo.Chunk[i]) } openFiles[fd] = nextFile return fd } return FAIL }
func AddChunks(fileName string, numChunks uint64, hash []byte) (int, sfs.ChunkInfo, bool) { var args sfs.GetNewChunkArgs var returnVal sfs.GetNewChunkReturn args.Name = fileName args.Count = numChunks args.Hash = hash // log.Printf("AddChunks: getting chunk for file %s with hash %x\n", fileName, args.Hash) masterConn, err := rpc.Dial("tcp", master+":1338") if err != nil { log.Println("Error Dialing Master(AddChunks):", err) return sfs.FAIL, returnVal.Info, returnVal.NewChunk } err = masterConn.Call("Master.GetNewChunk", &args, &returnVal) if err != nil { log.Println("Error Calling Master(AddChunks):", err) return sfs.FAIL, returnVal.Info, returnVal.NewChunk } masterConn.Close() return sfs.SUCCESS, returnVal.Info, returnVal.NewChunk }
func (t *Server) Write(args *sfs.WriteArgs, ret *sfs.WriteReturn) os.Error { requestLoad++ ret.Status = sfs.FAIL var id logger.TaskId id = logger.Start("Write") log.Println("chunk: Writing to chunk ", args.Info.ChunkID) if capacity < 1 { log.Println("chunk: Server Full!") return nil } data, present := chunkTable[args.Info.ChunkID] if !present { addedChunks.Push(args.Info) capacity-- } data.Data = args.Data.Data chunkTable[args.Info.ChunkID] = data tempServ := args.Info.Servers[0] var inRet sfs.WriteReturn for { if len(args.Info.Servers) < 2 { break } args.Info.Servers = args.Info.Servers[1:len(args.Info.Servers)] client, err := rpc.Dial("tcp", args.Info.Servers[0].String()) if err != nil { log.Println("chunk: dialing error: ", err) continue } log.Println("chunk: forwarding write to ", args.Info.Servers[0]) err = client.Call("Server.Write", &args, &inRet) client.Close() if err != nil { log.Println("chunk: server error: ", err) continue } break } ret.Info.Servers = make([]net.TCPAddr, len(inRet.Info.Servers)+1) for i := 0; i < len(ret.Info.Servers); i++ { if i < len(inRet.Info.Servers) { ret.Info.Servers[i] = inRet.Info.Servers[i] } else { ret.Info.Servers[i] = tempServ } } logger.End(id, false) ret.Status = sfs.SUCCESS return nil }
func RemoveServer(serv *server) os.Error { //Remove the Server sHeap.Remove(serv) for i := 0; i < sHeap.vec.Len(); i++ { if sHeap.vec.At(i).(*server).id == serv.id { log.Printf("master: RemoveServer: remove didn't actually remove server %d! Busto Rhymes\n", serv.id) return nil } } servers[serv.id] = &server{}, false addrToServerMap[serv.addr.String()] = &server{}, false str1 := fmt.Sprintf("removing server %s:%d", serv.addr.IP.String(), serv.addr.Port) ////////////////////////////////////////////////////////////////////// //////////// THIS IS A PROBLEM -- NEED TO SPREAD REPLICATION REQS ////////////////////////////////////////////////////////////////////// otherserver := sHeap.vec.At(0).(*server) str := fmt.Sprintf("%s:%d", otherserver.addr.IP.String(), otherserver.addr.Port) log.Printf("master: RemoveServer: dialing %s\n", str) client, err := rpc.Dial("tcp", str) if err != nil { log.Printf("master: RemoveServer: unable to dial %s\n", str) } else { log.Printf("master: RemoveServer: dial %s succeeded\n", str) } //for each chunk in the server, make a replication call. for cnt := 0; cnt < serv.chunks.Len(); cnt++ { chunk := serv.chunks.At(cnt).(*chunk) //populate chunk location vector chunklist := make([]net.TCPAddr, chunk.servers.Len()) for cnt1 := 0; cnt1 < chunk.servers.Len(); cnt1++ { chunklist[cnt1] = chunk.servers.At(cnt1).(*server).addr } //send rpc call off args := &sfs.ReplicateChunkArgs{chunk.chunkID, chunklist} reply := new(sfs.ReplicateChunkReturn) log.Printf("master: RemoveServer: issuing replication req to %s\n", str) err = client.Call("Server.ReplicateChunk", args, reply) if err != nil { log.Printf("master: RemoveServer: unable to call %s\n", str) } log.Printf("%s", reply) } log.Printf("RemoveServer: removing %s\n", str1) return nil }
func tryToConnect(network, address string) (client *rpc.Client, err os.Error) { t := 0 for { client, err = rpc.Dial(network, address) if err != nil && t < 1000 { time.Sleep(10e6) // wait 10 milliseconds t += 10 continue } break } return }
func (t *Server) ReplicateChunk(args *sfs.ReplicateChunkArgs, ret *sfs.ReplicateChunkReturn) os.Error { requestLoad++ if args.Servers == nil { log.Println("chunk: replication call: nil address.") return nil } log.Println("chunk: replication request chunk", args.ChunkID) _, present := chunkTable[args.ChunkID] if present { log.Println("chunk: already have it!") return nil } for i := 0; i < len(args.Servers); i++ { if args.Servers[i].String() == tcpAddr.String() { continue } replicationHost, err := rpc.Dial("tcp", args.Servers[i].String()) if replicationHost != nil { defer replicationHost.Close() } if err != nil { log.Println("chunk: replication error", err) continue } var readArgs sfs.ReadArgs var readRet sfs.ReadReturn readArgs.ChunkID = args.ChunkID readArgs.Nice = sfs.FORCE log.Println("chunk: replicating from", args.Servers[i]) err = replicationHost.Call("Server.Read", &readArgs, &readRet) if err != nil { log.Println("chunk: replication error", err) continue } log.Println("chunk: replication complete") chunkTable[args.ChunkID] = readRet.Data var info sfs.ChunkInfo info.ChunkID = readArgs.ChunkID addedChunks.Push(info) capacity-- break } return nil }
func (t *Server) Write(args *sfs.WriteArgs, ret *sfs.WriteReturn) os.Error { log.Println("chunk: Writing to chunk ", args.Info.ChunkID) data, present := chunkTable[args.Info.ChunkID] if !present { addedChunks.Push(args.Info) capacity-- } data.Data = args.Data.Data chunkTable[args.Info.ChunkID] = data tempServ := args.Info.Servers[0] var inRet sfs.WriteReturn for { if len(args.Info.Servers) < 2 { break } args.Info.Servers = args.Info.Servers[1:len(args.Info.Servers)] client, err := rpc.Dial("tcp", args.Info.Servers[0].String()) if err != nil { log.Printf("chunk: dialing:", err) continue } err = client.Call("Server.Write", &args, &inRet) if err != nil { log.Fatal("chunk: server error: ", err) } break } ret.Info.Servers = make([]net.TCPAddr, len(inRet.Info.Servers)+1) for i := 0; i < len(ret.Info.Servers); i++ { if i < len(inRet.Info.Servers) { ret.Info.Servers[i] = inRet.Info.Servers[i] } else { ret.Info.Servers[i] = tempServ } } return nil }
/* read */ func Read(fd int, size int) ([]byte, int) { //goes to chunk and gets a chunk of memory to read... fileInfo := new(sfs.ReadReturn) fileArgs := new(sfs.ReadArgs) fdFile, inMap := openFiles[fd] var entireRead []byte //this size needs to be fixed entireRead = make([]byte, fdFile.chunkInfo.Len()*sfs.CHUNK_SIZE) if !inMap { log.Printf("Client: File not in open list!\n") return entireRead, FAIL } index := 0 for i := 0; i < fdFile.chunkInfo.Len(); i++ { if len(fdFile.chunkInfo.At(i).(sfs.ChunkInfo).Servers) < 1 { log.Fatal("Client: No servers listed") } client, err := rpc.Dial("tcp", fdFile.chunkInfo.At(i).(sfs.ChunkInfo).Servers[0].String()) if err != nil { log.Printf("Client: Dial Failed in Read") return entireRead, FAIL } fileArgs.ChunkID = fdFile.chunkInfo.At(i).(sfs.ChunkInfo).ChunkID chunkCall := client.Go("Server.Read", &fileArgs, &fileInfo, nil) replyCall := <-chunkCall.Done if replyCall.Error != nil { log.Printf("Client: error in reply from rpc in read\n") return entireRead, FAIL } log.Printf("\nClient: Status = %d\n", fileInfo.Status) log.Printf("Client: Data = %d\n", fileInfo.Data) if fileInfo.Status != 0 { break } for j := 0; j < sfs.CHUNK_SIZE; j++ { entireRead[j] = fileInfo.Data.Data[j] index++ } } return entireRead, fileInfo.Status }
func ReadDir(path string) ([]string, int) { readDirArgs := new(sfs.ReadDirArgs) readDirRet := new(sfs.ReadDirReturn) readDirArgs.Prefix = path client, err := rpc.Dial("tcp", master+":1338") //IP needs to be changed to Master's IP defer client.Close() if err != nil { log.Println("Client: Dial Error", err) return readDirRet.FileNames, FAIL } else { err = client.Call("Master.ReadDir", &readDirArgs, &readDirRet) if err != nil { log.Println("Client: Read Dir fail ", err) return readDirRet.FileNames, FAIL } } // for i:= 0 ; i < len(readDirRet.FileNames) ; i++ { // log.Println("Client: Got back directory: ", readDirRet.FileNames[i]) // } return readDirRet.FileNames, WIN }
func clientFunc() int { addr := *addr if *sock == "unix" { addr = getSocketFilename() } // client client, err := rpc.Dial(*sock, addr) if err != nil { err = tryRunServer() if err != nil { fmt.Printf("%s\n", err.String()) return 1 } client, err = tryToConnect(*sock, addr) if err != nil { fmt.Printf("%s\n", err.String()) return 1 } } defer client.Close() if flag.NArg() > 0 { switch flag.Arg(0) { case "autocomplete": cmdAutoComplete(client) case "close": cmdClose(client) case "status": cmdStatus(client) case "drop-cache": cmdDropCache(client) case "set": cmdSet(client) } } return 0 }
func main() { serverAddress := flag.Arg(0) client, err := rpc.Dial("tcp", serverAddress+":1337") if err != nil { log.Fatal("dialing:", err) } var ret sfs.WriteReturn var args sfs.WriteArgs args.Info.ChunkID = 12 args.Data.Data[0] = 'a' err = client.Call("Server.Write", &args, &ret) if err != nil { log.Fatal("chunk server error: ", err) } var rdRet sfs.ReadReturn var rdArgs sfs.ReadArgs rdArgs.ChunkIDs = 12 err = client.Call("Server.Read", &rdArgs, &rdRet) if err != nil { log.Fatal("chunk server error: ", err) } if rdRet.Status == -1 { log.Fatal("FAILURE of read call") } if args.Data.Data[0] != rdRet.Data.Data[0] { fmt.Println(args.Data.Data[0], " VS ", rdRet.Data.Data[0]) log.Fatal("Data doesnt match!!!") } }
func AddChunks(fileName string, numChunks uint64) sfs.ChunkInfo { var args sfs.GetNewChunkArgs var returnVal sfs.GetNewChunkReturn args.Name = fileName args.Count = numChunks masterConn, err := rpc.Dial("tcp", master+":1338") if err != nil { log.Printf("Error Dialing Master(AddChunks):", err.String()) os.Exit(1) } err = masterConn.Call("Master.GetNewChunk", &args, &returnVal) if err != nil { log.Printf("Error Calling Master(AddChunks):", err.String()) os.Exit(1) } return returnVal.Info }
func Init(masterAddress string) { var args sfs.ChunkBirthArgs var ret sfs.ChunkBirthReturn args.Capacity = 5 host, _ := os.Hostname() _, iparray, _ := net.LookupHost(host) tcpAddr, _ := net.ResolveTCPAddr(iparray[0] + ":1337") args.ChunkServerIP = *tcpAddr log.Println(args.ChunkServerIP) master, err := rpc.Dial("tcp", masterAddress+":1338") if err != nil { log.Fatal("chunk dial error:", err) } err = master.Call("Master.BirthChunk", &args, &ret) if err != nil { log.Fatal("chunk call error: ", err) } chunkServerID = ret.ChunkServerID }
func RemoveDir(path string) int { var args sfs.RemoveDirArgs var returnVal sfs.RemoveDirReturn args.DirName = path masterConn, err := rpc.Dial("tcp", master+":1338") defer masterConn.Close() if err != nil { log.Println("Error Dialing Master(Remove Dir):", err) return sfs.FAIL } err = masterConn.Call("Master.RemoveDir", &args, &returnVal) if err != nil { log.Println("Error Calling Master(RemoveDir):", err) return sfs.FAIL } return returnVal.Status }
func GetChunk(fdFile file, chunkOffset int) (int, [sfs.CHUNK_SIZE]byte) { log.Println("Client: Getting Chunk", fdFile.chunkInfo.At(chunkOffset).(sfs.ChunkInfo).ChunkID) fileArgsRead := new(sfs.ReadArgs) fileInfoRead := new(sfs.ReadReturn) fileArgsRead.Nice = 1 // try things nicely first Servers := fdFile.chunkInfo.At(chunkOffset).(sfs.ChunkInfo).Servers numServers := len(Servers) for i := 0; i < (numServers * 2); i++ { if i >= numServers { fileArgsRead.Nice = 0 } client, err := rpc.Dial("tcp", Servers[i%numServers].String()) if client == nil { log.Println("Client: Dial Failed in GetChunk client == nil ") if i != (numServers*2)-1 { continue } else { log.Println("Client: missed continue in GetChunk ") return sfs.FAIL, fileInfoRead.Data.Data } } //defer client.Close() if err != nil { log.Println("Client: Dial Failed in GetChunk err != nil ", err) if i != (numServers*2 - 1) { continue } else { log.Println("Client: missed continue in GetChunk ") return sfs.FAIL, fileInfoRead.Data.Data } } fileArgsRead.ChunkID = fdFile.chunkInfo.At(chunkOffset).(sfs.ChunkInfo).ChunkID if fileArgsRead.ChunkID == 0 { log.Println("Client: ChunkID = 0, Chunk ID should never be 0") } err = client.Call("Server.Read", &fileArgsRead, &fileInfoRead) client.Close() if err != nil { log.Printf("Client: Server.Read failed: %s, on server %s\n", err.String(), Servers[i%numServers].String()) log.Printf("On try %d out of %d with %d# of servers\n", i, (numServers*2 - 1), numServers) if i != (numServers*2 - 1) { continue } return sfs.FAIL, fileInfoRead.Data.Data } if fileInfoRead.Status != sfs.SUCCESS { log.Println("Client: Read failed with status", fileInfoRead.Status, "on server", Servers[i%numServers]) if i != (numServers*2 - 1) { continue } return sfs.FAIL, fileInfoRead.Data.Data } else { break } log.Println("At end of function with status ", fileInfoRead.Status) } log.Println("Client: Read chunk", fileArgsRead.ChunkID) return sfs.SUCCESS, fileInfoRead.Data.Data }
func Open(filename string, flag int) int { log.Println("Client: opening ", filename) client, err := rpc.Dial("tcp", master+":1338") //IP needs to be changed to Master's IP if err != nil { log.Println("Client: Dial Error ", err) return FAIL } else { defer client.Close() _, openF := openFiles[filename] if !openF { fileInfo := new(sfs.OpenReturn) fileArgs := new(sfs.OpenArgs) fileArgs.Lock = false fileArgs.Name = filename if (flag & O_CREATE) == O_CREATE { log.Println("Client: Permissions for New file!") fileArgs.NewFile = true } else { fileArgs.NewFile = false } err := client.Call("Master.ReadOpen", &fileArgs, &fileInfo) if err != nil { log.Println("Client: Open fail ", err) return sfs.FAIL } if fileInfo.New && (flag&O_CREATE) == O_CREATE { log.Println("Client: New file!") } else if !fileInfo.New && (flag&O_CREATE) != O_CREATE { log.Println("Client: Old file!") } else { return sfs.FAIL } fd++ var nextFile file nextFile.size = 0 nextFile.name = filename nextFile.chunkInfo = new(vector.Vector) for i := 0; i < cap(fileInfo.Chunk); i++ { nextFile.chunkInfo.Push(fileInfo.Chunk[i]) nextFile.size += fileInfo.Chunk[i].Size } openFiles[filename] = &nextFile var d nameAndPtr d.name = filename d.filePtr = 0 d.permissions = flag openDescriptors[fd] = &d } else { fileInfo := new(sfs.OpenReturn) fileArgs := new(sfs.OpenArgs) fileArgs.Lock = false fileArgs.Name = filename err := client.Call("Master.ReadOpen", &fileArgs, &fileInfo) if err != nil { log.Println("Client: Open fail ", err) return sfs.FAIL } var nextFile file nextFile.size = 0 nextFile.name = filename nextFile.chunkInfo = new(vector.Vector) for i := 0; i < cap(fileInfo.Chunk); i++ { nextFile.chunkInfo.Push(fileInfo.Chunk[i]) } nextFile.size = openFiles[filename].size openFiles[filename] = &nextFile fd++ var d nameAndPtr d.name = filename d.permissions = flag d.filePtr = 0 openDescriptors[fd] = &d } return fd } return sfs.FAIL }
func main() { defer func() { if !*debug { if bad := recover(); bad != nil { fmt.Println(bad) } } }() flag.Parse() // Check for new versions of the client application. var upChan chan os.Error if *up { upChan = CheckForUpdates() } err := getConfig() if err != nil { err = genConfig() if err != nil { panic(err) } fmt.Println("\"" + user + "\":\"" + sekrit + "\"") return } r, e := rpc.Dial("tcp", host) if e != nil { fmt.Println("Cannot connect to server: " + host) os.Exit(-1) } remote := &LunchServer{r} dest, err := strconv.Atoi(flag.Arg(0)) var poll *LunchPoll switch { case *version: fmt.Printf("Go2Lunch %s\n", clientVersion) case *seats != 0: remote.drive(*seats) case *walk: remote.undrive() case *add: name := strings.Join(flag.Args(), " ") dest = remote.addPlace(name) case *del: remote.delPlace(dest) case *unvote: remote.unvote() case dest != 0: remote.vote(dest) case *comment: comment := strings.Join(flag.Args(), " ") remote.comment(comment) default: poll = remote.displayPlaces() } if poll != nil { if *printJson { out, err := json.Marshal(poll) if err != nil { panic(err.String()) } fmt.Println(string(out)) } else { for i, p := range poll.Places { if i != 0 || *noVotes { ppPlace(p) } } } } if *up { upErr := <-upChan if upErr != nil { panic(upErr) } } }
func SendHeartbeat(masterAddress string) { var args sfs.HeartbeatArgs var ret sfs.HeartbeatReturn master, err := rpc.Dial("tcp", masterAddress+":1338") if master != nil { defer master.Close() } if err != nil { log.Fatal("chunk: dialing:", err) } host, _ := os.Hostname() _, iparray, _ := net.LookupHost(host) tcpAddr, _ := net.ResolveTCPAddr(iparray[0] + ":1337") args.ChunkServerIP = *tcpAddr args.ChunkServerID = chunkServerID for { var id logger.TaskId if logging { id = logger.Start("Heart") } args.Capacity = capacity addedChunkSlice := make([]sfs.ChunkInfo, addedChunks.Len()) for i := 0; i < addedChunks.Len(); i++ { addedChunkSlice[i] = addedChunks.At(i).(sfs.ChunkInfo) } args.AddedChunks = addedChunkSlice err = master.Call("Master.BeatHeart", &args, &ret) if err != nil { log.Fatal("chunk: heartbeat error: ", err) } if ret.Accepted == false { var bArgs sfs.ChunkBirthArgs var bRet sfs.ChunkBirthReturn host, _ := os.Hostname() _, iparray, _ := net.LookupHost(host) tcpAddr, _ := net.ResolveTCPAddr(iparray[0] + ":1337") bArgs.ChunkServerIP = *tcpAddr bArgs.ChunkIDs = make([]uint64, len(chunkTable)) i := 0 for k, _ := range chunkTable { bArgs.ChunkIDs[i] = k i++ } log.Println("chunk: heartbeat") err = master.Call("Master.BirthChunk", &bArgs, &bRet) if err != nil { log.Fatal("chunk call error:", err) } chunkServerID = bRet.ChunkServerID } else if ret.ChunksToRemove != nil { for i := 0; i < ret.ChunksToRemove.Len(); i++ { chunkTable[ret.ChunksToRemove.At(i).(uint64)] = sfs.Chunk{}, false capacity++ } } addedChunks.Resize(0, 0) if logging { errString := logger.End(id, false) if errString != "" { logging = false } } //addCount(requestLoad) requestLoad = 0 time.Sleep(sfs.HEARTBEAT_WAIT) } return }
/* write */ func Write(fd int, data []byte) int { log.Println("Client: *************WRITE BEGIN**********") masterServ, masterErr := rpc.Dial("tcp", master+":1338") if masterErr != nil { log.Println("Client: dial fail: ", masterErr) return FAIL } if masterServ == nil { return FAIL } nameAndPointer, inMap := openDescriptors[fd] if !inMap { log.Println("Client: fd does not exist") return sfs.FAIL } filename := nameAndPointer.name filePtr := nameAndPointer.filePtr fdFile, inMap := openFiles[filename] if !inMap { log.Println("Client: File not in open list!") return FAIL } log.Println("Client: fileName ", fdFile.name) log.Println("Client: filestarting size = ", fdFile.size) if (nameAndPointer.permissions & O_WRONLY) != O_WRONLY { log.Println("Client: Cannot write without write permissions") return FAIL } indexWithinChunk := int(filePtr) % int(sfs.CHUNK_SIZE) chunkOffset := int(filePtr) / int(sfs.CHUNK_SIZE) var toWrite sfs.Chunk //special case if writing to middle of first chunk if (indexWithinChunk > 0) && (filePtr <= fdFile.size) { returned, bytesRead := GetChunk(*fdFile, chunkOffset) if returned == sfs.SUCCESS { for i := 0; i < indexWithinChunk; i++ { toWrite.Data[i] = bytesRead[i] } } else { log.Println("Client: Dial Failed in GetChunk trying to get beginning of first chunk") return FAIL } } fileArgs := new(sfs.WriteArgs) fileInfo := new(sfs.WriteReturn) for i := 0; i < len(data); i++ { toWrite.Data[int(indexWithinChunk)] = data[i] indexWithinChunk++ if indexWithinChunk == sfs.CHUNK_SIZE || i == len(data)-1 { //special case if write to middle of last chunk if i == len(data)-1 && fdFile.size > (filePtr+uint64(len(data))) && indexWithinChunk != sfs.CHUNK_SIZE { returned, bytesRead := GetChunk(*fdFile, chunkOffset) if returned == sfs.SUCCESS { // log.Println("BEFORE", toWrite.Data) // log.Println("READ", bytesRead) for i := indexWithinChunk; i < sfs.CHUNK_SIZE; i++ { toWrite.Data[i] = bytesRead[i] } // log.Println("AFTER", toWrite.Data) } else { log.Println("Client: Dial Failed in GetChunk trying to get beginning of last chunk", fdFile.size, "ptr", filePtr, "idx", indexWithinChunk) return FAIL } } hasher := sha256.New() hasher.Write(toWrite.Data[:]) if len(toWrite.Data) < sfs.CHUNK_SIZE { hasher.Write(make([]byte, (sfs.CHUNK_SIZE - len(toWrite.Data)))) } returned, toPush, newChunk := AddChunks(fdFile.name, 1, hasher.Sum()) if fdFile.chunkInfo.Len() <= chunkOffset { if returned == sfs.FAIL { log.Println("AddChunk failed 1") return sfs.FAIL } fdFile.chunkInfo.Push(toPush) log.Println("Client: adding chunk x") } else { if returned == sfs.FAIL { log.Println("AddChunk failed 1") return sfs.FAIL } fdFile.chunkInfo.Set(chunkOffset, toPush) log.Println("Client: adding chunk y") } log.Println("new chunk ? ", newChunk) if newChunk { fileArgs.Info = fdFile.chunkInfo.At(chunkOffset).(sfs.ChunkInfo) fileArgs.Data = toWrite if len(fdFile.chunkInfo.At(chunkOffset).(sfs.ChunkInfo).Servers) < 1 { log.Println("fdFile.chunkInfo ", fdFile.chunkInfo) } servers := fdFile.chunkInfo.At(chunkOffset).(sfs.ChunkInfo).Servers numChunkServers := len(servers) if numChunkServers < 1 { log.Println("Client: Dial Failed in Write") return sfs.FAIL } log.Println("Client: numChunkServers ", numChunkServers) for j := 0; j < (numChunkServers); j++ { client, err := rpc.Dial("tcp", servers[0].String()) if err != nil || client == nil { log.Println("Client: Dial to chunk failed, returned bad client", err) numServers := len(fileArgs.Info.Servers) tmp := fileArgs.Info.Servers[0] for n := 0; n < numServers-1; n++ { fileArgs.Info.Servers[n] = fileArgs.Info.Servers[n+1] } fileArgs.Info.Servers[numServers-1] = tmp if j == numChunkServers-1 { return sfs.FAIL } continue } err = client.Call("Server.Write", &fileArgs, &fileInfo) client.Close() if err != nil { log.Println("Client: Server.Write failed:", err) /* numServers := len(fileArgs.Info.Servers) tmp := fileArgs.Info.Servers[numServers-1] for n:=0 ; n<numServers -1 ; n++{ fileArgs.Info.Servers[n+1] = fileArgs.Info.Servers[n] } fileArgs.Info.Servers[0] = tmp */ if j == numChunkServers-1 { return sfs.FAIL } continue } if fileInfo.Status != 0 { log.Println("Client: Server.Write status non zero=", fileInfo.Status) if j == numChunkServers-1 { return sfs.FAIL } continue } log.Println("Client: Wrote chunk", fileArgs.Info.ChunkID) //, "with", fileArgs.Data) break } } else { fileArgs.Info = toPush } // reply to master fileInfo.Info.ChunkID = fileArgs.Info.ChunkID fileInfo.Info.Hash = hasher.Sum() fileInfo.Info.Size = uint64(((indexWithinChunk - 1) % int(sfs.CHUNK_SIZE)) + 1) mapArgs := &sfs.MapChunkToFileArgs{fdFile.name, chunkOffset, fileInfo.Info} var mapRet sfs.MapChunkToFileReturn err := masterServ.Call("Master.MapChunkToFile", &mapArgs, &mapRet) if err != nil { log.Println("Client: Master.MapChunkToFile failed:", err) return FAIL } chunkOffset++ indexWithinChunk = 0 } } if masterServ != nil { masterServ.Close() } if fileInfo.Status != FAIL && (openDescriptors[fd].filePtr+uint64(len(data)) > openFiles[filename].size) { openFiles[filename].size = openDescriptors[fd].filePtr + uint64(len(data)) } if openFiles[filename].size > fdFile.size { openFiles[filename].size = fdFile.size } openDescriptors[fd].filePtr += uint64(len(data)) if openDescriptors[fd].filePtr > fdFile.size { openDescriptors[fd].filePtr = fdFile.size } log.Println("Client: file ending size ", openFiles[filename].size) log.Println("Client: fileInfo.Status = ", fileInfo.Status) log.Println("Client: ************WRITE END**************") return fileInfo.Status }
func RemoveServer(serv *server) os.Error { log.Printf("master: RemoveServer: server heap pre removal:\n%s\n", sHeap.printPresent()) //Remove the Server sHeap.Remove(serv) log.Printf("master: RemoveServer: server heap post removal:\n%s\n", sHeap.printPresent()) for i := 0; i < sHeap.vec.Len(); i++ { if sHeap.vec.At(i).(*server).id == serv.id { log.Printf("master: RemoveServer: remove didn't actually remove server %d! Busto Rhymes\n", serv.id) return nil } } str := fmt.Sprintf("%s:%d", serv.addr.IP.String(), serv.addr.Port) servers[serv.id] = &server{}, false addrToServerMap[str] = &server{}, false str1 := fmt.Sprintf("removing server %s:%d", serv.addr.IP.String(), serv.addr.Port) log.Printf("master: RemoveServer: begin %s\n", str1) network_size := float64(sHeap.vec.Len()) if network_size <= 0 { return nil } //chunk_size := serv.chunks.Len() rep_factor := .9 //map the size of the network to some fraction of that size to replicate to if network_size < 10 { rep_factor = .5 } else { rep_factor = .3 } rep_size := int(math.Fmin(math.Ceil(rep_factor*network_size), network_size)) //for each chunk in the server, make a replication call sanity_threshhold1 := 4 sanity_threshhold2 := 10 sanity_count := 0 targetServerMap := make(map[string](bool)) ChunkReplicate: for cnt := 0; cnt < serv.chunks.Len(); { var index int if sanity_count > sanity_threshhold1 { index = rand.Intn(rep_size) } else { index = rand.Intn(sHeap.vec.Len()) } otherserver := sHeap.vec.At(index).(*server) chunk := serv.chunks.At(cnt).(*chunk) str := fmt.Sprintf("%s:%d", otherserver.addr.IP.String(), otherserver.addr.Port) sCnt := chunk.servers.Len() if sCnt >= len(servers) { log.Printf("master: RemoveServer: abort replication req for chunk %d; all active servers already hold replicas\n", chunk.chunkID) cnt++ sanity_count = 0 targetServerMap = make(map[string](bool)) } if targetServerMap[str] == true { continue } for ijk := 0; ijk < sCnt; ijk++ { if chunk.servers.At(ijk).(*server) == otherserver { targetServerMap[str] = true if len(targetServerMap) >= len(servers) { log.Printf("master: RemoveServer: abort replication req for chunk %d; all active servers already hold replicas\n", chunk.chunkID) cnt++ sanity_count = 0 targetServerMap = make(map[string](bool)) } continue ChunkReplicate } } log.Printf("master: RemoveServer: attempting to replicate chunk %d to server %s\n", chunk.chunkID, str) //log.Printf("master: RemoveServer: dialing %s to replicate\n", str) client, err := rpc.Dial("tcp", str) if err != nil { log.Printf("master: RemoveServer: unable to dial %s\n", str) sanity_count = sanity_count + 1 continue } else { log.Printf("master: RemoveServer: dial %s succeeded\n", str) } if sanity_count > sanity_threshhold2 { log.Printf("master: RemoveServer: tried %d times to dial servers to replicate, and gave up!!!!\n", sanity_threshhold2) break } //populate chunk location vector chunklist := make([]net.TCPAddr, chunk.servers.Len()) for cnt1 := 0; cnt1 < chunk.servers.Len(); cnt1++ { chunklist[cnt1] = chunk.servers.At(cnt1).(*server).addr } //send rpc call off args := &sfs.ReplicateChunkArgs{chunk.chunkID, chunklist} reply := new(sfs.ReplicateChunkReturn) log.Printf("master: RemoveServer: issuing replication req to %s\n", str) err = client.Call("Server.ReplicateChunk", args, reply) if err != nil { log.Printf("master: RemoveServer: unable to call %s\n", str) client.Close() continue } //log.Printf("%s", reply) client.Close() cnt++ sanity_count = 0 targetServerMap = make(map[string](bool)) } log.Printf("master: RemoveServer: finished %s\n", str1) log.Printf("master: RemoveServer: server heap post replication:\n%s\n", sHeap.printPresent()) str2 := fmt.Sprintf("%s:%d", serv.addr.IP.String(), serv.addr.Port) _, test1 := servers[serv.id] _, test2 := addrToServerMap[str2] if test1 == true || test2 == true { log.Printf("REMOVESERVER :: server (%s) with id (%d) :: serverMap (%v) :: addrMap (%v)", str1, serv.id, test1, test2) } return nil }
/* write */ func Write(fd int, data []byte) int { ///* fileArgs := new(sfs.WriteArgs) fileInfo := new(sfs.WriteReturn) fdFile, inMap := openFiles[fd] if !inMap { log.Printf("Client: File not in open list!\n") return FAIL } var indexWithinChunk int indexWithinChunk = int(fdFile.filePtr) % int(sfs.CHUNK_SIZE) chunkOffset := int(fdFile.filePtr) / int(sfs.CHUNK_SIZE) sizeToWrite := uint64(len(data)) // if((fdFile.size %sfs.CHUNK_SIZE)!= 0){ // numChunks++ // } //find capacity and add section of write to fill up remaining capacity // for(i:= 0 ; i < indexWithinChunk ; i++){ // toWrite.Data // } var toWrite sfs.Chunk for i := 0; i < len(data); i++ { toWrite.Data[int(indexWithinChunk)] = data[i] indexWithinChunk++ if indexWithinChunk == sfs.CHUNK_SIZE || i == len(data)-1 { if fdFile.chunkInfo.Len() <= chunkOffset+1 { fdFile.chunkInfo.Push(AddChunks(fdFile.name, 1)) } if fdFile.chunkInfo.At(chunkOffset).(sfs.ChunkInfo).ChunkID == 0 { fdFile.chunkInfo.Set(chunkOffset, AddChunks(fdFile.name, 1)) } if (i != fdFile.chunkInfo.Len()-1) || (sizeToWrite%sfs.CHUNK_SIZE == 0) { //fileArgs.Length = sfs.CHUNK_SIZE; } else { //fileArgs.Length =uint(sizeToWrite)% uint(sfs.CHUNK_SIZE) } fileArgs.Info = (fdFile.chunkInfo.At(chunkOffset).(sfs.ChunkInfo)) fileArgs.Data = toWrite //fileArgs.Offset = 0; if len(fdFile.chunkInfo.At(chunkOffset).(sfs.ChunkInfo).Servers) < 1 { log.Fatal("fdFile.chunkInfo ", fdFile.chunkInfo) } client, err := rpc.Dial("tcp", fdFile.chunkInfo.At(chunkOffset).(sfs.ChunkInfo).Servers[0].String()) if err != nil { log.Fatal("Client: dial fail:", err) } err = client.Call("Server.Write", &fileArgs, &fileInfo) if err != nil { log.Fatal("Client: error in reply from rpc in write\n") } if fileInfo.Status != 0 { log.Fatal("Client: Status non zero =", fileInfo.Status) } // reply to master fileInfo.Info.ChunkID = fileArgs.Info.ChunkID mapArgs := &sfs.MapChunkToFileArgs{fdFile.name, chunkOffset, fileInfo.Info} log.Println("what is this", mapArgs) var mapRet sfs.MapChunkToFileReturn masterServ, err := rpc.Dial("tcp", master+":1338") if err != nil { log.Fatal("Client: dial fail:", err) } err = masterServ.Call("Master.MapChunkToFile", &mapArgs, &mapRet) if err != nil { log.Fatal("Client: error in reply from rpc in write\n") } chunkOffset++ indexWithinChunk = 0 if fdFile.chunkInfo.Len() < chunkOffset { fdFile.chunkInfo.Push(AddChunks(fdFile.name, 1)) //toWrite = new(sfs.Chunk) for c := 0; c < sfs.CHUNK_SIZE; c++ { toWrite.Data[c] = 0 } } } } //*/ return fileInfo.Status }