vm_tools: add grpc timeout to all maitred_client calls

The maitred_client is used in the pre-stop stanza of an upstart
script. Adding gRPC timeouts will ensure the call does not block
indefinitely.

BUG=b:130041657
TEST=add sleep in shutdown call in maitred server;
shutdown VM using maitred_client;
observe that gRPC deadline is exceeded

Change-Id: I74434deec94aa9a4c688d5e0f95b8664be0134c8
Reviewed-on: https://chromium-review.googlesource.com/1555296
Commit-Ready: ChromeOS CL Exonerator Bot <chromiumos-cl-exonerator@appspot.gserviceaccount.com>
Commit-Ready: Trent Begin <tbegin@chromium.org>
Tested-by: Trent Begin <tbegin@chromium.org>
Reviewed-by: Chirantan Ekbote <chirantan@chromium.org>
diff --git a/vm_tools/host.gypi b/vm_tools/host.gypi
index cdb8dfa..d59e2e8 100644
--- a/vm_tools/host.gypi
+++ b/vm_tools/host.gypi
@@ -19,6 +19,11 @@
       'sources': [
         'maitred/client.cc',
       ],
+      'link_settings': {
+        'libraries': [
+          '-lgpr',
+        ],
+      },
     },
     {
       'target_name': 'libforwarder',
diff --git a/vm_tools/maitred/client.cc b/vm_tools/maitred/client.cc
index b420d12..2c86384 100644
--- a/vm_tools/maitred/client.cc
+++ b/vm_tools/maitred/client.cc
@@ -30,6 +30,10 @@
 namespace pb = google::protobuf;
 
 namespace {
+
+// Timeout in seconds for each gRPC call.
+constexpr int kDefaultTimeoutSeconds = 10;
+
 bool ParseFileToProto(base::FilePath path, pb::Message* msg) {
   if (!base::PathExists(path)) {
     LOG(ERROR) << path.value() << " does not exist";
@@ -57,6 +61,9 @@
 
   // Make the RPC.
   grpc::ClientContext ctx;
+  ctx.set_deadline(gpr_time_add(
+      gpr_now(GPR_CLOCK_MONOTONIC),
+      gpr_time_from_seconds(kDefaultTimeoutSeconds, GPR_TIMESPAN)));
   vm_tools::EmptyMessage empty;
 
   grpc::Status status = stub->ConfigureNetwork(&ctx, request, &empty);
@@ -74,6 +81,9 @@
   LOG(INFO) << "Shutting down VM";
 
   grpc::ClientContext ctx;
+  ctx.set_deadline(gpr_time_add(
+      gpr_now(GPR_CLOCK_MONOTONIC),
+      gpr_time_from_seconds(kDefaultTimeoutSeconds, GPR_TIMESPAN)));
   vm_tools::EmptyMessage empty;
 
   grpc::Status status = stub->Shutdown(&ctx, empty, &empty);
@@ -96,6 +106,9 @@
 
   // Make the RPC.
   grpc::ClientContext ctx;
+  ctx.set_deadline(gpr_time_add(
+      gpr_now(GPR_CLOCK_MONOTONIC),
+      gpr_time_from_seconds(kDefaultTimeoutSeconds, GPR_TIMESPAN)));
   vm_tools::LaunchProcessResponse response;
 
   grpc::Status status = stub->LaunchProcess(&ctx, request, &response);
@@ -142,6 +155,9 @@
 
   // Make the RPC.
   grpc::ClientContext ctx;
+  ctx.set_deadline(gpr_time_add(
+      gpr_now(GPR_CLOCK_MONOTONIC),
+      gpr_time_from_seconds(kDefaultTimeoutSeconds, GPR_TIMESPAN)));
   vm_tools::MountResponse response;
 
   grpc::Status status = stub->Mount(&ctx, request, &response);
@@ -173,6 +189,9 @@
 
   // Make the RPC.
   grpc::ClientContext ctx;
+  ctx.set_deadline(gpr_time_add(
+      gpr_now(GPR_CLOCK_MONOTONIC),
+      gpr_time_from_seconds(kDefaultTimeoutSeconds, GPR_TIMESPAN)));
   vm_tools::MountResponse response;
 
   grpc::Status status = stub->Mount9P(&ctx, request, &response);
@@ -202,6 +221,9 @@
 
   // Make the RPC.
   grpc::ClientContext ctx;
+  ctx.set_deadline(gpr_time_add(
+      gpr_now(GPR_CLOCK_MONOTONIC),
+      gpr_time_from_seconds(kDefaultTimeoutSeconds, GPR_TIMESPAN)));
   vm_tools::EmptyMessage response;
 
   grpc::Status status = stub->SetTime(&ctx, request, &response);