Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Refunding the restart/redeployment mechanisms.
[hpcvm.git] / src / and / hpcvm / Server.java
index dafd9c5..0c696a4 100644 (file)
@@ -1,5 +1,9 @@
 package and.hpcvm ;
 
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
 import java.rmi.Naming;
 import java.rmi.RemoteException;
 import java.rmi.registry.LocateRegistry;
@@ -82,14 +86,14 @@ public class Server extends UnicastRemoteObject implements ServicesServer
        {
                private ConnectedClient client ;
                private boolean save_status ;
-               private String save_neighbor ;
+               private ArrayList<ServicesClient> save_neighbor ;
                private String lastSaveName ;
                
                ComputingClient( ConnectedClient cl )
                {
                        client = cl ;
                        save_status = false ;
-                       save_neighbor = "none" ;
+                       save_neighbor = new ArrayList<ServicesClient>() ;
                        lastSaveName = "none" ;
                }
                
@@ -99,11 +103,18 @@ public class Server extends UnicastRemoteObject implements ServicesServer
                
                protected void setSaveStatus( boolean _status ) { save_status = _status ; }
                
-               protected void setSaveNeighbor( String _sn ) 
+               protected void setSaveNeighbor( ServicesClient _sn ) 
                { 
-                       if( _sn != null && ! _sn.isEmpty() )
+                       if( _sn != null )
                        {
-                               save_neighbor = _sn ; 
+                               if( save_neighbor.size() == 0 )
+                               {
+                                       save_neighbor.add( _sn ) ;
+                               } else {
+                                       save_neighbor.set( 0, _sn ) ;
+                               }
+                               
+//                             System.out.println( "My save neighbor is " + _sn ) ;
                        
                                try {
                                        client.getStub().setSavingNeighbor( _sn ) ;
@@ -115,7 +126,15 @@ public class Server extends UnicastRemoteObject implements ServicesServer
                        }
                }
                
-               protected String getSaveNeighbor() { return save_neighbor ; }
+               protected ServicesClient getSaveNeighbor() 
+               {
+                       if( save_neighbor.isEmpty() )
+                       {
+                               return null ;
+                       } else {
+                               return save_neighbor.get( 0 ) ;
+                       }
+               }
 
                public void setLastSave( String _saveName ) 
                {
@@ -169,6 +188,7 @@ public class Server extends UnicastRemoteObject implements ServicesServer
        private ConnectedMonitor monitor ;
        private DiscCount counter ;
        private ArrayList<IPAssociation> vmIPs ;
+       private String working_directory ;
        
        
        protected Server() throws RemoteException 
@@ -294,6 +314,8 @@ public class Server extends UnicastRemoteObject implements ServicesServer
                computingClients = new ArrayList<Server.ComputingClient>() ;
                monitor = null ;
                
+               working_directory = "/localhome/vmware" ;
+               
                exportObject() ;
 
                vmIPs = new ArrayList<IPAssociation>() ;
@@ -400,16 +422,13 @@ public class Server extends UnicastRemoteObject implements ServicesServer
                @Override
                public void run() 
                {
-                       synchronized( counter ){
-                       counter.inc() ;}
-                       System.out.println("ici");
                        if( cl != null && cl.getStatus().equalsIgnoreCase( "running" ) ||
                                        cl.getStatus().equalsIgnoreCase( "saving" ) )
                        {
-                               System.out.println("ok");
                                ComputingClient cc = cl.getComputingClient() ;
+//                             ServicesClient dead = cc.getClient().getStub() ;
                                String ipDead = cc.getClient().getIP() ;
-                               
+                                                               
                                boolean ok = false ;
                                
                                for( int i = 0 ; i < clients.size() ; i++ )
@@ -434,19 +453,20 @@ public class Server extends UnicastRemoteObject implements ServicesServer
                                                } else {
                                                        System.out.println( "Trying to replace " + cc.getClient().getName() + " with " +
                                                                        clients.get(i).getName() + " ... " ) ;
-                                                               
+                                                       
+                                                       String save_name = computingClients.get( pos ).getLastSave() ;
+                                                       
                                                        ComputingClient ccl = new ComputingClient( clients.get(i) ) ;
                                                        clients.get( i ).setComputingClient( ccl ) ;
-                                                       String sn = computingClients.get( pos ).getSaveNeighbor() ;
+                                                       ServicesClient sn = computingClients.get( pos ).getSaveNeighbor() ;
                                                        ccl.setSaveNeighbor( sn ) ;
                                                        computingClients.set( pos, ccl ) ;
-//                                                             computingClients.get( pos ).setSaveNeighbor( sn ) ;
-                                                               
+
                                                                
                                                        int res = 1 ;
                                                        try {
                                                                res = computingClients.get( pos ).getClient().getStub().
-                                                               retrieveSave( computingClients.get(i).getLastSave() ) ;
+                                                                     retrieveSave( save_name ) ;
                                                        } catch( RemoteException e ) {
                                                                System.err.println( "Unable to indicate to client to retrieve last save!" ) ;
                                                                e.printStackTrace() ;
@@ -486,8 +506,20 @@ public class Server extends UnicastRemoteObject implements ServicesServer
                                                        
                                                if( ok )
                                                {
+                                                       for( int k = 0 ; k < computingClients.size() ; k++ )
+                                                       {
+                                                               try {
+                                                                       computingClients.get( k ).getClient().getStub().
+                                                                               replaceSavingNeighbor( ipDead, clients.get( i ).getStub() ) ;
+                                                               } catch( RemoteException e ) {
+                                                                       System.err.println( "Unable to inform " + computingClients.get( k ).getClient().getName() +
+                                                                                       " of the replacement of a save neighbor!" ) ;
+                                                                       e.printStackTrace() ;
+                                                               }
+                                                       }
+                                                       
                                                        System.out.println( "Dead client successfully replaced." ) ;
-                                                       // restart vms
+
                                                        break ;
                                                } else {
                                                        System.err.println( "Dead client not replaced!!" ) ;
@@ -550,6 +582,9 @@ public class Server extends UnicastRemoteObject implements ServicesServer
 //                                                                     break ;
 //                                                             }
 //                                                     }
+                                                       synchronized( counter ){
+                                                               counter.inc() ;}
+                                                               
                                                        
                                                        new Server.FaultManager( cl ).start() ;
                                                        nb_disconnections_computing++ ;
@@ -579,7 +614,23 @@ public class Server extends UnicastRemoteObject implements ServicesServer
                                
                                if( nb_disconnections_computing > 0 )
                                {
-                                       System.out.println( "I will redeploy save and restart VMs ..." ) ;
+                                       System.out.println( "Sending emergency stop signal to all computing nodes ... " ) ;
+                                       
+                                       for( int i = 0 ; i < clients.size() ; i++ )
+                                       {
+                                               if( clients.get( i ).getStatus().equalsIgnoreCase( "running" ) 
+                                                       || clients.get( i ).getStatus().equalsIgnoreCase( "saving" ) )
+                                               {
+                                                       try {
+                                                               clients.get( i ).getStub().emergencyStop() ;
+                                                       } catch( RemoteException e ) {
+                                                               System.err.println( "Unable to invoke emergency stop signal on " + clients.get( i ).getName() ) ;
+                                                               e.printStackTrace() ;
+                                                       }
+                                               }
+                                       }
+                                       
+                                       System.out.println( "I will redeploy save and restart VMs ... " ) ;
                                        
                                        synchronized( counter ) 
                                        {
@@ -591,7 +642,7 @@ public class Server extends UnicastRemoteObject implements ServicesServer
                                                while( counter.getNb() != 0 )
                                                {
                                                        try {
-                                                               counter.wait() ;  // !!!!! synchro
+                                                               counter.wait() ;
                                                        } catch( InterruptedException e ) {
                                                                e.printStackTrace() ;
                                                        }
@@ -666,8 +717,25 @@ public class Server extends UnicastRemoteObject implements ServicesServer
                
                return 0 ;
        }
-
-
+       
+       
+       public Integer changeSaveName( String _ip, String _saveName )
+       {
+               if( _ip != null && _ip.length() > 0 && _saveName != null && _saveName.length() > 0 )
+               {
+                       for( int i = 0 ; i < computingClients.size() ; i ++ )
+                       {
+                               if( computingClients.get( i ).getClient().getIP().equalsIgnoreCase( _ip ) ) 
+                               {
+                                       computingClients.get( i ).setLastSave( _saveName ) ;
+                                       System.out.println( "Save name successfully change for " + _ip ) ;
+                                       return 0 ;
+                               }
+                       }
+               }
+               
+               return 1 ;
+       }
 
        @Override
        public ArrayList<ServicesClient> startApplication( int _nb ) 
@@ -724,7 +792,7 @@ public class Server extends UnicastRemoteObject implements ServicesServer
                                                {
                                                        System.err.println( "Problem in ComputingClients list!" ) ;
                                                } else {
-                                                       computingClients.get( index ).setSaveNeighbor( computingClients.get( index2 ).getClient().getIP() ) ;
+                                                       computingClients.get( index ).setSaveNeighbor( computingClients.get( index2 ).getClient().getStub() ) ;
                                                }
                                        } else {
                                                index = computingClients.indexOf( tmp.get( i ) ) ;
@@ -734,7 +802,7 @@ public class Server extends UnicastRemoteObject implements ServicesServer
                                                {
                                                        System.err.println( "Problem in ComputingClients list!" ) ;
                                                } else {
-                                                       computingClients.get( index ).setSaveNeighbor( computingClients.get( index2 ).getClient().getIP() ) ;
+                                                       computingClients.get( index ).setSaveNeighbor( computingClients.get( index2 ).getClient().getStub() ) ;
                                                }
                                        }
                                }
@@ -778,7 +846,7 @@ public class Server extends UnicastRemoteObject implements ServicesServer
 
 
        @Override
-       public String getAssociatedIP( String _ip ) throws RemoteException 
+       public String getAssociatedIP( String _ip )
        {
                String ret = null ;
                
@@ -794,6 +862,150 @@ public class Server extends UnicastRemoteObject implements ServicesServer
                return ret ;
        }
        
+       
+       public Integer deployVM( String _name, String _archive, String _directory )
+       {
+               int pb = -1 ;
+               int nb = 0 ;
+               
+               if( _name != null && _name.length() > 0 && _archive != null && _name.length() > 0 
+                               && _directory != null && _directory.length() > 0 )
+               {
+                       System.out.println( "Deploying the VM " + _name + " (" + _archive + ") ... " ) ;
+                       
+                       File file = new File( working_directory + "/" + _archive ) ;
+                       if( ! file.exists() )
+                       {
+                               System.err.println( "There is no archive named " + _archive + " in my working directory!" ) ;
+                               file = null ;
+                               return 1 ;
+                       } else if( file.isDirectory() ) {
+                               System.err.println( _archive + " is a directory!" ) ;
+                               file = null ;
+                               return 1 ;
+                       }
+                       
+                       file = null ;
+                       
+                       // TODO do a better deployment !!
+                       int ret ;
+                       boolean error ;
+                       
+                       pb = 0 ;
+                       
+                       for( int i = 0 ; i < clients.size() ; i++ )
+                       {
+                               ret = 1 ;
+                               error = false ;
+                               try {
+                                       ret = clients.get( i ).getStub().deployVM( _name, _archive, _directory ) ;
+                               } catch( RemoteException e ) {
+                                       System.err.println( "Unable to deploy the VM on " + clients.get( i ).getName() + "!" ) ;
+                                       e.printStackTrace() ;
+                               }
+                               
+                               // The client does not have the archive, we have to send it.
+                               if( ret == 2 )
+                               {
+                                       System.out.print( "Sending VM archive to " + clients.get( i ).getName() + " ... " ) ;
+                                       
+                                       String wd = "" ;
+                                       String snIP = "" ;
+                                       error = false ;
+                                       
+                                       try {
+                                               wd = clients.get( i ).getStub().getWorkingDirectory() ;
+                                               snIP = clients.get( i ).getStub().getIPHost() ;
+                                       } catch (RemoteException e2) {
+                                               System.err.println( "Unable to retrieve information on " + clients.get( i ).getName() + "!" ) ;
+                                               e2.printStackTrace() ;
+                                               error = true ;
+                                               pb++ ;
+                                       }
+                                       
+                                       String[] command = new String[]{ "/usr/bin/scp", working_directory + "/" + _archive,
+                                                               snIP + ":" + wd } ;
+                               
+                                       if( ! error )
+                                       try {
+                                               Process proc = Runtime.getRuntime().exec( command ) ;
+                                               proc.waitFor() ;
+                       
+                                               if( proc.exitValue() == 0 )
+                                               {
+                                                       System.out.println( "Initial VM archive successfully sent." ) ;
+                                               } else {
+                                                       System.err.println( "Initial VM archive not sent!" ) ;
+//                                                     printProcessError( p.getErrorStream() ) ;
+                                                       System.err.println( "Error: " + proc.exitValue() ) ;
+                                                       BufferedReader b = new BufferedReader( new InputStreamReader( proc.getErrorStream() ) ) ;
+                                                       
+                                                       String l ;
+                                                       try {
+                                                               while( (l = b.readLine()) != null )
+                                                               {
+                                                                       System.err.println( l ) ;
+                                                               }
+                                                       } catch( IOException e ) {
+                                                                       e.printStackTrace() ;
+                                                       }
+                                                       
+                                                       error = true ;
+                                                       pb++ ;
+                                               }
+                                       } catch( IOException e ) {
+                                               System.err.println( "Error during initial VM archive send command: " ) ;
+                                               e.printStackTrace() ;
+                                               error = true ;
+                                               pb++ ;
+                                       } catch( InterruptedException e ) {
+                                               e.printStackTrace() ;
+                                               error = true ;
+                                               pb++ ;
+                                       }
+                               
+                               
+                                       if( error )
+                                       {
+                                               continue ;
+                                       }
+                               
+                                       // Second try ...
+                                       ret = 1 ;
+                                       try {
+                                               ret = clients.get( i ).getStub().deployVM( _name, _archive, _directory ) ;
+                                       } catch( RemoteException e ) {
+                                               System.err.println( "Unable to deploy the VM on " + clients.get( i ).getName() + "!" ) ;
+                                               e.printStackTrace() ;
+                                               pb++ ;
+                                       }
+                               }
+                               
+                               if( ret == 0 )
+                               {
+                                       System.out.println( "Initial VM archive successfully deployed on " + clients.get( i ).getName() + "." ) ;
+                                       nb++ ;
+                               }
+                       }
+               }
+               
+               if( pb > 0 )
+               {
+                       if( pb == 1 )
+                               System.err.println( "** " + pb + " machine is not deployed!" ) ;
+                       if( pb > 1 )
+                               System.err.println( "** " + pb + " machine(s) are not deployed!" ) ;
+               }
+               
+               return nb ;
+       }
+       
+       
+       public String getWorkingDirectory()
+       {
+               return working_directory ;
+       }
+       
 }
 
 /** La programmation est un art, respectons ceux qui la pratiquent !! **/