Beispiel #1
0
def report_monitor(node_ip, osd_id):
	flag = 0
	#Will call monitor to state about the down node
	soc = socket.socket()
	soc.settimeout(5)
	print ("Socket successfully created for Recovery: Primary")

	monitor_1 = monitor_ip["primary"]
	
	try :
		soc.connect((monitor_1["ip"], monitor_1["port"]))	
		# soc.timeout(None)

		print(f"Connecting Primary monitor...")
		
		res = {"type": "FAIL", "ip" : node_ip, "osd_id" : osd_id}
		_send_msg(soc, res)
		
		msg = _wait_recv_msg(soc, MSG_SIZE)
		print(msg)
		if msg == None:
			pass
		elif msg["type"] == "ACK": 

			soc.close()
			return

	except Exception as e: 
		print(e)
		print("Didn't Connect! [Timeout] Primary Monitor is Down")

	soc.close()

	soc = socket.socket()
	soc.settimeout(5)
	print ("Socket successfully created for Recovery: Backup")
	

	monitor_2 = monitor_ip["backup"]

	try : 
		soc.connect((monitor_2["ip"], monitor_2["port"]))	
		soc.settimeout(None)			
		print(f"Connecting Backup monitor...")
	
		res = {"type": "FAIL", "ip" : node_ip, "osd_id" : osd_id}
		_send_msg(soc, res)

		msg = _wait_recv_msg(soc, MSG_SIZE)
		print(msg)
		if msg == None:
			pass
		elif msg["type"] == "ACK": 
			return

	except:
		print("MAY GOD HELP US!! WE ARE DOOMED\n\n")

	soc.close()
    def logout(self):
        msg = {"type": "CLIENT_LOGOUT", "username": self.username}

        s = socket.socket()
        # s.bind(('', 9090))
        ip = MDS_IPs["primary"]["ip"]
        port = MDS_IPs["primary"]["port"]

        try:
            s.connect((ip, port))

            _send_msg(s, msg)

            response = _wait_recv_msg(s, MSG_SIZE)

            if response["status"] == "SUCCESS":  # here check response from mds
                self.window.destroy()
                print(response["msg"])

            elif response["status"] == "ERROR":
                print(response["msg"])

        except Exception as e:

            print("[ERROR] login failed")
            print(e)

        finally:
            global LoginPage

            s.close()
            LoginPage()
    def _read(self, pg_id):
        s = socket.socket()

        # send monitor to ask for OSD details
        ip = MONITOR_IPs["primary"]
        port = CLIENT_REQ_PORT

        s.connect((ip, port))

        msg = {"type": "READ", "pg_id": pg_id}
        # d_msg = pickle.dumps(msg)

        _send_msg(s, msg)
        #s.send(d_msg)
        response = _wait_recv_msg(s, 1024)

        osd_addr = response["addrs"][0]

        # print(osd_ips)
        s.close()
        # print(osd_ips[0][0], osd_ips[0][1])
        # write on OSD
        s = socket.socket()
        s.connect(osd_addr)
        data_msg = {"type": "READ", "pg_id": pg_id}
        _send_msg(s, data_msg)

        osd_response = _wait_recv_msg(s, 1024)

        # print(osd_response)
        # print(osd_response["pg_id"] == pg_id)
        # print(osd_response["res"] == "SUCCESS")

        if osd_response["pg_id"] == pg_id and osd_response["res"] == "SUCCESS":
            s.close()
            print("PG received from OSD writing on disk")
            return 0, osd_response["pg"]

        else:
            s.close()
            print("Error - PG not received from OSD")
            return -2, None
def recv_gossip():

    while True:
        time.sleep(10)
        # Wait for 10 sec to  run this protocol

        i = 0
        for i in range(4):
            curr_osd = "osd_id" + str(i + 1)
            if curr_osd != STORAGE_ID:
                node_ip = storage_ip[curr_osd]["ip"]
                port = storage_ip[curr_osd]["port"]

                soc = socket.socket()
                soc.settimeout(5)
                print(
                    f"\n\nSocket successfully created for Gossip with osd {curr_osd}"
                )

                try:
                    soc.connect((node_ip, port))
                    soc.settimeout(None)

                    print(
                        f"Connecting {node_ip} storage node number {curr_osd} port {port}"
                    )

                    msg = {"type": "ALIVE"}
                    _send_msg(soc, msg)

                    rec = _wait_recv_msg(soc, MSG_SIZE)
                    print(msg)
                    if rec == None:
                        print(
                            f"Didn't receive data to Storage {curr_osd} ip {node_ip}! [Timeout] "
                        )
                        report_monitor(node_ip, curr_osd)

                    elif rec["type"] != "ACK":
                        report_monitor(node_ip, curr_osd)

                except:
                    print(
                        f"Didn't Connect to Storage {curr_osd} ip {node_ip}! [Timeout]"
                    )
                    report_monitor(node_ip, curr_osd)

                soc.close()

            time.sleep(3)
