Ejemplo n.º 1
0
 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
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
    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])