示例#1
0
static
#endif
int do_backup_phase2_server_protocol2(struct async *as, struct asfd *chfd,
	struct sdirs *sdirs, int resume, struct conf **confs)
{
	int ret=-1;
	uint8_t end_flags=0;
	struct slist *slist=NULL;
	struct iobuf wbuf;
	struct dpth *dpth=NULL;
	man_off_t *p1pos=NULL;
	struct manios *manios=NULL;
	// 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;
	struct asfd *asfd=NULL;
	struct cntr *cntr=NULL;
	struct sbuf *csb=NULL;
	uint64_t file_no=1;

	if(!as)
	{
		logp("async not provided to %s()\n", __func__);
		goto end;
	}
	if(!sdirs)
	{
		logp("sdirs not provided to %s()\n", __func__);
		goto end;
	}
	if(!confs)
	{
		logp("confs not provided to %s()\n", __func__);
		goto end;
	}
	asfd=as->asfd;
	if(!asfd)
	{
		logp("asfd not provided to %s()\n", __func__);
		goto end;
	}
	if(!chfd)
	{
		logp("chfd not provided to %s()\n", __func__);
		goto end;
	}
	cntr=get_cntr(confs);
	if(get_int(confs[OPT_BREAKPOINT])>=2000
	  && get_int(confs[OPT_BREAKPOINT])<3000)
	{
		breaking=get_int(confs[OPT_BREAKPOINT]);
		breakcount=breaking-2000;
	}

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

	if(!(dpth=dpth_alloc())
	  || dpth_protocol2_init(dpth,
		sdirs->data,
		get_string(confs[OPT_CNAME]),
		sdirs->cfiles,
		get_int(confs[OPT_MAX_STORAGE_SUBDIRS])))
			goto end;
	if(resume && !(p1pos=do_resume(sdirs, dpth, confs)))
                goto end;

	if(!(manios=manios_open_phase2(sdirs, p1pos, PROTO_2))
	  || !(slist=slist_alloc())
          || !(csb=sbuf_alloc(PROTO_2)))
		goto end;

	iobuf_free_content(asfd->rbuf);

	memset(&wbuf, 0, sizeof(struct iobuf));
	while(!(end_flags&END_BACKUP))
	{
		if(maybe_add_from_scan(manios, slist, chfd, &csb))
			goto end;

		if(!wbuf.len)
		{
			if(get_wbuf_from_sigs(&wbuf, slist, &end_flags))
				goto end;
			if(!wbuf.len)
			{
				get_wbuf_from_files(&wbuf, slist,
					manios, &end_flags, &file_no);
			}
		}

		if(wbuf.len
		 && asfd->append_all_to_write_buffer(asfd, &wbuf)==APPEND_ERROR)
			goto end;

		if(append_for_champ_chooser(chfd, slist->blist, end_flags))
			goto end;

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

		while(asfd->rbuf->buf)
		{
			if(deal_with_read(asfd->rbuf, slist, cntr,
				&end_flags, 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(chfd,
				slist->blist, &wrap_up, dpth, cntr))
					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, manios,
			slist, end_flags))
				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->protocol2->bend set.
	if(slist->head && slist->head->next)
	{
		struct sbuf *sb=NULL;
		sb=slist->head;
		slist->head=sb->next;
		sbuf_free(&sb);
		if(write_to_changed_file(asfd, chfd, manios,
			slist, end_flags))
				goto end;
	}

	if(manios_close(&manios))
		goto end;

	if(check_for_missing_work_in_slist(slist))
		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");
	sbuf_free(&csb);
	slist_free(&slist);
	if(asfd) iobuf_free_content(asfd->rbuf);
	if(chfd) iobuf_free_content(chfd->rbuf);
	dpth_free(&dpth);
	manios_close(&manios);
	man_off_t_free(&p1pos);
	return ret;
}
示例#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;
}