def login():
    global user, passwd, login_screen
    # send credentials to mds and wait for response

    client_id = "C200"  # received from mds
    print("username:: ", user.get())
    # print("password:: ", passwd.get())

    msg = {
        "type": "CLIENT_LOGIN",
        "username": user.get(),
        "password": passwd.get()
    }

    s = socket.socket()

    ip = MDS_IPs["primary"]["ip"]
    port = MDS_IPs["primary"]["port"]
    # print(s.gethostname())
    # s.bind(('', 9090))

    try:
        s.connect((ip, port))

        _send_msg(s, msg)

        response = _wait_recv_msg(s, MSG_SIZE)

        s.close()
        if response["status"] == "SUCCESS":  # here check response from mds
            print(response["msg"])
            login_screen.destroy()
            client = Client(response["tree"])

        elif response["status"] == "ERROR":
            # print(response["msg"])
            _popup("Login Failed", response["msg"])

    except Exception as e:
        s.close()

        print("[ERROR] login failed")
        print(e)
        _popup("Login Failed", str(e))

    finally:
        print("Exiting login..")
def update_backup_monitor(update_type, pg_or_osd_ids_list, osd_list):
    primary_update_socket = socket.socket()
    print ("primary update socket successfully created")

    try:
        primary_update_socket.connect((MONITOR_IPs["backup"], RECV_PRIMARY_UPDATE_PORT))
        msg = {"update_type": update_type, "pg_or_osd_ids_list": pg_or_osd_ids_list, \
                    "osd_list": osd_list}
        _send_msg(primary_update_socket, msg)
        response = _wait_recv_msg(primary_update_socket, MSG_SIZE)
        primary_update_socket.close()
        if response["status"] == "SUCCESS":
            print("written to monitor backup successfully")
        else:
            print("write to monitor backup failed")
    except Exception as e:
        print(e)
        primary_update_socket.close()
    def _update_primary(self, update_type, update):
        print("writing to backup..")
        s = socket.socket()

        # send backup mds to make data consistent
        ip = MDS_IPs["backup"]["ip"]
        port = MDS_IPs["backup"]["port"]

        try:
            s.connect((ip, port))

            msg = {"type": "UPD", "update_type": update_type, "update": update}
            # d_msg = pickle.dumps(msg)

            _send_msg(s, msg)
            #s.send(d_msg)
            response = _wait_recv_msg(s, 1024)

            if response["status"] == "SUCCESS":
                if update_type == "ADD_LOGIN_USER":
                    self.logged_in.append(update["user"])
                    self._write_logged_in()

                elif update_type == "REMOVE_LOGIN_USER":
                    self.logged_in.remove(update["user"])
                    self._write_logged_in()

                print("Successfully updated on Backup")
                return 0
            elif response["status"] == "ERROR":
                print(response["msg"])
                print("Couldn't update on Backup")
                return -1

        except Exception as e:
            print(e)
            print("Couldn't update on Backup")
            return -2

        finally:
            s.close()
            print("writing to backup completed.")
def send_replicate_request(pg_id, master_osd, clone_osd):
    soc = socket.socket()
    soc.settimeout(5)
    print(
        f"Socket successfully created for replicating {pg_id} from master {master_osd} to clone {clone_osd}"
    )

    # reserve a port on your computer in our
    ip_add = storage_ip[master_osd]["ip"]
    port = storage_ip[master_osd]["port"] + 10

    flag = -1
    try:
        soc.connect((ip_add, port))
        soc.settimeout(None)

        print(f"Connecting with {master_osd} on port {port}...")

        res = {"type": "REPLICATE", "pg_id": pg_id, "osd_id": clone_osd}
        _send_msg(soc, res)
        print("Message send for replication ")

        # time.sleep(5)

        msg = _wait_recv_msg(soc, MSG_SIZE)
        print(msg)
        if msg == None:
            flag = 0
        elif msg["type"] == "ACK":
            flag = 1

    except Exception as e:
        print(e)
        print(
            f"Didn't Connect! [Timeout] master {master_osd} is down,  port {port}"
        )

    soc.close()
    return flag
	ip = MDS_IPs["primary"]["ip"]
	port = MDS_IPs["primary"]["port"]


print("receiving data..")
s = socket.socket()         

