colo-failover.c 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. /*
  2. * COarse-grain LOck-stepping Virtual Machines for Non-stop Service (COLO)
  3. * (a.k.a. Fault Tolerance or Continuous Replication)
  4. *
  5. * Copyright (c) 2016 HUAWEI TECHNOLOGIES CO., LTD.
  6. * Copyright (c) 2016 FUJITSU LIMITED
  7. * Copyright (c) 2016 Intel Corporation
  8. *
  9. * This work is licensed under the terms of the GNU GPL, version 2 or
  10. * later. See the COPYING file in the top-level directory.
  11. */
  12. #include "qemu/osdep.h"
  13. #include "migration/colo.h"
  14. #include "migration/failover.h"
  15. #include "qemu/main-loop.h"
  16. #include "migration.h"
  17. #include "qapi/error.h"
  18. #include "qapi/qapi-commands-migration.h"
  19. #include "qapi/qmp/qerror.h"
  20. #include "qemu/error-report.h"
  21. #include "trace.h"
  22. static QEMUBH *failover_bh;
  23. static FailoverStatus failover_state;
  24. static void colo_failover_bh(void *opaque)
  25. {
  26. int old_state;
  27. qemu_bh_delete(failover_bh);
  28. failover_bh = NULL;
  29. old_state = failover_set_state(FAILOVER_STATUS_REQUIRE,
  30. FAILOVER_STATUS_ACTIVE);
  31. if (old_state != FAILOVER_STATUS_REQUIRE) {
  32. error_report("Unknown error for failover, old_state = %s",
  33. FailoverStatus_str(old_state));
  34. return;
  35. }
  36. colo_do_failover();
  37. }
  38. void failover_request_active(Error **errp)
  39. {
  40. if (failover_set_state(FAILOVER_STATUS_NONE,
  41. FAILOVER_STATUS_REQUIRE) != FAILOVER_STATUS_NONE) {
  42. error_setg(errp, "COLO failover is already actived");
  43. return;
  44. }
  45. failover_bh = qemu_bh_new(colo_failover_bh, NULL);
  46. qemu_bh_schedule(failover_bh);
  47. }
  48. void failover_init_state(void)
  49. {
  50. failover_state = FAILOVER_STATUS_NONE;
  51. }
  52. FailoverStatus failover_set_state(FailoverStatus old_state,
  53. FailoverStatus new_state)
  54. {
  55. FailoverStatus old;
  56. old = atomic_cmpxchg(&failover_state, old_state, new_state);
  57. if (old == old_state) {
  58. trace_colo_failover_set_state(FailoverStatus_str(new_state));
  59. }
  60. return old;
  61. }
  62. FailoverStatus failover_get_state(void)
  63. {
  64. return atomic_read(&failover_state);
  65. }
  66. void qmp_x_colo_lost_heartbeat(Error **errp)
  67. {
  68. if (get_colo_mode() == COLO_MODE_NONE) {
  69. error_setg(errp, QERR_FEATURE_DISABLED, "colo");
  70. return;
  71. }
  72. failover_request_active(errp);
  73. }