hv_snapshot.c 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287
  1. /*
  2. * An implementation of host initiated guest snapshot.
  3. *
  4. *
  5. * Copyright (C) 2013, Microsoft, Inc.
  6. * Author : K. Y. Srinivasan <kys@microsoft.com>
  7. *
  8. * This program is free software; you can redistribute it and/or modify it
  9. * under the terms of the GNU General Public License version 2 as published
  10. * by the Free Software Foundation.
  11. *
  12. * This program is distributed in the hope that it will be useful, but
  13. * WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE, GOOD TITLE or
  15. * NON INFRINGEMENT. See the GNU General Public License for more
  16. * details.
  17. *
  18. */
  19. #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
  20. #include <linux/net.h>
  21. #include <linux/nls.h>
  22. #include <linux/connector.h>
  23. #include <linux/workqueue.h>
  24. #include <linux/hyperv.h>
  25. /*
  26. * Global state maintained for transaction that is being processed.
  27. * Note that only one transaction can be active at any point in time.
  28. *
  29. * This state is set when we receive a request from the host; we
  30. * cleanup this state when the transaction is completed - when we respond
  31. * to the host with the key value.
  32. */
  33. static struct {
  34. bool active; /* transaction status - active or not */
  35. int recv_len; /* number of bytes received. */
  36. struct vmbus_channel *recv_channel; /* chn we got the request */
  37. u64 recv_req_id; /* request ID. */
  38. struct hv_vss_msg *msg; /* current message */
  39. } vss_transaction;
  40. static void vss_respond_to_host(int error);
  41. static struct cb_id vss_id = { CN_VSS_IDX, CN_VSS_VAL };
  42. static const char vss_name[] = "vss_kernel_module";
  43. static __u8 *recv_buffer;
  44. static void vss_send_op(struct work_struct *dummy);
  45. static DECLARE_WORK(vss_send_op_work, vss_send_op);
  46. /*
  47. * Callback when data is received from user mode.
  48. */
  49. static void
  50. vss_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
  51. {
  52. struct hv_vss_msg *vss_msg;
  53. vss_msg = (struct hv_vss_msg *)msg->data;
  54. if (vss_msg->vss_hdr.operation == VSS_OP_REGISTER) {
  55. pr_info("VSS daemon registered\n");
  56. vss_transaction.active = false;
  57. if (vss_transaction.recv_channel != NULL)
  58. hv_vss_onchannelcallback(vss_transaction.recv_channel);
  59. return;
  60. }
  61. vss_respond_to_host(vss_msg->error);
  62. }
  63. static void vss_send_op(struct work_struct *dummy)
  64. {
  65. int op = vss_transaction.msg->vss_hdr.operation;
  66. struct cn_msg *msg;
  67. struct hv_vss_msg *vss_msg;
  68. msg = kzalloc(sizeof(*msg) + sizeof(*vss_msg), GFP_ATOMIC);
  69. if (!msg)
  70. return;
  71. vss_msg = (struct hv_vss_msg *)msg->data;
  72. msg->id.idx = CN_VSS_IDX;
  73. msg->id.val = CN_VSS_VAL;
  74. vss_msg->vss_hdr.operation = op;
  75. msg->len = sizeof(struct hv_vss_msg);
  76. cn_netlink_send(msg, 0, GFP_ATOMIC);
  77. kfree(msg);
  78. return;
  79. }
  80. /*
  81. * Send a response back to the host.
  82. */
  83. static void
  84. vss_respond_to_host(int error)
  85. {
  86. struct icmsg_hdr *icmsghdrp;
  87. u32 buf_len;
  88. struct vmbus_channel *channel;
  89. u64 req_id;
  90. /*
  91. * If a transaction is not active; log and return.
  92. */
  93. if (!vss_transaction.active) {
  94. /*
  95. * This is a spurious call!
  96. */
  97. pr_warn("VSS: Transaction not active\n");
  98. return;
  99. }
  100. /*
  101. * Copy the global state for completing the transaction. Note that
  102. * only one transaction can be active at a time.
  103. */
  104. buf_len = vss_transaction.recv_len;
  105. channel = vss_transaction.recv_channel;
  106. req_id = vss_transaction.recv_req_id;
  107. vss_transaction.active = false;
  108. icmsghdrp = (struct icmsg_hdr *)
  109. &recv_buffer[sizeof(struct vmbuspipe_hdr)];
  110. if (channel->onchannel_callback == NULL)
  111. /*
  112. * We have raced with util driver being unloaded;
  113. * silently return.
  114. */
  115. return;
  116. icmsghdrp->status = error;
  117. icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION | ICMSGHDRFLAG_RESPONSE;
  118. vmbus_sendpacket(channel, recv_buffer, buf_len, req_id,
  119. VM_PKT_DATA_INBAND, 0);
  120. }
  121. /*
  122. * This callback is invoked when we get a VSS message from the host.
  123. * The host ensures that only one VSS transaction can be active at a time.
  124. */
  125. void hv_vss_onchannelcallback(void *context)
  126. {
  127. struct vmbus_channel *channel = context;
  128. u32 recvlen;
  129. u64 requestid;
  130. struct hv_vss_msg *vss_msg;
  131. struct icmsg_hdr *icmsghdrp;
  132. struct icmsg_negotiate *negop = NULL;
  133. if (vss_transaction.active) {
  134. /*
  135. * We will defer processing this callback once
  136. * the current transaction is complete.
  137. */
  138. vss_transaction.recv_channel = channel;
  139. return;
  140. }
  141. vmbus_recvpacket(channel, recv_buffer, PAGE_SIZE * 2, &recvlen,
  142. &requestid);
  143. if (recvlen > 0) {
  144. icmsghdrp = (struct icmsg_hdr *)&recv_buffer[
  145. sizeof(struct vmbuspipe_hdr)];
  146. if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
  147. vmbus_prep_negotiate_resp(icmsghdrp, negop,
  148. recv_buffer, MAX_SRV_VER, MAX_SRV_VER);
  149. /*
  150. * We currently negotiate the highest number the
  151. * host has presented. If this version is not
  152. * atleast 5.0, reject.
  153. */
  154. negop = (struct icmsg_negotiate *)&recv_buffer[
  155. sizeof(struct vmbuspipe_hdr) +
  156. sizeof(struct icmsg_hdr)];
  157. if (negop->icversion_data[1].major < 5)
  158. negop->icframe_vercnt = 0;
  159. } else {
  160. vss_msg = (struct hv_vss_msg *)&recv_buffer[
  161. sizeof(struct vmbuspipe_hdr) +
  162. sizeof(struct icmsg_hdr)];
  163. /*
  164. * Stash away this global state for completing the
  165. * transaction; note transactions are serialized.
  166. */
  167. vss_transaction.recv_len = recvlen;
  168. vss_transaction.recv_channel = channel;
  169. vss_transaction.recv_req_id = requestid;
  170. vss_transaction.active = true;
  171. vss_transaction.msg = (struct hv_vss_msg *)vss_msg;
  172. switch (vss_msg->vss_hdr.operation) {
  173. /*
  174. * Initiate a "freeze/thaw"
  175. * operation in the guest.
  176. * We respond to the host once
  177. * the operation is complete.
  178. *
  179. * We send the message to the
  180. * user space daemon and the
  181. * operation is performed in
  182. * the daemon.
  183. */
  184. case VSS_OP_FREEZE:
  185. case VSS_OP_THAW:
  186. schedule_work(&vss_send_op_work);
  187. return;
  188. case VSS_OP_HOT_BACKUP:
  189. vss_msg->vss_cf.flags =
  190. VSS_HBU_NO_AUTO_RECOVERY;
  191. vss_respond_to_host(0);
  192. return;
  193. case VSS_OP_GET_DM_INFO:
  194. vss_msg->dm_info.flags = 0;
  195. vss_respond_to_host(0);
  196. return;
  197. default:
  198. vss_respond_to_host(0);
  199. return;
  200. }
  201. }
  202. icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION
  203. | ICMSGHDRFLAG_RESPONSE;
  204. vmbus_sendpacket(channel, recv_buffer,
  205. recvlen, requestid,
  206. VM_PKT_DATA_INBAND, 0);
  207. }
  208. }
  209. int
  210. hv_vss_init(struct hv_util_service *srv)
  211. {
  212. int err;
  213. err = cn_add_callback(&vss_id, vss_name, vss_cn_callback);
  214. if (err)
  215. return err;
  216. recv_buffer = srv->recv_buffer;
  217. /*
  218. * When this driver loads, the user level daemon that
  219. * processes the host requests may not yet be running.
  220. * Defer processing channel callbacks until the daemon
  221. * has registered.
  222. */
  223. vss_transaction.active = true;
  224. return 0;
  225. }
  226. void hv_vss_deinit(void)
  227. {
  228. cn_del_callback(&vss_id);
  229. cancel_work_sync(&vss_send_op_work);
  230. }