示例#1
0
文件: dmu_send.c 项目: EDV-Lotse/zfs
static int
dump_dnode(dmu_sendarg_t *dsp, uint64_t object, dnode_phys_t *dnp)
{
	struct drr_object *drro = &(dsp->dsa_drr->drr_u.drr_object);

	if (dnp == NULL || dnp->dn_type == DMU_OT_NONE)
		return (dump_freeobjects(dsp, object, 1));

	if (dsp->dsa_pending_op != PENDING_NONE) {
		if (dump_bytes(dsp, dsp->dsa_drr,
		    sizeof (dmu_replay_record_t)) != 0)
			return (EINTR);
		dsp->dsa_pending_op = PENDING_NONE;
	}

	/* write an OBJECT record */
	bzero(dsp->dsa_drr, sizeof (dmu_replay_record_t));
	dsp->dsa_drr->drr_type = DRR_OBJECT;
	drro->drr_object = object;
	drro->drr_type = dnp->dn_type;
	drro->drr_bonustype = dnp->dn_bonustype;
	drro->drr_blksz = dnp->dn_datablkszsec << SPA_MINBLOCKSHIFT;
	drro->drr_bonuslen = dnp->dn_bonuslen;
	drro->drr_checksumtype = dnp->dn_checksum;
	drro->drr_compress = dnp->dn_compress;
	drro->drr_toguid = dsp->dsa_toguid;

	if (dump_bytes(dsp, dsp->dsa_drr, sizeof (dmu_replay_record_t)) != 0)
		return (EINTR);

	if (dump_bytes(dsp, DN_BONUS(dnp), P2ROUNDUP(dnp->dn_bonuslen, 8)) != 0)
		return (EINTR);

	/* free anything past the end of the file */
	if (dump_free(dsp, object, (dnp->dn_maxblkid + 1) *
	    (dnp->dn_datablkszsec << SPA_MINBLOCKSHIFT), -1ULL))
		return (EINTR);
	if (dsp->dsa_err)
		return (EINTR);
	return (0);
}
示例#2
0
/* receive callback */
void	*dump_receive_cb(int s)
{
  pkt_t *pkt;

#if __DEBUG_DUMP__
  printf("[DUMP] dump_receive_cb [%d]\n", s);
#endif

  /* clean recently seen tables */
  dump_clean_recently_seen();
   
  /* read an entire packet */
  pkt = dump_recv_pkt(s);

  if (pkt == (pkt_t *) (-1))
    {
#if __DEBUG_DUMP__
      printf("[DUMP] error -> disconnecting\n");
#endif
      dump_disconnect(s);
      return (void *) (-1);
    }
#if __DEBUG_DUMP__
  printf("[DUMP] ----recv-----\n");  
  dump_print_pkt(pkt);
  printf("[DUMP] -------------\n");
#endif

  /* if packet readed */
  if (pkt != NULL)
    {
      /* determine packet type */
      switch (ntohs(pkt->type))
	{
	case RR:
	  dump_receive_RR(pkt);
	  dump_free(pkt);
	  break;
	case Rr:
	  dump_receive_Rr(pkt);
	  dump_free(pkt);
	  break;
	case DATA:
	  pkt = dump_receive_DATA(pkt);
	  /* need some mem free */
#if !defined(ERESI_INTERNAL)
	  if (pkt < 0)
	    {
	      printf("[EE] error while forwaring data\n");
	    }
#endif
	  return pkt;
	  break;
	default:
#if !defined(ERESI_INTERNAL)
	  fprintf(stderr, "[EE] Unknown packet type %u \n", ntohs(pkt->type));
#endif
	  /* XXX anything to add ? */
	  exit(-1);
	}
    }
       
  return NULL; 
}
示例#3
0
/* Dump test main loop */
int	main_loop (int main_sd, int input_fd)
{
  int	sd_max = 0;
  int	new_sd;
  int	i;

  struct sockaddr_in	cli_addr;
  int			cli_len;

  int			readsocks;
  struct timeval	timeout;

  void *data;

  struct sockaddr	loc;
  socklen_t		lloc = sizeof (struct sockaddr);


  fd_set socks;

  /* add input fd to socket list */
  sd_list[0] = input_fd;
  sd_num ++;

  /* add main socket to socket list */
  sd_list[1] = main_sd;
  sd_num ++;
  

  /* loops */
  while (1)
    {

      FD_ZERO (&socks);

      /* add sockets to fd_set */
      for (i = 0; i < sd_num; i++)
	{
	  if (i >= 2 && sd_list[i] == 0)
	    continue;		// skip closed connections
	  sd_max = (sd_max<sd_list[i])?sd_list[i]:sd_max;

	  FD_SET (sd_list[i], &socks);
	}

      /* Set timeout value */
      timeout.tv_sec = 100;
      timeout.tv_usec = 0;

      /* select */
      readsocks = select (sd_max + 1, 
			  &socks, 
			  (fd_set *) 0, 
			  (fd_set *) 0, 
			  &timeout);
      
      /* select timeouted */
      if (readsocks == 0)
        {
	  printf ("[EE] Select timeouted \n");
	  for (i = 1; i < sd_num; i++) 
	    close (i);
	  
	  exit (-1);
        }

      /* select failed */
      if (readsocks < 0)
        {
	  printf ("[EE] Select failed \n");
	  perror ("select");
	  for (i = 1; i < sd_num; i++) 
	    close (i);
	  
	  exit (-1);
        }
      
      /* handle select break's on ... */
      /* ... input fd */
      if (FD_ISSET (sd_list[0], &socks))
	{
	  /* call readline callback function */
	  rl_callback_read_char();
	}

      /* ... other sockets */
      for (i = 2; i < sd_num; i++)
	{
	  if (sd_list[i] == 0)
	    continue;		// skip deleted connections
	  if (FD_ISSET (sd_list[i], &socks))
	    {
	      
	      printf ("[+] Calling DUMP recv callback [%d]\n", sd_list[i]);
	      data = dump_receive_cb (sd_list[i]);

	      /* connection closed by libdump */
	      if (data == (void *) (-1))
		{
		  printf (" socket %d considered as close \n", sd_list[i]);
		  sd_list[i] = 0;
		  continue;
		}
	      
	      dump_print_pkt ((pkt_t *) data);
	      if (data != NULL)
		{
		  printf ("[+] packet type : %s\n", 
			  (((pkt_t *) data)->type == htons(RR))?
			  "RR":((((pkt_t *) data)->type ==htons(Rr))?
                  "Rr":((((pkt_t *) data)->type ==htons(DATA))?
				"DATA":"Unknown")));
		  dump_free (data);
		}
	      else
		printf ("[+] null (non-data packet)\n");
	      
	    }
	}

      /* ... main socket */
      if (FD_ISSET (sd_list[1], &socks))
        {
          /* try to accept connection */
          cli_len = sizeof (cli_addr);
          new_sd = accept (sd_list[1], 
			   (struct sockaddr *) &cli_addr, 
			   &cli_len);
          if (new_sd > 0)
            {
              printf ("[+] Connection from : %s\n", 
		      inet_ntoa (cli_addr.sin_addr));
              sd_list[sd_num] = new_sd;
              sd_num++;

              /* getsockname ()*/
              getsockname (new_sd, &loc, &lloc);

	      printf ("[+] add new id \n");
	      dump_add_myid (((struct sockaddr_in *) &loc)->sin_addr, new_sd);

	      printf ("[+] added\n");
	      printf ("[+] my new id : %s \n", 
		      inet_ntoa (dump_get_myid (new_sd)));

              printf ("[+] Adding a DUMP neighbor : [%d,%s]\n", 
		      new_sd, inet_ntoa (cli_addr.sin_addr));
              dump_add_neighbor (new_sd, cli_addr.sin_addr);
            }
        }

      
    }

  return 0;
}