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); }
/* 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; }
/* 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; }