x86/hvmloader: improve error handling for xenbus interactions
authorAndrew Cooper <andrew.cooper3@citrix.com>
Tue, 7 Jul 2015 12:39:40 +0000 (14:39 +0200)
committerJan Beulich <jbeulich@suse.com>
Tue, 7 Jul 2015 12:39:40 +0000 (14:39 +0200)
Consume and ignore all XS_DEBUG packets, and pass the response type back to
the caller of xenbus_recv() so the caller can take appropriate action if an
unexpected reply was received.

Signed-off-by: Andrew Cooper <andrew.cooper3@citrix.com>
tools/firmware/hvmloader/xenbus.c

index 00513f70bbc55ee6c3ddde6671a2f17d5ad8e2c4..d0ed993cca228836127b2cd89e4dc8daff55d213 100644 (file)
@@ -208,15 +208,23 @@ static void xenbus_send(uint32_t type, ...)
  * Returns 0 for success, or an errno for error.
  * The answer is returned in a static buffer which is only
  * valid until the next call of xenbus_send(). */
-static int xenbus_recv(uint32_t *reply_len, const char **reply_data)
+static int xenbus_recv(uint32_t *reply_len, const char **reply_data,
+                       uint32_t *reply_type)
 {
     struct xsd_sockmsg hdr;
 
-    /* Pull the reply off the ring */
-    ring_read((char *) &hdr, sizeof(hdr));
-    ring_read(payload, hdr.len);
-    /* For sanity's sake, nul-terminate the answer */
-    payload[hdr.len] = '\0';
+    do
+    {
+        /* Pull the reply off the ring */
+        ring_read((char *) &hdr, sizeof(hdr));
+        ring_read(payload, hdr.len);
+        /* For sanity's sake, nul-terminate the answer */
+        payload[hdr.len] = '\0';
+
+    } while ( hdr.type == XS_DEBUG );
+
+    if ( reply_type )
+        *reply_type = hdr.type;
 
     /* Handle errors */
     if ( hdr.type == XS_ERROR )
@@ -247,7 +255,7 @@ static int xenbus_recv(uint32_t *reply_len, const char **reply_data)
  */
 const char *xenstore_read(const char *path, const char *default_resp)
 {
-    uint32_t len = 0;
+    uint32_t len = 0, type = 0;
     const char *answer = NULL;
 
     xenbus_send(XS_READ,
@@ -255,7 +263,7 @@ const char *xenstore_read(const char *path, const char *default_resp)
                 "", 1, /* nul separator */
                 NULL, 0);
 
-    if ( xenbus_recv(&len, &answer) )
+    if ( xenbus_recv(&len, &answer, &type) || (type != XS_READ) )
         answer = NULL;
 
     if ( (default_resp != NULL) && ((answer == NULL) || (*answer == '\0')) )
@@ -270,13 +278,23 @@ const char *xenstore_read(const char *path, const char *default_resp)
  */
 int xenstore_write(const char *path, const char *value)
 {
+    uint32_t len = 0, type = 0;
+    const char *answer = NULL;
+    int ret;
+
     xenbus_send(XS_WRITE,
                 path, strlen(path),
                 "", 1, /* nul separator */
                 value, strlen(value),
                 NULL, 0);
 
-    return ( xenbus_recv(NULL, NULL) );
+    ret = xenbus_recv(&len, &answer, &type);
+
+    if ( ret == 0 && ((type != XS_WRITE) || (len != 3) ||
+                      !answer || strcmp(answer, "OK")) )
+        ret = EIO;
+
+    return ret;
 }
 
 /*