def place_and_go(self, dest, msg, src=None, reset_tracker=True): '''Yes, reset_tracker defaults to True here.''' dest_indices = self.parse_target(dest) if src is None: src_indices = (self.id, ) else: src_indices = self.parse_target(src) if self.SI.args.verbose > 1: print('P&G dest %s=%s src %s=%s' % (dest, dest_indices, src, src_indices)) assert src_indices, 'missing or unknown source(s)' assert dest_indices, 'missing or unknown destination(s)' for S in src_indices: for D in dest_indices: if self.SI.args.verbose > 1: print('P&G(%s, "%s", %s)' % (D, msg, S)) try: self.requester_id = D self.responder_id = S # Yes it repeat-loads a mailslot D times but who cares send_payload(self, msg, reset_tracker=reset_tracker) except KeyError as e: print('No such peer id', str(e)) continue except Exception as e: print('place_and_go(%s, "%s", %s) failed: %s' % (D, msg, S, str(e))) return
def place_and_go(self, dest, msg, src=None, reset_tracker=True): '''Yes, reset_tracker defaults to True here.''' dest_indices = self.parse_target(self.id, dest) if src is None: src_indices = (self.id, ) else: src_indices = self.parse_target(self.id, src) if self.verbose > 1: print('P&G dest %s=%s src %s=%s' % (dest, dest_indices, src, src_indices)) assert src_indices, 'missing or unknown source(s)' assert dest_indices, 'missing or unknown destination(s)' for S in src_indices: for D in dest_indices: if self.verbose > 1: print('P&G(%s, "%s", %s)' % (D, msg, S)) try: # First get the list for dest, then the src ("from me") # doorbell EN. doorbell = self.id2EN_list[D][S] # This repeat-loads the source mailslot D times per S # but I don't care. send_payload(msg, S, doorbell, reset_tracker=reset_tracker) except KeyError as e: print('No such peer id', str(e)) continue except Exception as e: print('place_and_go(%s, "%s", %s) failed: %s' % (D, msg, S, str(e))) return
def connectionMade(self): recycled = self.SI.recycled # Does it exist? if recycled: recycled = self.SI.recycled.get(self.id, None) # Am I there? if recycled: del self.SI.recycled[recycled.id] msg = 'new socket %d == peer id %d %s' % ( self.transport.fileno(), self.id, 'recycled' if recycled else '') self.SI.logmsg(msg) if self.id == -1: # set from __init__ self.SI.logmsg('Max clients reached') self.send_initial_info(False) # client complains but with grace return # The original original code was written around this variable name. # Keep that convention for easier comparison. server_peer_list = list(self.SI.clients.values()) # Server line 175: create specified number of eventfds. These are # shared with all other clients who use them to signal each other. # Recycling keeps QEMU sessions from dying when other clients drop, # a perk not found in original code. if recycled: self.EN_list = recycled.EN_list else: try: self.EN_list = ivshmsg_event_notifier_list(MB.nEvents) except Exception as e: self.SI.logmsg('Event notifiers failed: %s' % str(e)) self.send_initial_info(False) return # Server line 183: send version, peer id, shm fd if self.verbose: PRINT('Sending initial info to new peer...') if not self.send_initial_info(): self.SI.logmsg('Send initial info failed') return # Server line 189: advertise the new peer to others. Note that # this new peer has not yet been added to the list; this loop is # NOT traversed for the first peer to connect. if not recycled: if self.verbose: PRINT('NOT recycled: advertising other peers...') for other_peer in server_peer_list: for peer_EN in self.EN_list: ivshmsg_send_one_msg(other_peer.transport.socket, self.id, peer_EN.wfd) # Server line 197: advertise the other peers to the new one. # Remember "this" new peer proxy has not been added to the list yet. if self.verbose: PRINT('Advertising other peers to the new peer...') for other_peer in server_peer_list: for other_peer_EN in other_peer.EN_list: ivshmsg_send_one_msg(self.transport.socket, other_peer.id, other_peer_EN.wfd) # Non-standard voodoo extension to previous advertisment: advertise # this server to the new peer. To QEMU it just looks like one more # grouping in the previous batch. Exists only in non-silent mode. if self.verbose: PRINT('Advertising this server to the new peer...') for server_EN in self.SI.EN_list: ivshmsg_send_one_msg(self.transport.socket, self.SI.id, server_EN.wfd) # Server line 205: advertise the new peer to itself, ie, send the # eventfds it needs for receiving messages. This final batch # where the embedded self.id matches the initial_info id is the # sentinel that communications are finished. if self.verbose: PRINT('Advertising the new peer to itself...') for peer_EN in self.EN_list: ivshmsg_send_one_msg( self.transport.socket, self.id, peer_EN.get_fd()) # Must be a good story here... # And now that it's finished: self.SI.clients[self.id] = self # QEMU did the connect but its VM is probably not yet running well # enough to respond. Since there's no (easy) way to tell, this is # a blind shot... self.printswitch(self.SI.clients) # default settling time if not self.SI.isPFM: send_payload('Link CTL Peer-Attribute', self.SI.id, self.EN_list[self.id])