diff options
Diffstat (limited to 'glusterfs-guts/src/guts-parse.c')
| -rw-r--r-- | glusterfs-guts/src/guts-parse.c | 217 | 
1 files changed, 217 insertions, 0 deletions
diff --git a/glusterfs-guts/src/guts-parse.c b/glusterfs-guts/src/guts-parse.c new file mode 100644 index 00000000000..dd17a737ebb --- /dev/null +++ b/glusterfs-guts/src/guts-parse.c @@ -0,0 +1,217 @@ +/* +   Copyright (c) 2008 Z RESEARCH, Inc. <http://www.zresearch.com> +   This file is part of GlusterFS. + +   GlusterFS is free software; you can redistribute it and/or modify +   it under the terms of the GNU General Public License as published +   by the Free Software Foundation; either version 3 of the License, +   or (at your option) any later version. + +   GlusterFS is distributed in the hope that it will be useful, but +   WITHOUT ANY WARRANTY; without even the implied warranty of +   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU +   General Public License for more details. + +   You should have received a copy of the GNU General Public License +   along with this program.  If not, see <http://www.gnu.org/licenses/>. +*/ + +#include "guts-parse.h" +#include "guts-tables.h" + +/* unavoidable usage of global data.. :'( */ +static int32_t tio_fd = 0; + +int32_t +guts_tio_init (const char *filename) +{ +  tio_fd = open (filename, O_WRONLY | O_CREAT); +   +  if (tio_fd < 0) { +    gf_log ("guts", +	    GF_LOG_ERROR, +	    "failed to open tio file %s", filename); +  } +   +  return tio_fd; +} + +void +guts_reply_dump (fuse_req_t req, +		 const void *arg, +		 int32_t len) +{ +  uint8_t *buf = NULL; +  uint8_t *ibuf = NULL; +  uint32_t buf_size = REP_HEADER_FULL_LEN + len; + +  ibuf = buf = CALLOC (1, buf_size); +   +  /* being paranoid, checking for both ibuf and buf.. ;) */ +  if (ibuf && buf) { +    memcpy (ibuf, REP_BEGIN, strlen (REP_BEGIN)); +    ibuf += strlen (REP_BEGIN); +    memcpy (ibuf, req, sizeof (struct fuse_req)); +    ibuf += sizeof (struct fuse_req); +    memcpy (ibuf, &len, sizeof (len)); +    ibuf += sizeof (len); +    memcpy (ibuf, arg, len); +   +    gf_full_write (tio_fd, buf, buf_size); +     +    free (buf); +  } else { +    gf_log ("glusterfs-guts", GF_LOG_DEBUG, +	    "failed to allocate memory while dumping reply"); +  } +} + +void +guts_req_dump (struct fuse_in_header *in, +	       const void *arg, +	       int32_t len) +{ +  /* GUTS_REQUEST_BEGIN:<fuse_in_header>:<arg-len>:<args>:GUTS_REQUEST_END */ +  uint8_t *buf = NULL; +  uint8_t *ibuf = NULL; +  uint32_t buf_size = REQ_HEADER_FULL_LEN + len; + +  ibuf = buf = CALLOC (1, buf_size); +   +  if (ibuf && buf) { +    memcpy (ibuf, REQ_BEGIN, strlen (REQ_BEGIN)); +    ibuf += strlen (REQ_BEGIN); +    memcpy (ibuf, in, sizeof (*in)); +    ibuf += sizeof (*in); +    memcpy (ibuf, &len, sizeof (len)); +    ibuf += sizeof (len); +    memcpy (ibuf, arg, len); +     +    gf_full_write (tio_fd, buf, buf_size); +     +    free (buf); +  } else { +    gf_log ("glusterfs-guts", GF_LOG_DEBUG, +	    "failed to allocate memory while dumping reply"); +  } +} + + + +guts_req_t * +guts_read_entry (guts_replay_ctx_t *ctx) +{ +  guts_req_t *req = NULL; +  guts_reply_t *reply = NULL; +  uint8_t begin[256] = {0,}; +  int32_t ret = 0; +  int32_t fd = ctx->tio_fd; + +  while (!req) { +    req = guts_get_request (ctx); +     +    if (!req) { +      ret = read (fd, begin, strlen (REQ_BEGIN)); +       +      if (ret == 0) { +	gf_log ("glusterfs-guts", GF_LOG_DEBUG,  +		"guts replay finished"); +	req = NULL; +      } +       +      if (is_request (begin)) { +	req = CALLOC (1, sizeof (*req)); +	ERR_ABORT (req); +	gf_full_read (fd, (char *)req, REQ_HEADER_LEN); +	 +	req->arg = CALLOC (1, req->arg_len + 1); +	ERR_ABORT (req->arg); +	gf_full_read (fd, req->arg, req->arg_len); +	gf_log ("guts", +		GF_LOG_DEBUG, +		"%s: fop %s (%d)\n",  +		begin, guts_log[req->header.opcode].name, req->header.opcode); +	guts_add_request (ctx, req); +	req = guts_get_request (ctx); +      } else { +	/* whenever a reply is read, we put it to a hash table and we would like to retrieve it whenever +	 * we get a reply for any call +	 */ +	reply = CALLOC (1, sizeof (*reply)); +	ERR_ABORT (reply); +	gf_full_read (fd, (char *)reply, REP_HEADER_LEN); +	 +	reply->arg = CALLOC (1, reply->arg_len + 1); +	ERR_ABORT (reply->arg); +	gf_full_read (fd, reply->arg, reply->arg_len); +	 +	/* add a new reply to */ +	ret = guts_add_reply (ctx, reply); +	gf_log ("guts", +		GF_LOG_DEBUG, +		"got a reply with unique: %ld", reply->req.unique); +      } +    } +  } +  return req; +} + +guts_reply_t * +guts_read_reply (guts_replay_ctx_t *ctx, +		 uint64_t unique) +{ +  guts_req_t *req = NULL; +  guts_reply_t *reply = NULL, *rep = NULL; +  uint8_t begin[256] = {0,}; +  int32_t ret = 0; +  int32_t fd = ctx->tio_fd; + +  while (!rep) { +     +    ret = read (fd, begin, strlen (REQ_BEGIN)); +     +    if (ret == 0) { +      printf ("\ndone\n"); +      return NULL; +    } +     +    if (is_request (begin)) { +      req = CALLOC (1, sizeof (*req)); +      ERR_ABORT (req); +      gf_full_read (fd, (char *)req, REQ_HEADER_LEN); +       +      req->arg = CALLOC (1, req->arg_len + 1); +      ERR_ABORT (req->arg); +      gf_full_read (fd, req->arg, req->arg_len); +      gf_log ("guts", +	      GF_LOG_DEBUG, +	      "%s: fop %s (%d)\n",  +	      begin, guts_log[req->header.opcode].name, req->header.opcode); +       +      ret = guts_add_request (ctx, req); +       +    } else { +      /* whenever a reply is read, we put it to a hash table and we would like to retrieve it whenever +       * we get a reply for any call +       */ +      reply = CALLOC (1, sizeof (*reply)); +      ERR_ABORT (reply); +      gf_full_read (fd, (char *)reply, REP_HEADER_LEN); +       +      reply->arg = CALLOC (1, reply->arg_len + 1); +      ERR_ABORT (reply->arg); +      gf_full_read (fd, reply->arg, reply->arg_len); +       +      /* add a new reply to */ +      if (reply->req.unique == unique) { +	return reply; +      } else { +	ret = guts_add_reply (ctx, reply); +	gf_log ("guts", +		GF_LOG_DEBUG, +		"got a reply with unique: %ld", reply->req.unique); +      } +    } +  } +  return NULL; +}  | 
