void VMUniverseMgr::freeVM(pid_t s_pid) { VMStarterInfo *info = findVMStarterInfoWithStarterPid(s_pid); if( !info ) { return; } MyString pid_dir; Directory execute_dir(info->m_execute_dir.Value(), PRIV_ROOT); pid_dir.formatstr("dir_%ld", (long)s_pid); if( execute_dir.Find_Named_Entry( pid_dir.Value() ) ) { // starter didn't exit cleanly, // maybe it seems to be killed by startd. // So we need to make sure that VM is really destroyed. killVM(info); } m_vm_used_memory -= info->m_memory; m_vm_starter_list.Delete(info); delete info; if( !m_vm_starter_list.Number() && m_needCheck ) { // the last vm job is just finished // if m_needCheck is true, we need to call docheckVMUniverse docheckVMUniverse(); } }
VirshType::~VirshType() { priv_state old_priv = set_user_priv(); Shutdown(); set_priv( old_priv ); if( getVMStatus() != VM_STOPPED ) { // To make sure VM exits killVM(); } setVMStatus(VM_STOPPED); XenDisk *disk = NULL; m_disk_list.Rewind(); while( m_disk_list.Next(disk) ) { m_disk_list.DeleteCurrent(); delete disk; } }
void VMUniverseMgr::killVM(VMStarterInfo *info) { if( !info ) { return; } if( !m_vm_type.Length() || !m_vmgahp_server.Length() ) { return; } if( info->m_vm_pid > 0 ) { dprintf( D_ALWAYS, "In VMUniverseMgr::killVM(), " "Sending SIGKILL to Process[%d]\n", (int)info->m_vm_pid); daemonCore->Send_Signal(info->m_vm_pid, SIGKILL); } MyString matchstring; MyString workingdir; workingdir.formatstr("%s%cdir_%ld", info->m_execute_dir.Value(), DIR_DELIM_CHAR, (long)info->m_pid); if( (strcasecmp(m_vm_type.Value(), CONDOR_VM_UNIVERSE_XEN ) == MATCH) || (strcasecmp(m_vm_type.Value(), CONDOR_VM_UNIVERSE_KVM) == 0)) { if( create_name_for_VM(&info->m_job_ad, matchstring) == false ) { dprintf(D_ALWAYS, "VMUniverseMgr::killVM() : " "cannot make the name of VM\n"); return; } }else { // Except Xen, we need the path of working directory of Starter // in order to destroy VM. matchstring = workingdir; } killVM( matchstring.Value() ); }
bool VMGahpServer::cleanup(void) { bool result = true; if( m_is_cleanuped ) { return true; } m_is_cleanuped = true; dprintf(D_FULLDEBUG,"Inside VM_GAHP_SERVER::cleanup()\n"); // Remove all pending requests int currentkey = 0; VMGahpRequest *req = NULL; m_request_table.startIterations(); while( m_request_table.iterate(currentkey, req) != 0) { if( req ) { req->detachVMGahpServer(); } } m_request_table.clear(); // Stop poll timer if(m_poll_tid != -1) { if( daemonCore ) { daemonCore->Cancel_Timer(m_poll_tid); } m_poll_tid = -1; } if(m_poll_real_soon_tid != -1) { if( daemonCore ) { daemonCore->Cancel_Timer(m_poll_real_soon_tid); } m_poll_real_soon_tid = -1; } // Stop stderr timer if( m_stderr_tid != -1 ) { if( daemonCore ) { daemonCore->Cancel_Timer(m_stderr_tid); } m_stderr_tid = -1; } if( m_is_initialized && (m_vmgahp_pid > 0 )) { result = command_quit(); } // print last messages from vmgahp before closing pipes printSystemErrorMsg(); // Close pipes if( m_vmgahp_readfd != -1 ) { if( daemonCore ) { daemonCore->Close_Pipe(m_vmgahp_readfd); } m_vmgahp_readfd = -1; } if( m_vmgahp_writefd != -1 ) { if( daemonCore ) { daemonCore->Close_Pipe(m_vmgahp_writefd); } m_vmgahp_writefd = -1; } if( m_vmgahp_errorfd != -1 ) { if( daemonCore ) { daemonCore->Close_Pipe(m_vmgahp_errorfd); } m_vmgahp_errorfd = -1; } m_vmgahp_error_buffer = ""; // Make sure Virtual machine exits. if( m_vm_id > 0 ) { killVM(); m_vm_id = 0; } m_is_initialized = false; m_is_async_mode = false; m_vmgahp_pid = -1; m_rotated_reqids = false; m_commands_supported.clearAll(); m_vms_supported.clearAll(); dprintf(D_FULLDEBUG,"End of VM_GAHP_SERVER::cleanup\n"); sleep(1); return result; }
bool VirshType::Shutdown() { vmprintf(D_FULLDEBUG, "Inside VirshType::Shutdown\n"); if( (m_configfile.Length() == 0) ) { m_result_msg = VMGAHP_ERR_INTERNAL; return false; } if( getVMStatus() == VM_STOPPED ) { if( m_self_shutdown ) { if( m_vm_no_output_vm ) { // A job user doesn't want to get back VM files. // So we will delete all files in working directory. m_delete_working_files = true; m_is_checkpointed = false; }else { if( !m_suspendfile.IsEmpty() ) { unlink(m_suspendfile.Value()); } m_suspendfile = ""; // delete the created xen vm configuration file if( !m_configfile.IsEmpty() ) { unlink(m_configfile.Value()); } // delete the checkpoint timestamp file MyString tmpfilename; tmpfilename.formatstr("%s%c%s", m_workingpath.Value(), DIR_DELIM_CHAR, XEN_CKPT_TIMESTAMP_FILE); unlink(tmpfilename.Value()); // We need to update timestamp of transferred writable disk files updateLocalWriteDiskTimestamp(time(NULL)); } } // We here set m_self_shutdown to false // So, above functions will not be called twice m_self_shutdown = false; return true; } // if( getVMStatus() == VM_SUSPENDED ) // do nothing // If a VM is soft suspended, resume it first ResumeFromSoftSuspend(); if( getVMStatus() == VM_RUNNING ) { priv_state priv = set_root_priv(); virDomainPtr dom = virDomainLookupByName(m_libvirt_connection, m_vm_name.Value()); set_priv(priv); if(dom == NULL) { virErrorPtr err = virConnGetLastError(m_libvirt_connection); if (err && err->code != VIR_ERR_NO_DOMAIN) { vmprintf(D_ALWAYS, "Error finding domain %s: %s\n", m_vm_name.Value(), (err ? err->message : "No reason found")); return false; } } else { priv = set_root_priv(); int result = virDomainShutdown(dom); virDomainFree(dom); set_priv(priv); if( result != 0 ) { // system error happens // killing VM by force killVM(); } } // Now we don't need working files any more m_delete_working_files = true; m_is_checkpointed = false; } setVMStatus(VM_STOPPED); m_stop_time.getTime(); return true; }