try:
	s.connect((ip, port)) 
	
	msg = {"type":"RECOVERY"}
	# d_msg = pickle.dumps(msg)
	
	_send_msg(s, msg)
	#s.send(d_msg)
	response = _wait_recv_msg(s, 1024)

	if response["status"] == "SUCCESS":
		trees = response["trees"]
		logged_in = response["logged_in"]
		# user_list = response["user_list"]

		for tree in trees:
			file = open("./tree/"+tree["username"], 'wb')

			obj_b = pickle.dumps(tree)
			file.write(obj_b)

			file.close()

		file = open("./logged_in", 'wb')
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 update_handler(self):

        # if n == 0:
        print("update handler started..")
        # if self.start_update_handler == True:

        while True:
            if len(self.processing) == 0:
                self.start_update_handler = False
                return

            msg = {
                "type": "WRITE_QUERY",
                "username": self.username,
                "processing": self.processing
            }

            s = socket.socket()

            ip = MDS_IPs["primary"]["ip"]
            port = MDS_IPs["primary"]["port"]
            # print(s.gethostname())
            # s.bind(('', 9090))

            try:
                s.connect((ip, port))

                _send_msg(s, msg)

                response = _wait_recv_msg(s, MSG_SIZE)

                s.close()
                if response[
                        "status"] == "SUCCESS":  # here check response from mds
                    print(response["msg"])
                    file_written = response["file_written"]

                    for file in file_written:  #populate listbox again
                        filename = file[0]
                        file_id = file[1]
                        file_path = file[2]
                        self.file_id_map[filename] = file_id
                        self.listbox.insert(tk.END, file_path)
                        # listbox.insert(END, percent)
                        self.listbox.update_idletasks()

                    tree = response["tree"]
                    self.dir_tree = tree["dir_tree"]
                    self.processing = tree["processing"]
                    print(self.processing)
                    if len(self.processing) == 0:
                        self.start_update_handler = False
                        print("Exiting update handler")

                    for file in file_written:
                        self._popup("Update",
                                    str(file[2]) + " UPLOADED SUCCESSFULLY")

                    # return
                    # update on GUI

                    # self._update_gui()

                    # for filename in file_written: #populate listbox again
                    # 	self.listbox.insert(END, filename)
                    # 	# listbox.insert(END, percent)
                    # 	self.listbox.update_idletasks()

                    # tk.mainloop()
                    # self.window.mainloop()
                elif response["status"] == "NO_UPD":
                    print(response["msg"])
                time.sleep(self.update_interval)

            except Exception as e:
                s.close()
                print("Update (write) from MDS failed")
                print(e)
                time.sleep(self.update_interval)

            finally:

                time.sleep(self.update_interval)
    def _write(self, pg, pg_data):
        s = socket.socket()

        # send monitor to ask for OSD details
        ip = MONITOR_IPs["primary"]
        port = CLIENT_REQ_PORT

        s.connect((ip, port))

        msg = {
            "type": "WRITE",
            "pg_id": pg.pg_id,
            "size": (sys.getsizeof(pg) / float(1 << 20))
        }
        # d_msg = pickle.dumps(msg)

        _send_msg(s, msg)
        #s.send(d_msg)
        res = _wait_recv_msg(s, MSG_SIZE)
        osd_dict = {}

        if res["status"] == "SUCCESS":
            osd_dict = res["osd_dict"]

        else:
            print(res["msg"])
            s.close()
            return -2
        # osd_dict = response["osd_dict"]

        # print(osd_ips)
        s.close()
        # print(osd_ips[0][0], osd_ips[0][1])
        # write on OSD
        osd_addr = osd_dict["addrs"][osd_dict["osd_ids"][0]]
        s = socket.socket()
        s.connect(osd_addr)
        data_msg = {
            "type": "CLIENT_WRITE",
            "pg": pg,
            "size": (sys.getsizeof(pg) / float(1 << 20)),
            "client_id": self.username,
            "client_addr": "",
            "osd_dict": osd_dict
        }
        _send_msg(s, data_msg)
        print(len(pg.object_list))

        self.processing[pg.pg_id] = pg_data
        threading.Thread(target=self.update_handler()).start()
        ### Add server to receive response
        osd_response = _wait_recv_msg(s, 1024)

        if osd_response["status"] == "RECEIVED":
            print("file sent to OSD")
            # self.processing[pg.pg_id] = pg_data
            # if self.start_update_handler == False:
            # 	self.start_update_handler = True
            # self.update_handler()
            # threading.Thread(target=self.update_handler())
            s.close()
            return 0

        else:
            s.close()
            print("Error - File not sent")
            return -2
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()