Revision 675d9367

View differences:

include/DispatchManager.h
46 46
    {
47 47
        SUSPEND_SUCCESS,/**< Send by LCM when a VM is suspended*/
48 48
        STOP_SUCCESS,   /**< Send by LCM when a VM is stopped*/
49
        SHUTDOWN_SAVE_SUCCESS,  /**< Send by LCM when a VM is shut down and saved*/
49 50
        POWEROFF_SUCCESS, /**< Send by LCM when a VM is powered off */
50 51
        DONE,           /**< Send by LCM when a VM is shut down*/
51 52
        FAILED,         /**< Send by LCM when one of the execution steps fails*/
......
131 132
        int vid);
132 133

  
133 134
    /**
135
     *  Shuts down a VM, but it is saved in the system DS instead of destroyed.
136
     *    @param vid VirtualMachine identification
137
     *    @param hard True to force the shutdown (cancel instead of shutdown)
138
     *    @return 0 on success, -1 if the VM does not exits or -2 if the VM is
139
     *    in a wrong a state
140
     */
141
    int shutdown_save(
142
        int vid,
143
        bool hard);
144

  
145
    /**
134 146
     *  Powers off a VM.
135 147
     *    @param vid VirtualMachine identification
136 148
     *    @return 0 on success, -1 if the VM does not exits or -2 if the VM is
......
396 408

  
397 409
    void  stop_success_action(int vid);
398 410

  
411
    void  shutdown_save_success_action(int vid);
412

  
399 413
    void  poweroff_success_action(int vid);
400 414

  
401 415
    void  done_action(int vid);
include/LifeCycleManager.h
84 84
        MIGRATE,          /**< Sent by the DM to migrate a VM to other host   */
85 85
        LIVE_MIGRATE,     /**< Sent by the DM to live-migrate a VM            */
86 86
        SHUTDOWN,         /**< Sent by the DM to shutdown a running VM        */
87
        SHUTDOWN_SAVE,      /**< Sent by the DM to shutdown a running VM      */
88
        SHUTDOWN_SAVE_HARD, /**< Sent by the DM to shutdown a running VM      */
87 89
        POWEROFF,         /**< Sent by the DM to power off a running VM       */
88 90
        RESTART,          /**< Sent by the DM to restart a deployed VM        */
89 91
        DELETE,           /**< Sent by the DM to delete a VM                  */
......
247 249

  
248 250
    void shutdown_action(int vid);
249 251

  
252
    void shutdown_save_action(int vid, bool hard);
253

  
250 254
    void poweroff_action(int vid);
251 255

  
252 256
    void failure_action(VirtualMachine * vm);
include/VirtualMachine.h
58 58
        SUSPENDED = 5,
59 59
        DONE      = 6,
60 60
        FAILED    = 7,
61
        POWEROFF  = 8
61
        POWEROFF  = 8,
62
        SHUTDOWN_SAVED = 9
62 63
    };
63 64

  
64 65
    /**
......
94 95
        HOTPLUG_NIC         = 25,
95 96
        HOTPLUG_SAVEAS           = 26,
96 97
        HOTPLUG_SAVEAS_POWEROFF  = 27,
97
        HOTPLUG_SAVEAS_SUSPENDED = 28
98
        HOTPLUG_SAVEAS_SUSPENDED = 28,
99
        SHUTDOWN_SAVE           = 29,
100
        EPILOG_SHUTDOWN_SAVE    = 30
98 101
    };
99 102

  
100 103
    // -------------------------------------------------------------------------
src/dm/DispatchManager.cc
77 77
        aname = "STOP_SUCCESS";
78 78
        break;
79 79

  
80
    case SHUTDOWN_SAVE_SUCCESS:
81
        aname = "SHUTDOWN_SAVE_SUCCESS";
82
        break;
83

  
80 84
    case POWEROFF_SUCCESS:
81 85
        aname = "POWEROFF_SUCCESS";
82 86
        break;
......
130 134
    {
131 135
        stop_success_action(vid);
132 136
    }
137
    else if (action == "SHUTDOWN_SAVE_SUCCESS")
138
    {
139
        shutdown_save_success_action(vid);
140
    }
133 141
    else if (action == "POWEROFF_SUCCESS")
134 142
    {
135 143
        poweroff_success_action(vid);
src/dm/DispatchManagerActions.cc
209 209
/* -------------------------------------------------------------------------- */
210 210
/* -------------------------------------------------------------------------- */
211 211

  
212
int DispatchManager::shutdown_save(
213
    int vid,
214
    bool hard)
