Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Refunding the restart/redeployment mechanisms.
[hpcvm.git] / src / and / hpcvm / Client.java
1 package and.hpcvm ;
2
3 import java.io.BufferedReader;
4 import java.io.File;
5 import java.io.FileWriter;
6 import java.io.IOException;
7 import java.io.InputStreamReader;
8 import java.net.MalformedURLException;
9 import java.net.ServerSocket;
10 import java.net.Socket;
11 import java.rmi.Naming;
12 import java.rmi.NotBoundException;
13 import java.rmi.RemoteException;
14 import java.rmi.registry.LocateRegistry;
15 import java.rmi.registry.Registry;
16 import java.rmi.server.UnicastRemoteObject;
17 import java.util.ArrayList;
18 import java.util.concurrent.Semaphore;
19
20
21 public class Client extends UnicastRemoteObject implements ServicesClient
22 {
23         private static final long serialVersionUID = 1L ;
24         
25         private String VmRunCommand ;
26 //      private String VmRunCommandArg ;
27         private VirtualMachine machine ;
28         private String server_ip ;
29         private int server_port ;
30         private int client_port ;
31         private int dialog_port ;
32         private ServicesServer serverStub ;
33         private ServicesClient myStub ;
34         private PingServer pingServer ;
35         private DialogVMServer dialogVmServer ;
36         private ServerSocket serverSocket ;
37         private String ushell ;
38         private String working_directory ;
39         private int wait_start ;
40         private int max_start_try ;
41         private boolean isRestartedSave ;
42         private long save_interleave ;
43         private long date_last_save ;
44         private SaveProcess saveProcess;
45         private int maxRetryVM ;
46         private int timeRetryVM ;
47         private Semaphore sema ;
48         private boolean emergencyStop ;
49         private Process procSave ;
50         private boolean lastSaveOk ;
51         
52                 
53         protected Client() throws RemoteException 
54         {
55                 super() ;
56         }
57
58         @Override
59         public void emergencyStop()
60         {
61                 emergencyStop = true ;
62                 
63                 // Saving processus stop
64                 synchronized( saveProcess ) {
65                         saveProcess.setStatus( false ) ;
66                         try {
67                                 saveProcess.notifyAll() ;
68                         } catch( Exception e ) {}}
69                 
70                 try {
71                         procSave.destroy() ;
72                 } catch( Exception e ) {}
73                 
74                 stopVM() ;
75         }
76         
77         @Override
78         public int startVM( int _mode ) 
79         {               
80                 if( machine != null && ! machine.getStatus().equalsIgnoreCase( "running" ) )
81                 {
82                         try {
83                                 sema.acquire() ;
84                         } catch( InterruptedException e2 ) {
85                                 System.err.println( "Problem with semaphore acquiring!" ) ;
86                                 e2.printStackTrace() ;
87                         }
88
89                         // Checking first start
90                         if( machine.checkVmx() == 1 )
91                         {
92                                 return 1 ;
93                         }
94                         
95                         boolean ret = true ;
96                         int retry = 0 ;
97                         
98                         /** Starting VM **/
99                         System.out.print( "Starting VM ... " ) ;
100                         
101                         machine.setStatus( "undefined" ) ;
102                         if( _mode == 0 )
103                         {
104                                 try {
105                                         LocalHost.Instance().getServerStub().changeStatus( 
106                                                 LocalHost.Instance().getIP(), "undefined" ) ;
107                                 } catch( RemoteException e ) {
108                                         System.err.println( "Unable to inform the server of the VM status!" ) ;
109                                         e.printStackTrace() ;
110                                 }
111                         }
112                         
113                         String[] command = new String[]{VmRunCommand, "-T", "player", "start",
114                         working_directory + "/" + machine.getDirectory() + "/" + machine.getVmx_name(), "nogui"} ;
115                         
116                         while( ret )
117                         {
118                                 
119                                 if( emergencyStop )
120                                 {
121                                         return 1 ;
122                                 }
123                 
124                                 try {
125                                         Process p = Runtime.getRuntime().exec( command ) ;
126                                         p.waitFor() ;
127                                 
128                                         if( p.exitValue() == 0 )
129                                         {
130                                                 System.out.println( "Virtual machine successfully started." ) ;
131                                                 ret = false ;
132                                         } else {
133                                                 System.err.println( "Virtual machine not started!" ) ;
134                                                 ret = printProcessError( p ) ;
135                                         
136                                                 if( ! ret )
137                                                 {
138                                                         sema.release() ;
139                                                 
140                                                         return 1 ;
141                                                 } else {
142                                                         retry++ ;
143                                                         if( retry >= maxRetryVM )
144                                                         {
145                                                                 System.err.println( "Unable to start VM!" ) ;
146                                                         
147                                                                 sema.release() ;
148                                                         
149                                                                 return 1 ;
150                                                         }
151                                                         System.out.println( "Retrying (" + retry + ") ... " ) ;
152                                                         Thread.sleep( timeRetryVM ) ;
153                                                 }
154                                         }
155                                 } catch( IOException e ) {
156                                         System.err.println( "Error during execution of start command: " ) ;
157                                         e.printStackTrace() ;
158                                 
159                                         sema.release() ;
160                                 
161                                         return 1 ;
162                                 } catch( InterruptedException e ) {
163                                         e.printStackTrace() ;
164                                 
165                                         sema.release() ;
166                                         return 1 ;
167                                 }
168                         }
169                         
170                         
171                         boolean started = false ;
172                         int count = 1 ;
173                         ret = true ;
174                         retry = 0 ;
175                         
176                         while( ! started )
177                         {
178                                 if( emergencyStop )
179                                 {
180                                         return 1 ;
181                                 }
182                                 
183                                 /** Waiting for VM being started **/
184                                 try {
185                                         Thread.sleep( wait_start ) ;
186                                 } catch( InterruptedException e ) {
187                                         e.printStackTrace() ;
188                                 }
189                                                         
190                                 String cmd2 = VmRunCommand + " -T " + " player " + " -gu " + machine.getVmUser() +
191                                 " -gp " + machine.getVmUserPasswd() + " runScriptInGuest " +
192                                 working_directory + "/" + machine.getDirectory() 
193                                 + "/" + machine.getVmx_name() + " " + ushell + 
194                                 " \"echo ok\"" ;// + " -noWait " ;
195                                 
196                                 try {
197                                         FileWriter fw = new FileWriter( new File( working_directory + "/testStarted.sh" ) ) ;
198                                         fw.write( cmd2 ) ;
199                                         fw.flush() ;
200                                         fw.close() ;
201                                 } catch( IOException e1 ) {
202                                         e1.printStackTrace() ;
203                                         
204                                         sema.release() ;
205                                         return 1 ;
206                                 }
207                                 
208                                 command = new String[]{ ushell, working_directory + "/testStarted.sh"} ;
209
210                                 while( ret )
211                                 {
212                                         if( emergencyStop )
213                                         {
214                                                 return 1 ;
215                                         }
216                                 
217                                         try {
218                                                 Process p = Runtime.getRuntime().exec( command ) ;
219                                                 p.waitFor() ;
220                                         
221                                                 if( p.exitValue() == 0 )
222                                                 {
223                                                         started = true ;
224 //                                              machine.setStatus( "running" ) ;
225 //                                              if( _mode == 0 )
226 //                                              {
227 //                                                      LocalHost.Instance().getServerStub().changeStatus( 
228 //                                                              LocalHost.Instance().getIP(), "running" ) ;
229 //                                              } 
230                                                         ret = false ;
231                                                 } else {
232                                                         System.err.println( "Error while checking if the VM is started!" ) ;
233 //                                              printProcessError( p.getErrorStream() ) ;
234                                                         ret = printProcessError( p ) ;
235                                                 
236                                                         if( ! ret )
237                                                         {
238                                                                 sema.release() ;
239                                                                 stopVM() ;
240                                                                 return 1 ;
241                                                         } else {
242                                                                 retry++ ;
243                                                                 if( retry >= maxRetryVM )
244                                                                 {
245                                                                         System.err.println( "Unable to check VM!" ) ;
246                                                                 
247                                                                         sema.release() ;
248                                                                         stopVM() ;
249                                                                         return 1 ;
250                                                                 }
251                                                                 System.out.println( "Retrying (" + retry + ") ... " ) ;
252                                                                 Thread.sleep( timeRetryVM ) ;
253                                                         }
254 //                                              wait_start = wait_start / 2 ;
255                                                         count++ ;
256                                                 }
257                                         } catch( IOException e ) {
258                                                 e.printStackTrace() ;
259                                                 sema.release() ;
260                                                 stopVM() ;
261                                                 return 1 ;
262                                         } catch( InterruptedException e ) {
263                                                 e.printStackTrace() ;
264                                                 sema.release() ;
265                                                 stopVM() ;
266                                                 return 1 ;
267                                         }
268                                 
269                                         if( count == max_start_try && ! started )
270                                         {
271                                                 System.err.println( "Virtual machine not responding!!" ) ;
272                                         
273                                                 try {
274                                                         LocalHost.Instance().getServerStub().changeStatus( 
275                                                                         LocalHost.Instance().getIP(), "undefined" ) ;
276                                                 } catch( RemoteException e ) {
277                                                         e.printStackTrace() ;
278                                                 }
279                                                 
280                                                 sema.release() ;
281                                         
282                                                 stopVM() ;
283                                         
284                                                 return 1 ;
285                                         } else {
286                                                 try {
287                                                         Thread.sleep( 3000 ) ;
288                                                 } catch( InterruptedException e ) {
289                                                         e.printStackTrace() ;
290                                                 }
291                                         }
292                                 }
293                         }
294                         
295                         /** Sending the host ip **/
296                         
297                         System.out.print( "Sending host IP to VM ... " ) ;
298                         
299                         String cmd2 = VmRunCommand + " -T " + " player " + " -gu " + machine.getVmUser() +
300                         " -gp " + machine.getVmUserPasswd() + " runScriptInGuest " +
301                         working_directory + "/" + machine.getDirectory() 
302                         + "/" + machine.getVmx_name() + " " +  ushell + 
303                         " \"echo " + LocalHost.Instance().getIP() + " " + dialog_port 
304                         + " > /tmp/vm_host_IP\"" ;
305                         
306                         try {
307                                 FileWriter fw = new FileWriter( new File( working_directory + "/sendHostIP.sh" ) ) ;
308                                 fw.write( cmd2 ) ;
309                                 fw.flush() ;
310                                 fw.close() ;
311                         } catch( IOException e1 ) {
312                                 e1.printStackTrace() ;
313                                 sema.release() ;
314                                 stopVM() ;
315                                 return 1 ;
316                         }
317                         
318                         command = new String[]{ ushell, working_directory + "/sendHostIP.sh"} ;
319                         
320                         ret = true ;
321                         retry = 0 ;
322                         
323                         while( ret )
324                         {
325                                 if( emergencyStop )
326                                 {
327                                         return 1 ;
328                                 }
329                         
330                                 try {
331                                         Process p = Runtime.getRuntime().exec( command ) ;
332                                         p.waitFor() ;
333                                 
334                                         if( p.exitValue() == 0 )
335                                         {
336                                                 System.out.println( "VM received the host IP." ) ;
337                                                 ret = false ;
338                                         } else {
339                                                 System.err.println( "VM did not received the host IP!" ) ;
340 //                                      printProcessError( p.getErrorStream() ) ;
341                                                 ret = printProcessError( p ) ;
342                                         
343                                                 if( ! ret )
344                                                 {
345                                                         sema.release() ;
346                                                         stopVM() ;
347                                                         return 1 ;
348                                                 } else {
349                                                         retry++ ;
350                                                         if( retry >= maxRetryVM )
351                                                         {
352                                                                 System.err.println( "Unable to send information to VM!" ) ;
353                                         
354                                                                 sema.release() ;
355                                                                 stopVM() ;
356                                                         
357                                                                 return 1 ;
358                                                         }
359                                                         System.out.println( "Retrying (" + retry + ") ... " ) ;
360                                                         Thread.sleep( timeRetryVM ) ;
361                                                 }
362                                         }
363                                 } catch( IOException e ) {
364                                         System.err.println( "Error during execution of runScriptInGuest command: " ) ;
365                                         e.printStackTrace() ;
366                                         sema.release() ;
367                                         stopVM() ;
368                                         return 1 ;
369                                 } catch( InterruptedException e) {
370                                         e.printStackTrace() ;
371                                         sema.release() ;
372                                         stopVM() ;
373                                         return 1 ;
374                                 }
375                         }
376                                         
377                         /** Sending the vm ip **/
378                         
379                         System.out.print( "Sending its IP to VM ... " ) ;
380                         
381                         cmd2 = VmRunCommand + " -T " + " player " + " -gu " + machine.getVmUser() +
382                         " -gp " + machine.getVmUserPasswd() + " runScriptInGuest " +
383                         working_directory + "/" + machine.getDirectory() 
384                         + "/" + machine.getVmx_name() + " " + ushell +
385                         " \"echo " + machine.getIp() 
386                         + " > /tmp/vm_IP\"" ;
387                         
388                         try {
389                                 FileWriter fw = new FileWriter( new File( working_directory + "/sendVmIP.sh" ) ) ;
390                                 fw.write( cmd2 ) ;
391                                 fw.flush() ;
392                                 fw.close() ;
393                         } catch( IOException e1 ) {
394                                 e1.printStackTrace() ;
395                                 sema.release() ;
396                                 stopVM() ;
397                                 return 1 ;
398                         }
399                         
400                         command = new String[]{ ushell, working_directory + "/sendVmIP.sh"} ;
401                         
402                         ret = true ;
403                         retry = 0 ;
404                         
405                         while( ret )
406                         {
407                                 if( emergencyStop )
408                                 {
409                                         return 1 ;
410                                 }
411                         
412                                 try {
413                                         Process p = Runtime.getRuntime().exec( command ) ;
414                                         p.waitFor() ;
415                                 
416                                         if( p.exitValue() == 0 )
417                                         {
418                                                 System.out.println( "VM received its assigned IP." ) ;
419 //                                      return 0 ;
420                                                 ret = false ;
421                                                 machine.setStatus( "running" ) ;
422                                         } else {
423                                                 System.err.println( "VM did not received its assigned IP!" ) ;
424 //                                      printProcessError( p.getErrorStream() ) ;
425                                                 ret = printProcessError( p ) ;
426                                         
427                                                 if( ! ret )
428                                                 {
429                                                         sema.release() ;
430                                                         stopVM() ;
431                                                         return 1 ;
432                                                 } else {
433                                                         retry++ ;
434                                                         if( retry >= maxRetryVM )
435                                                         {
436                                                                 System.err.println( "Unable to send information to VM!" ) ;
437                                                         
438                                                                 sema.release() ;
439                                                                 stopVM() ;
440                                                         
441                                                                 return 1 ;
442                                                         }
443                                                         System.out.println( "Retrying (" + retry + ") ... " ) ;
444                                                         Thread.sleep( timeRetryVM ) ;
445                                                 }
446                                         }
447                                 } catch( IOException e ) {
448                                         System.err.println( "Error during execution of runScriptInGuest command: " ) ;
449                                         e.printStackTrace() ;
450                                         sema.release() ; 
451                                         stopVM() ;
452                                         return 1 ;
453                                 } catch( InterruptedException e ) {
454                                         e.printStackTrace() ;
455                                         sema.release() ;
456                                         stopVM() ;
457                                         return 1 ;
458                                 }
459                         }
460                         
461                         if( _mode == 0 )
462                         {
463                                 try {
464                                         LocalHost.Instance().getServerStub().changeStatus( 
465                                                         LocalHost.Instance().getIP(), "running" ) ;
466                                 } catch (RemoteException e) {
467                                         System.err.println( "Unable to inform the server of the VM started status!" ) ;
468                                         e.printStackTrace();
469                                 }
470                         }
471                         
472                         sema.release() ;
473                         
474                         return 0 ;
475                 }
476                 
477                 sema.release() ;
478                 
479                 return 1 ;
480         }
481
482         @Override
483         public int stopVM() 
484         {               
485                 if( machine != null && machine.getStatus().equalsIgnoreCase( "stopped" ) )
486                 {
487                         emergencyStop = false ;
488                         return 0 ;
489                 }
490                 
491                 if( machine != null && ! machine.getStatus().equalsIgnoreCase( "stopped" ) )
492                 {
493                         try {
494                                 sema.acquire() ;
495                         } catch( InterruptedException e2 ) {
496                                 System.err.println( "Problem with semaphore acquiring!" ) ;
497                                 e2.printStackTrace() ;
498                         }
499                         
500                         System.out.print( "Stopping VM ... " ) ;
501                         
502                         boolean ret = true ;
503                         int retry = 0 ;
504                         
505                         machine.setStatus( "undefined" ) ;
506                         try {
507                                 LocalHost.Instance().getServerStub().changeStatus( 
508                                                 LocalHost.Instance().getIP(), "undefined" ) ;
509                         } catch( RemoteException e ) {
510                                 System.err.println( "Unable to inform the server of the VM status!" ) ;
511                                 e.printStackTrace() ;
512                         }
513                         
514                         String[] command = new String[]{VmRunCommand, "-T", "player", "stop",
515                         working_directory + "/" + machine.getDirectory() + "/" + machine.getVmx_name()} ;
516                         
517                         while( ret )
518                         try {
519                                 Process p = Runtime.getRuntime().exec( command ) ;
520                                 p.waitFor() ;
521                                 
522                                 if( p.exitValue() == 0 )
523                                 {
524                                         System.out.println( "Virtual machine successfully stopped." ) ;
525                                         machine.setStatus( "stopped" ) ;
526                                         ret = false ;
527                                 } else {
528                                         System.err.println( "Virtual machine not stopped!" ) ;
529 //                                      printProcessError( p.getErrorStream() ) ;
530                                         ret = printProcessError( p ) ;
531                                         
532                                         if( ! ret )
533                                         {
534                                                 sema.release() ;
535                                                 return 1 ;
536                                         } else {
537                                                 retry++ ;
538                                                 if( retry >= maxRetryVM )
539                                                 {
540                                                         System.err.println( "Unable to stop VM!" ) ;
541                                                         sema.release() ;
542                                                         return 1 ;
543                                                 }
544                                                 System.out.println( "Retrying (" + retry + ") ... " ) ;
545                                                 Thread.sleep( timeRetryVM ) ;
546                                         }
547                                         
548 //                                      return 1 ;
549                                 }
550                         } catch( IOException e ) {
551                                 System.err.println( "Error during execution of stop command: " ) ;
552                                 e.printStackTrace() ;
553                                 sema.release() ;
554                                 return 1 ;
555                         } catch( InterruptedException e ) {
556                                 e.printStackTrace() ;
557                                 sema.release() ;
558                                 return 1 ;
559                         }
560                         
561                         machine.setStatus( "stopped" ) ;
562                         try {
563                                 LocalHost.Instance().getServerStub().changeStatus( 
564                                                 LocalHost.Instance().getIP(), "stopped" ) ;
565                         } catch( RemoteException e1 ) {
566                                 System.err.println( "Unable to inform the server of the VM stopped status!" ) ;
567                                 e1.printStackTrace() ;
568                         }
569                         
570 //                      if( ! isRestartedSave )
571 //                      {
572 //                              /** Restoring the original vmx file (necessary after a crash) **/
573 //                              command = new String[]{ "/bin/cp", 
574 //                                              working_directory + "/" + machine.getDirectory() + "/" + machine.getVmx_name_normal(),
575 //                                              working_directory + "/" + machine.getDirectory() + "/" + machine.getVmx_name() } ;
576 //                              
577 //                                      try {
578 //                                              Process p = Runtime.getRuntime().exec( command ) ;
579 //                                              p.waitFor() ;
580 //                      
581 //                                              if( p.exitValue() == 0 )
582 //                                              {
583 //                                                      System.out.println( "Successfully replaced the VMX file." ) ;
584 //                                                      sema.release() ;
585 //                                                      emergencyStop = false ;
586 //                                                      return 0 ;
587 //                                              } else {
588 //                                                      System.err.println( "Unsuccessful replacement of the VMX file!" ) ;
589 ////                                                    printProcessError( p.getErrorStream() ) ;
590 //                                                      printProcessError( p ) ;
591 //                                                      sema.release() ;
592 //                                                      return 1 ;
593 //                                              }
594 //                                      } catch( IOException e ) {
595 //                                              System.err.println( "Error during VMX file replacement: " ) ;
596 //                                              e.printStackTrace() ;
597 //                                              sema.release() ;
598 //                                              return 1 ;
599 //                                      } catch( InterruptedException e ) {
600 //                                              e.printStackTrace() ;
601 //                                              sema.release() ;
602 //                                              return 1 ;
603 //                                      }
604 //                      } else {
605                         if(     machine.checkVmx() == 0 )
606                         {
607                                 sema.release() ;
608                                 emergencyStop = false ;
609                                 return 0 ;
610                         }
611                 }
612                 
613                 sema.release() ;
614                 
615                 return 1 ;
616         }
617
618         @Override
619         public int suspendVM( int _mode ) 
620         {               
621                 if( machine != null && machine.getStatus().equalsIgnoreCase( "suspended" ) )
622                 {
623                         return 0 ;
624                 }
625                 
626                 if( machine != null && ! machine.getStatus().equalsIgnoreCase( "suspended" ) )
627                 {
628                         try {
629                                 sema.acquire() ;
630                         } catch( InterruptedException e2 ) {
631                                 System.err.println( "Problem with semaphore acquiring!" ) ;
632                                 e2.printStackTrace() ;
633                         }
634                         
635                         System.out.print( "Suspending VM ... " ) ;
636                         
637                         boolean ret = true ;
638                         int retry = 0 ;
639                         
640                         machine.setStatus( "undefined" ) ;
641                         if( _mode == 0 )
642                         {
643                                 try {
644                                         LocalHost.Instance().getServerStub().changeStatus( 
645                                                 LocalHost.Instance().getIP(), "undefined" ) ;
646                                 } catch( RemoteException e ) {
647                                         System.err.println( "Unable to inform the server of the VM status!" ) ;
648                                         e.printStackTrace() ;
649                                 }
650                         }
651                         
652                         String[] command = new String[]{VmRunCommand, "-T", "player", "suspend",
653                         working_directory + "/" + machine.getDirectory() + "/" + machine.getVmx_name()} ;
654                         
655                         while( ret )
656                         try {
657                                 Process p = Runtime.getRuntime().exec( command ) ;
658                                 p.waitFor() ;
659                                 if( p.exitValue() == 0 )
660                                 {
661                                         System.out.println( "Virtual machine successfully suspended." ) ;
662                                         machine.setStatus( "suspended" ) ;
663                                         ret = false ;
664                                 } else {
665                                         System.err.println( "Virtual machine not suspended!" ) ;
666 //                                      printProcessError( p.getErrorStream() ) ;
667                                         ret = printProcessError( p ) ;
668                                         
669                                         if( ! ret )
670                                         {
671                                                 sema.release() ;
672                                                 
673                                                 return 1 ;
674                                         } else {
675                                                 retry++ ;
676                                                 if( retry >= maxRetryVM )
677                                                 {
678                                                         System.err.println( "Unable to suspend VM!" ) ;
679                                                         
680                                                         sema.release() ;
681                                                         
682                                                         return 1 ;
683                                                 }
684                                                 System.out.println( "Retrying (" + retry + ") ... " ) ;
685                                                 Thread.sleep( timeRetryVM ) ;
686                                         }
687                                         
688 //                                      return 1 ;
689                                 }
690                         } catch( IOException e ) {
691                                 System.err.println( "Error during execution of suspend command: " ) ;
692                                 e.printStackTrace() ;
693                         } catch( InterruptedException e ) {
694                                 e.printStackTrace() ;
695                         }
696                         
697                         machine.setStatus( "suspended" ) ;
698                         if( _mode == 0 )
699                         {
700                                 try {
701                                         LocalHost.Instance().getServerStub().changeStatus( 
702                                                 LocalHost.Instance().getIP(), "suspended" ) ;
703                                 } catch( RemoteException e ) {
704                                         System.err.println( "Unable to inform the server of the VM suspended status!" ) ;
705                                         e.printStackTrace() ;
706                                 }
707                         }
708                         
709                         sema.release() ;
710                         
711                         return 0 ;
712                 }
713                 
714                 sema.release() ;
715                 
716                 return 1 ;
717         }
718
719         @Override
720         public int restartVM() 
721         {               
722                 if( machine != null )
723                 {
724                         System.out.print( "Restarting VM ... " ) ;
725                         
726                         boolean ret = true ;
727                         int retry = 0 ;
728                         
729                         try {
730                                 LocalHost.Instance().getServerStub().changeStatus( 
731                                                 LocalHost.Instance().getIP(), "undefined" ) ;
732                         } catch( RemoteException e ) {
733                                 System.err.println( "Unable to inform the server of the VM status!" ) ;
734                                 e.printStackTrace() ;
735                         }
736                         
737                         String[] command = new String[]{VmRunCommand, "-T", "player", "reset",
738                         working_directory + "/" + machine.getDirectory() + "/" + machine.getVmx_name()} ;
739                         
740                         while( ret )
741                         try {
742                                 Process p = Runtime.getRuntime().exec( command ) ;
743                                 p.waitFor() ;
744                                 
745                                 if( p.exitValue() == 0 )
746                                 {
747                                         System.out.println( "Virtual machine successfully restarted." ) ;
748
749                                         if( sendSaveOkVM() == 1 ) { return 1 ; }
750                                         
751                                         ret = false ;
752                                         return 0 ;
753
754                                 } else {
755                                         System.err.println( "Virtual machine not restarted!" ) ;
756 //                                      printProcessError( p.getErrorStream() ) ;
757                                         ret = printProcessError( p ) ;
758                                         
759                                         if( ! ret )
760                                         {
761                                                 return 1 ;
762                                         } else {
763                                                 retry++ ;
764                                                 if( retry >= maxRetryVM )
765                                                 {
766                                                         System.err.println( "Unable to start VM!" ) ;
767                                                         return 1 ;
768                                                 }
769                                                 System.out.println( "Retrying (" + retry + ") ... " ) ;
770                                                 Thread.sleep( timeRetryVM ) ;
771                                         }
772                                         
773 //                                      return 1 ;
774                                 }
775                         } catch( IOException e ) {
776                                 System.err.println( "Error during execution of restart command: " ) ;
777                                 e.printStackTrace() ;
778                         } catch( InterruptedException e ) {
779                                 e.printStackTrace() ;
780                         }
781                 }
782
783                 return 1 ;
784         }
785
786         @Override
787         public int restartVMAfterCrash() 
788         {
789                 System.out.println( "Restarting VM after a crash ..." ) ;
790                 
791                 try {
792                         LocalHost.Instance().getServerStub().changeStatus( 
793                                         LocalHost.Instance().getIP(), "undefined" ) ;
794                 } catch( RemoteException e ) {
795                         System.err.println( "Unable to inform the server of the VM status!" ) ;
796                         e.printStackTrace() ;
797                 }
798                 
799                 if( stopVM() == 0 )
800                 {
801                         if( machine.deployLastSave() == 0 )
802                         {
803                                 if( isRestartedSave )
804                                 {
805                                         // Using the specific vmx file
806                                         machine.setDeployFault( true ) ;
807                                         
808                                         // Writing the restarted save mark
809                                         try {
810                                                 FileWriter fw = new FileWriter( new File( working_directory + "/" + machine.getDirectory() + "/fault.hpcvm" ) ) ;
811                                                 fw.write( "fault!" ) ;
812                                                 fw.flush() ;
813                                                 fw.close() ;
814                                                 fw = null ;
815                                         } catch( IOException e1 ) {
816                                                 e1.printStackTrace() ;
817                                                 System.err.println( "Unable to mark the fault!" ) ;
818                                         }       
819                                         
820                                         if( machine.checkVmx() == 1 )
821                                         {
822                                                 return 1 ;
823                                         }
824                                         
825 //                                      System.out.print( "Changing VMX file after crash ... " ) ;
826 //                              
827 //                                      String[] command = new String[]{ "/bin/cp", 
828 //                                              working_directory + "/" + machine.getDirectory() + "/" + machine.getVmx_name_crash(),
829 //                                              working_directory + "/" + machine.getDirectory() + "/" + machine.getVmx_name() } ;
830 //                                      
831 //                                      try {
832 //                                              Process p = Runtime.getRuntime().exec( command ) ;
833 //                                              p.waitFor() ;
834 //                              
835 //                                              if( p.exitValue() == 0 )
836 //                                              {
837 //                                                      System.out.println( "Successfully replaced the VMX file." ) ;
838 //                                              } else {
839 //                                                      System.err.println( "Unsuccessful replacement of the VMX file!" ) ;
840 ////                                                    printProcessError( p.getErrorStream() ) ;
841 //                                                      printProcessError( p ) ;
842 //                                                      
843 //                                                      return 1 ;
844 //                                              }
845 //                                      } catch( IOException e ) {
846 //                                              System.err.println( "Error during VMX file replacement: " ) ;
847 //                                              e.printStackTrace() ;
848 //                                      } catch( InterruptedException e ) {
849 //                                              e.printStackTrace() ;
850 //                                      }
851                                 
852                                         /** Retrieving VM assigned IP **/
853                                         String vmIP = null ;
854                                 
855                                         try {
856                                                 vmIP = LocalHost.Instance().getServerStub().getAssociatedIP( 
857                                                         LocalHost.Instance().getIP() ) ;
858                                         } catch (RemoteException e) {
859                                                 System.err.println( "Problem while retrieving the VM assigned IP!!" ) ;
860                                                 e.printStackTrace() ;
861                                                 return 1 ;
862                                         }
863                                 
864                                         machine.setIp( vmIP ) ;
865                                         
866                                         isRestartedSave = false ;
867                                 }
868                                 
869                                 if( startVM( 0 ) == 0 ) 
870                                 {
871                                         if( sendSaveOkVM() == 0 )
872                                         {
873                                                 date_last_save = System.currentTimeMillis() ;
874                                                 
875                                                 return 0 ;
876                                         }
877                                 } else {
878                                         stopVM() ;
879                                 }
880                         }
881                 }
882                 
883                 return 1 ;
884         }
885         
886         
887         private int sendSaveOkVM()
888         {
889                 boolean ret = true ;
890                 int retry = 0 ;
891                 
892                 /** Informing the program that it's ok **/
893                 System.out.print( "Sending OK signal to the program ... " ) ;
894                         
895                 String cmd2 = VmRunCommand + " -T " + " player " + " -gu " + machine.getVmUser() +
896                 " -gp " + machine.getVmUserPasswd() + " runScriptInGuest " +
897                 working_directory + "/" + machine.getDirectory() 
898                 + "/" + machine.getVmx_name() + " " + ushell + 
899                 " \"echo ok > /tmp/vm_save_ok\"" ;// + " -noWait " ;
900                 
901                 try {
902                         FileWriter fw = new FileWriter( new File( working_directory + "/saveOk.sh" ) ) ;
903                         fw.write( cmd2 ) ;
904                         fw.flush() ;
905                         fw.close() ;
906                 } catch( IOException e1 ) {
907                         e1.printStackTrace() ;
908                 }
909                         
910                 String[] command = new String[]{ ushell, working_directory + "/saveOk.sh"} ;
911                 
912                 while( ret )
913                 try {
914                         Process p = Runtime.getRuntime().exec( command ) ;
915                         p.waitFor() ;
916                         
917                         if( p.exitValue() == 0 )
918                         {
919                                 System.out.println( "Signal successfully sent." ) ;
920                                 ret = false ;
921                                 return 0 ;
922                         } else {
923                                 System.err.println( "Signal not sent!" ) ;
924 //                              printProcessError( p.getErrorStream() ) ;
925                                 ret = printProcessError( p ) ;
926                                 
927                                 if( ! ret )
928                                 {
929                                         return 1 ;
930                                 } else {
931                                         retry++ ;
932                                         if( retry >= maxRetryVM )
933                                         {
934                                                 System.err.println( "Unable to send ok signal to VM!" ) ;
935                                                 return 1 ;
936                                         }
937                                         System.out.println( "Retrying (" + retry + ") ... " ) ;
938                                         Thread.sleep( timeRetryVM ) ;
939                                 }
940 //                              return 1 ;
941                         }
942                 } catch( IOException e ) {
943                         System.err.println( "Error during ok save signal send command: " ) ;
944                         e.printStackTrace() ;
945                         return 1 ;
946                 } catch( InterruptedException e ) {
947                         e.printStackTrace() ;
948                         return 1 ;
949                 }
950                 
951                 return 1 ;
952         }
953
954         
955         @Override
956         public int saveVM() 
957         {
958                 synchronized( saveProcess ){
959                 while( saveProcess.getStatus() )
960                 {
961                         try {
962                                 saveProcess.wait() ;
963                         } catch( InterruptedException e ) {
964                                 e.printStackTrace() ;
965                         }
966                 }}
967                 
968                 System.out.println( "Saving VM ..." ) ;
969                 saveProcess.setStatus( true ) ;
970                 
971                 machine.setStatus( "saving" ) ;
972                 try {
973                         LocalHost.Instance().getServerStub().changeStatus( 
974                                 LocalHost.Instance().getIP(), "saving" ) ;
975                 } catch( RemoteException e ) {
976                         System.err.println( "Unable to inform the server of the VM status!" ) ;
977                         e.printStackTrace() ;
978                 }
979                 
980                 String[] command ;
981                 String saveName = "" ;
982                 boolean error = false ;
983                 boolean errorVM = false ;
984                 
985                 if( suspendVM( 1 ) == 1 ) { error = true ; errorVM = true ; }
986                 
987                 if( ! lastSaveOk )
988                 {
989                         System.out.println( "Deletion of last nok archive ... " ) ;
990                         
991                         command = new String[]{ "/bin/rm", "-rf", 
992                                         working_directory + "/" + machine.getName() + "_new_" + machine.getComputationId() + ".tar",
993                                         working_directory + "/" + machine.getName() + "_new_" + machine.getComputationId() + ".tar.gz", } ;
994                                                         
995                         try {
996                                 procSave = Runtime.getRuntime().exec( command ) ;
997                                 procSave.waitFor() ;
998                                 
999                                 if( procSave.exitValue() == 0 )
1000                                 {
1001                                         System.out.println( "Last nok archive successfully deleted." ) ;
1002                                 } else {
1003                                         System.err.println( "Last nok archive not deleted!" ) ;
1004 //                                      printProcessError( p.getErrorStream() ) ;
1005                                         printProcessError( procSave ) ;
1006                                         
1007                                         error = true ;
1008                                 }
1009                         } catch( IOException e ) {
1010                                 System.err.println( "Error during nok archive deletion command: " ) ;
1011                                 error = true ;
1012                                 e.printStackTrace() ;
1013                         } catch( InterruptedException e ) {
1014                                 e.printStackTrace() ;
1015                                 error = true ;
1016                         }
1017                 }
1018                 
1019                 if( ! error )
1020                 {
1021                         System.out.print( "Creation of the archive ... " ) ;
1022                         /** Archive creation **/
1023 //                      command = new String[]{ "/bin/tar", "-cf", 
1024 //                              working_directory + "/" + machine.getName() + "_new_" + machine.getComputationId() + ".tar",
1025 //                              working_directory + "/" + machine.getDirectory() } ;
1026 //                      
1027                         command = new String[]{ "/bin/tar", "-cf", 
1028                                         machine.getName() + "_new_" + machine.getComputationId() + ".tar",
1029                                         machine.getDirectory(), "-C", working_directory } ;
1030                                 
1031                         if( emergencyStop )
1032                         {
1033                                 return 1 ;
1034                         }
1035                         
1036                         try {
1037                                 procSave = Runtime.getRuntime().exec( command ) ;
1038                                 procSave.waitFor() ;
1039                                 
1040                                 if( procSave.exitValue() == 0 )
1041                                 {
1042                                         System.out.println( "Archive successfully created." ) ;
1043                                         
1044                                         lastSaveOk = false ;
1045                                         
1046                                 } else {
1047                                         System.err.println( "Archive not created!" ) ;
1048 //                                      printProcessError( p.getErrorStream() ) ;
1049                                         printProcessError( procSave ) ;
1050                                         
1051                                         error = true ;
1052                                 }
1053                         } catch( IOException e ) {
1054                                 System.err.println( "Error during archive creation command: " ) ;
1055                                 error = true ;
1056                                 e.printStackTrace() ;
1057                         } catch( InterruptedException e ) {
1058                                 e.printStackTrace() ;
1059                                 error = true ;
1060                         }
1061                 
1062                         /** Compression of the archive **/
1063                         if( ! error )
1064                         {
1065                                 System.out.print( "Compression of the archive ... " ) ;
1066                                 command = new String[]{ "/bin/gzip", 
1067                                                 working_directory + "/" + machine.getName() 
1068                                                 + "_new_" + machine.getComputationId() + ".tar" } ;
1069                                 
1070                                 if( emergencyStop )
1071                                 {
1072                                         return 1 ;
1073                                 }
1074                                 
1075                                 try {
1076                                         procSave = Runtime.getRuntime().exec( command ) ;
1077                                         procSave.waitFor() ;
1078                         
1079                                         if( procSave.exitValue() == 0 )
1080                                         {
1081                                                 System.out.println( "Archive successfully compressed." ) ;
1082                                         } else {
1083                                                 System.err.println( "Archive not compressed!" ) ;
1084 //                                              printProcessError( p.getErrorStream() ) ;
1085                                                 printProcessError( procSave ) ;
1086                                                 
1087                                                 error = true ;
1088                                         }
1089                                 } catch( IOException e ) {
1090                                         System.err.println( "Error during archive compression command: " ) ;
1091                                         e.printStackTrace() ;
1092                                         error = true ;
1093                                 } catch( InterruptedException e ) {
1094                                         e.printStackTrace() ;
1095                                         error = true ;
1096                                 }
1097                         }
1098                         
1099                         
1100                         /** Restarting VM **/
1101                         if( errorVM || startVM( 0 ) == 1 ) { error = true ; }
1102                         
1103                         
1104                         /** Sending ok save signal **/
1105 //                      if( ! error )
1106 //                      {
1107                                 if( sendSaveOkVM() == 1 ) { error = true ; }
1108                                 
1109                                 
1110 //                      }               
1111                         
1112 //                      /** Deletion of the tar archive **/
1113 //                      if( ! error )
1114 //                      {
1115 //                              command = new String[]{ "/bin/rm", 
1116 //                                              working_directory + "/" + machine.getName() 
1117 //                                              + "_new_" + machine.getComputationId() + ".tar" } ;
1118 //                              
1119 //                              try {
1120 //                                      Process p = Runtime.getRuntime().exec( command ) ;
1121 //                                      p.waitFor() ;
1122 //                      
1123 //                                      if( p.exitValue() == 0 )
1124 //                                      {
1125 //                                              System.out.println( "Archive (not compressed) successfully deleted." ) ;
1126 //                                      } else {
1127 //                                              System.err.println( "Archive (not compressed) not deleted!" ) ;
1128 //                                              printProcessError( p.getErrorStream() ) ;
1129 //                                              
1130 //                                              error = true ;
1131 //                                      }
1132 //                              } catch( IOException e ) {
1133 //                                      System.err.println( "Error during archive (not compressed) deletion command: " ) ;
1134 //                                      e.printStackTrace() ;
1135 //                                      error = true ;
1136 //                              } catch( InterruptedException e ) {
1137 //                                      e.printStackTrace() ;
1138 //                                      error = true ;
1139 //                              }
1140 //                      }       
1141                 
1142                         saveName = machine.getName() + "_new_" + machine.getComputationId() + ".tar.gz" ;       
1143                 
1144                         /** Sending save to neighbor **/
1145                         if( ! error )
1146                         {
1147                                 if( emergencyStop )
1148                                 {
1149                                         return 1 ;
1150                                 }
1151                                 
1152                                 ArrayList<ServicesClient> sn = machine.getSaveNeighbors() ;
1153                                 
1154                                 for( int i = 0 ; i < sn.size() ; i++ )
1155                                 {
1156                                         String name ;
1157                                         String wd ;
1158                                         String snIP ;
1159                                         
1160                                         try {
1161                                                 name = sn.get( i ).getName() ;
1162                                                 wd = sn.get( i ).getWorkingDirectory() ;
1163                                                 snIP = sn.get( i ).getIPHost() ;
1164                                         } catch (RemoteException e2) {
1165                                                 System.err.println( "Unable to retrieve information on one save neighbor!" ) ;
1166                                                 e2.printStackTrace() ;
1167                                                 continue ; 
1168                                         }
1169                                         
1170                                         System.out.print( "Sending save to " + name + " ... " ) ;
1171                                         
1172                                         command = new String[]{ "/usr/bin/scp", working_directory + "/" + saveName,
1173                                                                 snIP + ":" + wd } ;
1174                                 
1175                                         try {
1176                                                 procSave = Runtime.getRuntime().exec( command ) ;
1177                                                 procSave.waitFor() ;
1178                         
1179                                                 if( procSave.exitValue() == 0 )
1180                                                 {
1181                                                         System.out.println( "Archive successfully sent." ) ;
1182                                                 } else {
1183                                                         System.err.println( "Archive not sent!" ) ;
1184 //                                                      printProcessError( p.getErrorStream() ) ;
1185                                                         printProcessError( procSave ) ;
1186                                                 
1187                                                         error = true ;
1188                                                 }
1189                                         } catch( IOException e ) {
1190                                                 System.err.println( "Error during archive send command: " ) ;
1191                                                 e.printStackTrace() ;
1192                                                 error = true ;
1193                                         } catch( InterruptedException e ) {
1194                                                 e.printStackTrace() ;
1195                                                 error = true ;
1196                                         }
1197                                 }
1198                         }
1199                 }
1200                 
1201                 /** Informing the server the save is done **/
1202                 if( ! error )
1203                 {
1204                         try {
1205                                 LocalHost.Instance().getServerStub().saveOk( LocalHost.Instance().getIP(), saveName ) ;
1206                         } catch( RemoteException e ) {
1207                                 System.err.println( "Problem while informing the server about the save state!" ) ;
1208                                 e.printStackTrace() ;
1209                         }
1210                         
1211                         synchronized( saveProcess ) {
1212                         saveProcess.setStatus( false ) ;
1213                         try {
1214                                 saveProcess.notifyAll() ;
1215                         } catch( Exception e ) {}}
1216                         
1217                         return 0 ;
1218                 }
1219                 
1220                 synchronized( saveProcess ) {
1221                 saveProcess.setStatus( false ) ;
1222                 try {
1223                         saveProcess.notifyAll() ;
1224                 } catch( Exception e ) {}}
1225                 
1226                 return 1 ;
1227         }
1228
1229         
1230         @Override
1231         public int reloadConfig() 
1232         {
1233                 System.out.println( "Reloading configuration ... " ) ;
1234                 
1235                 // TODO !!!
1236                 return 0 ;
1237         }
1238
1239         public void init( String _server_ip, int _server_port, int _client_port, int _dialog_port ) 
1240         {
1241                 System.out.println( "Initialisation Client ... " ) ;
1242                 System.out.println( "IP " + LocalHost.Instance().getIP() ) ;
1243                 
1244                 server_ip = _server_ip ;
1245                 server_port = _server_port ;
1246                 client_port = _client_port ;
1247                 dialog_port = _server_port + 1 ; // _dialog_port ;
1248                 
1249                 serverStub = null ;
1250                 saveProcess = new SaveProcess() ;
1251                 
1252                 machine = new VirtualMachine() ;
1253                 
1254                 VmRunCommand = "/usr/bin/vmrun" ;
1255 //              VmRunCommandArg = "-T player" ;
1256                 
1257 //              vm_user = "mpi" ;
1258 //              vm_user_passwd = "mpi" ;
1259                 ushell = "/bin/bash" ;
1260                 working_directory = "/localhome/vmware" ;
1261                 
1262                 wait_start = 15000 ;
1263                 max_start_try = 10 ;
1264                 
1265                 sema = new Semaphore( 1 ) ;
1266                 emergencyStop = false ;
1267                 
1268                 maxRetryVM = 10 ;
1269                 timeRetryVM = 10000 ;
1270                 
1271                 save_interleave = 30 * 60 * 1000 ;
1272                 date_last_save = 0 ;
1273                 
1274                 isRestartedSave = false ;
1275                 lastSaveOk = true ;
1276                 
1277                 /** Connection to server **/
1278                 try {
1279                         serverStub = (ServicesServer) Naming.lookup( "rmi://"
1280                                         + server_ip + ":" + server_port + "/Server" ) ;
1281                 } catch (MalformedURLException e) {
1282                         e.printStackTrace();
1283                 } catch (RemoteException e) {
1284                         e.printStackTrace();
1285                 } catch (NotBoundException e) {
1286                         e.printStackTrace();
1287                 }
1288                 
1289                 if( serverStub == null )
1290                 {
1291                         System.err.println( "Unable to connect to server!!" ) ;
1292                         System.err.println( "Server IP: " + server_ip + " -- server port: " + server_port ) ;
1293                         
1294                         System.exit( 1 ) ;
1295                 }
1296                 
1297                 System.out.println( "Connected to server " + server_ip + " on port " + server_port + "." ) ;
1298                 
1299 //              LocalHost.Instance().setServerIP( server_ip ) ;
1300                 LocalHost.Instance().setServerStub( serverStub ) ;
1301                 
1302                 
1303                 /** Creating the local server **/
1304                 exportObject() ;
1305
1306                 /** Starting all threads **/
1307                 start() ;
1308         }
1309         
1310         private void exportObject() 
1311         {
1312 //              ServicesClient ref = null ;
1313                 Registry reg = null ;
1314                 
1315                 try 
1316                 {       
1317                         while( true )
1318                         {
1319                                 reg = LocateRegistry.getRegistry( client_port ) ;
1320
1321                                 String tab[] = reg.list() ;
1322                         
1323                                 System.out.println( "There is an existing RMI Registry on port " +
1324                                                 client_port + " with " + tab.length + " entries!" ) ;
1325                                 for( int i = 0 ; i < tab.length ; i++ )
1326                                 {
1327                                         try {
1328                                                 if( UnicastRemoteObject.unexportObject( Naming.lookup(tab[i]), true ) )
1329                                                 {
1330                                                         System.out.println( "Register successfuly deleted!" ) ;
1331                                                 } else {
1332                                                         System.err.println( "Register undeleted !!!" ) ;
1333                                                 }
1334                                         } catch( Exception e ) {
1335                                                 e.printStackTrace() ;
1336                                         }
1337                                 } 
1338                         }
1339                 } catch( RemoteException e ) {
1340                 }                       
1341                 
1342                 try {
1343                         if ( System.getSecurityManager() == null ) 
1344                         {
1345                     System.setSecurityManager( new SecurityManager() ) ;
1346                 }
1347                         
1348                         LocateRegistry.createRegistry( client_port ) ;
1349                         LocateRegistry.getRegistry( client_port ).rebind( "Client", this ) ;
1350                         myStub = (ServicesClient) Naming.lookup( "rmi://"
1351                                         + LocalHost.Instance().getIP() + ":" + client_port
1352                                         + "/Client" ) ;
1353                 } catch( Exception e ) {
1354                         System.err.println( "Error in Client.exportObject() when creating local services:" + e ) ;
1355                         System.err.println( "Exit from Client.exportObject" ) ;
1356                         System.exit( 1 ) ;
1357                 }
1358                 
1359                 LocalHost.Instance().setStub( myStub ) ;
1360         }
1361         
1362         
1363         private boolean printProcessError( Process _p )
1364         {
1365                 boolean ret = false ;
1366                 
1367                 if( _p != null )
1368                 {
1369                         System.err.println( "Error: " + _p.exitValue() ) ;
1370                         BufferedReader br = new BufferedReader( new InputStreamReader( _p.getErrorStream() ) ) ;
1371                         String line ;
1372                         try {
1373                                 while( (line = br.readLine()) != null )
1374                                 {
1375                                         System.err.println( line ) ;
1376                                         if( line.contains( "egmentation" ) ) 
1377                                         {
1378                                                 ret = true ;
1379                                         }
1380                                 }
1381                         } catch( IOException e ) {
1382                                 e.printStackTrace() ;
1383                         }
1384                 }
1385                 
1386                 return ret ;
1387         }
1388         
1389
1390         @Override
1391         public int start() 
1392         {
1393                 /** Registering on server **/
1394                 Integer ret = 0 ;
1395                 try {
1396                         ret = LocalHost.Instance().getServerStub().register( LocalHost.Instance().getStub() );
1397                 } catch (RemoteException e1) {  
1398                         e1.printStackTrace();
1399                         return 1 ;
1400                 }
1401                 
1402                 switch( ret )
1403                 {
1404                 case 0: System.out.println( "Successfully registered on server." ) ; break ;
1405                 case 1: System.err.println( "Problem on server while registreting!" ) ; return 1 ;
1406                 case 2: System.out.println( "Already registered on server!" ) ; break ;                 
1407                 }
1408                 
1409                 /** Retrieving VM assigned IP **/
1410                 String vmIP = null ;
1411                 
1412                 try {
1413                         vmIP = LocalHost.Instance().getServerStub().getAssociatedIP( 
1414                                         LocalHost.Instance().getIP() ) ;
1415                 } catch (RemoteException e) {
1416                         System.err.println( "Problem while retrieving the VM assigned IP!!" ) ;
1417                         e.printStackTrace() ;
1418                         return 1 ;
1419                 }
1420                 
1421                 machine.setIp( vmIP ) ;
1422                 
1423                 System.out.println( "Assigned IP address for the VM: " + vmIP ) ;
1424
1425                 
1426                 /** Starting alive ping to server **/
1427                 pingServer = new PingServer() ;
1428                 pingServer.start() ;
1429
1430                 /** Starting socket server for VM dialog **/
1431                 dialogVmServer = new DialogVMServer() ;
1432                 dialogVmServer.start() ;
1433                 
1434                 return 0 ;
1435         }
1436         
1437         
1438         private class PingServer extends Thread
1439         {
1440                 private boolean run ;
1441                 
1442                 PingServer()
1443                 {
1444                         run = true ;
1445                 }
1446                 
1447                 protected void stopPing() { run = false ; }
1448                 
1449                 @Override
1450                 public void run() 
1451                 {
1452                         while( run )
1453                         {
1454                                 try {
1455                                         LocalHost.Instance().getServerStub().ping( LocalHost.Instance().getIP() ) ;
1456                                 } catch (RemoteException e1) {
1457                                         e1.printStackTrace();
1458                                 }
1459                                 
1460                                 try {
1461                                         Thread.sleep( 2000 ) ;
1462                                 } catch( InterruptedException e ) {
1463                                         e.printStackTrace() ;
1464                                 }
1465                         }
1466                 }
1467         }
1468         
1469         
1470         private class DialogVMServer extends Thread
1471         {
1472                 private boolean run ;
1473                 private Socket socket ;
1474                 private ArrayList<DialogVM> dialogs = new ArrayList<DialogVM>() ;
1475                 
1476                 DialogVMServer()
1477                 {
1478                         run = true ;
1479                 }
1480                 
1481                 protected void stopDialogVMServer() 
1482                 { 
1483                         run = false ;
1484                         
1485                         if( serverSocket != null )
1486                         {
1487                                 try {
1488                                         serverSocket.close() ;
1489 //                                      socket = serverSocket.accept() ;
1490                                         
1491                                         for( int i = 0 ; i < dialogs.size() ; i++ )
1492                                         {
1493                                                 dialogs.get( i ).stopDialogVM() ;
1494                                         }
1495                                         
1496                                 } catch( IOException e ) {
1497                                         e.printStackTrace() ;
1498                                 }
1499                         }                       
1500                 }
1501                 
1502                 
1503                 @Override
1504                 public void run() 
1505                 {
1506                         try {
1507                                 serverSocket = new ServerSocket( 0 ) ;
1508                                 dialog_port = serverSocket.getLocalPort() ;
1509                                 
1510                                 System.out.println( "SocketServer listening on port " + dialog_port ) ;
1511                         } catch( IOException e ) {
1512                                 System.err.println( "Unable to launch the SocketServer on port " + dialog_port + "!" ) ;
1513                                 e.printStackTrace() ;
1514                                 
1515                                 run = false ;
1516                         }       
1517                         
1518                         while( run )
1519                         {                               
1520                                 try {
1521                                         socket = serverSocket.accept() ;
1522                                         
1523                                         dialogs.add( new DialogVM( socket ) ) ;
1524                                         dialogs.get( dialogs.size() - 1 ).start() ;     
1525                                 } catch( IOException e ) {
1526                                         System.err.println( "Problem with the accept function!" ) ;
1527                                         e.printStackTrace() ;
1528                                 }
1529                         }
1530                 }
1531         }
1532
1533         
1534         private class DialogVM extends Thread
1535         {
1536                 private boolean run ;
1537                 private Socket socket ;
1538                 private BufferedReader reader ;
1539                 private String line ;
1540                 
1541                 DialogVM( Socket _socket ) { run = true ; socket = _socket ; }
1542         
1543                 protected void stopDialogVM()
1544                 {
1545                         run = false ;
1546
1547                         try {
1548                                 reader.close() ; reader = null ;
1549                                 socket.close() ; socket = null ;
1550                         } catch( IOException e ) {
1551                                 e.printStackTrace() ;
1552                         }
1553                 }
1554         
1555                 @Override
1556                 public void run() 
1557                 {
1558                         try {
1559                                 reader = new BufferedReader( new InputStreamReader( socket.getInputStream() ) ) ;
1560                         } catch( IOException e ) {
1561                                 System.err.println( "Unable to open a dialog socket with the VM!" ) ;
1562                                 e.printStackTrace();
1563                                 stopDialogVM() ;
1564                         }
1565                         
1566                         while( run )
1567                         {
1568                                 try {
1569                                         line = null ;
1570                                         
1571                                         if( reader != null )
1572                                         {
1573                                                 line = reader.readLine() ;
1574                                         }
1575                                         
1576                                         /** VM is starting -- retrieving informations **/
1577                                         if( run && line != null &&  line.equalsIgnoreCase( "infos" ) )
1578                                         {
1579                                                 /* Receiving name */
1580                                                 machine.setName( reader.readLine() ) ;
1581                                                 
1582                                                 /* Receiving IP */
1583                                                 String ip = reader.readLine() ;
1584                                                 if( ! ip.equalsIgnoreCase( machine.getIp() ) )
1585                                                 {
1586                                                         System.err.println( "VM IP not well configured!!" ) ;
1587                                                 }
1588                                                 
1589                                                 /* Close streams */
1590                                                 reader.close() ; reader = null ;
1591                                                 socket.close() ; socket = null ;
1592                                                 
1593                                                 run = false ;
1594                                         }
1595                                         
1596                                         /** It's time to do a save **/
1597                                         if( run && line != null &&  line.equalsIgnoreCase( "save" ) )
1598                                         {
1599                                                 try {
1600                                                         machine.setComputationId( Integer.parseInt( reader.readLine() ) ) ;
1601                                                 } catch( Exception e ) {
1602                                                         System.err.println( "Problem while reading the computation id!" ) ;
1603                                                         e.printStackTrace() ;
1604                                                 }
1605                                                 
1606                                                 if( (System.currentTimeMillis() - date_last_save) > save_interleave )
1607                                                 {
1608                                                         date_last_save = System.currentTimeMillis() ; 
1609                                                         
1610                                                         /* Close streams */
1611                                                         reader.close() ; reader = null ;
1612                                                         socket.close() ; socket = null ;
1613                                                         
1614                                                         run = false ;
1615                                                 
1616                                                         /* Starting the VM save */
1617                                                         saveVM() ;
1618                                                         
1619                                                         date_last_save = System.currentTimeMillis() ; 
1620                                                 } else {
1621                                                         sendSaveOkVM() ;
1622                                                 }
1623                                         }
1624                                         
1625                                         
1626                                         /** Computation is done, we can shutdown the VM **/
1627                                         if( run && line != null &&  line.equalsIgnoreCase( "quit" ) )
1628                                         {
1629                                                 try {
1630                                                         Thread.sleep( 5000 ) ;
1631                                                 } catch( InterruptedException e ) {
1632                                                         e.printStackTrace() ;
1633                                                 }
1634                                                 
1635                                                 /* Close streams */
1636                                                 reader.close() ; reader = null ;
1637                                                 socket.close() ; socket = null ;
1638                                                 
1639                                                 run = false ;
1640                                                 
1641                                                 stopVM() ;
1642                                         }
1643                                         
1644                                 } catch( IOException e ) {
1645                                         e.printStackTrace() ;
1646                                 }
1647                         }
1648                 }
1649         }
1650
1651         @Override
1652         public void stop() 
1653         {
1654                 stopVM() ;
1655                 
1656                 pingServer.stopPing() ;
1657                 
1658                 dialogVmServer.stopDialogVMServer() ;
1659                 
1660                 // unexportObject ??
1661                 
1662                 System.exit( 0 ) ;
1663         }
1664
1665         @Override
1666         public String getIPHost() 
1667         {
1668                 return LocalHost.Instance().getIP() ;
1669         }
1670         
1671         @Override
1672         public String getName()
1673         {
1674                 return LocalHost.Instance().getName() ;
1675         }
1676         
1677         
1678         @Override
1679         public void saveOk() 
1680         {
1681                 String save_name = machine.getName() + "_last_" + machine.getComputationId() +
1682                         ".tar.gz" ;
1683                 
1684                 String save_new = machine.getName() + "_new_" 
1685                   + machine.getComputationId() + ".tar.gz" ;
1686                 
1687                 String[] command = new String[]{ "/bin/mv", 
1688                                 working_directory + "/" + save_new, 
1689                                 working_directory + "/" + save_name } ;
1690                 
1691                 try {
1692                         Process p = Runtime.getRuntime().exec( command ) ;
1693                         p.waitFor() ;
1694                 
1695                         if( p.exitValue() == 0 )
1696                         {
1697                                 machine.setSave_last( save_name ) ;
1698                                 System.out.println( "Last save OK" ) ;
1699                         } else {
1700                                 System.err.println( "Last save NOK!" ) ;
1701                                 System.err.println( "Error: " ) ;
1702 //                              printProcessError( p.getErrorStream() ) ;
1703                                 printProcessError( p ) ;
1704                         }
1705                 } catch( IOException e ) {
1706                         System.err.println( "Error during last archive move:" ) ;
1707                         e.printStackTrace() ;
1708                 } catch( InterruptedException e ) {
1709                         e.printStackTrace() ;
1710                 }
1711                 
1712                 // Changing on save neighbors
1713                 for( int i = 0 ; i < machine.getSaveNeighbors().size() ; i++ )
1714                 {
1715                         try {
1716                                 machine.getSaveNeighbors().get( i ).changeSaveName( save_new, save_name, machine.getComputationId() ) ;
1717                         } catch( RemoteException e ) {
1718                                 try {
1719                                         System.err.println( "Unable to change save name on " + machine.getSaveNeighbors().get( i ).getName() + "!" ) ;
1720                                 } catch( RemoteException e1 ) {
1721                                         System.err.println( "Unable to change save name on an unamed save neighbor!" ) ;
1722                                         e1.printStackTrace() ;
1723                                 }
1724                                 e.printStackTrace() ;
1725                         }
1726                 }
1727                 
1728                 // Informing the server
1729                 int ret = 1 ;
1730                 try {
1731                         ret = LocalHost.Instance().getServerStub().changeSaveName( LocalHost.Instance().getIP(), save_name ) ;
1732                 } catch( RemoteException e ) {
1733                         System.err.println( "Unable to inform the server about the new save name!" ) ;
1734                         e.printStackTrace() ;
1735                 }
1736                 
1737                 if( ret == 0 )
1738                 {
1739                         System.out.println( "Successfully informing the server about the new save name." ) ;
1740                 } else {
1741                         System.err.println( "Problem on the server while informing it about the new save name!" ) ;
1742                 }
1743                 
1744                 // Ok here
1745                 lastSaveOk = true ;
1746         }
1747         
1748         
1749         public void changeSaveName( String _n1, String _n2, int _id )
1750         {
1751                 if( _n1 != null && _n1.length() > 0 )
1752                 {
1753                         System.out.println( "Changing save name for processus " + _id + " ... " ) ;
1754                         
1755                         String[] command = new String[]{ "/bin/mv", 
1756                                         working_directory + "/" + _n1, 
1757                                         working_directory + "/" + _n2 } ;
1758                         
1759                         try {
1760                                 Process p = Runtime.getRuntime().exec( command ) ;
1761                                 p.waitFor() ;
1762                         
1763                                 if( p.exitValue() == 0 )
1764                                 {
1765                                         System.out.println( "Change save name OK" ) ;
1766                                 } else {
1767                                         System.err.println( "Change save name NOK!" ) ;
1768                                         System.err.println( "Error: " ) ;
1769 //                                      printProcessError( p.getErrorStream() ) ;
1770                                         printProcessError( p ) ;
1771                                 }
1772                         } catch( IOException e ) {
1773                                 System.err.println( "Error during save renaming:" ) ;
1774                                 e.printStackTrace() ;
1775                         } catch( InterruptedException e ) {
1776                                 e.printStackTrace() ;
1777                         }
1778                 }
1779         }
1780
1781         
1782         @Override
1783         public void setSavingNeighbor( ServicesClient _sn )
1784         {
1785                 if( _sn != null )
1786                 {
1787                         ArrayList<ServicesClient> as = new ArrayList<ServicesClient>() ;
1788                         as.add( _sn ) ;
1789                         
1790                         try {
1791                                 System.out.println( "Save neighbor: " + _sn.getName() ) ;
1792                         } catch( RemoteException e ) {
1793                                 System.err.println( "Unable to retrieve the name of the save neighbor!" ) ;
1794                                 e.printStackTrace() ;
1795                         }
1796                         
1797                         machine.setSaveNeighbors( as ) ;
1798                 }
1799         }
1800         
1801         
1802         @Override
1803         public void setSavingNeighbors( ArrayList<ServicesClient> _sn )
1804         {
1805                 if( _sn != null && _sn.size() > 0 )
1806                 {
1807                         System.out.print( "Save neighbors: " ) ;
1808                         for( int i = 0 ; i < _sn.size() ; i++ )
1809                         {
1810                                 try {
1811                                         System.out.print( _sn.get( i ).getName() ) ;
1812                                 } catch( RemoteException e ) {
1813                                         System.err.println( "Unable to retrieve the name of a save neighbor!" ) ;
1814                                         e.printStackTrace() ;
1815                                 }
1816                                 
1817                                 if( i != _sn.size() - 1 )
1818                                 {
1819                                         System.out.print( ", " ) ;
1820                                 } else {
1821                                         System.out.println( "." ) ;
1822                                 }
1823                         }
1824                         
1825                         machine.setSaveNeighbors( _sn ) ;
1826                 }
1827         }
1828
1829         
1830         @Override
1831         public void addSavingNeighbor( ServicesClient _sn )
1832         {
1833                 if( _sn != null )
1834                 {
1835                         try {
1836                                 System.out.println( "Adding save neighbor: " + _sn.getName() ) ;
1837                         } catch( RemoteException e ) {
1838                                 System.err.println( "Unable to retrieve the name of a save neighbor!" ) ;
1839                                 e.printStackTrace() ;
1840                         }
1841                         
1842                         machine.getSaveNeighbors().add( _sn ) ;
1843                 }
1844         }
1845         
1846         
1847         @Override
1848         public void addSavingNeighbors( ArrayList<ServicesClient> _sn )
1849         {
1850                 if( _sn != null && _sn.size() > 0 )
1851                 {
1852                         System.out.print( "Adding save neighbors: " ) ;
1853                         for( int i = 0 ; i < _sn.size() ; i++ )
1854                         {
1855                                 try {
1856                                         System.out.print( _sn.get( i ).getName() ) ;
1857                                 } catch( RemoteException e ) {
1858                                         System.err.println( "Unable to retrieve the name of a save neighbor!" ) ;
1859                                         e.printStackTrace() ;
1860                                 }
1861                                 
1862                                 if( i != _sn.size() - 1 )
1863                                 {
1864                                         System.out.print( ", " ) ;
1865                                 } else {
1866                                         System.out.println( "." ) ;
1867                                 }
1868                                 
1869                                 machine.getSaveNeighbors().add( _sn.get( i ) ) ;
1870                         }
1871                 }
1872         }
1873         
1874         
1875         @Override
1876         public void replaceSavingNeighbor( String _old, ServicesClient _new )
1877         {
1878                 System.out.print( "Replacing a save neihgbor ... " ) ;
1879                 if( _old != null && _new != null )
1880                 {
1881                         int i = 0 ;
1882                         
1883                         for( i = 0 ; i < machine.getSaveNeighbors().size() ; i++ )
1884                         {
1885                                 try {
1886                                         if( machine.getSaveNeighbors().get( i ).getIPHost().equalsIgnoreCase( _old ) )
1887                                         {
1888                                                 machine.getSaveNeighbors().set( i, _new ) ;
1889                                                 System.out.println( "Save neighbor successfully changed." ) ;
1890                                                 break ;
1891                                         }
1892                                 } catch( RemoteException e ) {
1893                                         System.err.println( "Unable to retrieve the IP address of a save neighbor!" ) ;
1894                                         e.printStackTrace() ;
1895                                 }
1896                         }
1897                         
1898                         if( i == machine.getSaveNeighbors().size() )
1899                         {
1900                                 System.out.println( "I am not concerned by the modification." ) ;
1901                         }
1902                 }
1903         }
1904         
1905         
1906         @Override
1907         public int retrieveSave( String _saveName )
1908         {               
1909                 if( _saveName != null )
1910                 {
1911                         if( ! _saveName.equalsIgnoreCase( "none" ) )
1912                         {
1913                                 machine.setSave_last( _saveName ) ;
1914                         } else {
1915                                 System.err.println( "I have no save to retrieve!!" ) ;
1916                                 return 1 ;
1917                         }
1918                         
1919                         // TODO NEIGHBORS !!!!
1920                         //System.out.println( "!!!! NEIGHBORS !!!!!" ) ;
1921                         boolean ok = false ;
1922                         boolean go = true ;
1923                         int i = 0 ;
1924                         
1925                         while( ! ok && i < machine.getSaveNeighbors().size() )
1926                         {
1927                                 try {
1928                                         System.out.print( "Retrieving a save on " + machine.getSaveNeighbors().get( 0 ).getName() + " ... " ) ;
1929                                 } catch( RemoteException e1 ) {
1930                                         System.err.println( "Unable to retrieve the name of a save neighbor!" ) ;
1931                                         e1.printStackTrace() ;
1932                                 }
1933                                 
1934                                 String command[] = {} ;
1935                                 
1936                                 try
1937                                 {
1938                                         command = new String[]{ "/usr/bin/scp", 
1939                                                         machine.getSaveNeighbors().get( i ).getIPHost() + ":" +
1940                                                         machine.getSaveNeighbors().get( i ).getWorkingDirectory() + "/" +
1941                                                         machine.getSave_last(),
1942                                                         working_directory } ;
1943                                 } catch( RemoteException e1 ) {
1944                                         System.err.println( "Unable to retrieve the name of a save neighbor!" ) ;
1945                                         e1.printStackTrace() ;
1946                                         go = false ;
1947                                 }       
1948                                 
1949                                 if( go )
1950                                 try {
1951                                         Process p = Runtime.getRuntime().exec( command ) ;
1952                                         p.waitFor() ;
1953                         
1954                                         if( p.exitValue() == 0 )
1955                                         {
1956                                                 System.out.println( "Archive successfully retrieved." ) ;
1957                                                 isRestartedSave = true ;
1958                                                 ok = true ;
1959                                         } else {
1960                                                 System.err.println( "Archive not retrieved!" ) ;
1961                                                 System.err.println( "Error: " ) ; 
1962 //                                              printProcessError( p.getErrorStream() ) ;
1963                                                 printProcessError( p ) ;
1964 //                                              error = true ;
1965                                         }
1966                                 } catch( IOException e ) {
1967                                         System.err.println( "Error during archive retrieve command: " ) ;
1968                                         e.printStackTrace() ;
1969 //                                      error = true ;
1970                                 } catch( InterruptedException e ) {
1971                                         e.printStackTrace() ;
1972 //                                      error = true ;
1973                                 }
1974                                 
1975                                 i++ ;
1976                         }
1977                         
1978                         if( ok )
1979                         {
1980                                 return 0 ;
1981                         } else {
1982                                 System.err.println( "Unable to retrieve a save archive from any neighbor!" ) ;
1983                         }
1984                 }
1985                 
1986                 return 1 ;
1987                 
1988         }
1989
1990         @Override
1991         public String getIPVM() throws RemoteException 
1992         {
1993                 if( machine != null )
1994                 {
1995                         return machine.getIp() ;
1996                 }
1997                 
1998                 return null ;
1999         }
2000         
2001         
2002         @Override
2003         public void setIPVM( String _ipVM ) throws RemoteException 
2004         {
2005                 if( _ipVM != null && ! _ipVM.isEmpty() )
2006                 {
2007                         System.out.println( "The VM IP is now: " + _ipVM ) ;
2008                         machine.setIp( _ipVM ) ;
2009                 }
2010         }
2011         
2012         
2013         public String getWorkingDirectory()
2014         {
2015                 return working_directory ;
2016         }
2017         
2018         
2019         public Integer deployVM( String _name, String _archive, String _directory )
2020         {
2021                 if( _name != null && _name.length() > 0 && _archive != null && _name.length() > 0 )
2022                 {
2023                         File file = new File( working_directory + "/" + _archive ) ;
2024                         if( ! file.exists() )
2025                         {
2026                                 System.err.println( "There is no archive named " + _archive + " in my working directory!" ) ;
2027                                 file = null ;
2028                                 return 2 ;
2029                         } else if( file.isDirectory() ) {
2030                                 System.err.println( _archive + " is a directory!" ) ;
2031                                 file = null ;
2032                                 return 1 ;
2033                         }
2034                         
2035                         file = null ;
2036                         
2037                         machine.setName( _name ) ;
2038                         machine.setInitial_archive_name( _archive ) ;
2039                         machine.setDirectory( _directory ) ;
2040                         
2041                         if( machine.deployInitialVM() == 1 ) 
2042                         {
2043                                 System.err.println( "Unable to deploy the initial VM archive!" ) ;
2044                         } else {                                
2045                                 return 0 ;
2046                         }
2047                 }
2048                 
2049                 return 1 ;
2050         }
2051         
2052         
2053         private class SaveProcess
2054         {
2055                 boolean status ;
2056                 
2057                 SaveProcess()
2058                 {
2059                         status = false ;
2060                 }
2061                 
2062                 protected boolean getStatus() { return status ; }
2063                 
2064                 protected void setStatus( boolean _b ) { status = _b ; }
2065         }
2066         
2067 }
2068
2069
2070 /** La programmation est un art, respectons ceux qui la pratiquent !! **/