示例#1
0
文件: champ_server.c 项目: grke/burp
static int champ_chooser_new_client(struct async *as, struct conf **confs)
{
	int fd=-1;
	socklen_t t;
	struct asfd *newfd=NULL;
	struct sockaddr_un remote;
	struct blist *blist=NULL;

	t=sizeof(remote);
	if((fd=accept(as->asfd->fd, (struct sockaddr *)&remote, &t))<0)
	{
		logp("accept error in %s: %s\n", __func__, strerror(errno));
		goto error;
	}

	if(!(blist=blist_alloc())
	  || !(newfd=setup_asfd(as, "(unknown)", &fd, /*listen*/"")))
		goto error;
	newfd->blist=blist;
	newfd->set_timeout(newfd, get_int(confs[OPT_NETWORK_TIMEOUT]));

	logp("Connected to fd %d\n", newfd->fd);

	return 0;
error:
	close_fd(&fd);
	blist_free(&blist);
	return -1;
}
示例#2
0
int backup_phase2_server(struct async *as, struct sdirs *sdirs,
	const char *manifest_dir, int resume, struct conf *conf)
{
	int ret=-1;
	int sigs_end=0;
	int backup_end=0;
	int requests_end=0;
	int blk_requests_end=0;
	struct slist *slist=NULL;
	struct blist *blist=NULL;
	struct iobuf *wbuf=NULL;
	struct dpth *dpth=NULL;
	struct manio *cmanio=NULL;	// current manifest
	struct manio *p1manio=NULL;	// phase1 scan manifest
	struct manio *chmanio=NULL;	// changed manifest
	struct manio *unmanio=NULL;	// unchanged manifest
	// This is used to tell the client that a number of consecutive blocks
	// have been found and can be freed.
	uint64_t wrap_up=0;
	// Main fd is first in the list.
	struct asfd *asfd=as->asfd;
	// Champ chooser fd is second in the list.
	struct asfd *chfd=asfd->next;

	logp("Phase 2 begin (recv backup data)\n");

	//if(champ_chooser_init(sdirs->data, conf)
	if(!(cmanio=manio_alloc())
	  || !(p1manio=manio_alloc())
	  || !(chmanio=manio_alloc())
	  || !(unmanio=manio_alloc())
	  || manio_init_read(cmanio, sdirs->cmanifest)
	  || manio_init_read(p1manio, sdirs->phase1data)
	  || manio_init_write(chmanio, sdirs->changed)
	  || manio_init_write(unmanio, sdirs->unchanged)
	  || !(slist=slist_alloc())
	  || !(blist=blist_alloc())
	  || !(wbuf=iobuf_alloc())
	  || !(dpth=dpth_alloc(sdirs->data))
	  || dpth_init(dpth))
		goto end;

	// The phase1 manifest looks the same as a burp1 one.
	manio_set_protocol(p1manio, PROTO_BURP1);

	while(!backup_end)
	{
		if(maybe_add_from_scan(asfd,
			p1manio, cmanio, unmanio, slist, conf))
				goto end;

		if(!wbuf->len)
		{
			if(get_wbuf_from_sigs(wbuf, slist, blist,
			  sigs_end, &blk_requests_end, dpth, conf))
				goto end;
			if(!wbuf->len)
			{
				get_wbuf_from_files(wbuf, slist,
					p1manio, &requests_end);
			}
		}

		if(wbuf->len)
			asfd->append_all_to_write_buffer(asfd, wbuf);

		append_for_champ_chooser(chfd, blist, sigs_end);

		if(as->read_write(as))
		{
			logp("error in %s\n", __func__);
			goto end;
		}

		while(asfd->rbuf->buf)
		{
			if(deal_with_read(asfd->rbuf, slist, blist,
				conf, &sigs_end, &backup_end, dpth))
					goto end;
			// Get as much out of the
			// readbuf as possible.
			if(asfd->parse_readbuf(asfd)) goto end;
		}
		while(chfd->rbuf->buf)
		{
			if(deal_with_read_from_chfd(asfd, chfd,
				blist, &wrap_up, dpth)) goto end;
			// Get as much out of the
			// readbuf as possible.
			if(chfd->parse_readbuf(chfd)) goto end;
		}

		if(write_to_changed_file(asfd, chfd, chmanio,
			slist, blist, dpth, backup_end, conf))
				goto end;
	}

	// Hack: If there are some entries left after the last entry that
	// contains block data, it will not be written to the changed file
	// yet because the last entry of block data has not had
	// sb->burp2->bend set.
	if(slist->head && slist->head->next)
	{
		slist->head=slist->head->next;
		if(write_to_changed_file(asfd, chfd, chmanio,
			slist, blist, dpth, backup_end, conf))
				goto end;
	}

	if(manio_close(unmanio)
	  || manio_close(chmanio))
		goto end;

	if(blist->head)
	{
		logp("ERROR: finishing but still want block: %lu\n",
			blist->head->index);
		goto end;
	}

	// Need to release the last left. There should be one at most.
	if(dpth->head && dpth->head->next)
	{
		logp("ERROR: More data locks remaining after: %s\n",
			dpth->head->save_path);
		goto end;
	}
	if(dpth_release_all(dpth)) goto end;

	ret=0;
end:
	logp("End backup\n");
	slist_free(slist);
	blist_free(blist);
	iobuf_free_content(asfd->rbuf);
	iobuf_free_content(chfd->rbuf);
	// Write buffer did not allocate 'buf'. 
	if(wbuf) wbuf->buf=NULL;
	iobuf_free(wbuf);
	dpth_release_all(dpth);
	dpth_free(&dpth);
	manio_free(&cmanio);
	manio_free(&p1manio);
	manio_free(&chmanio);
	manio_free(&unmanio);
	return ret;
}
示例#3
0
int backup_phase2_client_burp2(struct asfd *asfd, struct conf *conf, int resume)
{
	int ret=-1;
	int sigs_end=0;
	int backup_end=0;
	int requests_end=0;
	int blk_requests_end=0;
	struct win *win=NULL; // Rabin sliding window.
	struct slist *slist=NULL;
	struct blist *blist=NULL;
	struct iobuf *rbuf=NULL;
	struct iobuf *wbuf=NULL;

	logp("Phase 2 begin (send backup data)\n");

	if(!(slist=slist_alloc())
	  || !(blist=blist_alloc())
	  || !(wbuf=iobuf_alloc())
	  || blks_generate_init(conf)
	  || !(win=win_alloc(&conf->rconf)))
		goto end;
	rbuf=asfd->rbuf;

	if(!resume)
	{
		// Only do this bit if the server did not tell us to resume.
		if(asfd->write_str(asfd, CMD_GEN, "backupphase2")
		  || asfd->read_expect(asfd, CMD_GEN, "ok"))
			goto end;
	}
	else if(conf->send_client_cntr)
	{
		// On resume, the server might update the client with the
		// counters.
		if(cntr_recv(asfd, conf))
			goto end;
        }

	while(!backup_end)
	{
		if(!wbuf->len)
		{
			get_wbuf_from_data(conf, wbuf, slist, blist,
				blk_requests_end);
			if(!wbuf->len)
			{
				get_wbuf_from_blks(wbuf, slist,
					requests_end, &sigs_end);
			}
		}

		if(wbuf->len)
			asfd->append_all_to_write_buffer(asfd, wbuf);
		if(asfd->as->read_write(asfd->as))
		{
			logp("error in %s\n", __func__);
			goto end;
		}

		if(rbuf->buf && deal_with_read(rbuf, slist, blist,
			conf, &backup_end, &requests_end, &blk_requests_end))
				goto end;

		if(slist->head
		// Need to limit how many blocks are allocated at once.
		  && (!blist->head
		   || blist->tail->index - blist->head->index<BLKS_MAX_IN_MEM)
		)
		{
			if(add_to_blks_list(asfd, conf, slist, blist, win))
				goto end;
		}

		if(blk_requests_end)
		{
			// If got to the end of the file request list
			// and the last block of the last file, and
			// the write buffer is empty, we got to the end.
			if(slist->head==slist->tail)
			{
				if(!slist->tail
				  || blist->last_sent==slist->tail->burp2->bend)
				{
					if(!wbuf->len)
						break;
				}
			}

		}
	}

	if(asfd->write_str(asfd, CMD_GEN, "backup_end"))
		goto end;

	ret=0;
end:
blk_print_alloc_stats();
//sbuf_print_alloc_stats();
	win_free(win);
	slist_free(&slist);
	blist_free(&blist);
	// Write buffer did not allocate 'buf'.
	wbuf->buf=NULL;
	iobuf_free(&wbuf);

	cntr_print_end(conf->cntr);
	cntr_print(conf->cntr, ACTION_BACKUP);
	if(ret) logp("Error in backup\n");
	logp("End backup\n");

	return ret;
}