|
@@ -67,11 +67,11 @@ static const char vss_devname[] = "vmbus/hv_vss";
|
|
|
static __u8 *recv_buffer;
|
|
|
static struct hvutil_transport *hvt;
|
|
|
|
|
|
-static void vss_send_op(struct work_struct *dummy);
|
|
|
static void vss_timeout_func(struct work_struct *dummy);
|
|
|
+static void vss_handle_request(struct work_struct *dummy);
|
|
|
|
|
|
static DECLARE_DELAYED_WORK(vss_timeout_work, vss_timeout_func);
|
|
|
-static DECLARE_WORK(vss_send_op_work, vss_send_op);
|
|
|
+static DECLARE_WORK(vss_handle_request_work, vss_handle_request);
|
|
|
|
|
|
static void vss_poll_wrapper(void *channel)
|
|
|
{
|
|
@@ -156,8 +156,7 @@ static int vss_on_msg(void *msg, int len)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-static void vss_send_op(struct work_struct *dummy)
|
|
|
+static void vss_send_op(void)
|
|
|
{
|
|
|
int op = vss_transaction.msg->vss_hdr.operation;
|
|
|
int rc;
|
|
@@ -174,6 +173,9 @@ static void vss_send_op(struct work_struct *dummy)
|
|
|
vss_msg->vss_hdr.operation = op;
|
|
|
|
|
|
vss_transaction.state = HVUTIL_USERSPACE_REQ;
|
|
|
+
|
|
|
+ schedule_delayed_work(&vss_timeout_work, VSS_USERSPACE_TIMEOUT);
|
|
|
+
|
|
|
rc = hvutil_transport_send(hvt, vss_msg, sizeof(*vss_msg), NULL);
|
|
|
if (rc) {
|
|
|
pr_warn("VSS: failed to communicate to the daemon: %d\n", rc);
|
|
@@ -188,6 +190,40 @@ static void vss_send_op(struct work_struct *dummy)
|
|
|
return;
|
|
|
}
|
|
|
|
|
|
+static void vss_handle_request(struct work_struct *dummy)
|
|
|
+{
|
|
|
+ switch (vss_transaction.msg->vss_hdr.operation) {
|
|
|
+ /*
|
|
|
+ * Initiate a "freeze/thaw" operation in the guest.
|
|
|
+ * We respond to the host once the operation is complete.
|
|
|
+ *
|
|
|
+ * We send the message to the user space daemon and the operation is
|
|
|
+ * performed in the daemon.
|
|
|
+ */
|
|
|
+ case VSS_OP_THAW:
|
|
|
+ case VSS_OP_FREEZE:
|
|
|
+ if (vss_transaction.state < HVUTIL_READY) {
|
|
|
+ /* Userspace is not registered yet */
|
|
|
+ vss_respond_to_host(HV_E_FAIL);
|
|
|
+ return;
|
|
|
+ }
|
|
|
+ vss_transaction.state = HVUTIL_HOSTMSG_RECEIVED;
|
|
|
+ vss_send_op();
|
|
|
+ return;
|
|
|
+ case VSS_OP_HOT_BACKUP:
|
|
|
+ vss_transaction.msg->vss_cf.flags = VSS_HBU_NO_AUTO_RECOVERY;
|
|
|
+ break;
|
|
|
+ case VSS_OP_GET_DM_INFO:
|
|
|
+ vss_transaction.msg->dm_info.flags = 0;
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ vss_respond_to_host(0);
|
|
|
+ hv_poll_channel(vss_transaction.recv_channel, vss_poll_wrapper);
|
|
|
+}
|
|
|
+
|
|
|
/*
|
|
|
* Send a response back to the host.
|
|
|
*/
|
|
@@ -272,48 +308,8 @@ void hv_vss_onchannelcallback(void *context)
|
|
|
vss_transaction.recv_req_id = requestid;
|
|
|
vss_transaction.msg = (struct hv_vss_msg *)vss_msg;
|
|
|
|
|
|
- switch (vss_msg->vss_hdr.operation) {
|
|
|
- /*
|
|
|
- * Initiate a "freeze/thaw"
|
|
|
- * operation in the guest.
|
|
|
- * We respond to the host once
|
|
|
- * the operation is complete.
|
|
|
- *
|
|
|
- * We send the message to the
|
|
|
- * user space daemon and the
|
|
|
- * operation is performed in
|
|
|
- * the daemon.
|
|
|
- */
|
|
|
- case VSS_OP_FREEZE:
|
|
|
- case VSS_OP_THAW:
|
|
|
- if (vss_transaction.state < HVUTIL_READY) {
|
|
|
- /* Userspace is not registered yet */
|
|
|
- vss_respond_to_host(HV_E_FAIL);
|
|
|
- return;
|
|
|
- }
|
|
|
- vss_transaction.state = HVUTIL_HOSTMSG_RECEIVED;
|
|
|
- schedule_work(&vss_send_op_work);
|
|
|
- schedule_delayed_work(&vss_timeout_work,
|
|
|
- VSS_USERSPACE_TIMEOUT);
|
|
|
- return;
|
|
|
-
|
|
|
- case VSS_OP_HOT_BACKUP:
|
|
|
- vss_msg->vss_cf.flags =
|
|
|
- VSS_HBU_NO_AUTO_RECOVERY;
|
|
|
- vss_respond_to_host(0);
|
|
|
- return;
|
|
|
-
|
|
|
- case VSS_OP_GET_DM_INFO:
|
|
|
- vss_msg->dm_info.flags = 0;
|
|
|
- vss_respond_to_host(0);
|
|
|
- return;
|
|
|
-
|
|
|
- default:
|
|
|
- vss_respond_to_host(0);
|
|
|
- return;
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
+ schedule_work(&vss_handle_request_work);
|
|
|
+ return;
|
|
|
}
|
|
|
|
|
|
icmsghdrp->icflags = ICMSGHDRFLAG_TRANSACTION
|
|
@@ -364,6 +360,6 @@ void hv_vss_deinit(void)
|
|
|
{
|
|
|
vss_transaction.state = HVUTIL_DEVICE_DYING;
|
|
|
cancel_delayed_work_sync(&vss_timeout_work);
|
|
|
- cancel_work_sync(&vss_send_op_work);
|
|
|
+ cancel_work_sync(&vss_handle_request_work);
|
|
|
hvutil_transport_destroy(hvt);
|
|
|
}
|