[Qemu-devel] Re: [RFC][PATCH v5 03/21] virtagent: common code for managing client/server rpc jobs

2010-12-07 Thread Jes Sorensen
On 12/03/10 19:03, Michael Roth wrote:
 This implements a simple state machine to manage client/server rpc
 jobs being multiplexed over a single channel.
 
 A client job consists of sending an rpc request, reading an
 rpc response, then making the appropriate callbacks. We allow one
 client job to be processed at a time, which will make the following
 state transitions:
 
 VA_CLIENT_IDLE - VA_CLIENT_SEND (job queued, send channel open)
 VA_CLIENT_SEND - VA_CLIENT_WAIT (request sent, awaiting response)
 VA_CLIENT_WAIT - VA_CLIENT_IDLE (response recieved, callbacks made)
 
 A server job consists of recieving an rpc request, generating a
 response, then sending the response. We expect to receive one server
 request at a time due to the 1 at a time restriction for client jobs.
 Server jobs make the following transitions:
 
 VA_SERVER_IDLE - VA_SERVER_WAIT (recieved/executed request, send
 channel busy, response deferred)
 VA_SERVER_IDLE - VA_SERVER_SEND (recieved/executed request, send
 channel open, sending response)
 VA_SERVER_WAIT - VA_SERVER_SEND (send channel now open, sending
 response)
 VA_SERVER_SEND - VA_SERVER_IDLE (response sent)
 
 Signed-off-by: Michael Roth mdr...@linux.vnet.ibm.com

As mentioned before, I really don't understand why this is part of QEMU,
the guest agent really should be able to run totally outside of QEMU.

 +
 +#define DEBUG_VA
 +
 +#ifdef DEBUG_VA
 +#define TRACE(msg, ...) do { \
 +fprintf(stderr, %s:%s():L%d:  msg \n, \
 +__FILE__, __FUNCTION__, __LINE__, ## __VA_ARGS__); \
 +} while(0)
 +#else
 +#define TRACE(msg, ...) \
 +do { } while (0)
 +#endif
 +
 +#define LOG(msg, ...) do { \
 +fprintf(stderr, %s:%s():  msg \n, \
 +__FILE__, __FUNCTION__, ## __VA_ARGS__); \
 +} while(0)

This must be like the 217th copy of these functions, could you please
use some of the code that is already in the tree, and make it generic if
needed.

 +
 +#define VERSION 1.0
 +#define EOL \r\n
 +
 +#define VA_HDR_LEN_MAX 4096 /* http header limit */
 +#define VA_CONTENT_LEN_MAX 2*1024*1024 /* rpc/http send limit */
 +#define VA_CLIENT_JOBS_MAX 5 /* max client rpcs we can queue */
 +#define VA_SERVER_JOBS_MAX 1 /* max server rpcs we can queue */

As mentioned last time, please make this stuff configurable and not hard
coded.

Cheers,
Jes



Re: [Qemu-devel] Re: [RFC][PATCH v5 03/21] virtagent: common code for managing client/server rpc jobs

2010-12-07 Thread Michael Roth

On 12/07/2010 07:38 AM, Jes Sorensen wrote:

On 12/03/10 19:03, Michael Roth wrote:

This implements a simple state machine to manage client/server rpc
jobs being multiplexed over a single channel.

A client job consists of sending an rpc request, reading an
rpc response, then making the appropriate callbacks. We allow one
client job to be processed at a time, which will make the following
state transitions:

VA_CLIENT_IDLE -  VA_CLIENT_SEND (job queued, send channel open)
VA_CLIENT_SEND -  VA_CLIENT_WAIT (request sent, awaiting response)
VA_CLIENT_WAIT -  VA_CLIENT_IDLE (response recieved, callbacks made)

A server job consists of recieving an rpc request, generating a
response, then sending the response. We expect to receive one server
request at a time due to the 1 at a time restriction for client jobs.
Server jobs make the following transitions:

VA_SERVER_IDLE -  VA_SERVER_WAIT (recieved/executed request, send
channel busy, response deferred)
VA_SERVER_IDLE -  VA_SERVER_SEND (recieved/executed request, send
channel open, sending response)
VA_SERVER_WAIT -  VA_SERVER_SEND (send channel now open, sending
response)
VA_SERVER_SEND -  VA_SERVER_IDLE (response sent)

Signed-off-by: Michael Rothmdr...@linux.vnet.ibm.com


As mentioned before, I really don't understand why this is part of QEMU,
the guest agent really should be able to run totally outside of QEMU.


+
+#define DEBUG_VA
+
+#ifdef DEBUG_VA
+#define TRACE(msg, ...) do { \
+fprintf(stderr, %s:%s():L%d:  msg \n, \
+__FILE__, __FUNCTION__, __LINE__, ## __VA_ARGS__); \
+} while(0)
+#else
+#define TRACE(msg, ...) \
+do { } while (0)
+#endif
+
+#define LOG(msg, ...) do { \
+fprintf(stderr, %s:%s():  msg \n, \
+__FILE__, __FUNCTION__, ## __VA_ARGS__); \
+} while(0)


This must be like the 217th copy of these functions, could you please
use some of the code that is already in the tree, and make it generic if
needed.


+
+#define VERSION 1.0
+#define EOL \r\n
+
+#define VA_HDR_LEN_MAX 4096 /* http header limit */
+#define VA_CONTENT_LEN_MAX 2*1024*1024 /* rpc/http send limit */
+#define VA_CLIENT_JOBS_MAX 5 /* max client rpcs we can queue */
+#define VA_SERVER_JOBS_MAX 1 /* max server rpcs we can queue */


As mentioned last time, please make this stuff configurable and not hard
coded.



Yup, definitely on the TODO. Should be in the next round.


Cheers,
Jes






[Qemu-devel] Re: [RFC][PATCH v5 03/21] virtagent: common code for managing client/server rpc jobs

2010-12-06 Thread Adam Litke
On Fri, 2010-12-03 at 12:03 -0600, Michael Roth wrote:
 +/* create new client job and then put it on the queue. this can be
 + * called externally from virtagent. Since there can only be one virtagent
 + * instance we access state via an object-scoped global rather than pass
 + * it around.
 + *
 + * if this is successful virtagent will handle cleanup of req_xml after
 + * making the appropriate callbacks, otherwise callee should handle it
 + */

Explain please. Do you mean caller should handle it? Are you trying to
say that this function, when successful, steals the reference to
req_xml?

 +int va_client_job_add(xmlrpc_mem_block *req_xml, VAClientCallback *cb,
 +  MonitorCompletion *mon_cb, void *mon_data)
 +{
 +int ret;
 +VAClientJob *client_job;
 +TRACE(called);
 +
 +client_job = va_client_job_new(req_xml, cb, mon_cb, mon_data);
 +if (client_job == NULL) {
 +return -EINVAL;
 +}
 +
 +ret = va_push_client_job(client_job);
 +if (ret != 0) {
 +LOG(error adding client to queue: %s, strerror(ret));
 +qemu_free(client_job);
 +return ret;
 +}
 +
 +return 0;
 +}

-- 
Thanks,
Adam




[Qemu-devel] Re: [RFC][PATCH v5 03/21] virtagent: common code for managing client/server rpc jobs

2010-12-06 Thread Adam Litke
On Fri, 2010-12-03 at 12:03 -0600, Michael Roth wrote: 
 +/* create new client job and then put it on the queue. this can be
 + * called externally from virtagent. Since there can only be one virtagent
 + * instance we access state via an object-scoped global rather than pass
 + * it around.
 + *
 + * if this is successful virtagent will handle cleanup of req_xml after
 + * making the appropriate callbacks, otherwise callee should handle it
 + */

Explain please. Do you mean caller should handle it? Are you trying to
say that this function, when successful, steals the reference to
req_xml?

 +int va_client_job_add(xmlrpc_mem_block *req_xml, VAClientCallback *cb,
 +  MonitorCompletion *mon_cb, void *mon_data)
 +{
 +int ret;
 +VAClientJob *client_job;
 +TRACE(called);
 +
 +client_job = va_client_job_new(req_xml, cb, mon_cb, mon_data);
 +if (client_job == NULL) {
 +return -EINVAL;
 +}
 +
 +ret = va_push_client_job(client_job);
 +if (ret != 0) {
 +LOG(error adding client to queue: %s, strerror(ret));
 +qemu_free(client_job);
 +return ret;
 +}
 +
 +return 0;
 +}
 +
 +/* create new server job and then put it on the queue in wait state
 + * this should only be called from within our read handler callback
 + */

Since this function is only 4 lines and has only one valid call site.
perhaps its better to fold it directly into the read handler callback.

 +static int va_server_job_add(xmlrpc_mem_block *resp_xml)
 +{
 +VAServerJob *server_job;
 +TRACE(called);
 +
 +server_job = va_server_job_new(resp_xml);
 +assert(server_job != NULL);
 +va_push_server_job(server_job);
 +return 0;
 +}

-- 
Thanks,
Adam





[Qemu-devel] Re: [RFC][PATCH v5 03/21] virtagent: common code for managing client/server rpc jobs

2010-12-06 Thread Michael Roth

On 12/06/2010 03:54 PM, Adam Litke wrote:

On Fri, 2010-12-03 at 12:03 -0600, Michael Roth wrote:

+/* create new client job and then put it on the queue. this can be
+ * called externally from virtagent. Since there can only be one virtagent
+ * instance we access state via an object-scoped global rather than pass
+ * it around.
+ *
+ * if this is successful virtagent will handle cleanup of req_xml after
+ * making the appropriate callbacks, otherwise callee should handle it
+ */


Explain please. Do you mean caller should handle it? Are you trying to
say that this function, when successful, steals the reference to
req_xml?



Yup, should be caller. And yes, cleanup duty gets taken over if the call 
succeeds (after transmitting the request we have no need for the 
req_xml, so it didn't seem to make sense to carry it around just so the 
caller can free it when it gets it's call later on)



+int va_client_job_add(xmlrpc_mem_block *req_xml, VAClientCallback *cb,
+  MonitorCompletion *mon_cb, void *mon_data)
+{
+int ret;
+VAClientJob *client_job;
+TRACE(called);
+
+client_job = va_client_job_new(req_xml, cb, mon_cb, mon_data);
+if (client_job == NULL) {
+return -EINVAL;
+}
+
+ret = va_push_client_job(client_job);
+if (ret != 0) {
+LOG(error adding client to queue: %s, strerror(ret));
+qemu_free(client_job);
+return ret;
+}
+
+return 0;
+}







[Qemu-devel] Re: [RFC][PATCH v5 03/21] virtagent: common code for managing client/server rpc jobs

2010-12-06 Thread Michael Roth

On 12/06/2010 03:57 PM, Adam Litke wrote:

On Fri, 2010-12-03 at 12:03 -0600, Michael Roth wrote:

+/* create new client job and then put it on the queue. this can be
+ * called externally from virtagent. Since there can only be one virtagent
+ * instance we access state via an object-scoped global rather than pass
+ * it around.
+ *
+ * if this is successful virtagent will handle cleanup of req_xml after
+ * making the appropriate callbacks, otherwise callee should handle it
+ */


Explain please. Do you mean caller should handle it? Are you trying to
say that this function, when successful, steals the reference to
req_xml?


+int va_client_job_add(xmlrpc_mem_block *req_xml, VAClientCallback *cb,
+  MonitorCompletion *mon_cb, void *mon_data)
+{
+int ret;
+VAClientJob *client_job;
+TRACE(called);
+
+client_job = va_client_job_new(req_xml, cb, mon_cb, mon_data);
+if (client_job == NULL) {
+return -EINVAL;
+}
+
+ret = va_push_client_job(client_job);
+if (ret != 0) {
+LOG(error adding client to queue: %s, strerror(ret));
+qemu_free(client_job);
+return ret;
+}
+
+return 0;
+}
+
+/* create new server job and then put it on the queue in wait state
+ * this should only be called from within our read handler callback
+ */


Since this function is only 4 lines and has only one valid call site.
perhaps its better to fold it directly into the read handler callback.


+static int va_server_job_add(xmlrpc_mem_block *resp_xml)
+{
+VAServerJob *server_job;
+TRACE(called);
+
+server_job = va_server_job_new(resp_xml);
+assert(server_job != NULL);
+va_push_server_job(server_job);
+return 0;
+}




What I was mainly shooting for was to have the entry-points for adding 
client and server jobs be clear and somewhat similar. I've actually 
moved the read handler callback body into 
virtagent-server.c:va_do_server_rpc() since then. So client jobs get 
added by hmp/qmp-virtagent:va_do_rpc()-va_push_client_job() and server 
jobs by read 
handler-virtagent-server.c:va_do_server_rpc()-va_push_server_job().