示例#1
0
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);
        }
    }
}