Pārlūkot izejas kodu

modules/ctl: remove limitation on number of message chunks

binrpc uses an iovec to send out replies, which is limited in size and so
severely limits the number of elements that can be returned. This patch adds
a callback function to send out and empty the iovec array every time it gets
full while it's being populated.
Richard Fuchs 13 gadi atpakaļ
vecāks
revīzija
c9ea269242
1 mainītis faili ar 27 papildinājumiem un 6 dzēšanām
  1. 27 6
      modules/ctl/binrpc_run.c

+ 27 - 6
modules/ctl/binrpc_run.c

@@ -107,11 +107,13 @@ struct iovec_array{
 	struct iovec* v;
 	int idx;
 	int len;
+	void *ctx;
 };
 
 /* send */
 static void rpc_fault(struct binrpc_ctx* ctx, int code, char* fmt, ...);
 static int rpc_send(struct binrpc_ctx* ctx);
+static int rpc_send_v(struct iovec_array *a);
 static int rpc_add(struct binrpc_ctx* ctx, char* fmt, ...);
 static int rpc_scan(struct binrpc_ctx* ctx, char* fmt, ...);
 static int rpc_printf(struct binrpc_ctx* ctx, char* fmt, ...);
@@ -254,15 +256,17 @@ error:
 inline static int append_iovec(struct iovec_array* a, unsigned char* buf,
 								int len)
 {
-	
-	if (a->idx >= a->len)
-		goto error;
+	int ret;
+
+	if (a->idx >= a->len) {
+		ret = rpc_send_v(a);
+		if (ret < 0)
+			return ret;
+	}
 	a->v[a->idx].iov_base=buf;
 	a->v[a->idx].iov_len=len;
 	a->idx++;
 	return 0;
-error:
-	return -1; /* overflow */
 }
 
 
@@ -537,6 +541,22 @@ static void rpc_fault_reset(struct binrpc_ctx* ctx)
 	}
 }
 
+/* wrapper around sock_send_v for staggered buffer writing */
+static int rpc_send_v(struct iovec_array *a)
+{
+	int ret;
+
+	if (a->idx <= 0)
+		return 0;
+
+	ret = sock_send_v(a->ctx, a->v, a->idx);
+	if (ret < 0)
+		return ret;
+
+	a->idx = 0;
+	return 0;
+}
+
 /* build the reply from the current body */
 static int rpc_send(struct binrpc_ctx* ctx)
 {
@@ -551,6 +571,7 @@ static int rpc_send(struct binrpc_ctx* ctx)
 	a.v=v;
 	a.idx=1;
 	a.len=MAX_MSG_CHUNKS;
+	a.ctx = ctx->send_h;
 	
 	if (ctx->replied){
 		LOG(L_ERR, "ERROR: binrpc: rpc_send: rpc method %s tried to reply"
@@ -573,7 +594,7 @@ static int rpc_send(struct binrpc_ctx* ctx)
 		LOG(L_ERR, "ERROR: binrprc: rpc_send: too many message chunks\n");
 		goto error;
 	}
-	if ((err=sock_send_v(ctx->send_h, v, a.idx))<0){
+	if ((err = rpc_send_v(&a)) < 0){
 		if (err==-2){
 			LOG(L_ERR, "ERROR: binrpc: rpc_send: send failed: "
 					"datagram too big\n");