Uploaded image for project: 'Jenkins'
  1. Jenkins
  2. JENKINS-8218

Cannot start slave with script on master

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Unresolved
    • Icon: Critical Critical
    • remoting
    • None
    • Master on Linux / Slave on Linux+Windows

      Recently we updated the Hudson installation in our company from a nearly one year old version to the current 1.386 version. Unfortunately all slaves stopped working from this time on.

      We start our slaves with a script on the master. This script calls several times rsync and ssh before it finally calls "java -jar slave.jar" via ssh on the slave. But beginning with the update the slaves didn't start anymore. Instead we got an EOFException with different stacktraces all the times the master tried to start a slave.

      I tried to debug Hudson and discovered that the exchange of the capabilities doesn't work. At the end the reason was simple. The master sends the capabilities preamble and the capabilities themselve immediately after calling the script to start the slave. But on the way through the script from its beginning to the final call to ssh to start the client, these data were lost.

      Therefore I changed the class hudson.remoting.Channel that way, that the master now waits before sending any data till the slave sent its preamble. At this time I could be save that the slave will receive the capabilities and everything else.

      This is what I changed:

      Index: remoting/src/main/java/hudson/remoting/Channel.java
      ===================================================================
      --- remoting/src/main/java/hudson/remoting/Channel.java	(revision 37111)
      +++ remoting/src/main/java/hudson/remoting/Channel.java	(working copy)
      @@ -354,10 +354,10 @@
               //
               // so use magic preamble and discard all the data up to that to improve robustness.
       
      -        capability.writePreamble(os);
      -
               ObjectOutputStream oos = null;
               if(mode!= Mode.NEGOTIATE) {
      +            // obviously we are the slave, so start sending immediately
      +            capability.writePreamble(os);
                   os.write(mode.preamble);
                   oos = new ObjectOutputStream(mode.wrap(os));
                   oos.flush();    // make sure that stream preamble is sent to the other end. avoids dead-lock
      @@ -383,8 +383,10 @@
                                   case 1:
                                       // transmission mode negotiation
                                       if(mode==Mode.NEGOTIATE) {
      +                                    // we are master and the slave has started sending data, so we can start too...
                                           // now we know what the other side wants, so send the consistent preamble
                                           mode = modes[i];
      +                                    capability.writePreamble(os);
                                           os.write(mode.preamble);
                                           oos = new ObjectOutputStream(mode.wrap(os));
                                           oos.flush();
      

      This patch is against the 1.386 tag but it should be the same for trunk.

            Unassigned Unassigned
            axel_petzold axel_petzold
            Votes:
            1 Vote for this issue
            Watchers:
            3 Start watching this issue

              Created:
              Updated: