Drivers: hv: kvp,vss: Fast propagation of userspace communication failure
authorVitaly Kuznetsov <vkuznets@redhat.com>
Thu, 6 Nov 2014 17:21:25 +0000 (18:21 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Thu, 27 Nov 2014 03:00:32 +0000 (19:00 -0800)
If we fail to send a message to userspace daemon with cn_netlink_send()
there is no need to wait for userspace to reply as it is not going to
happen. This happens when kvp or vss daemon is stopped after a successful
handshake. Report HV_E_FAIL immediately and cancel the timeout job so
host won't receive two failures.
Use pr_warn() for VSS and pr_debug() for KVP deliberately as VSS request
are rare and result in a failed backup. KVP requests are much more frequent
after a successful handshake so avoid flooding logs. It would be nice to
have an ability to de-negotiate with the host in case userspace daemon gets
disconnected so we won't receive new requests. But I'm not sure it is
possible.

Signed-off-by: Vitaly Kuznetsov <vkuznets@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
drivers/hv/hv_kvp.c
drivers/hv/hv_snapshot.c

index 521c14625b3ae10515b8720e0e43f305816b2606..beb8105c0e7bace32769198fd9f253c59d2fa543 100644 (file)
@@ -350,6 +350,7 @@ kvp_send_key(struct work_struct *dummy)
        __u8 pool = kvp_transaction.kvp_msg->kvp_hdr.pool;
        __u32 val32;
        __u64 val64;
+       int rc;
 
        msg = kzalloc(sizeof(*msg) + sizeof(struct hv_kvp_msg) , GFP_ATOMIC);
        if (!msg)
@@ -446,7 +447,13 @@ kvp_send_key(struct work_struct *dummy)
        }
 
        msg->len = sizeof(struct hv_kvp_msg);
-       cn_netlink_send(msg, 0, 0, GFP_ATOMIC);
+       rc = cn_netlink_send(msg, 0, 0, GFP_ATOMIC);
+       if (rc) {
+               pr_debug("KVP: failed to communicate to the daemon: %d\n", rc);
+               if (cancel_delayed_work_sync(&kvp_work))
+                       kvp_respond_to_host(message, HV_E_FAIL);
+       }
+
        kfree(msg);
 
        return;
index 21e51be74e6c4a15a915796ab38d368170bdf5f6..9d5e0d1efdb51bd235f87bcdd914d2c5656d6d45 100644 (file)
@@ -96,6 +96,7 @@ vss_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
 static void vss_send_op(struct work_struct *dummy)
 {
        int op = vss_transaction.msg->vss_hdr.operation;
+       int rc;
        struct cn_msg *msg;
        struct hv_vss_msg *vss_msg;
 
@@ -111,7 +112,12 @@ static void vss_send_op(struct work_struct *dummy)
        vss_msg->vss_hdr.operation = op;
        msg->len = sizeof(struct hv_vss_msg);
 
-       cn_netlink_send(msg, 0, 0, GFP_ATOMIC);
+       rc = cn_netlink_send(msg, 0, 0, GFP_ATOMIC);
+       if (rc) {
+               pr_warn("VSS: failed to communicate to the daemon: %d\n", rc);
+               if (cancel_delayed_work_sync(&vss_timeout_work))
+                       vss_respond_to_host(HV_E_FAIL);
+       }
        kfree(msg);
 
        return;