diff options
author | Vitaly Kuznetsov <vkuznets@redhat.com> | 2014-11-06 12:21:25 -0500 |
---|---|---|
committer | Greg Kroah-Hartman <gregkh@linuxfoundation.org> | 2014-11-26 22:00:32 -0500 |
commit | 8d9560ebcc6448472b3afe8f36f37d6b0de8f5a4 (patch) | |
tree | 3111728c85dfb7bbd26fce7625d9dfcae742860c /drivers/hv | |
parent | 649142074d86afebe0505431a93957505d244dd6 (diff) |
Drivers: hv: kvp,vss: Fast propagation of userspace communication failure
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>
Diffstat (limited to 'drivers/hv')
-rw-r--r-- | drivers/hv/hv_kvp.c | 9 | ||||
-rw-r--r-- | drivers/hv/hv_snapshot.c | 8 |
2 files changed, 15 insertions, 2 deletions
diff --git a/drivers/hv/hv_kvp.c b/drivers/hv/hv_kvp.c index 521c14625b3a..beb8105c0e7b 100644 --- a/drivers/hv/hv_kvp.c +++ b/drivers/hv/hv_kvp.c | |||
@@ -350,6 +350,7 @@ kvp_send_key(struct work_struct *dummy) | |||
350 | __u8 pool = kvp_transaction.kvp_msg->kvp_hdr.pool; | 350 | __u8 pool = kvp_transaction.kvp_msg->kvp_hdr.pool; |
351 | __u32 val32; | 351 | __u32 val32; |
352 | __u64 val64; | 352 | __u64 val64; |
353 | int rc; | ||
353 | 354 | ||
354 | msg = kzalloc(sizeof(*msg) + sizeof(struct hv_kvp_msg) , GFP_ATOMIC); | 355 | msg = kzalloc(sizeof(*msg) + sizeof(struct hv_kvp_msg) , GFP_ATOMIC); |
355 | if (!msg) | 356 | if (!msg) |
@@ -446,7 +447,13 @@ kvp_send_key(struct work_struct *dummy) | |||
446 | } | 447 | } |
447 | 448 | ||
448 | msg->len = sizeof(struct hv_kvp_msg); | 449 | msg->len = sizeof(struct hv_kvp_msg); |
449 | cn_netlink_send(msg, 0, 0, GFP_ATOMIC); | 450 | rc = cn_netlink_send(msg, 0, 0, GFP_ATOMIC); |
451 | if (rc) { | ||
452 | pr_debug("KVP: failed to communicate to the daemon: %d\n", rc); | ||
453 | if (cancel_delayed_work_sync(&kvp_work)) | ||
454 | kvp_respond_to_host(message, HV_E_FAIL); | ||
455 | } | ||
456 | |||
450 | kfree(msg); | 457 | kfree(msg); |
451 | 458 | ||
452 | return; | 459 | return; |
diff --git a/drivers/hv/hv_snapshot.c b/drivers/hv/hv_snapshot.c index 21e51be74e6c..9d5e0d1efdb5 100644 --- a/drivers/hv/hv_snapshot.c +++ b/drivers/hv/hv_snapshot.c | |||
@@ -96,6 +96,7 @@ vss_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp) | |||
96 | static void vss_send_op(struct work_struct *dummy) | 96 | static void vss_send_op(struct work_struct *dummy) |
97 | { | 97 | { |
98 | int op = vss_transaction.msg->vss_hdr.operation; | 98 | int op = vss_transaction.msg->vss_hdr.operation; |
99 | int rc; | ||
99 | struct cn_msg *msg; | 100 | struct cn_msg *msg; |
100 | struct hv_vss_msg *vss_msg; | 101 | struct hv_vss_msg *vss_msg; |
101 | 102 | ||
@@ -111,7 +112,12 @@ static void vss_send_op(struct work_struct *dummy) | |||
111 | vss_msg->vss_hdr.operation = op; | 112 | vss_msg->vss_hdr.operation = op; |
112 | msg->len = sizeof(struct hv_vss_msg); | 113 | msg->len = sizeof(struct hv_vss_msg); |
113 | 114 | ||
114 | cn_netlink_send(msg, 0, 0, GFP_ATOMIC); | 115 | rc = cn_netlink_send(msg, 0, 0, GFP_ATOMIC); |
116 | if (rc) { | ||
117 | pr_warn("VSS: failed to communicate to the daemon: %d\n", rc); | ||
118 | if (cancel_delayed_work_sync(&vss_timeout_work)) | ||
119 | vss_respond_to_host(HV_E_FAIL); | ||
120 | } | ||
115 | kfree(msg); | 121 | kfree(msg); |
116 | 122 | ||
117 | return; | 123 | return; |