[paramiko] Exception from paramiko. EOFError

jdsw jdsw2002 at yahoo.com
Sun Oct 29 15:15:05 PST 2006


Hi
   I was getting None from open_channel at few places... and found that transport.active was becoming false. (related to gnome-vfs. I do not know the exact cause.. anyone ?)

   After digging and putting print statements... found the following.
   Basically in run() method of paramiko transport.py , there was a socket exception being thrown with Error 11 Resource Temporarily unavailable. Looking in to doc.. found that clients need to retry the operations and handle EAGAIN from socket.

  Added retry block around the recv where the problem was.  We might have to wrap this while sending too.

 Attached is section of patched transport.py file. Could u please validate and see how this can be encorporated in to mainline. (currently we have released this modification with our product XenMan and telling users to patch it.). I checked 1.6.2 also, this section of the code is not changed.

Thanks
/Jd


===== Attached modified run method in transport.py  based on 1.6.1 =======
===== Look for Jd for area where things are changed. =====

def run(self):
        # (use the exposed "run" method, because if we specify a thread 
target
        # of a private method, threading.Thread will keep a reference 
to it
        # indefinitely, creating a GC cycle and not letting Transport 
ever be
        # GC'd.  it's a bug in Thread.)
        
        # active=True occurs before the thread is launched, to avoid a 
race
        _active_threads.append(self)
        if self.server_mode:
            self._log(DEBUG, 'starting thread (server mode): %s' % 
hex(long(id(self)) & 0xffffffffL))
        else:
            self._log(DEBUG, 'starting thread (client mode): %s' % 
hex(long(id(self)) & 0xffffffffL))
        try:
            self.packetizer.write_all(self.local_version + '\r\n')
            self._check_banner()
            self._send_kex_init()
            self.expected_packet = MSG_KEXINIT

            while self.active:
                if self.packetizer.need_rekey() and not self.in_kex:
                    self._send_kex_init()
                try:
                    retry = 5
                    ptype, m = self.packetizer.read_message()
                except NeedRekeyException:
                    continue
                except socket.error, e: # Added retry Jd
                    if type(e.args) is tuple:
                        #emsg = '%s (%d)' % (e.args[1], e.args[0])
                        #print "CAUGHT " + emsg
                        if e.args[0] == 11:
                            retry = retry -1
                            if retry >=0:
                                time.sleep(0.01)
                                #print "retrying...", retry
                                continue
                    raise
                if ptype == MSG_IGNORE:
                    continue
                elif ptype == MSG_DISCONNECT:
                    self._parse_disconnect(m)
                    self.active = False
                    self.packetizer.close()
                    break
                elif ptype == MSG_DEBUG:
                    self._parse_debug(m)
                    continue
                if self.expected_packet != 0:
                    if ptype != self.expected_packet:
                        raise SSHException('Expecting packet %d, got 
%d' % (self.expected_packet, ptype))
                    self.expected_packet = 0
                    if (ptype >= 30) and (ptype <= 39):
                        self.kex_engine.parse_next(ptype, m)
                        continue

                if self._handler_table.has_key(ptype):
                    self._handler_table[ptype](self, m)
                elif self._channel_handler_table.has_key(ptype):
                    chanid = m.get_int()
                    if self.channels.has_key(chanid):
                        
self._channel_handler_table[ptype](self.channels[chanid], m)
                    elif self.channels_seen.has_key(chanid):
                        self._log(DEBUG, 'Ignoring message for dead 
channel %d' % chanid)
                    else:
                        self._log(ERROR, 'Channel request for unknown 
channel %d' % chanid)
                        self.active = False
                        self.packetizer.close()
                elif (self.auth_handler is not None) and 
self.auth_handler._handler_table.has_key(ptype):
                    
self.auth_handler._handler_table[ptype](self.auth_handler, m)
                else:
                    self._log(WARNING, 'Oops, unhandled type %d' % 
ptype)
                    msg = Message()
                    msg.add_byte(chr(MSG_UNIMPLEMENTED))
                    msg.add_int(m.seqno)
                    self._send_message(msg)
        except SSHException, e:
            self._log(ERROR, 'Exception: ' + str(e))
            self._log(ERROR, util.tb_strings())
            self.saved_exception = e
            #print "SSHException  :", traceback.print_exc()
        except EOFError, e:
            self._log(DEBUG, 'EOF in transport thread')
            #self._log(DEBUG, util.tb_strings())
            self.saved_exception = e
            #print "EOF error :", traceback.print_exc()
        except socket.error, e:
            if type(e.args) is tuple:
                emsg = '%s (%d)' % (e.args[1], e.args[0])
            else:
                emsg = e.args
            self._log(ERROR, 'Socket exception: ' + emsg)
            self.saved_exception = e
            #print "socket error :", 
threading.currentThread(),traceback.print_exc()
        except Exception, e:
            self._log(ERROR, 'Unknown exception: ' + str(e))
            self._log(ERROR, util.tb_strings())
            self.saved_exception = e
            #print "other exception :", traceback.print_exc()
        _active_threads.remove(self)
        for chan in self.channels.values():
            chan._unlink()
        if self.active:
            self.active = False
            self.packetizer.close()
            if self.completion_event != None:
                self.completion_event.set()
            if self.auth_handler is not None:
                self.auth_handler.abort()
            for event in self.channel_events.values():
                event.set()
        self.sock.close()


 
---------------------------------
Cheap Talk? Check out Yahoo! Messenger's low  PC-to-Phone call rates.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.lag.net/pipermail/paramiko/attachments/20061029/7463a6b9/attachment.htm 


More information about the paramiko mailing list