#include "bluesky.h"
extern BlueSkyFS *fs;
+static int outstanding_rpcs = 0;
+static struct bluesky_stats *rpc_recv_stats, *rpc_send_stats;
+
/* TCP port number to use for NFS protocol. (Should be 2049.) */
#define NFS_SERVICE_PORT 2051
{
struct rpc_fail_reply header;
+ g_atomic_int_add(&outstanding_rpcs, -1);
+
header.xid = htonl(req->xid);
header.type = htonl(1); /* REPLY */
header.stat = htonl(MSG_ACCEPTED);
async_rpc_flush(req->connection);
g_mutex_unlock(req->connection->send_lock);
+ bluesky_profile_free(req->profile);
+
if (req->args != NULL) {
char buf[4];
XDR xdr;
/* For UDP, a connection only exists for the duration of a single
* message. */
g_mutex_free(req->connection->send_lock);
+ g_string_free(req->connection->msgbuf, TRUE);
g_string_free(req->connection->sendbuf, TRUE);
g_free(req->connection);
}
{
bluesky_time_hires time_end;
+ bluesky_profile_add_event(req->profile,
+ g_strdup("Start encoding NFS response"));
+
GString *str = g_string_new("");
XDR xdr_out;
xdr_string_create(&xdr_out, str, XDR_ENCODE);
return;
}
+ g_atomic_int_add(&outstanding_rpcs, -1);
+ bluesky_stats_add(rpc_send_stats, str->len);
+
struct rpc_reply header;
header.xid = htonl(req->xid);
header.type = htonl(1); /* REPLY */
time_end = bluesky_now_hires();
+#if 0
printf("RPC[%"PRIx32"]: time = %"PRId64" ns\n",
req->xid, time_end - req->time_start);
+#endif
+
+ bluesky_profile_add_event(req->profile,
+ g_strdup("NFS reply sent"));
+ bluesky_profile_print(req->profile);
/* Clean up. */
+ bluesky_profile_free(req->profile);
g_string_free(str, TRUE);
if (req->args != NULL) {
/* For UDP, a connection only exists for the duration of a single
* message. */
g_mutex_free(req->connection->send_lock);
+ g_string_free(req->connection->msgbuf, TRUE);
g_string_free(req->connection->sendbuf, TRUE);
g_free(req->connection);
}
xdrproc_t _xdr_argument, _xdr_result;
char *(*local)(char *, RPCRequest *);
+ bluesky_profile_set(req->profile);
+
if (req->req_proc < sizeof(nfs_proc_names) / sizeof(const char *)) {
- printf("Dispatched NFS RPC message type %s\n",
- nfs_proc_names[req->req_proc]);
- } else {
- printf("Dispatched unknown NFS RPC message type %d\n", req->req_proc);
+ bluesky_profile_add_event(
+ req->profile,
+ g_strdup_printf("Dispatching NFS %s request",
+ nfs_proc_names[req->req_proc])
+ );
}
switch (req->req_proc) {
static gboolean async_flushd(gpointer data)
{
+#if 0
+ int rpc_count = g_atomic_int_get(&outstanding_rpcs);
+ if (rpc_count != 0) {
+ g_print("Currently outstanding RPC requests: %d\n", rpc_count);
+ }
+#endif
+
if (fs_dump_requested) {
bluesky_debug_dump(fs);
+ bluesky_stats_dump_all();
fs_dump_requested = 0;
}
GString *msg = rpc->msgbuf;
const char *buf = msg->str;
+ bluesky_stats_add(rpc_recv_stats, msg->len);
+
if (msg->len < sizeof(struct rpc_call_header)) {
fprintf(stderr, "Short RPC message: only %zd bytes!\n", msg->len);
return FALSE;
return FALSE;
}
+ g_atomic_int_add(&outstanding_rpcs, 1);
+
RPCRequest *req = g_new0(RPCRequest, 1);
req->connection = rpc;
- req->time_start = time_start;
+ req->profile = bluesky_profile_new();
+ bluesky_profile_add_event(req->profile, g_strdup("Receive NFS request"));
req->xid = xid;
if (ntohl(header->prog) != NFS_PROGRAM) {
buf += sizeof(struct rpc_call_header);
for (i = 0; i < 2; i++) {
struct rpc_auth *auth = (struct rpc_auth *)buf;
- if (buf - msg->str + sizeof(struct rpc_auth) > msg->len)
+ if (buf - msg->str + sizeof(struct rpc_auth) > msg->len) {
+ g_atomic_int_add(&outstanding_rpcs, -1);
return FALSE;
+ }
gsize authsize = ntohl(auth->len) + sizeof(struct rpc_auth);
- if (authsize > MAX_RPC_MSGSIZE)
+ if (authsize > MAX_RPC_MSGSIZE) {
+ g_atomic_int_add(&outstanding_rpcs, -1);
return FALSE;
+ }
buf += authsize;
}
- if (buf - msg->str > msg->len)
+ if (buf - msg->str > msg->len) {
+ g_atomic_int_add(&outstanding_rpcs, -1);
return FALSE;
+ }
req->raw_args = msg;
req->raw_args_header_bytes = buf - msg->str;
{
SVCXPRT *transp;
+ rpc_recv_stats = bluesky_stats_new("NFS RPC Messages In");
+ rpc_send_stats = bluesky_stats_new("NFS RPC Messages Out");
+
async_rpc_init();
/* MOUNT protocol */