215
{
216
    VirtualMachine *    vm;
217
    ostringstream       oss;
218

  
219
    vm = vmpool->get(vid,true);
220

  
221
    if ( vm == 0 )
222
    {
223
        return -1;
224
    }
225

  
226
    oss << "Shutting down VM " << vid;
227
    NebulaLog::log("DiM",Log::DEBUG,oss);
228

  
229
    if (vm->get_state()     == VirtualMachine::ACTIVE &&
230
        vm->get_lcm_state() == VirtualMachine::RUNNING )
231
    {
232
        Nebula&             nd  = Nebula::instance();
233
        LifeCycleManager *  lcm = nd.get_lcm();
234

  
235
        if (hard)
236
        {
237
            lcm->trigger(LifeCycleManager::SHUTDOWN_SAVE_HARD,vid);
238
        }
239
        else
240
        {
241
            lcm->trigger(LifeCycleManager::SHUTDOWN_SAVE,vid);
242
        }
243
    }
244
    else
245
    {
246
        goto error;
247
    }
248

  
249
    vm->unlock();
250

  
251
    return 0;
252

  
253
error:
254
    oss.str("");
255
    oss << "Could not shutdown VM " << vid << ", wrong state.";
256
    NebulaLog::log("DiM",Log::ERROR,oss);
257

  
258
    vm->unlock();
259
    return -2;
260
}
261

  
262
/* -------------------------------------------------------------------------- */
263
/* -------------------------------------------------------------------------- */
264

  
212 265
int DispatchManager::poweroff (
213 266
    int vid)
