X-Git-Url: http://git.vrable.net/?a=blobdiff_plain;f=nfs3%2Fsynclient.c;h=ef614d3444c0913a188e7fa148ce2d2613ff6bbc;hb=173738187e4798ff42d3be002f65c142c3b2abc9;hp=fc33146af10a3fbdfe34f9742fd1276dbef7b24a;hpb=b114ba6e47b8e36ee568afa95e3463da1af12cf4;p=bluesky.git diff --git a/nfs3/synclient.c b/nfs3/synclient.c index fc33146..ef614d3 100644 --- a/nfs3/synclient.c +++ b/nfs3/synclient.c @@ -35,6 +35,9 @@ /* Maximum size of a single RPC message that we will accept (8 MB). */ #define MAX_RPC_MSGSIZE (8 << 20) +int threads; +int completed = 0; + struct rpc_reply { uint32_t xid; uint32_t type; @@ -85,8 +88,12 @@ typedef struct { GHashTable *xid_table; } NFSConnection; + +typedef void (*NFSFunc)(NFSConnection *nfs, + gpointer user_data, const char *reply, size_t len); + typedef struct { - GFunc callback; + NFSFunc callback; gpointer user_data; int64_t start, end; } CallInfo; @@ -125,7 +132,7 @@ static void do_write(NFSConnection *conn, const char *buf, size_t len) } static void send_rpc(NFSConnection *nfs, int proc, GString *msg, - GFunc completion_handler, gpointer user_data) + NFSFunc completion_handler, gpointer user_data) { static int xid_count = 0; struct rpc_call_header header; @@ -173,13 +180,18 @@ static void process_reply(NFSConnection *nfs, GString *msg) } info->end = now_hires(); - g_print("Call(XID = %d) duration: %"PRIi64" ns\n", - xid, info->end - info->start); + printf("XID %d: Time = %"PRIi64"\n", xid, info->end - info->start); if (info->callback != NULL) - info->callback(nfs, info->user_data); + info->callback(nfs, info->user_data, + msg->str + sizeof(*reply), msg->len - sizeof(*reply)); g_hash_table_remove(nfs->xid_table, key); g_free(info); + + completed++; + if (completed == 5 * threads) { + g_main_loop_quit(main_loop); + } } static gboolean read_handler(GIOChannel *channel, @@ -250,7 +262,7 @@ static gboolean read_handler(GIOChannel *channel, /* We were reading in the fragment body. */ nfs->frag_len -= bytes_read; - if (nfs->frag_len = 0x80000000) { + if (nfs->frag_len == 0x80000000) { process_reply(nfs, nfs->msgbuf); nfs->frag_len = 0; g_string_set_size(nfs->msgbuf, 0); @@ -260,13 +272,61 @@ static gboolean read_handler(GIOChannel *channel, return TRUE; } +static void send_read_requests(NFSConnection *nfs, const struct nfs_fh3 *fh) +{ + int i; + + g_print("Sending read requests...\n"); + for (i = 0; i < 4; i++) { + char buf[64]; + struct read3args read; + memcpy(&read.file, fh, sizeof(struct nfs_fh3)); + read.offset = (1 << 20) * i; + read.count = (1 << 20); + + GString *str = g_string_new(""); + XDR xdr; + xdr_string_create(&xdr, str, XDR_ENCODE); + xdr_read3args(&xdr, &read); + send_rpc(nfs, NFSPROC3_READ, str, NULL, NULL); + g_string_free(str, TRUE); + } +} + +static void store_fh(NFSConnection *nfs, gpointer user_data, + const char *reply, size_t len) +{ + struct lookup3res res; + XDR xdr; + memset(&res, 0, sizeof(res)); + xdrmem_create(&xdr, (char *)reply, len, XDR_DECODE); + if (!xdr_lookup3res(&xdr, &res)) { + g_print("Decode error for lookup3res!\n"); + return; + } + if (res.status != NFS3_OK) { + g_print("Response not NFS3_OK\n"); + return; + } + + struct nfs_fh3 *fh = g_new0(struct nfs_fh3, 1); + fh->data.data_len = res.lookup3res_u.resok.object.data.data_len; + fh->data.data_val = g_memdup(res.lookup3res_u.resok.object.data.data_val, + fh->data.data_len); + + xdr.x_op = XDR_FREE; + xdr_lookup3res(&xdr, &res); + + send_read_requests(nfs, fh); +} + static gboolean idle_handler(gpointer data) { NFSConnection *nfs = (NFSConnection *)data; int i; g_print("Sending requests...\n"); - for (i = 0; i < 64; i++) { + for (i = 0; i < threads; i++) { char buf[64]; struct diropargs3 lookup; uint64_t rootfh = GUINT64_TO_BE(1); @@ -280,7 +340,7 @@ static gboolean idle_handler(gpointer data) XDR xdr; xdr_string_create(&xdr, str, XDR_ENCODE); xdr_diropargs3(&xdr, &lookup); - send_rpc(nfs, NFSPROC3_LOOKUP, str, NULL, NULL); + send_rpc(nfs, NFSPROC3_LOOKUP, str, store_fh, NULL); g_string_free(str, TRUE); } @@ -336,6 +396,10 @@ int main(int argc, char *argv[]) g_set_prgname("synclient"); g_print("Launching synthetic NFS RPC client...\n"); + threads = 8; + if (argc > 1) + threads = atoi(argv[1]); + main_loop = g_main_loop_new(NULL, FALSE); nfs_connect("niniel.sysnet.ucsd.edu");