int main(int argc, char** argv) { BOINC_OPTIONS options; BOINC_STATUS status; double cpu_time=0, cpu_chkpt_time=0; FILE*fp; char buffer[2048]; // Enough size for the VBoxManage list vms output unsigned int i; bool graphics = false; bool headless = false; bool vrde = false; bool vm_name = false; bool retval = false; // Name for the VM vmdk filename string cernvm = "cernvm.vmdk"; string resolved_name; unsigned int output; // Get BOINC APP INIT DATA // boinc_get_init_data(aid); // The VM VM vm; // Registering time for progress accounting time_t init_secs = time (NULL); //fprintf(stderr,"INFO: %ld seconds since January 1, 1970\n", init_secs); // Checking command line options for (i=1; i<(unsigned int)argc; i++) { if (!strcmp(argv[i], "--graphics")) graphics = true; if (!strcmp(argv[i], "--headless")) headless = true; if (!strcmp(argv[i], "--vmname")) { vm.virtual_machine_name = argv[i+1]; fprintf(stderr,"INFO: The name of the VM is: %s\n",vm.virtual_machine_name.c_str()); } } // If the wrapper has not be called with the command line argument --vmname NAME, give a default name to the VM if (vm.virtual_machine_name.empty()) { vm.virtual_machine_name = "BOINC_VM"; } memset(&options, 0, sizeof(options)); options.main_program = true; options.check_heartbeat = true; options.handle_process_control = true; options.send_status_msgs = true; if (graphics) { options.backwards_compatible_graphics = true; } boinc_init_options(&options); // Setting up the PATH for Windows machines: #ifdef _WIN32 // DEBUG information: fprintf(stderr,"\nSetting VirtualBox PATH in Windows...\n"); // First get the HKEY_LOCAL_MACHINE\SOFTWARE\Oracle\VirtualBox fprintf(stderr,"Trying to grab installation path of VirtualBox from Windows Registry...\n"); TCHAR szPath[4096]; DWORD dwType; DWORD cbSize = sizeof(szPath) - sizeof(TCHAR); // Leave room for nul terminator if (SHGetValue(HKEY_LOCAL_MACHINE,TEXT("SOFTWARE\\Oracle\\VirtualBox"),TEXT("InstallDir"),&dwType,szPath,&cbSize) == ERROR_SUCCESS) { //szPath[cbSize / sizeof(TCHAR)] = TEXT(´\0´); fprintf(stderr,"Success!!! Installation PATH of VirtualBox is: %s.\n",szPath); } else { fprintf(stderr,"ERROR: Retrieving the HKEY_LOCAL_MACHINE\\SOFTWARE\\Oracle\\VirtualBox\\InstallDir value was impossible\n\n"); fprintf(stderr,"Trying with VBOX_INSTALL_PATH environment variable...\n"); LPTSTR VBoxInsPath; DWORD dwRet, dwErr; BOOL fExist, fSuccess; // Retrieve old PATH variable VBoxInsPath = (LPTSTR) malloc(4096*sizeof(TCHAR)); if(NULL == VBoxInsPath) { fprintf(stderr,"ERROR: malloc for VBoxInsPAth variable. Reason: Out of memory\n"); return FALSE; } dwRet = GetEnvironmentVariable("VBOX_INSTALL_PATH", VBoxInsPath, 4096); if(0 == dwRet) { dwErr = GetLastError(); if( ERROR_ENVVAR_NOT_FOUND == dwErr ) { fprintf(stderr,"ERROR: VBOX_INSTALL_PATH environment variable does not exist.\n"); fprintf(stderr,"ERROR: Impossible to set up the VirtualBox PATH. Aborting execution.\n\n"); fExist=FALSE; boinc_finish(1); } else { fprintf(stderr,"ERROR: GetLastError ouput for VBOX_INSTALL_PATH environment variable: %u\n", dwErr); fprintf(stderr,"INFO: GetLastError Aborting\n"); fExist=FALSE; boinc_finish(1); } } free(VBoxInsPath); } // New variables for setting the environment variable PATH LPTSTR pszOldVal; LPTSTR newVirtualBoxPath; LPTSTR virtualbox; DWORD dwRet, dwErr; BOOL fExist, fSuccess; // Create the new PATH variable newVirtualBoxPath = (LPTSTR) malloc(4096*sizeof(TCHAR)); if(NULL == newVirtualBoxPath) { fprintf(stderr, "ERROR: malloc for newVirtualBoxPath variable. Reason: Out of memory\n"); return FALSE; } virtualbox = szPath; // Retrieve old PATH variable pszOldVal = (LPTSTR) malloc(4096*sizeof(TCHAR)); if(NULL == pszOldVal) { fprintf(stderr,"ERROR: malloc of pszOldVal variable. Reason: Out of memory\n"); return FALSE; } dwRet = GetEnvironmentVariable("PATH", pszOldVal, 4096); if(0 == dwRet) { dwErr = GetLastError(); if( ERROR_ENVVAR_NOT_FOUND == dwErr ) { fprintf(stderr,"ERROR: PATH environment variable does not exist.\n"); fExist=FALSE; exit(1); } } else { // DEBUG: print old PATH enviroment variable fprintf(stderr,"Old PATH environment variable:\n"); fprintf(stderr,pszOldVal); fprintf(stderr,"\n"); // Set new PATH environment variable lstrcat(pszOldVal,";"); // Concat ; to old PATH // Add VirtualBox path SetEnvironmentVariable("PATH",lstrcat(pszOldVal,virtualbox)); dwRet = GetEnvironmentVariable("PATH", pszOldVal, 4096); fprintf(stderr,"\nAdding VirtualBox to PATH:\n"); fprintf(stderr,pszOldVal); fprintf(stderr,"\n"); } // Free memory free(pszOldVal); free(newVirtualBoxPath); #endif // We check if the VM has already been created and launched if (fp=fopen("VMName","r")) { fclose(fp); vm_name = true; } else { // First remove old versions fprintf(stderr,"INFO: Cleaning old VMs of the project...\n"); vm.remove(); fprintf(stderr,"INFO: Cleaning completed\n"); // Then, Decompress the new VM.gz file fprintf(stderr,"\nInitializing VM...\n"); fprintf(stderr,"Decompressing the VM\n"); retval = boinc_resolve_filename_s("cernvm.vmdk.gz",resolved_name); if (retval) fprintf(stderr,"can't resolve cernvm.vmdk.gz filename"); unzip(resolved_name.c_str(),cernvm.c_str()); fprintf(stderr,"Uncompressed finished\n"); vm_name= false; } if (vm_name) { fprintf(stderr,"VMName exists\n"); bool VMexist=false; string arg_list; //if((fp=fopen(vm.name_path.c_str(),"r"))==NULL){ // fprintf(stderr,"Main fopen failed\n"); // boinc_finish(1); //} //if(fgets(buffer,256,fp)) vm.virtual_machine_name=buffer; //fclose(fp); fprintf(stderr,"INFO: Virtual machine name %s\n",vm.virtual_machine_name.c_str()); // DEBUG for the name of the VM // fprintf(stderr,"Name of the VM:\n"); // fprintf(stderr,vm.virtual_machine_name.c_str()); arg_list=""; arg_list=" list vms"; if (!vbm_popen(arg_list,buffer,sizeof(buffer))){ fprintf(stderr, "CernVMManager list failed!\n"); boinc_finish(1); } string VMlist=buffer; // DEBUG for the list of running VMs // fprintf(stderr,"List of running VMs:\n"); // fprintf(stderr,VMlist.c_str()); // fprintf(stderr,"\n"); if(VMlist.find(vm.virtual_machine_name.c_str()) != string::npos){ VMexist=true; } //Maybe voluteers delete CernVM using VB GUI if(!VMexist){ fprintf(stderr,"INFO: VM does not exists.\n"); fprintf(stderr,"INFO: Cleaning old instances...\n"); vm.remove(); fprintf(stderr,"INFO: Done!\n"); fprintf(stderr,"INFO: Unzipping image...\n"); retval = boinc_resolve_filename_s("cernvm.vmdk.gz",resolved_name); if (retval) fprintf(stderr,"can't resolve cernvm.vmdk.gz filename"); unzip(resolved_name.c_str(),cernvm.c_str()); fprintf(stderr,"INFO: Uncompressed finished\n"); fprintf(stderr,"Registering a new VM from an unzipped image...\n"); vm.create(); fprintf(stderr,"Done!\n"); } } else{ fprintf(stderr,"INFO: Cleaning old instances...\n"); vm.remove(); fprintf(stderr,"Registering a new VM from unzipped image...\n"); vm.create(); fprintf(stderr,"Done!\n"); } time_t elapsed_secs = 0, dif_secs = 0; long int t = 0; double frac_done = 0; read_cputime(cpu_time); cpu_chkpt_time = cpu_time; vm.current_period=cpu_time; vm.start(vrde,headless); vm.last_poll_point = time(NULL); while (1) { boinc_get_status(&status); poll_boinc_messages(vm, status); // Report progress to BOINC client if (!status.suspended) { vm.poll(); if (vm.suspended) { fprintf(stderr,"WARNING: VM should be running as the WU is not suspended.\n"); vm.resume(); } //if(vm.current_period >= CHECK_PERIOD) // write_cputime(vm.current_period); //if(vm.current_period >= TRICK_PERIOD) //vm.send_cputime_message(); elapsed_secs = time(NULL); dif_secs = update_progress(elapsed_secs - init_secs); // Convert it for Windows machines: t = static_cast<int>(dif_secs); fprintf(stderr,"INFO: Running seconds %ld\n",dif_secs); // For 24 hours: frac_done = floor((t/86400.0)*100.0)/100.0; fprintf(stderr,"INFO: Fraction done %f\n",frac_done); // Checkpoint for reporting correctly the time boinc_time_to_checkpoint(); boinc_checkpoint_completed(); boinc_fraction_done(frac_done); if (frac_done >= 1.0) { fprintf(stderr,"INFO: Stopping the VM...\n"); vm.savestate(); fprintf(stderr,"INFO: VM stopped!\n"); vm.remove(); // Update the ProgressFile for starting from zero next WU write_progress(0); fprintf(stderr,"INFO: Done!! Cleanly exiting.\n"); fprintf(stderr,"INFO: Work Unit completed.\n"); // Output file: fprintf(stderr,"INFO: Creating output file...\n"); FILE* output = fopen("output", "w"); fprintf(output, "Work Unit completed!\n"); fclose(output); fprintf(stderr,"INFO: Done!\n"); boinc_finish(0); } else { init_secs = elapsed_secs; boinc_sleep(POLL_PERIOD); } } else { init_secs = time(NULL); boinc_sleep(POLL_PERIOD); } } }