Logo AND Algorithmique Numérique Distribuée

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