From 3502bc1e43c70f69ae488cb8418a0ef4fd885d19 Mon Sep 17 00:00:00 2001 From: =?utf8?q?S=C3=A9bastien=20Miqu=C3=A9e?= Date: Fri, 24 Jun 2011 14:47:22 +0200 Subject: [PATCH 1/1] First ~stable~ version. --- Makefile | 37 + Manifest | 3 + src/InGuest.java | 101 ++ src/and/hpcvm/Client.java | 1583 +++++++++++++++++++++++++++++ src/and/hpcvm/Configuration.java | 11 + src/and/hpcvm/HpcVm.java | 163 +++ src/and/hpcvm/LocalHost.java | 103 ++ src/and/hpcvm/Server.java | 800 +++++++++++++++ src/and/hpcvm/ServicesClient.java | 45 + src/and/hpcvm/ServicesServer.java | 28 + src/and/hpcvm/Status.java | 49 + src/and/hpcvm/User.java | 92 ++ src/and/hpcvm/VirtualMachine.java | 279 +++++ 13 files changed, 3294 insertions(+) create mode 100644 Makefile create mode 100644 Manifest create mode 100644 src/InGuest.java create mode 100644 src/and/hpcvm/Client.java create mode 100644 src/and/hpcvm/Configuration.java create mode 100644 src/and/hpcvm/HpcVm.java create mode 100644 src/and/hpcvm/LocalHost.java create mode 100644 src/and/hpcvm/Server.java create mode 100644 src/and/hpcvm/ServicesClient.java create mode 100644 src/and/hpcvm/ServicesServer.java create mode 100644 src/and/hpcvm/Status.java create mode 100644 src/and/hpcvm/User.java create mode 100644 src/and/hpcvm/VirtualMachine.java diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..ab30c0d --- /dev/null +++ b/Makefile @@ -0,0 +1,37 @@ +# +# Makefile for HpcVm plateform +# Author: Sébastien Miquée +# + +SRC=src +PACKAGE=and/hpcvm +BIN=bin +LIB=${HOME}/lib +JAR=HpcVm.jar + +all: compile jar copy + +compile:clean + javac -d ./$(BIN) ./$(SRC)/$(PACKAGE)/*.java + javac -d ./$(BIN) ./$(SRC)/*.java + rmic -classpath $(BIN) -d ./$(BIN) and.hpcvm.Server + rmic -classpath $(BIN) -d ./$(BIN) and.hpcvm.Client + +rmi:compile + rmic -classpath $(BIN) -d ./$(BIN) and.hpcvm.Server + rmic -classpath $(BIN) -d ./$(BIN) and.hpcvm.Client + +jar: + jar cvfm ./$(JAR) Manifest -C ./$(BIN) $(PACKAGE) + +copy: + cp $(JAR) $(LIB) + +clean: + rm -rf ./$(BIN)/* $(JAR) + + +# +## +# + diff --git a/Manifest b/Manifest new file mode 100644 index 0000000..d4afea8 --- /dev/null +++ b/Manifest @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: and.hpcvm.HpcVm +Class-path: ./HpcVm.jar:. \ No newline at end of file diff --git a/src/InGuest.java b/src/InGuest.java new file mode 100644 index 0000000..4c61c68 --- /dev/null +++ b/src/InGuest.java @@ -0,0 +1,101 @@ +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.FileNotFoundException; +import java.io.FileReader; +import java.io.IOException; +import java.io.OutputStreamWriter; +import java.io.PrintWriter; +import java.net.InetAddress; +import java.net.Socket; +import java.net.UnknownHostException; + + +public class InGuest +{ + + private static String name ; + private static String IP ; + private static String path = "/tmp/vm_host_ip" ; + private static FileReader fr ; + private static String host_ip ; + private static String host_port ; + + public static void main( String argv[] ) + { + System.out.println( "Running information program for HpcVm ..." ) ; + + /** Retrieving informations **/ + try { + InetAddress ia = InetAddress.getLocalHost() ; + name = ia.getCanonicalHostName() ; + IP = ia.getHostAddress() ; + } catch( Exception e ) { + System.err.println( "Error: Unknown Host: " + e ) ; + } + + /** Retrieving host informations **/ + try { + fr = new FileReader( path ) ; + } catch( FileNotFoundException e ) { + e.printStackTrace() ; + } + BufferedReader bf = new BufferedReader( fr ) ; + + String line = null ; + + try { + line = bf.readLine() ; + } catch( IOException e ) { + e.printStackTrace() ; + } + + String[] infos = line.split( " " ) ; + + try { + host_ip = infos[0] ; + host_port = infos[1] ; + } catch( Exception e ) { + e.printStackTrace() ; + } + + /* Close file */ + try { + bf.close() ; + fr.close() ; + } catch( IOException e ) { + e.printStackTrace() ; + } + + + /** Sending informations to host **/ + try { + Socket socket = new Socket( host_ip, Integer.parseInt( host_port ) ) ; + + PrintWriter pw = new PrintWriter( new BufferedWriter( + new OutputStreamWriter( socket.getOutputStream() ) ), true ) ; + + pw.print( "infos" ) ; + + /* Sending name */ + pw.print( name ) ; + + /* Sending IP */ + pw.print( IP ) ; + + + /* Close streams */ + pw.close() ; + socket.close() ; + + + } catch( NumberFormatException e ) { + e.printStackTrace(); + } catch( UnknownHostException e ) { + e.printStackTrace() ; + } catch( IOException e ) { + e.printStackTrace() ; + } + + System.out.println( "... Ok" ) ; + } +} \ No newline at end of file diff --git a/src/and/hpcvm/Client.java b/src/and/hpcvm/Client.java new file mode 100644 index 0000000..2f1e01b --- /dev/null +++ b/src/and/hpcvm/Client.java @@ -0,0 +1,1583 @@ +package and.hpcvm ; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.io.InputStreamReader; +import java.net.MalformedURLException; +import java.net.ServerSocket; +import java.net.Socket; +import java.rmi.Naming; +import java.rmi.NotBoundException; +import java.rmi.RemoteException; +import java.rmi.registry.LocateRegistry; +import java.rmi.registry.Registry; +import java.rmi.server.UnicastRemoteObject; +import java.util.ArrayList; + + +public class Client extends UnicastRemoteObject implements ServicesClient +{ + private static final long serialVersionUID = 1L ; + + private String VmRunCommand ; +// private String VmRunCommandArg ; + private VirtualMachine machine ; + private String server_ip ; + private int server_port ; + private int client_port ; + private int dialog_port ; + private ServicesServer serverStub ; + private ServicesClient myStub ; + private PingServer pingServer ; + private DialogVMServer dialogVmServer ; + private ServerSocket serverSocket ; + private String ushell ; + private String working_directory ; + private int wait_start ; + private int max_start_try ; + private boolean isRestartedSave ; + private long save_interleave ; + private long date_last_save ; + private SaveProcess saveProcess; + private int maxRetryVM ; + private int timeRetryVM ; + + + protected Client() throws RemoteException + { + super() ; + } + + + @Override + public int startVM( int _mode ) + { + if( machine != null && ! machine.getStatus().equalsIgnoreCase( "running" ) ) + { + boolean ret = true ; + int retry = 0 ; + + /** Starting VM **/ + System.out.print( "Starting VM ... " ) ; + + machine.setStatus( "undefined" ) ; + if( _mode == 0 ) + { + try { + LocalHost.Instance().getServerStub().changeStatus( + LocalHost.Instance().getIP(), "undefined" ) ; + } catch( RemoteException e ) { + System.err.println( "Unable to inform the server of the VM status!" ) ; + e.printStackTrace() ; + } + } + + String[] command = new String[]{VmRunCommand, "-T", "player", "start", + working_directory + "/" + machine.getDirectory() + "/" + machine.getVmx_name(), "nogui"} ; + + while( ret ) + try { + Process p = Runtime.getRuntime().exec( command ) ; + p.waitFor() ; + + if( p.exitValue() == 0 ) + { + System.out.println( "Virtual machine successfully started." ) ; + ret = false ; + } else { + System.err.println( "Virtual machine not started!" ) ; + ret = printProcessError( p ) ; + + if( ! ret ) + { + return 1 ; + } else { + retry++ ; + if( retry >= maxRetryVM ) + { + System.err.println( "Unable to start VM!" ) ; + return 1 ; + } + System.out.println( "Retrying (" + retry + ") ... " ) ; + Thread.sleep( timeRetryVM ) ; + } + } + } catch( IOException e ) { + System.err.println( "Error during execution of start command: " ) ; + e.printStackTrace() ; + return 1 ; + } catch( InterruptedException e ) { + e.printStackTrace() ; + return 1 ; + } + + + boolean started = false ; + int count = 1 ; + ret = true ; + retry = 0 ; + + while( ! started ) + { + /** Waiting for VM being started **/ + try { + Thread.sleep( wait_start ) ; + } catch( InterruptedException e ) { + e.printStackTrace() ; + } + + String cmd2 = VmRunCommand + " -T " + " player " + " -gu " + machine.getVmUser() + + " -gp " + machine.getVmUserPasswd() + " runScriptInGuest " + + working_directory + "/" + machine.getDirectory() + + "/" + machine.getVmx_name() + " " + ushell + + " \"echo ok\"" ;// + " -noWait " ; + + try { + FileWriter fw = new FileWriter( new File( working_directory + "/testStarted.sh" ) ) ; + fw.write( cmd2 ) ; + fw.flush() ; + fw.close() ; + } catch( IOException e1 ) { + e1.printStackTrace() ; + } + + command = new String[]{ ushell, working_directory + "/testStarted.sh"} ; + + while( ret ) + try { + Process p = Runtime.getRuntime().exec( command ) ; + p.waitFor() ; + + if( p.exitValue() == 0 ) + { + started = true ; +// machine.setStatus( "running" ) ; +// if( _mode == 0 ) +// { +// LocalHost.Instance().getServerStub().changeStatus( +// LocalHost.Instance().getIP(), "running" ) ; +// } + ret = false ; + } else { + System.err.println( "Error while checking if the VM is started!" ) ; +// printProcessError( p.getErrorStream() ) ; + ret = printProcessError( p ) ; + + if( ! ret ) + { + return 1 ; + } else { + retry++ ; + if( retry >= maxRetryVM ) + { + System.err.println( "Unable to check VM!" ) ; + return 1 ; + } + System.out.println( "Retrying (" + retry + ") ... " ) ; + Thread.sleep( timeRetryVM ) ; + } +// wait_start = wait_start / 2 ; + count++ ; + } + } catch( IOException e ) { + e.printStackTrace() ; + } catch( InterruptedException e ) { + e.printStackTrace() ; + } + + if( count == max_start_try && ! started ) + { + System.err.println( "Virtual machine not responding!!" ) ; + + try { + LocalHost.Instance().getServerStub().changeStatus( + LocalHost.Instance().getIP(), "undefined" ) ; + } catch( RemoteException e ) { + e.printStackTrace() ; + } + + stopVM() ; + + return 1 ; + } else { + try { + Thread.sleep( 3000 ) ; + } catch( InterruptedException e ) { + e.printStackTrace() ; + } + } + } + + /** Sending the host ip **/ + + System.out.print( "Sending host IP to VM ... " ) ; + + String cmd2 = VmRunCommand + " -T " + " player " + " -gu " + machine.getVmUser() + + " -gp " + machine.getVmUserPasswd() + " runScriptInGuest " + + working_directory + "/" + machine.getDirectory() + + "/" + machine.getVmx_name() + " " + ushell + + " \"echo " + LocalHost.Instance().getIP() + " " + dialog_port + + " > /tmp/vm_host_IP\"" ; + + try { + FileWriter fw = new FileWriter( new File( working_directory + "/sendHostIP.sh" ) ) ; + fw.write( cmd2 ) ; + fw.flush() ; + fw.close() ; + } catch( IOException e1 ) { + e1.printStackTrace() ; + } + + command = new String[]{ ushell, working_directory + "/sendHostIP.sh"} ; + + ret = true ; + retry = 0 ; + + while( ret ) + try { + Process p = Runtime.getRuntime().exec( command ) ; + p.waitFor() ; + + if( p.exitValue() == 0 ) + { + System.out.println( "VM received the host IP." ) ; + ret = false ; + } else { + System.err.println( "VM did not received the host IP!" ) ; +// printProcessError( p.getErrorStream() ) ; + ret = printProcessError( p ) ; + + if( ! ret ) + { + return 1 ; + } else { + retry++ ; + if( retry >= maxRetryVM ) + { + System.err.println( "Unable to send information to VM!" ) ; + + stopVM() ; + + return 1 ; + } + System.out.println( "Retrying (" + retry + ") ... " ) ; + Thread.sleep( timeRetryVM ) ; + } + } + } catch( IOException e ) { + System.err.println( "Error during execution of runScriptInGuest command: " ) ; + e.printStackTrace() ; + } catch( InterruptedException e) { + e.printStackTrace() ; + } + + /** Sending the vm ip **/ + + System.out.print( "Sending its IP to VM ... " ) ; + + cmd2 = VmRunCommand + " -T " + " player " + " -gu " + machine.getVmUser() + + " -gp " + machine.getVmUserPasswd() + " runScriptInGuest " + + working_directory + "/" + machine.getDirectory() + + "/" + machine.getVmx_name() + " " + ushell + + " \"echo " + machine.getIp() + + " > /tmp/vm_IP\"" ; + + try { + FileWriter fw = new FileWriter( new File( working_directory + "/sendVmIP.sh" ) ) ; + fw.write( cmd2 ) ; + fw.flush() ; + fw.close() ; + } catch( IOException e1 ) { + e1.printStackTrace() ; + } + + command = new String[]{ ushell, working_directory + "/sendVmIP.sh"} ; + + ret = true ; + retry = 0 ; + + while( ret ) + try { + Process p = Runtime.getRuntime().exec( command ) ; + p.waitFor() ; + + if( p.exitValue() == 0 ) + { + System.out.println( "VM received its assigned IP." ) ; +// return 0 ; + ret = false ; + machine.setStatus( "running" ) ; + } else { + System.err.println( "VM did not received its assigned IP!" ) ; +// printProcessError( p.getErrorStream() ) ; + ret = printProcessError( p ) ; + + if( ! ret ) + { + return 1 ; + } else { + retry++ ; + if( retry >= maxRetryVM ) + { + System.err.println( "Unable to send information to VM!" ) ; + + stopVM() ; + + return 1 ; + } + System.out.println( "Retrying (" + retry + ") ... " ) ; + Thread.sleep( timeRetryVM ) ; + } + } + } catch( IOException e ) { + System.err.println( "Error during execution of runScriptInGuest command: " ) ; + e.printStackTrace() ; + } catch( InterruptedException e ) { + e.printStackTrace() ; + } + + if( _mode == 0 ) + { + try { + LocalHost.Instance().getServerStub().changeStatus( + LocalHost.Instance().getIP(), "running" ) ; + } catch (RemoteException e) { + System.err.println( "Unable to inform the server of the VM started status!" ) ; + e.printStackTrace(); + } + } + + return 0 ; + } + + return 1 ; + } + + @Override + public int stopVM() + { + if( machine != null && machine.getStatus().equalsIgnoreCase( "stopped" ) ) + { + return 0 ; + } + + if( machine != null && ! machine.getStatus().equalsIgnoreCase( "stopped" ) ) + { + System.out.print( "Stopping VM ... " ) ; + + boolean ret = true ; + int retry = 0 ; + + machine.setStatus( "undefined" ) ; + try { + LocalHost.Instance().getServerStub().changeStatus( + LocalHost.Instance().getIP(), "undefined" ) ; + } catch( RemoteException e ) { + System.err.println( "Unable to inform the server of the VM status!" ) ; + e.printStackTrace() ; + } + + String[] command = new String[]{VmRunCommand, "-T", "player", "stop", + working_directory + "/" + machine.getDirectory() + "/" + machine.getVmx_name()} ; + + while( ret ) + try { + Process p = Runtime.getRuntime().exec( command ) ; + p.waitFor() ; + + if( p.exitValue() == 0 ) + { + System.out.println( "Virtual machine successfully stopped." ) ; + machine.setStatus( "stopped" ) ; + ret = false ; + } else { + System.err.println( "Virtual machine not stopped!" ) ; +// printProcessError( p.getErrorStream() ) ; + ret = printProcessError( p ) ; + + if( ! ret ) + { + return 1 ; + } else { + retry++ ; + if( retry >= maxRetryVM ) + { + System.err.println( "Unable to stop VM!" ) ; + return 1 ; + } + System.out.println( "Retrying (" + retry + ") ... " ) ; + Thread.sleep( timeRetryVM ) ; + } + +// return 1 ; + } + } catch( IOException e ) { + System.err.println( "Error during execution of stop command: " ) ; + e.printStackTrace() ; + } catch( InterruptedException e ) { + e.printStackTrace() ; + } + + machine.setStatus( "stopped" ) ; + try { + LocalHost.Instance().getServerStub().changeStatus( + LocalHost.Instance().getIP(), "stopped" ) ; + } catch( RemoteException e1 ) { + System.err.println( "Unable to inform the server of the VM stopped status!" ) ; + e1.printStackTrace() ; + } + + if( ! isRestartedSave ) + { + /** Restoring the original vmx file (necessary after a crash) **/ + command = new String[]{ "/bin/cp", + working_directory + "/" + machine.getDirectory() + "/" + machine.getVmx_name_normal(), + working_directory + "/" + machine.getDirectory() + "/" + machine.getVmx_name() } ; + + try { + Process p = Runtime.getRuntime().exec( command ) ; + p.waitFor() ; + + if( p.exitValue() == 0 ) + { + System.out.println( "Successfully replaced the VMX file." ) ; + return 0 ; + } else { + System.err.println( "Unsuccessful replacement of the VMX file!" ) ; +// printProcessError( p.getErrorStream() ) ; + printProcessError( p ) ; + + return 1 ; + } + } catch( IOException e ) { + System.err.println( "Error during VMX file replacement: " ) ; + e.printStackTrace() ; + } catch( InterruptedException e ) { + e.printStackTrace() ; + } + } else { + return 0 ; + } + } + + return 1 ; + } + + @Override + public int suspendVM( int _mode ) + { + if( machine != null && machine.getStatus().equalsIgnoreCase( "suspended" ) ) + { + return 0 ; + } + + if( machine != null && ! machine.getStatus().equalsIgnoreCase( "suspended" ) ) + { + System.out.print( "Suspending VM ... " ) ; + + boolean ret = true ; + int retry = 0 ; + + machine.setStatus( "undefined" ) ; + if( _mode == 0 ) + { + try { + LocalHost.Instance().getServerStub().changeStatus( + LocalHost.Instance().getIP(), "undefined" ) ; + } catch( RemoteException e ) { + System.err.println( "Unable to inform the server of the VM status!" ) ; + e.printStackTrace() ; + } + } + + String[] command = new String[]{VmRunCommand, "-T", "player", "suspend", + working_directory + "/" + machine.getDirectory() + "/" + machine.getVmx_name()} ; + + while( ret ) + try { + Process p = Runtime.getRuntime().exec( command ) ; + p.waitFor() ; + if( p.exitValue() == 0 ) + { + System.out.println( "Virtual machine successfully suspended." ) ; + machine.setStatus( "suspended" ) ; + ret = false ; + } else { + System.err.println( "Virtual machine not suspended!" ) ; +// printProcessError( p.getErrorStream() ) ; + ret = printProcessError( p ) ; + + if( ! ret ) + { + return 1 ; + } else { + retry++ ; + if( retry >= maxRetryVM ) + { + System.err.println( "Unable to suspend VM!" ) ; + return 1 ; + } + System.out.println( "Retrying (" + retry + ") ... " ) ; + Thread.sleep( timeRetryVM ) ; + } + +// return 1 ; + } + } catch( IOException e ) { + System.err.println( "Error during execution of suspend command: " ) ; + e.printStackTrace() ; + } catch( InterruptedException e ) { + e.printStackTrace() ; + } + + machine.setStatus( "suspended" ) ; + if( _mode == 0 ) + { + try { + LocalHost.Instance().getServerStub().changeStatus( + LocalHost.Instance().getIP(), "suspended" ) ; + } catch( RemoteException e ) { + System.err.println( "Unable to inform the server of the VM suspended status!" ) ; + e.printStackTrace() ; + } + } + + return 0 ; + } + + return 1 ; + } + + @Override + public int restartVM() + { + if( machine != null ) + { + System.out.print( "Restarting VM ... " ) ; + + boolean ret = true ; + int retry = 0 ; + + try { + LocalHost.Instance().getServerStub().changeStatus( + LocalHost.Instance().getIP(), "undefined" ) ; + } catch( RemoteException e ) { + System.err.println( "Unable to inform the server of the VM status!" ) ; + e.printStackTrace() ; + } + + String[] command = new String[]{VmRunCommand, "-T", "player", "reset", + working_directory + "/" + machine.getDirectory() + "/" + machine.getVmx_name()} ; + + while( ret ) + try { + Process p = Runtime.getRuntime().exec( command ) ; + p.waitFor() ; + + if( p.exitValue() == 0 ) + { + System.out.println( "Virtual machine successfully restarted." ) ; + + if( sendSaveOkVM() == 1 ) { return 1 ; } + + ret = false ; + return 0 ; + + } else { + System.err.println( "Virtual machine not restarted!" ) ; +// printProcessError( p.getErrorStream() ) ; + ret = printProcessError( p ) ; + + if( ! ret ) + { + return 1 ; + } else { + retry++ ; + if( retry >= maxRetryVM ) + { + System.err.println( "Unable to start VM!" ) ; + return 1 ; + } + System.out.println( "Retrying (" + retry + ") ... " ) ; + Thread.sleep( timeRetryVM ) ; + } + +// return 1 ; + } + } catch( IOException e ) { + System.err.println( "Error during execution of restart command: " ) ; + e.printStackTrace() ; + } catch( InterruptedException e ) { + e.printStackTrace() ; + } + } + + return 1 ; + } + + @Override + public int restartVMAfterCrash() + { + System.out.println( "Restarting VM after a crash ..." ) ; + + try { + LocalHost.Instance().getServerStub().changeStatus( + LocalHost.Instance().getIP(), "undefined" ) ; + } catch( RemoteException e ) { + System.err.println( "Unable to inform the server of the VM status!" ) ; + e.printStackTrace() ; + } + + if( stopVM() == 0 ) + { + if( machine.deployLastSave() == 0 ) + { + if( isRestartedSave ) + { + // Using the specific vmx file + System.out.print( "Changing VMX file after crash ... " ) ; + + String[] command = new String[]{ "/bin/cp", + working_directory + "/" + machine.getDirectory() + "/" + machine.getVmx_name_crash(), + working_directory + "/" + machine.getDirectory() + "/" + machine.getVmx_name() } ; + + try { + Process p = Runtime.getRuntime().exec( command ) ; + p.waitFor() ; + + if( p.exitValue() == 0 ) + { + System.out.println( "Successfully replaced the VMX file." ) ; + } else { + System.err.println( "Unsuccessful replacement of the VMX file!" ) ; +// printProcessError( p.getErrorStream() ) ; + printProcessError( p ) ; + + return 1 ; + } + } catch( IOException e ) { + System.err.println( "Error during VMX file replacement: " ) ; + e.printStackTrace() ; + } catch( InterruptedException e ) { + e.printStackTrace() ; + } + + // Removing lock files + System.out.print( "Removing lock files ... " ) ; + + command = new String[]{ "/bin/rm", "-rf", + working_directory + "/" + machine.getDirectory() + + "/" + machine.getVmx_name() + ".lck" } ; + + try { + Process p = Runtime.getRuntime().exec( command ) ; + p.waitFor() ; + + if( p.exitValue() == 0 ) + { + System.out.println( "Successfully deleted lock files." ) ; + } else { + System.err.println( "Unsuccessful deletion of lock files!" ) ; +// printProcessError( p.getErrorStream() ) ; + printProcessError( p ) ; + + return 1 ; + } + } catch( IOException e ) { + System.err.println( "Error during lock files deletion: " ) ; + e.printStackTrace() ; + } catch( InterruptedException e ) { + e.printStackTrace() ; + } + + /** Retrieving VM assigned IP **/ + String vmIP = null ; + + try { + vmIP = LocalHost.Instance().getServerStub().getAssociatedIP( + LocalHost.Instance().getIP() ) ; + } catch (RemoteException e) { + System.err.println( "Problem while retrieving the VM assigned IP!!" ) ; + e.printStackTrace() ; + return 1 ; + } + + machine.setIp( vmIP ) ; + + isRestartedSave = false ; + } + + if( startVM( 0 ) == 0 ) + { + if( sendSaveOkVM() == 0 ) + { + return 0 ; + } + } else { + stopVM() ; + } + } + } + + return 1 ; + } + + + private int sendSaveOkVM() + { + boolean ret = true ; + int retry = 0 ; + + /** Informing the program that it's ok **/ + System.out.print( "Sending OK signal to the program ... " ) ; + + String cmd2 = VmRunCommand + " -T " + " player " + " -gu " + machine.getVmUser() + + " -gp " + machine.getVmUserPasswd() + " runScriptInGuest " + + working_directory + "/" + machine.getDirectory() + + "/" + machine.getVmx_name() + " " + ushell + + " \"echo ok > /tmp/vm_save_ok\"" ;// + " -noWait " ; + + try { + FileWriter fw = new FileWriter( new File( working_directory + "/saveOk.sh" ) ) ; + fw.write( cmd2 ) ; + fw.flush() ; + fw.close() ; + } catch( IOException e1 ) { + e1.printStackTrace() ; + } + + String[] command = new String[]{ ushell, working_directory + "/saveOk.sh"} ; + + while( ret ) + try { + Process p = Runtime.getRuntime().exec( command ) ; + p.waitFor() ; + + if( p.exitValue() == 0 ) + { + System.out.println( "Signal successfully sent." ) ; + ret = false ; + return 0 ; + } else { + System.err.println( "Signal not sent!" ) ; +// printProcessError( p.getErrorStream() ) ; + ret = printProcessError( p ) ; + + if( ! ret ) + { + return 1 ; + } else { + retry++ ; + if( retry >= maxRetryVM ) + { + System.err.println( "Unable to send ok signal to VM!" ) ; + return 1 ; + } + System.out.println( "Retrying (" + retry + ") ... " ) ; + Thread.sleep( timeRetryVM ) ; + } +// return 1 ; + } + } catch( IOException e ) { + System.err.println( "Error during ok save signal send command: " ) ; + e.printStackTrace() ; + return 1 ; + } catch( InterruptedException e ) { + e.printStackTrace() ; + return 1 ; + } + + return 1 ; + } + + + @Override + public int saveVM() + { + synchronized( saveProcess ){ + while( saveProcess.getStatus() ) + { + try { + saveProcess.wait() ; + } catch( InterruptedException e ) { + e.printStackTrace() ; + } + }} + + System.out.println( "Saving VM ..." ) ; + saveProcess.setStatus( true ) ; + + machine.setStatus( "saving" ) ; + try { + LocalHost.Instance().getServerStub().changeStatus( + LocalHost.Instance().getIP(), "saving" ) ; + } catch( RemoteException e ) { + System.err.println( "Unable to inform the server of the VM status!" ) ; + e.printStackTrace() ; + } + + String[] command ; + String saveName = "" ; + boolean error = false ; + boolean errorVM = false ; + + if( suspendVM( 1 ) == 1 ) { error = true ; errorVM = true ; } + + if( ! error ) + { + System.out.print( "Creation of the archive ... " ) ; + /** Archive creation **/ + command = new String[]{ "/bin/tar", "-cvf", + working_directory + "/" + machine.getName() + "_new_" + machine.getComputationId() + ".tar", + working_directory + "/" + machine.getDirectory() } ; + + try { + Process p = Runtime.getRuntime().exec( command ) ; + p.waitFor() ; + + if( p.exitValue() == 0 ) + { + System.out.println( "Archive successfully created." ) ; + } else { + System.err.println( "Archive not created!" ) ; +// printProcessError( p.getErrorStream() ) ; + printProcessError( p ) ; + + error = true ; + } + } catch( IOException e ) { + System.err.println( "Error during archive creation command: " ) ; + error = true ; + e.printStackTrace() ; + } catch( InterruptedException e ) { + e.printStackTrace() ; + error = true ; + } + + /** Compression of the archive **/ + if( ! error ) + { + System.out.print( "Compression of the archive ... " ) ; + command = new String[]{ "/bin/gzip", + working_directory + "/" + machine.getName() + + "_new_" + machine.getComputationId() + ".tar" } ; + + try { + Process p = Runtime.getRuntime().exec( command ) ; + p.waitFor() ; + + if( p.exitValue() == 0 ) + { + System.out.println( "Archive successfully compressed." ) ; + } else { + System.err.println( "Archive not compressed!" ) ; +// printProcessError( p.getErrorStream() ) ; + printProcessError( p ) ; + + error = true ; + } + } catch( IOException e ) { + System.err.println( "Error during archive compression command: " ) ; + e.printStackTrace() ; + error = true ; + } catch( InterruptedException e ) { + e.printStackTrace() ; + error = true ; + } + } + + + /** Restarting VM **/ + if( errorVM || startVM( 0 ) == 1 ) { error = true ; } + + + /** Sending ok save signal **/ + if( ! error ) + { + if( sendSaveOkVM() == 1 ) { error = true ; } + } + +// /** Deletion of the tar archive **/ +// if( ! error ) +// { +// command = new String[]{ "/bin/rm", +// working_directory + "/" + machine.getName() +// + "_new_" + machine.getComputationId() + ".tar" } ; +// +// try { +// Process p = Runtime.getRuntime().exec( command ) ; +// p.waitFor() ; +// +// if( p.exitValue() == 0 ) +// { +// System.out.println( "Archive (not compressed) successfully deleted." ) ; +// } else { +// System.err.println( "Archive (not compressed) not deleted!" ) ; +// printProcessError( p.getErrorStream() ) ; +// +// error = true ; +// } +// } catch( IOException e ) { +// System.err.println( "Error during archive (not compressed) deletion command: " ) ; +// e.printStackTrace() ; +// error = true ; +// } catch( InterruptedException e ) { +// e.printStackTrace() ; +// error = true ; +// } +// } + + saveName = working_directory + "/" + machine.getName() + "_new_" + + machine.getComputationId() + ".tar.gz" ; + + /** Sending save to neighbor **/ + if( ! error ) + { + ArrayList sn = machine.getSaveNeighbors() ; + + for( int i = 0 ; i < sn.size() ; i++ ) + { + System.out.print( "Sending save to " + sn.get( i ) + " ... " ) ; + command = new String[]{ "/usr/bin/scp", saveName, + sn.get( i ) + ":" + + working_directory } ; + + try { + Process p = Runtime.getRuntime().exec( command ) ; + p.waitFor() ; + + if( p.exitValue() == 0 ) + { + System.out.println( "Archive successfully sent." ) ; + } else { + System.err.println( "Archive not sent!" ) ; +// printProcessError( p.getErrorStream() ) ; + printProcessError( p ) ; + + error = true ; + } + } catch( IOException e ) { + System.err.println( "Error during archive send command: " ) ; + e.printStackTrace() ; + error = true ; + } catch( InterruptedException e ) { + e.printStackTrace() ; + error = true ; + } + } + } + } + + /** Informing the server the save is done **/ + if( ! error ) + { + try { + LocalHost.Instance().getServerStub().saveOk( LocalHost.Instance().getIP(), saveName ) ; + } catch( RemoteException e ) { + System.err.println( "Problem while informing the server about the save state!" ) ; + e.printStackTrace() ; + } + + synchronized( saveProcess ) { + saveProcess.setStatus( false ) ; + try { + saveProcess.notifyAll() ; + } catch( Exception e ) {}} + + return 0 ; + } + + synchronized( saveProcess ) { + saveProcess.setStatus( false ) ; + try { + saveProcess.notifyAll() ; + } catch( Exception e ) {}} + + return 1 ; + } + + + @Override + public int reloadConfig() + { + System.out.println( "Reloading configuration ... " ) ; + + // TODO !!! + return 0 ; + } + + public void init( String _server_ip, int _server_port, int _client_port, int _dialog_port ) + { + System.out.println( "Initialisation Client ... " ) ; + System.out.println( "IP " + LocalHost.Instance().getIP() ) ; + + server_ip = _server_ip ; + server_port = _server_port ; + client_port = _client_port ; + dialog_port = _server_port + 1 ; // _dialog_port ; + + serverStub = null ; + saveProcess = new SaveProcess() ; + + machine = new VirtualMachine() ; + + VmRunCommand = "/usr/bin/vmrun" ; +// VmRunCommandArg = "-T player" ; + +// vm_user = "mpi" ; +// vm_user_passwd = "mpi" ; + ushell = "/bin/bash" ; + working_directory = "/localhome/vmware" ; + + wait_start = 15000 ; + max_start_try = 10 ; + + maxRetryVM = 10 ; + timeRetryVM = 10000 ; + + save_interleave = 30 * 60 * 1000 ; + date_last_save = 0 ; + + isRestartedSave = false ; + + /** Connection to server **/ + try { + serverStub = (ServicesServer) Naming.lookup( "rmi://" + + server_ip + ":" + server_port + "/Server" ) ; + } catch (MalformedURLException e) { + e.printStackTrace(); + } catch (RemoteException e) { + e.printStackTrace(); + } catch (NotBoundException e) { + e.printStackTrace(); + } + + if( serverStub == null ) + { + System.err.println( "Unable to connect to server!!" ) ; + System.err.println( "Server IP: " + server_ip + " -- server port: " + server_port ) ; + + System.exit( 1 ) ; + } + + System.out.println( "Connected to server " + server_ip + " on port " + server_port + "." ) ; + +// LocalHost.Instance().setServerIP( server_ip ) ; + LocalHost.Instance().setServerStub( serverStub ) ; + + + /** Creating the local server **/ + exportObject() ; + + /** Starting all threads **/ + start() ; + } + + private void exportObject() + { +// ServicesClient ref = null ; + Registry reg = null ; + + try + { + while( true ) + { + reg = LocateRegistry.getRegistry( client_port ) ; + + String tab[] = reg.list() ; + + System.out.println( "There is an existing RMI Registry on port " + + client_port + " with " + tab.length + " entries!" ) ; + for( int i = 0 ; i < tab.length ; i++ ) + { + try { + if( UnicastRemoteObject.unexportObject( Naming.lookup(tab[i]), true ) ) + { + System.out.println( "Register successfuly deleted!" ) ; + } else { + System.err.println( "Register undeleted !!!" ) ; + } + } catch( Exception e ) { + e.printStackTrace() ; + } + } + } + } catch( RemoteException e ) { + } + + try { + if ( System.getSecurityManager() == null ) + { + System.setSecurityManager( new SecurityManager() ) ; + } + + LocateRegistry.createRegistry( client_port ) ; + LocateRegistry.getRegistry( client_port ).rebind( "Client", this ) ; + myStub = (ServicesClient) Naming.lookup( "rmi://" + + LocalHost.Instance().getIP() + ":" + client_port + + "/Client" ) ; + } catch( Exception e ) { + System.err.println( "Error in Client.exportObject() when creating local services:" + e ) ; + System.err.println( "Exit from Client.exportObject" ) ; + System.exit( 1 ) ; + } + + LocalHost.Instance().setStub( myStub ) ; + } + + + private boolean printProcessError( Process _p ) + { + boolean ret = false ; + + if( _p != null ) + { + System.err.println( "Error: " + _p.exitValue() ) ; + BufferedReader br = new BufferedReader( new InputStreamReader( _p.getErrorStream() ) ) ; + String line ; + try { + while( (line = br.readLine()) != null ) + { + System.err.println( line ) ; + if( line.contains( "egmentation" ) ) + { + ret = true ; + } + } + } catch( IOException e ) { + e.printStackTrace() ; + } + } + + return ret ; + } + + + @Override + public int start() + { + /** Registering on server **/ + Integer ret = 0 ; + try { + ret = LocalHost.Instance().getServerStub().register( LocalHost.Instance().getStub() ); + } catch (RemoteException e1) { + e1.printStackTrace(); + return 1 ; + } + + switch( ret ) + { + case 0: System.out.println( "Successfully registered on server." ) ; break ; + case 1: System.err.println( "Problem on server while registreting!" ) ; return 1 ; + case 2: System.out.println( "Already registered on server!" ) ; break ; + } + + /** Retrieving VM assigned IP **/ + String vmIP = null ; + + try { + vmIP = LocalHost.Instance().getServerStub().getAssociatedIP( + LocalHost.Instance().getIP() ) ; + } catch (RemoteException e) { + System.err.println( "Problem while retrieving the VM assigned IP!!" ) ; + e.printStackTrace() ; + return 1 ; + } + + machine.setIp( vmIP ) ; + + System.out.println( "Assigned IP address for the VM: " + vmIP ) ; + + + /** Starting alive ping to server **/ + pingServer = new PingServer() ; + pingServer.start() ; + + /** Starting socket server for VM dialog **/ + dialogVmServer = new DialogVMServer() ; + dialogVmServer.start() ; + + return 0 ; + } + + + private class PingServer extends Thread + { + private boolean run ; + + PingServer() + { + run = true ; + } + + protected void stopPing() { run = false ; } + + @Override + public void run() + { + while( run ) + { + try { + LocalHost.Instance().getServerStub().ping( LocalHost.Instance().getIP() ) ; + } catch (RemoteException e1) { + e1.printStackTrace(); + } + + try { + Thread.sleep( 2000 ) ; + } catch( InterruptedException e ) { + e.printStackTrace() ; + } + } + } + } + + + private class DialogVMServer extends Thread + { + private boolean run ; + private Socket socket ; + private ArrayList dialogs = new ArrayList() ; + + DialogVMServer() + { + run = true ; + } + + protected void stopDialogVMServer() + { + run = false ; + + if( serverSocket != null ) + { + try { + serverSocket.close() ; +// socket = serverSocket.accept() ; + + for( int i = 0 ; i < dialogs.size() ; i++ ) + { + dialogs.get( i ).stopDialogVM() ; + } + + } catch( IOException e ) { + e.printStackTrace() ; + } + } + } + + + @Override + public void run() + { + try { + serverSocket = new ServerSocket( 0 ) ; + dialog_port = serverSocket.getLocalPort() ; + + System.out.println( "SocketServer listening on port " + dialog_port ) ; + } catch( IOException e ) { + System.err.println( "Unable to launch the SocketServer on port " + dialog_port + "!" ) ; + e.printStackTrace() ; + + run = false ; + } + + while( run ) + { + try { + socket = serverSocket.accept() ; + + dialogs.add( new DialogVM( socket ) ) ; + dialogs.get( dialogs.size() - 1 ).start() ; + } catch( IOException e ) { + System.err.println( "Problem with the accept function!" ) ; + e.printStackTrace() ; + } + } + } + } + + + private class DialogVM extends Thread + { + private boolean run ; + private Socket socket ; + private BufferedReader reader ; + private String line ; + + DialogVM( Socket _socket ) { run = true ; socket = _socket ; } + + protected void stopDialogVM() + { + run = false ; + + try { + reader.close() ; reader = null ; + socket.close() ; socket = null ; + } catch( IOException e ) { + e.printStackTrace() ; + } + } + + @Override + public void run() + { + try { + reader = new BufferedReader( new InputStreamReader( socket.getInputStream() ) ) ; + } catch( IOException e ) { + System.err.println( "Unable to open a dialog socket with the VM!" ) ; + e.printStackTrace(); + stopDialogVM() ; + } + + while( run ) + { + try { + line = null ; + + if( reader != null ) + { + line = reader.readLine() ; + } + + /** VM is starting -- retrieving informations **/ + if( run && line != null && line.equalsIgnoreCase( "infos" ) ) + { + /* Receiving name */ + machine.setName( reader.readLine() ) ; + + /* Receiving IP */ + String ip = reader.readLine() ; + if( ! ip.equalsIgnoreCase( machine.getIp() ) ) + { + System.err.println( "VM IP not well configured!!" ) ; + } + + /* Close streams */ + reader.close() ; reader = null ; + socket.close() ; socket = null ; + + run = false ; + } + + /** It's time to do a save **/ + if( run && line != null && line.equalsIgnoreCase( "save" ) ) + { + try { + machine.setComputationId( Integer.parseInt( reader.readLine() ) ) ; + } catch( Exception e ) { + System.err.println( "Problem while reading the computation id!" ) ; + e.printStackTrace() ; + } + + if( (System.currentTimeMillis() - date_last_save) > save_interleave ) + { + date_last_save = System.currentTimeMillis() ; + + /* Close streams */ + reader.close() ; reader = null ; + socket.close() ; socket = null ; + + run = false ; + + /* Starting the VM save */ + saveVM() ; + } else { + sendSaveOkVM() ; + } + } + + + /** Computation is done, we can shutdown the VM **/ + if( run && line != null && line.equalsIgnoreCase( "quit" ) ) + { + try { + Thread.sleep( 5000 ) ; + } catch( InterruptedException e ) { + e.printStackTrace() ; + } + + /* Close streams */ + reader.close() ; reader = null ; + socket.close() ; socket = null ; + + run = false ; + + stopVM() ; + } + + } catch( IOException e ) { + e.printStackTrace() ; + } + } + } + } + + @Override + public void stop() + { + stopVM() ; + + pingServer.stopPing() ; + + dialogVmServer.stopDialogVMServer() ; + + // unexportObject ?? + + System.exit( 0 ) ; + } + + @Override + public String getIPHost() + { + return LocalHost.Instance().getIP() ; + } + + @Override + public String getName() + { + return LocalHost.Instance().getName() ; + } + + + @Override + public void saveOk() + { + String save_name = "VmTest_" + machine.getComputationId() + + "_last.tar.gz" ; + + String save_new = working_directory + "/" + machine.getName() + "_new_" + + machine.getComputationId() + ".tar.gz" ; + + String[] command = new String[]{ "/bin/mv", + save_new, save_name } ; + + try { + Process p = Runtime.getRuntime().exec( command ) ; + p.waitFor() ; + + if( p.exitValue() == 0 ) + { + System.out.println( "Last save OK" ) ; + machine.setSave_last( save_name ) ; + } else { + System.err.println( "Last save NOK!" ) ; + System.err.println( "Error: " ) ; +// printProcessError( p.getErrorStream() ) ; + printProcessError( p ) ; + } + } catch( IOException e ) { + System.err.println( "Error during last archive move:" ) ; + e.printStackTrace() ; + } catch( InterruptedException e ) { + e.printStackTrace() ; + } + } + + @Override + public void setSavingNeighbor( String _sn ) throws RemoteException + { + if( _sn != null && _sn.length() > 0 ) + { + ArrayList as = new ArrayList() ; + as.add( _sn ) ; + + System.out.println( "Save neighbor: " + _sn ) ; + + machine.setSaveNeighbors( as ) ; + } + } + + @Override + public int retrieveSave( String _saveName ) throws RemoteException + { + if( _saveName != null ) + { + if( ! _saveName.equalsIgnoreCase( "none" ) ) + { + machine.setSave_last( _saveName ) ; + } else { + System.err.println( "I have no saving neighbor to contact!!" ) ; + return 1 ; + } + + // TODO NEIGHBORS !!!! + //System.out.println( "!!!! NEIGHBORS !!!!!" ) ; + System.out.print( "Retrieving a save on " + machine.getSaveNeighbors().get( 0 ) + " ..." ) ; + String[] command = new String[]{ "/usr/bin/scp", + machine.getSaveNeighbors().get( 0 ) + ":" + + working_directory + "/" + machine.getSave_last(), + working_directory } ; + + try { + Process p = Runtime.getRuntime().exec( command ) ; + p.waitFor() ; + + if( p.exitValue() == 0 ) + { + System.out.println( "Archive successfully retrieved." ) ; + isRestartedSave = true ; + return 0 ; + } else { + System.err.println( "Archive not retrieved!" ) ; + System.err.println( "Error: " ) ; +// printProcessError( p.getErrorStream() ) ; + printProcessError( p ) ; +// error = true ; + } + } catch( IOException e ) { + System.err.println( "Error during archive retrieve command: " ) ; + e.printStackTrace() ; +// error = true ; + } catch( InterruptedException e ) { + e.printStackTrace() ; +// error = true ; + } + } + + return 1 ; + + } + + @Override + public String getIPVM() throws RemoteException + { + if( machine != null ) + { + return machine.getIp() ; + } + + return null ; + } + + + @Override + public void setIPVM( String _ipVM ) throws RemoteException + { + if( _ipVM != null && ! _ipVM.isEmpty() ) + { + System.out.println( "The VM IP is now: " + _ipVM ) ; + machine.setIp( _ipVM ) ; + } + } + + + private class SaveProcess + { + boolean status ; + + SaveProcess() + { + status = false ; + } + + protected boolean getStatus() { return status ; } + + protected void setStatus( boolean _b ) { status = _b ; } + } + +} + + +/** La programmation est un art, respectons ceux qui la pratiquent !! **/ diff --git a/src/and/hpcvm/Configuration.java b/src/and/hpcvm/Configuration.java new file mode 100644 index 0000000..f0431c6 --- /dev/null +++ b/src/and/hpcvm/Configuration.java @@ -0,0 +1,11 @@ +package and.hpcvm ; + + +public class Configuration +{ + + +} + + +/** La programmation est un art, respectons ceux qui la pratiquent !! **/ diff --git a/src/and/hpcvm/HpcVm.java b/src/and/hpcvm/HpcVm.java new file mode 100644 index 0000000..d3416a8 --- /dev/null +++ b/src/and/hpcvm/HpcVm.java @@ -0,0 +1,163 @@ +package and.hpcvm ; + +public class HpcVm +{ + private static int client_port ; + private static String server_ip ; + private static int server_port ; + private static int dialog_port ; +// private static int mode ; // 0: server, 1: client + private static Client client ; + private static Server server ; + + + public static void main( String argv[] ) + { + + /** Initialisation of defaults variables **/ + client_port = 2667 ; + server_ip = "127.0.0.1" ; + server_port = 2666 ; + dialog_port = 7788 ; +// mode = -1 ; + + +// /** Signals handlers **/ +// SignalHandler signalHandler = new SignalHandler() { +// public void handle( Signal signal ) +// { +// System.out.println( "Exiting because of signal: " + signal ) ; +// System.out.println( "Killing all applications ..." ) ; +// +// switch( mode ) +// { +// case 0: if( server != null ) +// { +// server.stop() ; +// } +// break ; +// case 1: if( client != null ) +// { +// client.stop() ; +// } +// break ; +// } +// +// System.exit( 100 ) ; +// } +// } ) ; +// Signal.handle( new Signal( "TERM" ), signalHandler ) ; +// Signal.handle( new Signal( "INT" ), signalHandler ) ; + + + /** Launching ... **/ + + /** Server **/ + if( argv[0].equalsIgnoreCase( "server" ) ) + { + if( argv.length == 2 ) + { + server_port = Integer.parseInt( argv[1] ) ; + } + + try + { +// mode = 0 ; + server = new Server() ; + server.init( server_port ) ; + } catch( Exception e ) { + System.err.println( "Error while launching Server: " + e ) ; + } + + + /** Client **/ + } else if( argv[0].equalsIgnoreCase( "client" ) ) + { + /** Command line verification **/ + if( argv.length < 2 ) + { + usage() ; + System.exit( 1 ) ; + } + + + switch( argv.length ) + { + case 2: server_ip = argv[1] ; break ; + + case 3: server_ip = argv[1] ; + server_port = Integer.parseInt( argv[2] ) ; break ; + + case 4: server_ip = argv[1] ; + server_port = Integer.parseInt( argv[2] ) ; + client_port = Integer.parseInt( argv[3] ) ; break ; + + case 5: server_ip = argv[1] ; + server_port = Integer.parseInt( argv[2] ) ; + client_port = Integer.parseInt( argv[3] ) ; + dialog_port = Integer.parseInt( argv[4] ) ; break ; + } + + try + { +// mode = 1 ; + client = new Client() ; + client.init( server_ip, server_port, client_port, dialog_port ) ; + } catch( Exception e ) { + System.err.println( "Error while launching Client: " + e ) ; + } + } else if( argv[0].equalsIgnoreCase( "user" ) ) { + if( argv.length < 4 ) + { + usage() ; + System.exit( 1 ) ; + } + + User user = new User( argv[1], Integer.parseInt( argv[2] ) ) ; + + if( argv[3].equalsIgnoreCase( "stop" ) ) + { + user.stopMachines() ; + System.exit( 0 ) ; + } + + if( argv[3].equalsIgnoreCase( "stopall" ) ) + { + user.stopAll() ; + System.exit( 0 ) ; + } + + if( argv[3].equalsIgnoreCase( "start" ) ) + { + if( argv.length != 5 ) + { + usage() ; + System.exit( 1 ) ; + } + + user.reserveMachines( Integer.parseInt( argv[4] ) ) ; + + System.exit( 0 ) ; + } + + } else { + usage() ; + System.exit( 1 ) ; + } + } + + + private static void usage() + { + System.err.println( "Usage: " ) ; + System.err.println( "HpcVm client server_ip server_port client_port " ) ; + System.err.println( "HpcVm server server_port" ) ; + System.err.println( "HpcVm user server_ip server_port {start nbVM | stop | stopAll}" ) ; + System.out.println() ; + } + +} + + +/** La programmation est un art, respectons ceux qui la pratiquent !! **/ + diff --git a/src/and/hpcvm/LocalHost.java b/src/and/hpcvm/LocalHost.java new file mode 100644 index 0000000..60950b0 --- /dev/null +++ b/src/and/hpcvm/LocalHost.java @@ -0,0 +1,103 @@ +package and.hpcvm ; + + +import java.net.InetAddress; + +public class LocalHost +{ + // attributes + private static LocalHost Instance ; + private static String name ; + private String IP ; + private int port ; + private int socketPort = 1097 ; + private static ServicesClient ref = null ; + private static ServicesServer refServer = null ; + private boolean startedThreads = false ; + + private LocalHost() { + try { + if ( System.getSecurityManager() == null ) + { + System.setSecurityManager( new SecurityManager() ) ; + } + + InetAddress ia = InetAddress.getLocalHost() ; + name = ia.getCanonicalHostName() ; + IP = ia.getHostAddress() ; + } catch( Exception e ) { + System.err.println( "Error: Unknown Host: " + e ) ; + } + } + + public int getSocketPort() { + return socketPort ; + } + + public synchronized static LocalHost Instance() { + if (Instance == null) { + Instance = new LocalHost() ; + } + return Instance ; + } + + public void kill() { + Instance = null ; + } + + public String resolve( String name ) { + String ip = null ; + try { + ip = InetAddress.getByName(name).getHostAddress() ; + } catch (java.net.UnknownHostException e) { + System.err.println( "Cannot find IP address of " + name + ":" + e ) ; + } + return ip ; + } + + public synchronized void setPort( int portOfComm ) { + port = portOfComm ; + } + + public int getPort() { + return port ; + } + + public synchronized String getName() { + return name ; + } + + public synchronized String getIP() { + return IP ; + } + + public synchronized void setStub(ServicesClient stub) { + ref = null ; + ref = stub ; + } + + public synchronized void setServerStub(ServicesServer stub) { + refServer = null ; + refServer = stub ; + } + + public ServicesServer getServerStub() { + return refServer ; + } + + public synchronized ServicesClient getStub() { + return ref ; + } + + public synchronized void setStartedThreads( boolean b ) { + startedThreads = b ; + } + + public synchronized boolean getStartedThreads() { + return startedThreads ; + } +} + + +/** La programmation est un art, respectons ceux qui la pratiquent !! **/ + diff --git a/src/and/hpcvm/Server.java b/src/and/hpcvm/Server.java new file mode 100644 index 0000000..dafd9c5 --- /dev/null +++ b/src/and/hpcvm/Server.java @@ -0,0 +1,800 @@ +package and.hpcvm ; + +import java.rmi.Naming; +import java.rmi.RemoteException; +import java.rmi.registry.LocateRegistry; +import java.rmi.registry.Registry; +import java.rmi.server.UnicastRemoteObject; +import java.util.ArrayList; +import java.util.Iterator; + + +public class Server extends UnicastRemoteObject implements ServicesServer +{ + private class DiscCount + { + private int nb ; + + DiscCount() { nb = 0 ; } + + protected void inc() { nb++ ; } + + protected void dec() { + if( nb > 0 ) + { + nb-- ; + } + } + + protected int getNb() { return nb ; } + } + + + private class ConnectedClient + { + private ServicesClient stub ; + private int timeout ; + private Status state ; + private String ip ; + private String name ; + private ComputingClient cl ; + + ConnectedClient( ServicesClient _stub ) + { + stub = _stub ; + timeout = 0 ; + state = new Status() ; + state.setStatus( "connected" ) ; + try { + ip = stub.getIPHost() ; + name = stub.getName() ; + } catch (RemoteException e) { + e.printStackTrace(); + } + cl = null ; + } + + protected ServicesClient getStub() { return stub ; } + + protected void setStub( ServicesClient _stub ) { stub = _stub ; } + + protected int getTimeout() { return timeout ; } + + protected void incTimeout() { timeout++ ; } + + protected void resetTimeout() { timeout = 0 ; } + + protected String getStatus() { return state.getStatus() ; } + + protected void setStatus( String _state ) { state.setStatus( _state ) ; } + + protected String getIP() { return ip ; } + + protected String getName() { return name ; } ; + + protected void setComputingClient( ComputingClient _cl ) { cl = _cl ; } + + protected ComputingClient getComputingClient() { return cl ; } + } + + + private class ComputingClient + { + private ConnectedClient client ; + private boolean save_status ; + private String save_neighbor ; + private String lastSaveName ; + + ComputingClient( ConnectedClient cl ) + { + client = cl ; + save_status = false ; + save_neighbor = "none" ; + lastSaveName = "none" ; + } + + protected ConnectedClient getClient() { return client ; } + + protected boolean getSaveStatus(){ return save_status ; } + + protected void setSaveStatus( boolean _status ) { save_status = _status ; } + + protected void setSaveNeighbor( String _sn ) + { + if( _sn != null && ! _sn.isEmpty() ) + { + save_neighbor = _sn ; + + try { + client.getStub().setSavingNeighbor( _sn ) ; + } catch( RemoteException e ) { + System.err.println( "Error while setting save neighbor on " + + client.getName() + "(" + client.getIP() + ")!" ) ; + e.printStackTrace() ; + } + } + } + + protected String getSaveNeighbor() { return save_neighbor ; } + + public void setLastSave( String _saveName ) + { + lastSaveName = _saveName ; + } + + public String getLastSave() { return lastSaveName ; } + + } + + + private class IPAssociation + { + private String vmIP ; + private String hostIP ; + + IPAssociation() + { + vmIP = null ; + hostIP = null ; + } + + protected void setVmIP( String _vmIP ) + { + vmIP = _vmIP ; + } + + protected void setHostIP( String _hostIP ) + { + hostIP = _hostIP ; + } + + protected String getVmIP() + { + return vmIP ; + } + + protected String getHostIP() + { + return hostIP ; + } + } + + + + private static final long serialVersionUID = 1L ; + private int port ; + private ArrayList clients ; + private ArrayList computingClients ; + private int max_timeout ; + private ConnectedMonitor monitor ; + private DiscCount counter ; + private ArrayList vmIPs ; + + + protected Server() throws RemoteException + { + super() ; + } + + + + @Override + public Integer register( ServicesClient _stub ) + { + if( _stub != null ) + { + String ip = "" ; + try { + ip = _stub.getIPHost() ; + } catch (RemoteException e) { + e.printStackTrace() ; + return 1 ; + } + + boolean exists = false ; + int i ; + + for( i = 0 ; i < clients.size() ; i++ ) + { + if( ip.equals( clients.get( i ).getIP() ) ) + { + exists = true ; + System.out.println( "Client already connected!" ) ; + break ; + } + } + + if( exists ) + { + System.out.println( "The client stub will be replaced." ) ; + clients.get( i ).setStub( _stub ) ; + System.out.println( "(reconnection of " + clients.get( i ).getName() + ")" ) ; + return 2 ; + } else { + System.out.println( "New connection!" ) ; + clients.add( new ConnectedClient( _stub ) ) ; + System.out.println( "(connection of " + clients.get( clients.size() - 1 ).getName() + ")" ) ; + generateVmIP( ip ) ; + + if( clients.size() == 0 ) + { + System.out.println( "There is no client connected." ) ; + } else if( clients.size() == 1 ) { + System.out.println( "There is one client connected." ) ; + } else { + System.out.println( "There are " + clients.size() + " clients connected." ) ; + } + + return 0 ; + } + } + + return 1 ; + } + + + private void generateVmIP( String _ip ) + { + if( _ip != null && ! _ip.equals( "" ) ) + { + for( int i = 0 ; i < vmIPs.size() ; i++ ) + { + if( vmIPs.get( i ).getHostIP() == null ) + { + vmIPs.get( i ).setHostIP( _ip ) ; + + break ; + } + } + } + } + + + @Override + public void ping( String _ip ) + { + if( _ip != null ) + { + for( int i = 0 ; i < clients.size() ; i++ ) + { + if( _ip.equals( clients.get( i ).getIP() ) ) + { + clients.get( i ).resetTimeout() ; + break ; + } + } + } + } + + + @Override + public void changeStatus( String _ip, String _status ) + { + if( _ip != null && _status != null ) + { + for( int i = 0 ; i < clients.size() ; i++ ) + { + if( _ip.equals( clients.get( i ).getIP() ) ) + { + clients.get( i ).setStatus( _status ) ; + System.out.println( "Client " + clients.get( i ).getName() + " changed its status to: " + _status ) ; + break ; + } + } + } + } + + + public void init( int _port ) + { + port = _port ; + max_timeout = 4 ; + + clients = new ArrayList() ; + computingClients = new ArrayList() ; + monitor = null ; + + exportObject() ; + + vmIPs = new ArrayList() ; + // TODO initialisation of VM IPs + for( int i = 2 ; i < 101 ; i++ ) + { + vmIPs.add( new IPAssociation() ) ; + vmIPs.get( vmIPs.size() - 1 ).setVmIP( "10.11.10." + i ) ; + } + + clients = new ArrayList() ; + + counter = new DiscCount() ; + + monitor = new ConnectedMonitor() ; + monitor.start() ; + } + + + public void stop() + { + if( monitor != null ) { monitor.stopMonitor() ; } + + for( int i = 0 ; i < clients.size() ; i++ ) + { + try { + clients.get( i ).getStub().stop() ; + } catch (RemoteException e) { + e.printStackTrace(); + } + } + + // unexportObject ? + + System.exit( 0 ) ; + } + + + private void exportObject() + { + ServicesServer ref = null ; + Registry reg = null ; + + try + { + while( true ) + { + reg = LocateRegistry.getRegistry( port ) ; + + String tab[] = reg.list() ; + + System.out.println( "There is an existing RMI Registry on port " + + port + " with " + tab.length + " entries!" ) ; + for( int i = 0 ; i < tab.length ; i++ ) + { + try { + if( UnicastRemoteObject.unexportObject( Naming.lookup(tab[i]), true ) ) + { + System.out.println( "Register successfuly deleted!" ) ; + } else { + System.err.println( "Register undeleted !!!" ) ; + } + } catch( Exception e ) { + e.printStackTrace() ; + } + } + } + } catch( RemoteException e ) { + } + + try { + if ( System.getSecurityManager() == null ) + { + System.setSecurityManager( new SecurityManager() ) ; + } + + LocateRegistry.createRegistry( port ) ; + LocateRegistry.getRegistry( port ).rebind( "Server", this ) ; + ref = (ServicesServer) Naming.lookup( "rmi://" + + LocalHost.Instance().getIP() + ":" + port + + "/Server" ) ; + } catch ( Exception e ) { + System.err.println( "Error in Server.exportObject() when creating local services:" + e ) ; + System.err.println( "Exit from Server.exportObject" ) ; + System.exit( 1 ) ; + } + + LocalHost.Instance().setServerStub( ref ) ; + + System.out.println( "Server launched on IP " + LocalHost.Instance().getIP() + + " on port " + port + "." ) ; + } + + /** Fault manager thread **/ + private class FaultManager extends Thread + { + ConnectedClient cl ; + + FaultManager( ConnectedClient _cl ) + { + cl = _cl ; + } + + @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() ; + String ipDead = cc.getClient().getIP() ; + + boolean ok = false ; + + for( int i = 0 ; i < clients.size() ; i++ ) + { + if( clients.get( i ).getStatus().equalsIgnoreCase( "connected" ) ) + { +// int res = 1 ; +// try { +// res = clients.get( i ).getStub().startVM() ; +// } catch( RemoteException e ) { +// e.printStackTrace(); +// } +// +// if( res == 0 ) +// { + //clients.get(i).setStatus( "running" ) ; + + int pos = computingClients.indexOf( cc ) ; + if( pos == -1 ) + { + System.err.println( "Dead client not found in the computing clients list!" ) ; + } else { + System.out.println( "Trying to replace " + cc.getClient().getName() + " with " + + clients.get(i).getName() + " ... " ) ; + + ComputingClient ccl = new ComputingClient( clients.get(i) ) ; + clients.get( i ).setComputingClient( ccl ) ; + String 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() ) ; + } catch( RemoteException e ) { + System.err.println( "Unable to indicate to client to retrieve last save!" ) ; + e.printStackTrace() ; + } + + if( res == 0 ) + { + ok = true ; + + // replace dead client in vmIPs + for( int j = 0 ; j < vmIPs.size() ; j++ ) + { + if( vmIPs.get( j ).getHostIP().equalsIgnoreCase( ipDead ) ) + { + String vmIP = vmIPs.get( j ).getVmIP() ; + vmIPs.get( j ).setHostIP( computingClients.get( pos ).getClient().getIP() ) ; + + try { + computingClients.get( pos ).getClient().getStub().setIPVM( vmIP ) ; + } catch( RemoteException e ) { + System.err.println( "Unable to set the new VM IP on the replacing client!" ) ; + e.printStackTrace() ; + } + break ; + } + } + + System.out.println( "Successful redeployment of the VM." ) ; + } else { + System.err.println( "Unable to deploy the save on the new computing client!" ) ; + } + } +// } else { +// System.err.println( "Problem while launching the VM on " +// + clients.get(i).getName() + "!" ) ; +// } + + if( ok ) + { + System.out.println( "Dead client successfully replaced." ) ; + // restart vms + break ; + } else { + System.err.println( "Dead client not replaced!!" ) ; + } + } + } + } + + try { + synchronized( counter ) { + counter.dec() ; + counter.notifyAll() ;} + } catch( Exception e ) {} + } + } + + + /** Monitoring thread **/ + private class ConnectedMonitor extends Thread + { + boolean run ; + + ConnectedMonitor() + { + run = true ; + } + + protected void stopMonitor() { run = false ; } + + @Override + public void run() + { + boolean change ; + + while( run ) + { + change = false ; + Iterator it = clients.iterator() ; + int nb_disconnections = 0 ; + int nb_disconnections_computing = 0 ; + + while( it.hasNext() ) + { + ConnectedClient cl = it.next() ; + cl.incTimeout() ; + + if( cl.getTimeout() > max_timeout ) + { + System.out.println( "Disconnection of " + cl.getName() ) ; + if( cl.getStatus().equalsIgnoreCase( "running" ) || cl.getStatus().equalsIgnoreCase( "saving" ) ) + { + System.out.println( "A VM was running on it!!" ) ; + System.out.println( "I will redeploy a save and restart all VM ..." ) ; + +// for( int i = 0 ; i < computingClients.size() ; i++ ) +// { +// if( computingClients.get( i ).getClient().getIP().equals( cl.getIP() ) ) +// { +// computingClients.remove( i ) ; +// break ; +// } +// } + + new Server.FaultManager( cl ).start() ; + nb_disconnections_computing++ ; + } else { + System.out.println( "There was no VM running on it." ) ; + System.out.println( "Maybe it will come back later :)" ) ; + } + + it.remove() ; + nb_disconnections++ ; + change = true ; + } + } + + if( change ) + { + if( clients.size() == 0 ) + { + System.out.println( "There is no client connected." ) ; + } else if( clients.size() == 1 ) { + System.out.println( "There is one client connected." ) ; + } else { + System.out.println( "There are " + clients.size() + " clients connected." ) ; + } + } + + + if( nb_disconnections_computing > 0 ) + { + System.out.println( "I will redeploy save and restart VMs ..." ) ; + + synchronized( counter ) + { + if( counter.getNb() > 0 ) + { + System.out.println( "... waiting all redeployments done ..." ) ; + } + + while( counter.getNb() != 0 ) + { + try { + counter.wait() ; // !!!!! synchro + } catch( InterruptedException e ) { + e.printStackTrace() ; + } + } + } + + for( int i = 0 ; i < computingClients.size() ; i++ ) + { + final ServicesClient sc = computingClients.get( i ).getClient().getStub() ; + + new Thread( new Runnable() { + + @Override + public void run() + { + try { + sc.restartVMAfterCrash() ; + } catch( RemoteException e ) { + e.printStackTrace() ; + } + } + } ).start() ; + } + } + + try + { + Thread.sleep( 2000 ) ; + } catch( InterruptedException e ) { + e.printStackTrace() ; + } + } + } + } + + @Override + public Integer saveOk( String _ip, String _saveName ) + { + int i ; + for( i = 0 ; i < computingClients.size() ; i ++ ) + { + if( computingClients.get( i ).getClient().getIP().equalsIgnoreCase( _ip ) ) + { + computingClients.get( i ).setLastSave( _saveName ) ; + computingClients.get( i ).setSaveStatus( true ) ; + break ; + } + } + + + boolean all_ok = true ; + i = 0 ; + + while( all_ok && i < computingClients.size() ) + { + all_ok = all_ok & computingClients.get( i ).getSaveStatus() ; + i++ ; + } + + if( all_ok ) + { + for( i = 0 ; i < computingClients.size() ; i++ ) + { + try { + computingClients.get( i ).getClient().getStub().saveOk() ; + } catch (RemoteException e) { + e.printStackTrace(); + } + computingClients.get( i ).setSaveStatus( false ) ; + } + } + + return 0 ; + } + + + + @Override + public ArrayList startApplication( int _nb ) + { + int nb = clients.size() - computingClients.size() ; + + if( nb > _nb ) + { + ArrayList ac = new ArrayList() ; + ArrayList tmp = new ArrayList() ; + + int i = 0 ; + + while( i < clients.size() && ac.size() < _nb ) + { + if( clients.get(i).getStatus().equalsIgnoreCase( "connected" ) ) + { + int res = 1 ; + try { + res = clients.get( i ).getStub().startVM( 0 ) ; + } catch( RemoteException e ) { + e.printStackTrace(); + } + + if( res == 0 ) + { + ac.add( clients.get( i ).getStub() ) ; + clients.get( i ).setStatus( "running" ) ; + ComputingClient cl = new ComputingClient( clients.get( i ) ) ; + clients.get( i ).setComputingClient( cl ) ; + computingClients.add( cl ) ; + tmp.add( cl ) ; + } else { + System.err.println( "Problem while launching the VM on " + + clients.get(i).getName() + "!" ) ; + } + } + + i++ ; + } + + if( ac.size() == _nb ) + { + int index, index2 ; + /* Choosing save neighbors */ + for( i = 0 ; i < tmp.size() ; i++ ) + { + if( i == tmp.size() - 1 ) + { + index = computingClients.indexOf( tmp.get( i ) ) ; + index2 = computingClients.indexOf( tmp.get( 0 ) ) ; + + if( index == -1 || index2 == -1 ) + { + System.err.println( "Problem in ComputingClients list!" ) ; + } else { + computingClients.get( index ).setSaveNeighbor( computingClients.get( index2 ).getClient().getIP() ) ; + } + } else { + index = computingClients.indexOf( tmp.get( i ) ) ; + index2 = computingClients.indexOf( tmp.get( i + 1 ) ) ; + + if( index == -1 || index2 == -1 ) + { + System.err.println( "Problem in ComputingClients list!" ) ; + } else { + computingClients.get( index ).setSaveNeighbor( computingClients.get( index2 ).getClient().getIP() ) ; + } + } + } + } + + /* Cleaning */ + tmp.clear() ; + tmp = null ; + + return ac ; + } + + return null ; + } + + + + @Override + public void endApplication() + { + Iterator it = computingClients.iterator() ; + + while( it.hasNext() ) + { + ComputingClient cl = it.next() ; + + try { + cl.getClient().getStub().stopVM() ; + } catch (RemoteException e) { + e.printStackTrace(); + } + + cl.getClient().setStatus( "connected" ) ; + cl.getClient().setComputingClient( null ) ; + it.remove() ; + cl = null ; + } + + } + + + + @Override + public String getAssociatedIP( String _ip ) throws RemoteException + { + String ret = null ; + + for( int i = 0 ; i < vmIPs.size() ; i++ ) + { + if( vmIPs.get( i ).getHostIP().equalsIgnoreCase( _ip ) ) + { + ret = vmIPs.get( i ).getVmIP() ; + break ; + } + } + + return ret ; + } + +} + +/** La programmation est un art, respectons ceux qui la pratiquent !! **/ + diff --git a/src/and/hpcvm/ServicesClient.java b/src/and/hpcvm/ServicesClient.java new file mode 100644 index 0000000..d5535dd --- /dev/null +++ b/src/and/hpcvm/ServicesClient.java @@ -0,0 +1,45 @@ +package and.hpcvm ; + +import java.rmi.Remote; +import java.rmi.RemoteException; + +public interface ServicesClient extends Remote +{ + + public int startVM( int _mode ) throws RemoteException ; + + public int stopVM() throws RemoteException ; + + public int suspendVM( int _mode ) throws RemoteException ; + + public int restartVM() throws RemoteException ; + + public int restartVMAfterCrash() throws RemoteException ; + + public int saveVM() throws RemoteException ; + + public int reloadConfig() throws RemoteException ; + + public int start() throws RemoteException ; + + public void stop() throws RemoteException ; + + public String getIPHost() throws RemoteException ; + + public String getIPVM() throws RemoteException ; + + public void setIPVM( String _ipVM ) throws RemoteException ; + + public String getName() throws RemoteException ; + + public void saveOk() throws RemoteException ; + + public void setSavingNeighbor( String _sn ) throws RemoteException ; + + public int retrieveSave( String _saveName ) throws RemoteException ; + +} + + +/** La programmation est un art, respectons ceux qui la pratiquent !! **/ + diff --git a/src/and/hpcvm/ServicesServer.java b/src/and/hpcvm/ServicesServer.java new file mode 100644 index 0000000..6eb2f97 --- /dev/null +++ b/src/and/hpcvm/ServicesServer.java @@ -0,0 +1,28 @@ +package and.hpcvm ; + +import java.rmi.Remote; +import java.rmi.RemoteException; +import java.util.ArrayList; + +public interface ServicesServer extends Remote +{ + public Integer register( ServicesClient _stub ) throws RemoteException ; + + public String getAssociatedIP( String _ip ) throws RemoteException ; + + public void ping( String _ip ) throws RemoteException ; + + public void changeStatus( String _ip, String _status ) throws RemoteException ; + + public Integer saveOk( String _ip, String _saveName ) throws RemoteException ; + + public ArrayList startApplication( int _nb ) throws RemoteException ; + + public void endApplication() throws RemoteException ; + + public void stop() throws RemoteException ; +} + + +/** La programmation est un art, respectons ceux qui la pratiquent !! **/ + diff --git a/src/and/hpcvm/Status.java b/src/and/hpcvm/Status.java new file mode 100644 index 0000000..0f3cf72 --- /dev/null +++ b/src/and/hpcvm/Status.java @@ -0,0 +1,49 @@ +package and.hpcvm ; + + +public class Status +{ + private enum status { + undefined( "Undefined" ), + running( "Running" ), + connected( "Connected" ), + stopped( "Stopped" ), + suspended( "Suspended" ), + responding( "Responding" ), + lost( "Lost" ), + crashed( "Crashed" ), + saving( "Saving" ) ; + + private String label ; + + + status( String _label ) + { label = _label ; } + + + public String getLabel() + { return label ; } + } + + + private status s ; + + public Status() + { + s = status.undefined ; + } + + public String getStatus() + { + return s.getLabel() ; + } + + public void setStatus( String _status ) + { + s = status.valueOf( _status.toLowerCase() ) ; + } + +} + +/** La programmation est un art, respectons ceux qui la pratiquent !! **/ + diff --git a/src/and/hpcvm/User.java b/src/and/hpcvm/User.java new file mode 100644 index 0000000..e70bc43 --- /dev/null +++ b/src/and/hpcvm/User.java @@ -0,0 +1,92 @@ +package and.hpcvm ; + +import java.net.MalformedURLException; +import java.rmi.Naming; +import java.rmi.NotBoundException; +import java.rmi.RemoteException; +import java.util.ArrayList; + + +public class User +{ + private ServicesServer ss ; + + public User( String _serverIP, int _serverPort ) + { + System.out.println( "Connecting to server ..." ) ; + /** Connection to server **/ + try { + ss = (ServicesServer) Naming.lookup( "rmi://" + + _serverIP + ":" + _serverPort + "/Server" ) ; + } catch( MalformedURLException e ) { + e.printStackTrace() ; + } catch( RemoteException e ) { + e.printStackTrace() ; + } catch( NotBoundException e ) { + e.printStackTrace() ; + } + + if( ss == null ) + { + System.err.println( "Unable to connect to server!!" ) ; + System.err.println( "Server IP: " + _serverIP + " -- server port: " + _serverPort ) ; + + System.exit( 1 ) ; + } + + System.out.println( "Connected to server " + _serverIP + " on port " + _serverPort + "." ) ; + } + + public void reserveMachines( int _nb ) + { + ArrayList sc = null ; + + try { + sc = ss.startApplication( _nb ) ; + } catch( RemoteException e ) { + System.err.println( "Unable to retrieve VMs!!" ) ; + e.printStackTrace() ; + } + + if( sc == null ) + { + System.err.println( "There are not enough ressources!!" ) ; + System.exit( 1 ) ; + } + + System.out.println( "List of VMs: " ) ; + for( int i = 0 ; i < sc.size() ; i++ ) + { + try { + System.out.println( " " + sc.get( i ).getName() + " (" + sc.get( i ).getIPVM() + ")" ) ; + } catch( RemoteException e ) { + System.err.println( "Unable to retrieve VM informations!" ) ; + e.printStackTrace() ; + } + } + } + + + public void stopMachines() + { + try { + ss.endApplication() ; + } catch( RemoteException e ) { + e.printStackTrace() ; + } + } + + + public void stopAll() + { + try { + ss.stop() ; + } catch (RemoteException e) { + e.printStackTrace(); + } + } + +} + + +/** La programmation est un art, respectons ceux qui la pratiquent !! **/ diff --git a/src/and/hpcvm/VirtualMachine.java b/src/and/hpcvm/VirtualMachine.java new file mode 100644 index 0000000..1d7075d --- /dev/null +++ b/src/and/hpcvm/VirtualMachine.java @@ -0,0 +1,279 @@ +package and.hpcvm ; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStreamReader; +import java.util.ArrayList; + +public class VirtualMachine +{ + private String name ; + private String ip ; + private String initial_archive_name ; + private String directory ; + private String vmx_name ; + private String vmx_name_normal ; + private String vmx_name_crash ; + private String save_current ; + private String save_last ; + private int no_save ; + private int no_save_last ; + private Status status ; + private int computation_id ; + private String working_directory ; + private ArrayList save_neighbors ; + private String clientInVM ; + private String vm_user ; + private String vm_user_passwd ; + + public VirtualMachine() + { + name = "VmTest" ; + ip = "127.0.0.1" ; + initial_archive_name = "VmTest.tgz" ; + directory = "VmTest" ; + vmx_name = "VmTest.vmx" ; + vmx_name_normal = "VmTest.vmx.normal" ; + vmx_name_crash = "VmTest.vmx.crash" ; + save_current = "VmTest.tgz" ; + save_last = "VmTest.tgz" ; + working_directory = "/localhome/vmware" ; + no_save = 0 ; + no_save_last = 0 ; + status = new Status() ; + status.setStatus( "stopped" ) ; + computation_id = -1 ; + save_neighbors = new ArrayList() ; + save_neighbors.add( "127.0.0.1" ) ; + clientInVM = "/home/mpi/InGuest" ; + vm_user = "mpi" ; + vm_user_passwd = "mpi" ; + } + + + public ArrayList getSaveNeighbors() { return save_neighbors ; } + + @SuppressWarnings("unchecked") + public void setSaveNeighbors( ArrayList _sn ) + { + if( _sn != null ) + { + save_neighbors = (ArrayList) _sn.clone() ; + } + } + + public void addSaveNeighbor( String _sn ) + { + if( _sn != null && _sn.length() > 0 ) + { + save_neighbors.add( _sn ) ; + } + } + + + public String getVmUser() + { + return vm_user ; + } + + + public void setVmUser( String _user ) + { + vm_user = _user ; + } + + + public String getVmUserPasswd() + { + return vm_user_passwd ; + } + + + public void setVmUserPasswd( String _user_passwd ) + { + vm_user_passwd = _user_passwd ; + } + + + public String getClientInVM() + { + return clientInVM ; + } + + + public void setClientInVM( String _civ ) + { + clientInVM = _civ ; + } + + + public String getStatus() + { + return status.getStatus() ; + } + + + public void setStatus( String _status ) + { + status.setStatus( _status ) ; + } + + + public String getWorkingDirectory() + { + return working_directory ; + } + + + public void setWorkingDirectory( String _wd ) + { + working_directory = _wd ; + } + + public String getName() { + return name; + } + + + public void setName(String name) { + this.name = name; + } + + public String getIp() { + return ip; + } + + public void setIp(String ip) { + this.ip = ip; + } + + public String getInitial_archive_name() { + return initial_archive_name; + } + + public void setInitial_archive_name(String initial_archive_name) { + this.initial_archive_name = initial_archive_name; + } + + public String getDirectory() { + return directory; + } + + public void setDirectory(String directory) { + this.directory = directory; + } + + public String getVmx_name() { + return vmx_name; + } + + public void setVmx_name(String vmx_name) { + this.vmx_name = vmx_name; + } + + public String getVmx_name_normal() { + return vmx_name_normal; + } + + public void setVmx_name_normal(String vmx_name_normal) { + this.vmx_name_normal = vmx_name_normal; + } + + public String getVmx_name_crash() { + return vmx_name_crash; + } + + public void setVmx_name_crash(String vmx_name_crash) { + this.vmx_name_crash = vmx_name_crash; + } + + public String getSave_current() { + return save_current; + } + + public void setSave_current(String save_current) { + this.save_current = save_current; + } + + public String getSave_last() { + return save_last; + } + + public void setSave_last(String save_last) { + this.save_last = save_last; + } + + public int getNo_save() + { + return no_save ; + } + + public void setNo_save( int no_save ) + { + this.no_save = no_save ; + } + + public int getNo_save_last() + { + return no_save_last ; + } + + public void setNo_save_last( int no_save_last ) + { + this.no_save_last = no_save_last ; + } + + public int getComputationId() { return computation_id ; } + + + public void setComputationId( int _id ) + { + computation_id = _id ; + } + + + public int deployLastSave() + { + System.out.print( "Deploying the last save ..." ) ; + + String[] command = new String[] { "/bin/tar", "-xzvf", + working_directory + "/" + save_last, + "-C", working_directory } ; + Process pr = null ; + try { + pr = Runtime.getRuntime().exec( command ) ; +// synchronized( pr ){ + pr.waitFor() ; //;} + } catch( IOException e ) { + System.err.println( "Error while deploying the last secure save!" ) ; + e.printStackTrace() ; + } catch( InterruptedException e ) { + e.printStackTrace() ; + } + + if( pr.exitValue() == 0 ) + { + System.out.println( "Successful extraction of the save archive." ) ; + return 0 ; + } else { + System.err.println( "Error: " + pr.exitValue() ) ; + BufferedReader b = new BufferedReader( new InputStreamReader( pr.getErrorStream() ) ) ; + + String l ; + try { + while( (l = b.readLine()) != null ) + { + System.err.println( l ) ; + } + } catch( IOException e ) { + e.printStackTrace() ; + } + } + + return 1 ; + } + + +} + +/** La programmation est un art, respectons ceux qui la pratiquent !! **/ -- 2.20.1