Exemple #1
0
/* fd is open connection to erlang node */
int ei_reg_dump(int fd, ei_reg *reg, const char *mntab, int flags)
{
  ei_hash *tab;
  erlang_pid self;
  erlang_pid mnesia;
  ei_bucket *b;
  ei_reg_obj *obj;
  const char *key;
  ei_cnode *ec;
  int i;
  
  if (!reg || !mntab) return -1; /* return EI_BADARG; */
  tab = reg->tab;
  
  /* make a self pid */
  
  if ((ec = ei_fd_to_cnode(fd)) == NULL) {
      return -1;
  }
  strcpy(self.node,ei_thisnodename(ec));
  self.num = fd;
  self.serial = 0;
  self.creation = ei_thiscreation(ec);

  if (mn_start_dump(fd,&self,&mnesia,mntab)) return -1;

  /* traverse the table, passing objects to mnesia */
  for (i=0; i<tab->size; i++) {
    b=tab->tab[i];
    while (b) {
      obj = (ei_reg_obj*)(b->value); /* cast to eliminate 'const' warning */
      key = b->key;

      if ((flags & EI_FORCE) || (obj->attr & EI_DIRTY)) {
	if (obj->attr & EI_DELET) {
	  if (mn_send_delete(fd,&mnesia,key)) {
	    ei_send_exit(fd,&self,&mnesia,"delete failed");
	    return -1;
	  }
	}
	else {
	  if (mn_send_write(fd,&mnesia,key,obj)) {
	    ei_send_exit(fd,&self,&mnesia,"update failed");
	    return -1;
	  }
	}
      }
      b = b->next;
    }
  }

  /* end the transaction */
  if (mn_send_commit(fd,&mnesia,&self)) {
    ei_send_exit(fd,&self,&mnesia,"commit failed");
    return -1;
  }

  /* wait for unlink */
  if (mn_get_unlink(fd)) return -1;
  
  /* this point only reached if all went ok so far... */
  
  /* now remove all deleted objects, unless the caller asked us not to */
  if (!(flags & EI_NOPURGE)) ei_reg_purge(reg);

  /* success */
  return 0;

}
Exemple #2
0
int ei_reg_restore(int fd, ei_reg *reg, const char *mntab)
{
  int i,j;
  char tag[32];
  char sbuf[EISMALLBUF];
  char *dbuf = NULL;
  char *msgbuf = NULL;
  char *keybuf = NULL;
  erlang_pid self;
  erlang_pid mnesia = {"",0,0,0};
  erlang_msg msg;
  int index = 0;
  int len = 0;
  int msglen;
  int version = 0;
  int arity = 0;
  long count = 0;
  long maxkey = 0;
  long maxobj = 0;
  ei_cnode *ec;

  if (!reg || !mntab) return -1; /* return EI_BADARG; */

  /* make a self pid */

  if ((ec = ei_fd_to_cnode(fd)) == NULL) {
      return -1;
  }
  strcpy(self.node,ei_thisnodename(ec));
  self.num = fd;
  self.serial = 0;
  self.creation = ei_thiscreation(ec);

  
  if (mn_start_restore(fd,&self,&mnesia,mntab,&count,&maxkey,&maxobj)) {
    /* send exit *only* if we have pid */
    if (mnesia.node[0]) ei_send_exit(fd,&self,&mnesia,"bad response from rpc start");
    return -1;
  }

  if (count <= 0) {
    ei_send_exit(fd,&self,&mnesia,"nothing to do");
    return 0;
  }
  
  /* make sure receive buffer can handle largest expected message */
  len = maxkey + maxobj + 512; 
  if (len > EISMALLBUF)
    if (!(dbuf = malloc(len))) {
      ei_send_exit(fd,&self,&mnesia,"cannot allocate space for incoming data");
      return -1;
    }
  msgbuf = (dbuf ? dbuf : sbuf);

  /* allocate space for largest key */
  if (!(keybuf = malloc(maxkey+1))) goto restore_failure;
  
  /* get this ball rolling */
  index = 0;
  ei_encode_version(msgbuf,&index);
  ei_encode_tuple_header(msgbuf,&index,2);
  ei_encode_atom(msgbuf,&index,"send_records");
  ei_encode_pid(msgbuf,&index,&self);
  if (ei_send_encoded(fd,&mnesia,msgbuf,index)) goto restore_failure;

  /* read as much as possible, until count or EXIT */
  for (i=0; i<count; i++) {
    index = len;
    while ((j = ei_recv_internal(fd,&msgbuf,&index,&msg,&msglen,1,0)) == 0) index = len;
    if (j<0) goto restore_failure;
    
    /* decode the first part of the message */
    index = 0;
    if ((msg.msgtype != ERL_SEND) 
	|| ei_decode_version(msgbuf,&index,&version) 
	|| ei_decode_tuple_header(msgbuf,&index,&arity) 
	|| (arity != 6) 
	|| ei_decode_atom(msgbuf,&index,tag) 
	|| strcmp(tag,EI_MNESIA_RECV)) 
      goto restore_failure;

    /* decode the rest of the message and insert data into table */
    if (mn_decode_insert(reg,msgbuf,&index,keybuf)) goto restore_failure;
  }
  
  if (keybuf) free(keybuf);
  if (dbuf) free(dbuf);

  /* wait for unlink */
  if (mn_unlink(fd)) return -1;

  /* clear all the dirty bits */
  ei_hash_foreach(reg->tab,clean_obj);

  /* success */
  return 0;

restore_failure:
  ei_send_exit(fd,&self,&mnesia,"restore failure");
  if (keybuf) free(keybuf);
  if (dbuf) free(dbuf);
  return -1;
}
Exemple #3
0
short erl_thiscreation(void)
{
    return ei_thiscreation(&erl_if_ec);
}