]> xenbits.xensource.com Git - libvirt.git/commitdiff
rpc: Don't close connection if program is unknown
authorJiri Denemark <jdenemar@redhat.com>
Fri, 26 Aug 2011 15:11:03 +0000 (17:11 +0200)
committerJiri Denemark <jdenemar@redhat.com>
Fri, 26 Aug 2011 15:29:44 +0000 (17:29 +0200)
In case we add a new program in the future (we did that in the past and
we are going to do it again soon) current daemon will behave badly with
new client that wants to use the new program. Before the RPC rewrite we
used to just send an error reply to any request with unknown program.
With the RPC rewrite in 0.9.3 the daemon just closes the connection
through which such request was sent. This patch fixes this regression.

src/rpc/virnetserver.c
src/rpc/virnetserverprogram.c
src/rpc/virnetserverprogram.h

index 1a49dbbd8ae34fd55dbb0f2c0e861b105332f478..fd8781d6759928efa9037b563ffaa13f5bee6205 100644 (file)
@@ -143,10 +143,12 @@ static void virNetServerHandleJob(void *jobOpaque, void *opaque)
     }
 
     if (!prog) {
-        VIR_DEBUG("Cannot find program %d version %d",
-                  job->msg->header.prog,
-                  job->msg->header.vers);
-        goto error;
+        if (virNetServerProgramUnknownError(job->client,
+                                            job->msg,
+                                            &job->msg->header) < 0)
+            goto error;
+        else
+            goto cleanup;
     }
 
     virNetServerProgramRef(prog);
@@ -159,20 +161,18 @@ static void virNetServerHandleJob(void *jobOpaque, void *opaque)
         goto error;
 
     virNetServerLock(srv);
+
+cleanup:
     virNetServerProgramFree(prog);
     virNetServerUnlock(srv);
     virNetServerClientFree(job->client);
-
     VIR_FREE(job);
     return;
 
 error:
-    virNetServerUnlock(srv);
-    virNetServerProgramFree(prog);
     virNetMessageFree(job->msg);
     virNetServerClientClose(job->client);
-    virNetServerClientFree(job->client);
-    VIR_FREE(job);
+    goto cleanup;
 }
 
 
index ca80ae09ed845ce660c55f6bdb59a53c6186ad61..ac3f0fdfb2d9f6d623dd0dcf4d47bfd3fec907a4 100644 (file)
@@ -110,7 +110,8 @@ static virNetServerProgramProcPtr virNetServerProgramGetProc(virNetServerProgram
 
 
 static int
-virNetServerProgramSendError(virNetServerProgramPtr prog,
+virNetServerProgramSendError(unsigned program,
+                             unsigned version,
                              virNetServerClientPtr client,
                              virNetMessagePtr msg,
                              virNetMessageErrorPtr rerr,
@@ -119,13 +120,13 @@ virNetServerProgramSendError(virNetServerProgramPtr prog,
                              int serial)
 {
     VIR_DEBUG("prog=%d ver=%d proc=%d type=%d serial=%d msg=%p rerr=%p",
-              prog->program, prog->version, procedure, type, serial, msg, rerr);
+              program, version, procedure, type, serial, msg, rerr);
 
     virNetMessageSaveError(rerr);
 
     /* Return header. */
-    msg->header.prog = prog->program;
-    msg->header.vers = prog->version;
+    msg->header.prog = program;
+    msg->header.vers = version;
     msg->header.proc = procedure;
     msg->header.type = type;
     msg->header.serial = serial;
@@ -170,7 +171,8 @@ virNetServerProgramSendReplyError(virNetServerProgramPtr prog,
      * For data streams, errors are sent back as data streams
      * For method calls, errors are sent back as method replies
      */
-    return virNetServerProgramSendError(prog,
+    return virNetServerProgramSendError(prog->program,
+                                        prog->version,
                                         client,
                                         msg,
                                         rerr,
@@ -187,7 +189,8 @@ int virNetServerProgramSendStreamError(virNetServerProgramPtr prog,
                                        int procedure,
                                        int serial)
 {
-    return virNetServerProgramSendError(prog,
+    return virNetServerProgramSendError(prog->program,
+                                        prog->version,
                                         client,
                                         msg,
                                         rerr,
@@ -197,6 +200,27 @@ int virNetServerProgramSendStreamError(virNetServerProgramPtr prog,
 }
 
 
+int virNetServerProgramUnknownError(virNetServerClientPtr client,
+                                    virNetMessagePtr msg,
+                                    virNetMessageHeaderPtr req)
+{
+    virNetMessageError rerr;
+
+    virNetError(VIR_ERR_RPC,
+                _("Cannot find program %d version %d"), req->prog, req->vers);
+
+    memset(&rerr, 0, sizeof(rerr));
+    return virNetServerProgramSendError(req->prog,
+                                        req->vers,
+                                        client,
+                                        msg,
+                                        &rerr,
+                                        req->proc,
+                                        VIR_NET_REPLY,
+                                        req->serial);
+}
+
+
 static int
 virNetServerProgramDispatchCall(virNetServerProgramPtr prog,
                                 virNetServerPtr server,
index ca31b7e53e4b2aae27252daced2651c6605166ba..06b16d72bb1f44a4a2c14ca86d2411713b742bf2 100644 (file)
@@ -86,6 +86,10 @@ int virNetServerProgramSendStreamError(virNetServerProgramPtr prog,
                                        int procedure,
                                        int serial);
 
+int virNetServerProgramUnknownError(virNetServerClientPtr client,
+                                    virNetMessagePtr msg,
+                                    virNetMessageHeaderPtr req);
+
 int virNetServerProgramSendStreamData(virNetServerProgramPtr prog,
                                       virNetServerClientPtr client,
                                       virNetMessagePtr msg,