hv_snapshot.c 7.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  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. #define VSS_MAJOR 5
  26. #define VSS_MINOR 0
  27. #define VSS_VERSION (VSS_MAJOR << 16 | VSS_MINOR)
  28. #define VSS_USERSPACE_TIMEOUT (msecs_to_jiffies(10 * 1000))
  29. /*
  30. * Global state maintained for transaction that is being processed.
  31. * Note that only one transaction can be active at any point in time.
  32. *
  33. * This state is set when we receive a request from the host; we
  34. * cleanup this state when the transaction is completed - when we respond
  35. * to the host with the key value.
  36. */
  37. static struct {
  38. bool active; /* transaction status - active or not */
  39. int recv_len; /* number of bytes received. */
  40. struct vmbus_channel *recv_channel; /* chn we got the request */
  41. u64 recv_req_id; /* request ID. */
  42. struct hv_vss_msg *msg; /* current message */
  43. } vss_transaction;
  44. static void vss_respond_to_host(int error);
  45. static struct cb_id vss_id = { CN_VSS_IDX, CN_VSS_VAL };
  46. static const char vss_name[] = "vss_kernel_module";
  47. static __u8 *recv_buffer;
  48. static void vss_send_op(struct work_struct *dummy);
  49. static void vss_timeout_func(struct work_struct *dummy);
  50. static DECLARE_DELAYED_WORK(vss_timeout_work, vss_timeout_func);
  51. static DECLARE_WORK(vss_send_op_work, vss_send_op);
  52. /*
  53. * Callback when data is received from user mode.
  54. */
  55. static void vss_timeout_func(struct work_struct *dummy)
  56. {
  57. /*
  58. * Timeout waiting for userspace component to reply happened.
  59. */
  60. pr_warn("VSS: timeout waiting for daemon to reply\n");
  61. vss_respond_to_host(HV_E_FAIL);
  62. }
  63. static void
  64. vss_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
  65. {
  66. struct hv_vss_msg *vss_msg;
  67. vss_msg = (struct hv_vss_msg *)msg->data;
  68. if (vss_msg->vss_hdr.operation == VSS_OP_REGISTER) {
  69. pr_info("VSS daemon registered\n");
  70. vss_transaction.active = false;
  71. if (vss_transaction.recv_channel != NULL)
  72. hv_vss_onchannelcallback(vss_transaction.recv_channel);
  73. return;
  74. }
  75. if (cancel_delayed_work_sync(&vss_timeout_work))
  76. vss_respond_to_host(vss_msg->error);
  77. }
  78. static void vss_send_op(struct work_struct *dummy)
  79. {
  80. int op = vss_transaction.msg->vss_hdr.operation;
  81. int rc;
  82. struct cn_msg *msg;
  83. struct hv_vss_msg *vss_msg;
  84. msg = kzalloc(sizeof(*msg) + sizeof(*vss_msg), GFP_ATOMIC);
  85. if (!msg)
  86. return;
  87. vss_msg = (struct hv_vss_msg *)msg->data;
  88. msg->id.idx = CN_VSS_IDX;
  89. msg->id.val = CN_VSS_VAL;
  90. vss_msg->vss_hdr.operation = op;
  91. msg->len = sizeof(struct hv_vss_msg);
  92. rc = cn_netlink_send(msg, 0, 0, GFP_ATOMIC);
  93. if (rc) {
  94. pr_warn("VSS: failed to communicate to the daemon: %d\n", rc);
  95. if (cancel_delayed_work_sync(&vss_timeout_work))
  96. vss_respond_to_host(HV_E_FAIL);
  97. }
  98. kfree(msg);
  99. return;
  100. }
  101. /*
  102. * Send a response back to the host.
  103. */
  104. static void
  105. vss_respond_to_host(int error)
  106. {
  107. struct icmsg_hdr *icmsghdrp;
  108. u32 buf_len;
  109. struct vmbus_channel *channel;
  110. u64 req_id;
  111. /*
  112. * If a transaction is not active; log and return.
  113. */
  114. if (!vss_transaction.active) {
  115. /*
  116. * This is a spurious call!
  117. */
  118. pr_warn("VSS: Transaction not active\n");
  119. return;
  120. }
  121. /*
  122. * Copy the global state for completing the transaction. Note that
  123. * only one transaction can be active at a time.
  124. */
  125. buf_len = vss_transaction.recv_len;
  126. channel = vss_transaction.recv_channel;
  127. req_id = vss_transaction.recv_req_id;
  128. vss_transaction.active = false;
  129. icmsghdrp = (struct icmsg_hdr *)
  130. &recv_buffer[sizeof(struct vmbuspipe_hdr)];
  131. if (channel->onchannel_callback == NULL)
  132. /*
  133. * We have raced with util driver being unloaded;
  134. * silently return.
  135. */
  136. return;
  137. icmsghdrp->status = error;
  138. icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION | ICMSGHDRFLAG_RESPONSE;
  139. vmbus_sendpacket(channel, recv_buffer, buf_len, req_id,
  140. VM_PKT_DATA_INBAND, 0);
  141. }
  142. /*
  143. * This callback is invoked when we get a VSS message from the host.
  144. * The host ensures that only one VSS transaction can be active at a time.
  145. */
  146. void hv_vss_onchannelcallback(void *context)
  147. {
  148. struct vmbus_channel *channel = context;
  149. u32 recvlen;
  150. u64 requestid;
  151. struct hv_vss_msg *vss_msg;
  152. struct icmsg_hdr *icmsghdrp;
  153. struct icmsg_negotiate *negop = NULL;
  154. if (vss_transaction.active) {
  155. /*
  156. * We will defer processing this callback once
  157. * the current transaction is complete.
  158. */
  159. vss_transaction.recv_channel = channel;
  160. return;
  161. }
  162. vmbus_recvpacket(channel, recv_buffer, PAGE_SIZE * 2, &recvlen,
  163. &requestid);
  164. if (recvlen > 0) {
  165. icmsghdrp = (struct icmsg_hdr *)&recv_buffer[
  166. sizeof(struct vmbuspipe_hdr)];
  167. if (icmsghdrp->icmsgtype == ICMSGTYPE_NEGOTIATE) {
  168. vmbus_prep_negotiate_resp(icmsghdrp, negop,
  169. recv_buffer, UTIL_FW_VERSION,
  170. VSS_VERSION);
  171. } else {
  172. vss_msg = (struct hv_vss_msg *)&recv_buffer[
  173. sizeof(struct vmbuspipe_hdr) +
  174. sizeof(struct icmsg_hdr)];
  175. /*
  176. * Stash away this global state for completing the
  177. * transaction; note transactions are serialized.
  178. */
  179. vss_transaction.recv_len = recvlen;
  180. vss_transaction.recv_channel = channel;
  181. vss_transaction.recv_req_id = requestid;
  182. vss_transaction.active = true;
  183. vss_transaction.msg = (struct hv_vss_msg *)vss_msg;
  184. switch (vss_msg->vss_hdr.operation) {
  185. /*
  186. * Initiate a "freeze/thaw"
  187. * operation in the guest.
  188. * We respond to the host once
  189. * the operation is complete.
  190. *
  191. * We send the message to the
  192. * user space daemon and the
  193. * operation is performed in
  194. * the daemon.
  195. */
  196. case VSS_OP_FREEZE:
  197. case VSS_OP_THAW:
  198. schedule_work(&vss_send_op_work);
  199. schedule_delayed_work(&vss_timeout_work,
  200. VSS_USERSPACE_TIMEOUT);
  201. return;
  202. case VSS_OP_HOT_BACKUP:
  203. vss_msg->vss_cf.flags =
  204. VSS_HBU_NO_AUTO_RECOVERY;
  205. vss_respond_to_host(0);
  206. return;
  207. case VSS_OP_GET_DM_INFO:
  208. vss_msg->dm_info.flags = 0;
  209. vss_respond_to_host(0);
  210. return;
  211. default:
  212. vss_respond_to_host(0);
  213. return;
  214. }
  215. }
  216. icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION
  217. | ICMSGHDRFLAG_RESPONSE;
  218. vmbus_sendpacket(channel, recv_buffer,
  219. recvlen, requestid,
  220. VM_PKT_DATA_INBAND, 0);
  221. }
  222. }
  223. int
  224. hv_vss_init(struct hv_util_service *srv)
  225. {
  226. int err;
  227. err = cn_add_callback(&vss_id, vss_name, vss_cn_callback);
  228. if (err)
  229. return err;
  230. recv_buffer = srv->recv_buffer;
  231. /*
  232. * When this driver loads, the user level daemon that
  233. * processes the host requests may not yet be running.
  234. * Defer processing channel callbacks until the daemon
  235. * has registered.
  236. */
  237. vss_transaction.active = true;
  238. return 0;
  239. }
  240. void hv_vss_deinit(void)
  241. {
  242. cn_del_callback(&vss_id);
  243. cancel_delayed_work_sync(&vss_timeout_work);
  244. cancel_work_sync(&vss_send_op_work);
  245. }