214 267
{
......
804 857
        break;
805 858

  
806 859
        case VirtualMachine::STOPPED:
860
        case VirtualMachine::SHUTDOWN_SAVED:
807 861
            tm->trigger(TransferManager::EPILOG_DELETE_STOP,vid);
808 862
            finalize_cleanup(vm);
809 863
        break;
......
878 932

  
879 933
        case VirtualMachine::HOLD: // Move the VM to PENDING in any of these
880 934
        case VirtualMachine::STOPPED:
935
        case VirtualMachine::SHUTDOWN_SAVED:
881 936
            vm->set_state(VirtualMachine::LCM_INIT);
882 937
            vm->set_state(VirtualMachine::PENDING);
883 938

  
src/dm/DispatchManagerStates.cc
98 98
/* -------------------------------------------------------------------------- */
99 99
/* -------------------------------------------------------------------------- */
100 100

  
101
void  DispatchManager::shutdown_save_success_action(int vid)
102
{
103
    VirtualMachine *    vm;
104

  
105
    vm = vmpool->get(vid,true);
106

  
107
    if ( vm == 0 )
108
    {
109
        return;
110
    }
111

  
112
    // TODO: prolog_resume, or new prolog?
113

  
114
    if ((vm->get_state() == VirtualMachine::ACTIVE) &&
115
        (vm->get_lcm_state() == VirtualMachine::EPILOG_SHUTDOWN_SAVE ||
116
        vm->get_lcm_state() == VirtualMachine::PROLOG_RESUME))
117
    {
118
        vm->set_state(VirtualMachine::SHUTDOWN_SAVED);
119

  
120
        vm->set_state(VirtualMachine::LCM_INIT);
121

  
122
        vmpool->update(vm);
123

  
124
        vm->log("DiM", Log::INFO, "New VM state is SHUTDOWN_SAVED");
125
    }
126
    else
127
    {
128
        ostringstream oss;
129

  
130
        oss << "shutdown_save_success action received but VM " << vid
131
            << " not in ACTIVE state";
132
        NebulaLog::log("DiM",Log::ERROR,oss);
133
    }
134

  
135
    vm->unlock();
136

  
137
    return;
138
}
139

  
140
/* -------------------------------------------------------------------------- */
141
/* -------------------------------------------------------------------------- */
142

  
101 143
void  DispatchManager::poweroff_success_action(int vid)
102 144
{
103 145
    VirtualMachine *    vm;
src/lcm/LifeCycleActions.cc
337 337
/* -------------------------------------------------------------------------- */
338 338
/* -------------------------------------------------------------------------- */
339 339

  
340
void  LifeCycleManager::shutdown_save_action(int vid, bool hard)
341
{
342
    VirtualMachine *    vm;
343

  
344
    vm = vmpool->get(vid,true);
345

  
346
    if ( vm == 0 )
347
    {
348
        return;
349
    }
350

  
351
    if (vm->get_state()     == VirtualMachine::ACTIVE &&
352
        vm->get_lcm_state() == VirtualMachine::RUNNING)
353
    {
354
        Nebula&                 nd = Nebula::instance();
355
        VirtualMachineManager * vmm = nd.get_vmm();
356

  
357
        //----------------------------------------------------
358
        //             SHUTDOWN_SAVE STATE
359
        //----------------------------------------------------
360

  
361
        vm->set_state(VirtualMachine::SHUTDOWN_SAVE);
362

  
363
        vm->set_resched(false);
364

  
365
        vmpool->update(vm);
366

  
367
        vm->log("LCM",Log::INFO,"New VM state is SHUTDOWN_SAVE");
368

  
369
        //----------------------------------------------------
370

  
371
        if (hard)
372
        {
373
            vmm->trigger(VirtualMachineManager::CANCEL,vid);
374
        }
375
        else
376
        {
377
            vmm->trigger(VirtualMachineManager::SHUTDOWN,vid);
378
        }
379
    }
380
    else
381
    {
382
        vm->log("LCM", Log::ERROR, "shutdown_save_action, VM in a wrong state.");
383
    }
384

  
385
    vm->unlock();
386

  
387
    return;
388
}
389

  
390

  
391
/* -------------------------------------------------------------------------- */
392
/* -------------------------------------------------------------------------- */
393

  
340 394
void  LifeCycleManager::poweroff_action(int vid)
341 395
{
342 396
    VirtualMachine *    vm;
src/lcm/LifeCycleManager.cc
232 232
        aname = "SHUTDOWN";
233 233
        break;
234 234

  
235
    case SHUTDOWN_SAVE:
236
        aname = "SHUTDOWN_SAVE";
237
        break;
238

  
239
    case SHUTDOWN_SAVE_HARD:
240
        aname = "SHUTDOWN_SAVE_HARD";
241
        break;
242

  
235 243
    case RESTART:
236 244
        aname = "RESTART";
237 245
        break;
......
441 449
    {
442 450
        shutdown_action(vid);
443 451
    }
452
    else if (action == "SHUTDOWN_SAVE")
453
    {
454
        shutdown_save_action(vid, false);
455
    }
456
    else if (action == "SHUTDOWN_SAVE_HARD")
457
    {
458
        shutdown_save_action(vid, true);
459
    }
444 460
    else if (action == "RESTART")
445 461
    {
446 462
        restart_action(vid);
src/lcm/LifeCycleStates.cc
514 514

  
515 515
        dm->trigger(DispatchManager::POWEROFF_SUCCESS,vid);
516 516
    }
517
    else if (vm->get_lcm_state() == VirtualMachine::SHUTDOWN_SAVE)
518
    {
519
        //----------------------------------------------------
520
        //            EPILOG_SHUTDOWN_SAVE STATE
521
        //----------------------------------------------------
522

  
523
        vm->set_state(VirtualMachine::EPILOG_SHUTDOWN_SAVE);
524

  
525
        vm->delete_snapshots();
526

  
527
        vmpool->update(vm);
528

  
529
        vm->set_epilog_stime(the_time);
530

  
531
        vm->set_running_etime(the_time);
532

  
533
        vm->set_reason(History::STOP_RESUME);
534

  
535
        vmpool->update_history(vm);
536

  
537
        vm->log("LCM", Log::INFO, "New VM state is EPILOG_SHUTDOWN_SAVE");
538

  
539
        //----------------------------------------------------
540

  
541
        tm->trigger(TransferManager::EPILOG_STOP,vid);
542
    }
517 543
    else
518 544
    {
519 545
        vm->log("LCM",Log::ERROR,"shutdown_success_action, VM in a wrong state");
......
540 566
    }
541 567

  
542 568
    if ( vm->get_lcm_state() == VirtualMachine::SHUTDOWN ||
543
         vm->get_lcm_state() == VirtualMachine::SHUTDOWN_POWEROFF )
569
         vm->get_lcm_state() == VirtualMachine::SHUTDOWN_POWEROFF ||
570
         vm->get_lcm_state() == VirtualMachine::SHUTDOWN_SAVE )
544 571
    {
545 572
        //----------------------------------------------------
546 573
        //    RUNNING STATE FROM SHUTDOWN
......
734 761
    {
735 762
        action = DispatchManager::STOP_SUCCESS;
736 763
    }
764
    else if ( state == VirtualMachine::EPILOG_SHUTDOWN_SAVE )
765
    {
766
        action = DispatchManager::SHUTDOWN_SAVE_SUCCESS;
767
    }
737 768
    else if ( state == VirtualMachine::EPILOG )
738 769
    {
739 770
        action = DispatchManager::DONE;
......
834 865
        dm->trigger(DispatchManager::RESUBMIT, vid);
835 866
    }
836 867
    else if ( vm->get_lcm_state() == VirtualMachine::EPILOG_STOP ||
868
              vm->get_lcm_state() == VirtualMachine::EPILOG_SHUTDOWN_SAVE ||
837 869
              vm->get_lcm_state() == VirtualMachine::EPILOG )
838 870
    {
839 871
        vm->set_epilog_etime(the_time);
......
893 925

  
894 926
        tm->trigger(TransferManager::EPILOG,vid);
895 927
    }
928
    else if (vm->get_lcm_state() == VirtualMachine::SHUTDOWN_SAVE)
929
    {
930
        //----------------------------------------------------
931
        //            EPILOG_SHUTDOWN_SAVE STATE
932
        //----------------------------------------------------
933

  
934
        vm->set_state(VirtualMachine::EPILOG_SHUTDOWN_SAVE);
935

  
936
        vm->delete_snapshots();
937

  
938
        vmpool->update(vm);
939

  
940
        vm->set_epilog_stime(the_time);
941

  
942
        vm->set_running_etime(the_time);
943

  
944
        vm->set_reason(History::STOP_RESUME);
945

  
946
        vmpool->update_history(vm);
947

  
948
        vm->log("LCM", Log::INFO, "New VM state is EPILOG_SHUTDOWN_SAVE");
949

  
950
        //----------------------------------------------------
951

  
952
        tm->trigger(TransferManager::EPILOG_STOP,vid);
953
    }
896 954
    else
897 955
    {
898 956
        vm->log("LCM",Log::ERROR,"cancel_success_action, VM in a wrong state");
......
918 976
        return;
919 977
    }
920 978

  
921
    if ( vm->get_lcm_state() == VirtualMachine::CANCEL )
979
    if ( vm->get_lcm_state() == VirtualMachine::CANCEL ||
980
         vm->get_lcm_state() == VirtualMachine::SHUTDOWN_SAVE )
922 981
    {
923 982
        //----------------------------------------------------
924 983
        //    RUNNING STATE FROM CANCEL
src/rm/RequestManagerVirtualMachine.cc
381 381
    {
382 382
        rc = dm->poweroff(id);
383 383
    }
384
    else if (action == "shutdown-save")
385
    {
386
        rc = dm->shutdown_save(id, false);
387
    }
388
    else if (action == "shutdown-save-hard")
389
    {
390
        rc = dm->shutdown_save(id, true);
391
    }
384 392

  
385 393
    switch (rc)
386 394
    {
......
1246 1254
        case VirtualMachine::PENDING:
1247 1255
        case VirtualMachine::HOLD:
1248 1256
        case VirtualMachine::FAILED:
1257
        case VirtualMachine::SHUTDOWN_SAVED:
1249 1258
        break;
1250 1259

  
1251 1260
        case VirtualMachine::STOPPED:
......
1423 1432
        case VirtualMachine::HOLD:
1424 1433
        case VirtualMachine::FAILED:
1425 1434
        case VirtualMachine::POWEROFF:
1435
        case VirtualMachine::SHUTDOWN_SAVED:
1426 1436
            ret = vm->resize(ncpu, nmemory, nvcpu, error_str);
1427 1437

  
1428 1438
            if (ret != 0)
src/tm/TransferManagerDriver.cc
127 127

  
128 128
                case VirtualMachine::EPILOG:
129 129
                case VirtualMachine::EPILOG_STOP:
130
                case VirtualMachine::EPILOG_SHUTDOWN_SAVE:
130 131
                case VirtualMachine::CLEANUP_RESUBMIT:
131 132
                    lcm_action = LifeCycleManager::EPILOG_SUCCESS;
132 133
                    break;
......
170 171

  
171 172
                case VirtualMachine::EPILOG:
172 173
                case VirtualMachine::EPILOG_STOP:
174
                case VirtualMachine::EPILOG_SHUTDOWN_SAVE:
173 175
                case VirtualMachine::CLEANUP_RESUBMIT:
174 176
                    lcm_action = LifeCycleManager::EPILOG_FAILURE;
175 177
                    break;
src/vmm/VirtualMachineManager.cc
902 902
    os << "cancel_action, error getting driver " << vm->get_vmm_mad();
903 903

  
904 904
error_common:
905
    if ( vm->get_lcm_state() == VirtualMachine::CANCEL ) //not in DELETE
905
    if ( vm->get_lcm_state() == VirtualMachine::CANCEL ||
906
         vm->get_lcm_state() == VirtualMachine::SHUTDOWN_SAVE ) //not in DELETE
906 907
    {
907 908
        Nebula              &ne = Nebula::instance();
908 909
        LifeCycleManager *  lcm = ne.get_lcm();

Also available in: Unified diff