diff --git a/include/VirtualMachine.h b/include/VirtualMachine.h index 0c352518ec..c50e1717c7 100644 --- a/include/VirtualMachine.h +++ b/include/VirtualMachine.h @@ -656,10 +656,12 @@ public: // Context related functions // ------------------------------------------------------------------------ /** - * Writes the context file for this VM. + * Writes the context file for this VM, and gets the paths to be included + * in the context block device (CBD) + * @param files space separated list of paths to be included in the CBD * @return 0 if success */ - int write_context(); + int generate_context(string &files); private: diff --git a/src/tm/TransferManager.cc b/src/tm/TransferManager.cc index 902e428769..5ad05a2376 100644 --- a/src/tm/TransferManager.cc +++ b/src/tm/TransferManager.cc @@ -33,11 +33,11 @@ extern "C" void * tm_action_loop(void *arg) tm = static_cast(arg); Nebula::log("TrM",Log::INFO,"Transfer Manager started."); - + tm->am.loop(0,0); Nebula::log("TrM",Log::INFO,"Transfer Manager stopped."); - + return 0; } @@ -54,7 +54,7 @@ int TransferManager::start() { return -1; } - + Nebula::log("TrM",Log::INFO,"Starting Transfer Manager..."); pthread_attr_init (&pattr); @@ -84,11 +84,11 @@ void TransferManager::trigger(Actions action, int _vid) case PROLOG_MIGR: aname = "PROLOG_MIGR"; break; - + case PROLOG_RESUME: aname = "PROLOG_RESUME"; break; - + case EPILOG: aname = "EPILOG"; break; @@ -96,7 +96,7 @@ void TransferManager::trigger(Actions action, int _vid) case EPILOG_STOP: aname = "EPILOG_STOP"; break; - + case CHECKPOINT: aname = "CHECKPOINT"; break; @@ -104,7 +104,7 @@ void TransferManager::trigger(Actions action, int _vid) case FINALIZE: aname = ACTION_FINALIZE; break; - + default: delete vid; return; @@ -128,7 +128,7 @@ void TransferManager::do_action(const string &action, void * arg) vid = *(static_cast(arg)); delete static_cast(arg); - + if (action == "PROLOG") { prolog_action(vid); @@ -140,7 +140,7 @@ void TransferManager::do_action(const string &action, void * arg) else if (action == "PROLOG_RESUME") { prolog_resume_action(vid); - } + } else if (action == "EPILOG") { epilog_action(vid); @@ -148,7 +148,7 @@ void TransferManager::do_action(const string &action, void * arg) else if (action == "EPILOG_STOP") { epilog_stop_action(vid); - } + } else if (action == "CHECKPOINT") { checkpoint_action(vid); @@ -156,14 +156,14 @@ void TransferManager::do_action(const string &action, void * arg) else if (action == ACTION_FINALIZE) { Nebula::log("TrM",Log::INFO,"Stopping Transfer Manager..."); - + MadManager::stop(); } else { ostringstream oss; oss << "Unknown action name: " << action; - + Nebula::log("TrM", Log::ERROR, oss); } } @@ -176,28 +176,29 @@ void TransferManager::prolog_action(int vid) ofstream xfr; ostringstream os; string xfr_name; - + const VectorAttribute * disk; string source; string type; string clon; - + string files; + VirtualMachine * vm; Nebula& nd = Nebula::instance(); - + const TransferManagerDriver * tm_md; - + vector attrs; int num; - - + + // ------------------------------------------------------------------------ // Setup & Transfer script // ------------------------------------------------------------------------ vm = vmpool->get(vid,true); - - if (vm == 0) + + if (vm == 0) { return; } @@ -206,66 +207,65 @@ void TransferManager::prolog_action(int vid) { goto error_history; } - + tm_md = get(vm->get_uid(),vm->get_tm_mad()); - + if ( tm_md == 0 ) { goto error_driver; } - + xfr.open(vm->get_transfer_file().c_str(), ios::out | ios::trunc); if (xfr.fail() == true) { goto error_file; } - + // ------------------------------------------------------------------------ // Swap and image Commands // ------------------------------------------------------------------------ num = vm->get_template_attribute("DISK",attrs); - + for (int i=0; i < num ;i++,source="",type="",clon="") { disk = dynamic_cast(attrs[i]); - + if ( disk == 0 ) { continue; } - + type = disk->vector_value("TYPE"); - + if ( type.empty() == false) { transform(type.begin(),type.end(),type.begin(),(int(*)(int))toupper); } - + if ( type == "SWAP" ) { + // ----------------------------------------------------------------- + // Generate a swap disk image + // ----------------------------------------------------------------- string size = disk->vector_value("SIZE"); if (size.empty()==true) { size = "1"; } - + xfr << "MKSWAP " << size << " " << vm->get_hostname() << ":" << vm->get_remote_dir() << "/disk." << i << endl; } else { - source = disk->vector_value("SOURCE"); - - if ( source.empty() ) - { - goto error_empty_disk; - } - + // ----------------------------------------------------------------- + // CLONE or LINK disk images + // ----------------------------------------------------------------- clon = disk->vector_value("CLONE"); - + if ( clon.empty() == true ) { clon = "YES"; //Clone by default @@ -274,7 +274,7 @@ void TransferManager::prolog_action(int vid) { transform(clon.begin(),clon.end(),clon.begin(),(int(*)(int))toupper); } - + if (clon == "YES") { xfr << "CLONE "; @@ -283,61 +283,91 @@ void TransferManager::prolog_action(int vid) { xfr << "LN "; } - + + // ----------------------------------------------------------------- + // Get the disk image, and set source URL + // ----------------------------------------------------------------- + source = disk->vector_value("SOURCE"); + + if ( source.empty() ) + { + goto error_empty_disk; + } + if ( source.find(":") == string::npos ) //Regular file { xfr << nd.get_nebula_hostname() << ":" << source << " "; - } + } else //TM Plugin specific protocol { xfr << source << " "; } - + xfr << vm->get_hostname() << ":" << vm->get_remote_dir() << "/disk." << i << endl; } } // ------------------------------------------------------------------------ - // TODO: Context commands + // Generate context file (There are 0...num-1 disks, constext is disk.num) // ------------------------------------------------------------------------ + if ( vm->generate_context(files) != 0 ) + { + goto error_context; + } + + xfr << "CONTEXT " << vm->get_context_file() << " "; + + if (!files.empty()) + { + xfr << files << " "; + } + + xfr << vm->get_hostname() << ":" << vm->get_remote_dir() + << "/disk." << num << endl; + xfr.close(); - + tm_md->transfer(vid,vm->get_transfer_file()); - + vm->unlock(); - + return; - + +error_context: + os.str(""); + os << "prolog, could not write context file for VM " << vid; + goto error_common; + error_history: os.str(""); os << "prolog, VM " << vid << " has no history"; goto error_common; - + error_file: os.str(""); os << "prolog, could not open file: " << vm->get_transfer_file(); goto error_common; - + error_driver: os.str(""); os << "prolog, error getting driver " << vm->get_tm_mad(); goto error_common; - + error_empty_disk: os.str(""); os << "prolog, undefined source disk image in VM template"; xfr.close(); goto error_common; - + error_common: (nd.get_lcm())->trigger(LifeCycleManager::PROLOG_FAILURE,vid); vm->log("TM", Log::ERROR, os); - + vm->unlock(); return; -} +} /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ @@ -346,20 +376,20 @@ void TransferManager::prolog_migr_action(int vid) { ofstream xfr; ostringstream os; - + VirtualMachine * vm; Nebula& nd = Nebula::instance(); - + const TransferManagerDriver * tm_md; - - + + // ------------------------------------------------------------------------ // Setup & Transfer script // ------------------------------------------------------------------------ vm = vmpool->get(vid,true); - if (vm == 0) + if (vm == 0) { return; } @@ -368,21 +398,21 @@ void TransferManager::prolog_migr_action(int vid) { goto error_history; } - + tm_md = get(vm->get_uid(),vm->get_tm_mad()); - + if ( tm_md == 0 ) { goto error_driver; } - + xfr.open(vm->get_transfer_file().c_str(), ios::out | ios::trunc); if (xfr.fail() == true) { goto error_file; } - + // ------------------------------------------------------------------------ // Move image directory // ------------------------------------------------------------------------ @@ -396,35 +426,35 @@ void TransferManager::prolog_migr_action(int vid) // ------------------------------------------------------------------------ xfr.close(); - + tm_md->transfer(vid,vm->get_transfer_file()); - + vm->unlock(); - + return; - + error_history: os.str(""); os << "prolog_migr, VM " << vid << " has no history"; goto error_common; - + error_file: os.str(""); os << "prolog_migr, could not open file: " << vm->get_transfer_file(); goto error_common; - + error_driver: os.str(""); os << "prolog_migr, error getting driver " << vm->get_tm_mad(); goto error_common; - + error_common: (nd.get_lcm())->trigger(LifeCycleManager::PROLOG_FAILURE,vid); vm->log("TM", Log::ERROR, os); - + vm->unlock(); return; - + (nd.get_lcm())->trigger(LifeCycleManager::PROLOG_SUCCESS,vid); } @@ -435,20 +465,20 @@ void TransferManager::prolog_resume_action(int vid) { ofstream xfr; ostringstream os; - + VirtualMachine * vm; Nebula& nd = Nebula::instance(); - + const TransferManagerDriver * tm_md; - - + + // ------------------------------------------------------------------------ // Setup & Transfer script // ------------------------------------------------------------------------ vm = vmpool->get(vid,true); - if (vm == 0) + if (vm == 0) { return; } @@ -457,21 +487,21 @@ void TransferManager::prolog_resume_action(int vid) { goto error_history; } - + tm_md = get(vm->get_uid(),vm->get_tm_mad()); - + if ( tm_md == 0 ) { goto error_driver; } - + xfr.open(vm->get_transfer_file().c_str(), ios::out | ios::trunc); if (xfr.fail() == true) { goto error_file; } - + // ------------------------------------------------------------------------ // Move image directory // ------------------------------------------------------------------------ @@ -485,32 +515,32 @@ void TransferManager::prolog_resume_action(int vid) // ------------------------------------------------------------------------ xfr.close(); - + tm_md->transfer(vid,vm->get_transfer_file()); - + vm->unlock(); - + return; - + error_history: os.str(""); os << "prolog_resume, VM " << vid << " has no history"; goto error_common; - + error_file: os.str(""); os << "prolog_resume, could not open file: " << vm->get_transfer_file(); goto error_common; - + error_driver: os.str(""); os << "prolog_resume, error getting driver " << vm->get_tm_mad(); goto error_common; - + error_common: (nd.get_lcm())->trigger(LifeCycleManager::PROLOG_FAILURE,vid); vm->log("TM", Log::ERROR, os); - + vm->unlock(); return; } @@ -524,28 +554,28 @@ void TransferManager::epilog_action(int vid) ofstream xfr; ostringstream os; string xfr_name; - + const VectorAttribute * disk; string source; string save; string clon; - + VirtualMachine * vm; Nebula& nd = Nebula::instance(); - + const TransferManagerDriver * tm_md; - + vector attrs; int num; - - + + // ------------------------------------------------------------------------ // Setup & Transfer script // ------------------------------------------------------------------------ vm = vmpool->get(vid,true); - - if (vm == 0) + + if (vm == 0) { return; } @@ -554,45 +584,45 @@ void TransferManager::epilog_action(int vid) { goto error_history; } - + tm_md = get(vm->get_uid(),vm->get_tm_mad()); - + if ( tm_md == 0 ) { goto error_driver; } - + xfr.open(vm->get_transfer_file().c_str(), ios::out | ios::trunc); if (xfr.fail() == true) { goto error_file; } - + // ------------------------------------------------------------------------ // copy back VM image (DISK with SAVE="yes") // ------------------------------------------------------------------------ num = vm->get_template_attribute("DISK",attrs); - + for (int i=0; i < num ;i++,save="") { disk = dynamic_cast(attrs[i]); - + if ( disk == 0 ) { continue; } - + save = disk->vector_value("SAVE"); - + if ( save.empty() == true) { continue; } - + transform(save.begin(),save.end(),save.begin(),(int(*)(int))toupper); - + if ( save == "YES" ) { xfr << "MV " << vm->get_hostname() << ":" << vm->get_remote_dir() @@ -605,34 +635,34 @@ void TransferManager::epilog_action(int vid) xfr << "DELETE " << vm->get_hostname() <<":"<< vm->get_remote_dir() << endl; xfr.close(); - + tm_md->transfer(vid,vm->get_transfer_file()); - + vm->unlock(); - + return; - + error_history: os.str(""); os << "epilog, VM " << vid << " has no history"; goto error_common; - + error_file: os.str(""); os << "epilog, could not open file: " << vm->get_transfer_file(); goto error_common; - + error_driver: os.str(""); os << "epilog, error getting driver " << vm->get_vmm_mad(); goto error_common; - + error_common: (nd.get_lcm())->trigger(LifeCycleManager::PROLOG_FAILURE,vid); vm->log("TM", Log::ERROR, os); - + vm->unlock(); - return; + return; } /* -------------------------------------------------------------------------- */ @@ -642,20 +672,20 @@ void TransferManager::epilog_stop_action(int vid) { ofstream xfr; ostringstream os; - + VirtualMachine * vm; Nebula& nd = Nebula::instance(); - + const TransferManagerDriver * tm_md; - - + + // ------------------------------------------------------------------------ // Setup & Transfer script // ------------------------------------------------------------------------ vm = vmpool->get(vid,true); - if (vm == 0) + if (vm == 0) { return; } @@ -664,21 +694,21 @@ void TransferManager::epilog_stop_action(int vid) { goto error_history; } - + tm_md = get(vm->get_uid(),vm->get_tm_mad()); - + if ( tm_md == 0 ) { goto error_driver; } - + xfr.open(vm->get_transfer_file().c_str(), ios::out | ios::trunc); if (xfr.fail() == true) { goto error_file; } - + // ------------------------------------------------------------------------ // Move image directory // ------------------------------------------------------------------------ @@ -692,35 +722,35 @@ void TransferManager::epilog_stop_action(int vid) // ------------------------------------------------------------------------ xfr.close(); - + tm_md->transfer(vid,vm->get_transfer_file()); - + vm->unlock(); - + return; - + error_history: os.str(""); os << "epilog_stop, VM " << vid << " has no history"; goto error_common; - + error_file: os.str(""); os << "epilog_stop, could not open file: " << vm->get_transfer_file(); goto error_common; - + error_driver: os.str(""); os << "epilog_stop, error getting driver " << vm->get_tm_mad(); goto error_common; - + error_common: (nd.get_lcm())->trigger(LifeCycleManager::EPILOG_FAILURE,vid); vm->log("TM", Log::ERROR, os); - + vm->unlock(); return; - + (nd.get_lcm())->trigger(LifeCycleManager::EPILOG_SUCCESS,vid); } @@ -744,36 +774,36 @@ void TransferManager::load_mads(int uid) int rc; string name; TransferManagerDriver * tm_driver = 0; - + oss << "Loading Transfer Manager drivers."; - + Nebula::log("TM",Log::INFO,oss); - + for(i=0,oss.str("");i(mad_conf[i]); - + name = vattr->vector_value("NAME"); - + oss << "\tLoading driver: " << name; Nebula::log("VMM", Log::INFO, oss); - + tm_driver = new TransferManagerDriver( - uid, + uid, vattr->value(), (uid != 0), vmpool); - + if ( tm_driver == 0 ) continue; - + rc = add(tm_driver); - + if ( rc == 0 ) { oss.str(""); oss << "\tDriver " << name << " loaded."; - + Nebula::log("TM",Log::INFO,oss); } } diff --git a/src/vm/VirtualMachine.cc b/src/vm/VirtualMachine.cc index fb28b66a44..dbcf7ae7ba 100644 --- a/src/vm/VirtualMachine.cc +++ b/src/vm/VirtualMachine.cc @@ -632,7 +632,7 @@ void VirtualMachine::release_network_leases() /* -------------------------------------------------------------------------- */ /* -------------------------------------------------------------------------- */ -int VirtualMachine::write_context() +int VirtualMachine::generate_context(string &files) { ofstream file; @@ -641,6 +641,8 @@ int VirtualMachine::write_context() map::const_iterator it; + files = ""; + if ( history == 0 ) return -1; @@ -669,6 +671,8 @@ int VirtualMachine::write_context() return -1; } + files = context->vector_value("FILES"); + const map values = context->value(); file << "# Context variables generated by OpenNebula\n";