def recv_inactive_osd(): recv_inactive_osd_socket = socket.socket() print ("inactive osd listener socket successfully created") recv_inactive_osd_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # reserve a port on your computer port = OSD_INACTIVE_STATUS_PORT # Next bind to the port # we have not entered any ip in the ip field # instead we have inputted an empty string # this makes the server listen to requests # coming from other computers on the network recv_inactive_osd_socket.bind(('', port)) print ("inactive osd listener socket bound to %s" %(port)) # put the socket into listening mode recv_inactive_osd_socket.listen(5) print ("inactive osd listener socket is listening") # a forever loop until we interrupt it or # an error occurs while True: # Establish connection with client. c, addr = recv_inactive_osd_socket.accept() print ('Got connection from', addr) # recv the inactive osd osd = _recv_msg(c, 1024) # START THE RECOVERY recv_inactive_osd_socket.close()
def heartbeat_protocol(soc, live_osd): # Establish connection with client. c, addr = soc.accept() print(f"\nGot connection from {addr}") n = os.fork() if n == 0: print(F"Inside child process {os.getpid()}") msg = _recv_msg(c, MSG_SIZE) print(msg) if msg == None: print(f"Didn't receive data! [Timeout] {addr}") elif msg["type"] == "ALIVE": res = {"type": "ACK"} _send_msg(c, res) elif msg["type"] == "FAIL": res = {"type": "ACK"} _send_msg(c, res) gossip(c, msg, live_osd) c.close() print(f"Exiting from pid {os.getpid()} ..\n") os._exit(1) return
def recv_primary_update(): recv_primary_update_socket = socket.socket() print("recv primary update socket successfully created") recv_primary_update_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # reserve a port on your computer port = RECV_PRIMARY_UPDATE_PORT # Next bind to the port # we have not entered any ip in the ip field # instead we have inputted an empty string # this makes the server listen to requests # coming from other computers on the network recv_primary_update_socket.bind(('', port)) print("primary update socket bound to %s" % (port)) # put the socket into listening mode recv_primary_update_socket.listen(5) print("primary update socket is listening") # a forever loop until we interrupt it or # an error occurs while True: # Establish connection with osd c, addr = recv_primary_update_socket.accept() print('Got connection from', addr) # recv the update update = _recv_msg(c, 1024) print(update) if update["update_type"] == "hash_table": for i in range(len(update["pg_or_osd_ids_list"])): hashtable[update["pg_or_osd_ids_list"] [i]] = update["osd_list"][i] else: for i in range(len(update["pg_or_osd_ids_list"])): cluster_topology[update["pg_or_osd_ids_list"] [i]] = update["osd_list"][i] hashtable_file = open('hashtable', 'wb') hashtable_dump = pickle.dumps(hashtable) hashtable_file.write(hashtable_dump) hashtable_file.close() cluster_topology_file = open('cluster_topology', 'wb') cluster_topology_dump = pickle.dumps(cluster_topology) cluster_topology_file.write(cluster_topology_dump) cluster_topology_file.close() msg = {"status": "SUCCESS"} _send_msg(c, msg) # send the acknowledgement c.close() recv_primary_update_socket.close()
def dispatch_primary(self): while True: # Establish connection with client. print("waiting for messages..") c, addr = self.mds_socket.accept() print('Got connection from', addr) msg = {} try: msg = _recv_msg(c, MSG_SIZE) except Exception as e: print(e) c.close() continue res = {} print(msg) if msg["type"] == "CLIENT_LOGIN": res = self._login_handle(msg) print(res["msg"]) elif msg["type"] == "CLIENT_LOGOUT": res = self._logout_handle(msg) print(res["msg"]) elif msg["type"] == "WRITE_RESPONSE": res = self.update_handle(msg) print(res["msg"]) elif msg["type"] == "WRITE_QUERY": res = self._client_query_handle(msg) print(res["msg"]) elif msg["type"] == "RECOVERY": res = self._recovery_handle() print(res["msg"]) try: _send_msg(c, res) except Exception as e: print(e) finally: c.close()
def send_heartbeat(): #This will check for incoming messages #from other nodes and reply s = socket.socket() print("Socket successfully created for Heartbeat") port = storage_ip[STORAGE_ID]["port"] s.bind(('', port)) print("Socket binded to %s" % (port)) # put the socket into listening mode s.listen(5) while True: # Establish connection with client. c, addr = s.accept() print(f"\nGot connection from {addr}") n = os.fork() if n == 0: print(F"Inside child process {os.getpid()}") msg = _recv_msg(c, MSG_SIZE) print(msg) if msg == None: print(f"Didn't receive data from ip {addr}! [Timeout] ") report_monitor(addr, None) elif msg["type"] == "ALIVE": res = {"type": "ACK"} _send_msg(c, res) c.close() print(f"Exiting from pid {os.getpid()} ..\n\n") os._exit(1)
def replicate_pg(soc): # This will be always true loop that will run in parallel c, addr = soc.accept() print(f"Got connection from {addr} to do the replication") n = os.fork() if n == 0: msg = _recv_msg(c, MSG_SIZE) print(msg) if msg == None: print(f"Didn't receive data! [Timeout] {addr}") msg = {"type": "SEND AGAIN"} _send_msg(c, msg) elif msg["type"] == "REPLICATE": # Can do one thing here # call the func that act as access this pg_id for the client # then call other function that act as send this pg to osd to do a write pg_id = msg["pg_id"] osd_id = msg["osd_id"] file = open("./data/" + pg_id, 'rb') pg_b = file.read() pg = pickle.loads(pg_b) ## Connect to this osd_id with new socket new_soc = socket.socket() print( f"Socket created to send request to SAVE data at OSD {osd_id}") ip_add = storage_ip[osd_id]["ip"] port = storage_ip[osd_id]["port"] + 10 # Remember replication is on normal port + 10 try: new_soc.connect((ip_add, port)) print(f"Connection made with {ip_add} on {port}") msg = {"type": "SAVE", "pg_id": pg_id, "pg": pg} _send_msg(new_soc, msg) print("Msg send to SAVE the data") msg = _wait_recv_msg(new_soc, MSG_SIZE) print("Msg received !") except Exception as e: print(e) if msg == None: res = {"type": "REPLICATION FAIL"} _send_msg(c, res) print("Fail Msg send to the monitor") elif msg["type"] == "ACK": res = {"type": "ACK"} _send_msg(c, res) print("Success Msg send to the monitor") elif msg["type"] == "SAVE": # This will take request from other osd to save some data # This is basic replication strategy pg_id = msg["pg_id"] pg = msg["pg"] try: file = open("./data/" + pg_id, 'wb') print("Replicated data is saved") pg_dump = pickle.dump(pg) file.write(pg_dump) except Exception as e: print(e) msg = {"type": "ACK"} _send_msg(c, msg) print("Write successful..send back Ack to the master osd") else: print("[ERROR] Check the code in replication") c.close() print(f"Exiting from pid {os.getpid()} ..") os._exit(1)
def dispatch_backup(self): while True: # Establish connection with client. print("waiting for messages..") c, addr = self.mds_socket.accept() print('Got connection from', addr) msg = {} try: msg = _recv_msg(c, MSG_SIZE) except Exception as e: print(e) c.close() continue res = {"status": "", "msg": ""} print(msg) if msg["type"] == "UPD": if msg["update_type"] == "ADD_LOGIN_USER": self.logged_in.append(msg["update"]["user"]) self._write_logged_in() res["status"] = "SUCCESS" elif msg["update_type"] == "REMOVE_LOGIN_USER": self.logged_in.remove(msg["update"]["user"]) self._write_logged_in() res["status"] = "SUCCESS" elif msg["update_type"] == "WRITE_SUCCESS": username = msg["update"]["user"] tree = self._read_tree(username) pg_id = msg["update"]["pg_id"] direc = tree["processing"][pg_id][0] file_id = tree["processing"][pg_id][1] filename = tree["processing"][pg_id][2] tree["dir_tree"][direc][file_id] = [filename, [pg_id]] tree["processing"][pg_id][3] = 1 self._write_tree(username, tree) res["status"] = "SUCCESS" elif msg["update_type"] == "UPDATE_PROCESSING": username = msg["update"]["username"] pg_written = msg["update"]["pg_written"] pg_wait = msg["update"]["pg_wait"] tree = self._read_tree(username) for pg_id in pg_written: tree["processing"].pop(pg_id) for pg_id in pg_wait.keys(): tree["processing"][pg_id] = pg_wait[pg_id] self._write_tree(username, tree) res["status"] = "SUCCESS" elif msg["type"] == "RECOVERY": res = self._recovery_handle() print(res["msg"]) else: res["status"] = "ERROR" res["msg"] = "msg type not define !" try: _send_msg(c, res) except Exception as e: print(e) finally: c.close()
def recv_client_reqs(): global MY_OSD_ID recv_client_reqs_socket = socket.socket() print("client reqs socket successfully created") recv_client_reqs_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # reserve a port on your computer port = READ_WRITE_PORT # Next bind to the port # we have not entered any ip in the ip field # instead we have inputted an empty string # this makes the server listen to requests # coming from other computers on the network recv_client_reqs_socket.bind(('', port)) print("write ack socket bound to %s" % (port)) # put the socket into listening mode recv_client_reqs_socket.listen(5) print("socket is listening") # a forever loop until we interrupt it or # an error occurs while True: # Establish connection with client. c, addr = recv_client_reqs_socket.accept() print('Got connection from', addr) # recv the acknowledgement req = _recv_msg(c, 1024) print(req) if (req["type"] == "CLIENT_WRITE"): res = {"status": "RECEIVED", "msg": "data received"} _send_msg(c, res) client_id = req["client_id"] # client_addr = req["client_addr"] osd_dict = req["osd_dict"] for osd_id in osd_dict["osd_ids"]: if osd_id == MY_OSD_ID: continue # sending write update to client write_forward_socket = socket.socket() print("write forward socket successfully created") write_forward_socket.connect(osd_dict["addrs"][osd_id]) req["type"] = "OSD_WRITE" _send_msg(write_forward_socket, req) write_forward_socket.close() pg = req["pg"] file = open("./data/" + pg.pg_id, 'wb') pg_dump = pickle.dumps(pg) file.write(pg_dump) file.close() # sending write ack to monitor write_ack_socket = socket.socket() print("write forward socket successfully created") write_ack_socket.connect((MONITOR_IP, WRITE_ACK_PORT)) ack = {} ack["client_id"] = client_id # ack["client_addr"] = client_addr # addr = (ip, port) ack["pg_id"] = pg.pg_id ack["free_space"] = FREESPACE - req["size"] ack["osd_id"] = MY_OSD_ID _send_msg(write_ack_socket, ack) write_ack_socket.close() # _send_msg(c, [pg.pg_id, "SUCCESS"]) elif req["type"] == "OSD_WRITE": client_id = req["client_id"] # client_addr = req["client_addr"] pg = req["pg"] file = open("./data/" + pg.pg_id, 'wb') pg_dump = pickle.dumps(pg) file.write(pg_dump) file.close() # sending write ack to monitor write_ack_socket = socket.socket() print("write forward socket successfully created") write_ack_socket.connect((MONITOR_IP, WRITE_ACK_PORT)) ack = {} ack["client_id"] = client_id # ack["client_addr"] = client_addr # addr = (ip, port) ack["pg_id"] = pg.pg_id ack["free_space"] = FREESPACE - sys.getsizeof(pg_dump) ack["osd_id"] = MY_OSD_ID _send_msg(write_ack_socket, ack) write_ack_socket.close() elif req["type"] == "READ": pg_id = req["pg_id"] file = open("./data/" + pg_id, 'rb') pg_b = file.read() pg = pickle.loads(pg_b) file.close() # print(pg) print("sending pg to client " + str(pg_id)) msg = {"pg_id": pg.pg_id, "res": "SUCCESS", "pg": pg} _send_msg(c, msg) c.close() # print(msg) recv_client_reqs_socket.close()
def recv_write_acks(): global hashtable, cluster_topology, MDS_IP, MDS_flags write_ack_socket = socket.socket() print ("write ack socket successfully created") write_ack_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # reserve a port on your computer port = WRITE_ACK_PORT # Next bind to the port # we have not entered any ip in the ip field # instead we have inputted an empty string # this makes the server listen to requests # coming from other computers on the network write_ack_socket.bind(('', port)) print ("write ack socket bound to %s" %(port)) # put the socket into listening mode write_ack_socket.listen(5) print ("socket is listening") # a forever loop until we interrupt it or # an error occurs while True: # Establish connection with osd c, addr = write_ack_socket.accept() print ('Got connection from', addr) # recv the acknowledgement ack = _recv_msg(c, 1024) print(ack) # extracting the written pd_id, free_space, osd_id of that osd client_id = ack["client_id"] # client_addr = ack["client_addr"] # addr = (ip, port) pg_id = ack["pg_id"] free_space = ack["free_space"] osd_id = ack["osd_id"] # if the osd is down or out, make it up again # [need to check this] if cluster_topology[osd_id]["status"] != 0: cluster_topology[osd_id]["status"] = 0 # updating the write status of the osd to 1 for i in range(len(hashtable[pg_id])): if hashtable[pg_id][i][0] == osd_id: hashtable[pg_id][i][1] = 1 replication_factor = 0 # adding the new friend for osd in hashtable[pg_id]: if osd[0] != osd_id: if osd[1] == 1: replication_factor += 1 cluster_topology[osd_id]["friends"].add(osd[0]) cluster_topology[osd[0]]["friends"].add(osd_id) cluster_topology[osd_id]["free_space"] = free_space if isPrimary: # updating the backup update_backup_monitor("hash_table", [pg_id], [hashtable[pg_id]]) update_backup_monitor("cluster_topology", [osd[0] for osd in hashtable[pg_id]], \ [cluster_topology[osd[0]] for osd in hashtable[pg_id]]) hashtable_file = open('hashtable', 'wb') cluster_topology_file = open('cluster_topology', 'wb') hashtable_dump = pickle.dumps(hashtable) hashtable_file.write(hashtable_dump) hashtable_file.close() cluster_topology_dump = pickle.dumps(cluster_topology) cluster_topology_file.write(cluster_topology_dump) cluster_topology_file.close() if replication_factor > 1: # # sending write update to client # client_update = socket.socket() # print ("client write ack socket successfully created") # client_update.connect(client_addr) # msg = {"type": "WRITE_RESPONSE", "PG_ID": pg_id, \ # "status": "SUCCESS", "message": "write successful",\ # "client_id": client_id} # _send_msg(client_update, msg) # client_update.close() # sending write update to MDS MDS_update_socket = socket.socket() print ("MDS write ack socket successfully created") MDS_update_socket.connect((MDS_IP, MDS_PORT)) msg = {"type": "WRITE_RESPONSE", "PG_ID": pg_id, \ "status": "SUCCESS", "message": "write successful",\ "client_id": client_id} _send_msg(MDS_update_socket, msg) MDS_ack = _wait_recv_msg(MDS_update_socket, 1024) pg_id = MDS_ack["pg_id"] if MDS_ack["status"] == "SUCCESS": print("Write successful") MDS_flags[pg_id] = 0 else: print("Write error from MDS") print(MDS_ack["msg"]) MDS_flags[pg_id] = 1 ## resend pgs in MDS_flags with flag = 1 ## start that loop here MDS_update_socket.close() error = "" status = "SUCCESS" # send success _send_msg(c, {"error":error, "status":status}) c.close() write_ack_socket.close()
def recv_client_reqs(): global cluster_topology, hashtable recv_client_reqs_socket = socket.socket() print ("client req listener socket successfully created") recv_client_reqs_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) # reserve a port on your computer port = CLIENT_REQ_PORT # Next bind to the port # we have not entered any ip in the ip field # instead we have inputted an empty string # this makes the server listen to requests # coming from other computers on the network recv_client_reqs_socket.bind(('', port)) print ("client req listener socket bound to %s" %(port)) # put the socket into listening mode recv_client_reqs_socket.listen(5) print ("client req listener socket is listening") # a forever loop until we interrupt it or # an error occurs while True: # Establish connection with client. c, addr = recv_client_reqs_socket.accept() print ('Got connection from', addr) # recv the pg_id, size req = _recv_msg(c, 1024) if(req["type"] == "WRITE"): pg_id = req["pg_id"] size = req["size"] print(size) hashtable[pg_id] = [] i = 0 for osd_id in cluster_topology: if cluster_topology[osd_id]["free_space"] > size and cluster_topology[osd_id]["status"] == 0: hashtable[pg_id].append([osd_id, 0]) i = i+1 if(i>2): break if i < 3: print("less than two osds are free/alive") response = {"status":"ERROR", "msg": "sufficent storage not available"} _send_msg(c, response) c.close() continue osd_ids = [osd[0] for osd in hashtable[pg_id]] addrs = {} for osd_id in osd_ids: addrs[osd_id] = (cluster_topology[osd_id]["ip"], cluster_topology[osd_id]["port"]) osd_dict = {"osd_ids": osd_ids, "addrs": addrs} response = {"osd_dict": osd_dict, "status":"SUCCESS", "msg": "written succefully"} if isPrimary: # updating the backup(only hash_table) update_backup_monitor("hash_table", [pg_id], [hashtable[pg_id]]) hashtable_file = open('hashtable', 'wb') hashtable_dump = pickle.dumps(hashtable) hashtable_file.write(hashtable_dump) hashtable_file.close() _send_msg(c, response) elif req["type"] == "READ": pg_id = req["pg_id"] osd_ids = [hashtable[pg_id][i][0] for i in range(3)] addrs = [(cluster_topology[osd_id]["ip"], cluster_topology[osd_id]["port"]) \ for osd_id in osd_ids] osds_dict = {"osd_ids": osd_ids, "addrs": addrs} _send_msg(c, osds_dict) c.close() recv_client_reqs_socket.close()