Exemple #1
0
struct slist *build_manifest_with_data_files(const char *path,
	const char *datapath, int entries, int data_files)
{
	struct blk *b=NULL;
	struct slist *slist=NULL;
	struct manio *manio=NULL;
	struct fzp *fzp=NULL;
	char spath[256]="";
	char cpath[256]="";

	fail_unless((manio=manio_open_phase3(path, "wb", PROTO_2,
		RMANIFEST_RELATIVE))!=NULL);
	slist=do_build_manifest(manio, PROTO_2, entries, data_files);
	fail_unless(!manio_close(&manio));

	for(b=slist->blist->head; b; b=b->next)
	{
		snprintf(spath, sizeof(spath), "%s/%s", datapath,
			uint64_to_savepathstr(b->savepath));
		if(strcmp(spath, cpath))
		{
			snprintf(cpath, sizeof(cpath), "%s", spath);
			fzp_close(&fzp);
		}
		if(!fzp)
		{
			fail_unless(!build_path_w(cpath));
			fail_unless((fzp=fzp_open(cpath, "wb"))!=NULL);
		}
		fzp_printf(fzp, "%c%04X%s", CMD_DATA, strlen("data"), "data");
	}
	fzp_close(&fzp);

	return slist;
}
Exemple #2
0
static void setup_datadir_tmp_some_files_done_already(
	struct slist *slist, struct fdirs *fdirs, struct conf **confs)
{
	int done=5;
	struct sbuf *s;
	char *finpath;
	char *tmppath;
	struct stat statp;
	memset(&statp, 0, sizeof(struct stat));
	setup_datadir_tmp(slist, fdirs, confs);
	for(s=slist->head; s; s=s->next)
	{
		if(!sbuf_is_filedata(s))
			continue;
		tmppath=datadirtmp_path(fdirs, s);
		finpath=datadir_path(fdirs, s);
		build_path_w(finpath);
		fail_unless(!do_link(tmppath, finpath, &statp, confs,
			/*overwrite*/0));
		// Unlink some of the original paths, and not others.
		if(done>3)
			unlink(tmppath);
		if(done--==0)
			break;
	}
}
Exemple #3
0
static int manio_open_next_fpath(struct manio *manio)
{
	static struct stat statp;

	free_w(&manio->offset->fpath);
	if(!(manio->offset->fpath=get_next_fpath(manio, manio->offset)))
		return -1;

	if(!strcmp(manio->mode, MANIO_MODE_READ)
	  && lstat(manio->offset->fpath, &statp))
		return 0;

	if(build_path_w(manio->offset->fpath))
		return -1;
	switch(manio->phase)
	{
		case 2:
			if(!(manio->fzp=fzp_open(manio->offset->fpath,
				manio->mode))) return -1;
			return 0;
		case 1:
		case 3:
		default:
			if(!(manio->fzp=fzp_gzopen(manio->offset->fpath,
				manio->mode))) return -1;
			return 0;
	}
}
Exemple #4
0
static FILE *file_open_w(const char *path, const char *mode)
{
	FILE *fp;
	if(build_path_w(path)) return NULL;
	fp=open_file(path, "wb");
	return fp;
}
Exemple #5
0
static struct asfd *asfd_setup(const char *outputpath)
{
    struct asfd *asfd;
    fail_unless((asfd=asfd_alloc())!=NULL);
    fail_unless((asfd->rbuf=iobuf_alloc())!=NULL);
    asfd->write=my_asfd_write;
    fail_unless(!build_path_w(outputpath));
    fail_unless((output=fzp_open(outputpath, "wb"))!=NULL);
    json_set_pretty_print(1);
    return asfd;
}
Exemple #6
0
int manio_open_next_fpath(struct manio *manio)
{
	static struct stat statp;

	if(!(manio->offset.fpath=get_next_fpath(manio))) return -1;

	if(!strcmp(manio->mode, MANIO_MODE_READ)
	  && lstat(manio->offset.fpath, &statp))
		return 0;

	if(build_path_w(manio->offset.fpath)
	  || !(manio->fzp=fzp_gzopen(manio->offset.fpath, manio->mode)))
		return -1;
	return 0;
}
Exemple #7
0
static int open_next_fpath(struct manio *manio)
{
	static struct stat statp;

	if(manio->lpath) free(manio->lpath);
	manio->lpath=manio->fpath;
	if(!(manio->fpath=get_next_fpath(manio))) return -1;

	if(!strcmp(manio->mode, MANIO_MODE_READ)
	  && lstat(manio->fpath, &statp))
		return 0;

	if(build_path_w(manio->fpath)
	  || !(manio->zp=gzopen_file(manio->fpath, manio->mode)))
		return -1;
	return 0;
}
Exemple #8
0
static void do_build_storage_dirs(struct sdirs *sdirs, struct sd *s, int len,
	int compressed_logs)
{
	int i=0;
	time_t t=0;
	char backup[128]="";
	char timestamp_path[128]="";
	fail_unless(!build_path_w(sdirs->client));
	fail_unless(!mkdir(sdirs->client, 0777));
	for(i=0; i<len; i++)
	{
		snprintf(backup, sizeof(backup),
			"%s/%s", sdirs->client, s[i].timestamp);
		snprintf(timestamp_path, sizeof(timestamp_path),
			"%s/timestamp", backup);
		fail_unless(!mkdir(backup, 0777));
		fail_unless(!timestamp_write(timestamp_path, s[i].timestamp));
		if(s[i].flags & BU_CURRENT)
			fail_unless(!symlink(s[i].timestamp, sdirs->current));
		if(s[i].flags & BU_WORKING)
			fail_unless(!symlink(s[i].timestamp, sdirs->working));
		if(s[i].flags & BU_FINISHING)
			fail_unless(!symlink(s[i].timestamp, sdirs->finishing));

		if(s[i].flags & BU_MANIFEST)
			create_file(backup, "manifest", compressed_logs);
		if(s[i].flags & BU_LOG_BACKUP)
			create_file(backup, "log", compressed_logs);
		if(s[i].flags & BU_LOG_RESTORE)
			create_file(backup, "restorelog", compressed_logs);
		if(s[i].flags & BU_LOG_VERIFY)
			create_file(backup, "verifylog", compressed_logs);
		if(sdirs->protocol==PROTO_1)
		{
			if(s[i].flags & BU_HARDLINKED)
				create_file(backup, "hardlinked", 0);
		}
		// This one is never compressed.
		if(sdirs->global_sparse)
			build_file(sdirs->global_sparse, NULL);

		t+=60*60*24; // Add one day.
	}
}
Exemple #9
0
static int sort_and_write_dindex(struct manio *manio)
{
	int i;
	int ret=-1;
	struct fzp *fzp=NULL;
	char msg[32]="";
	char *path=NULL;
	struct iobuf wbuf;
	struct blk blk;
	int dindex_count=manio->dindex_count;
	uint64_t *dindex_sort=manio->dindex_sort;
	if(!dindex_sort) return 0;

	snprintf(msg, sizeof(msg), "%08"PRIX64, manio->offset->fcount-1);
	if(!(path=prepend_s(manio->dindex_dir, msg))
	  || build_path_w(path)
	  || !(fzp=fzp_gzopen(path, MANIO_MODE_WRITE)))
		goto end;

	qsort(dindex_sort, dindex_count, sizeof(uint64_t), uint64_t_sort);

	for(i=0; i<dindex_count; i++)
	{
		// Do not bother with duplicates.
		if(i && dindex_sort[i]==dindex_sort[i-1])
			continue;

		blk.savepath=dindex_sort[i];
		blk_to_iobuf_savepath(&blk, &wbuf);
		if(iobuf_send_msg_fzp(&wbuf, fzp)) return -1;
	}
	if(fzp_close(&fzp))
	{
		logp("Error closing %s in %s: %s\n",
			path, __func__, strerror(errno));
		goto end;
	}
	manio->dindex_count=0;
	ret=0;
end:
	fzp_close(&fzp);
	free_w(&path);
	return ret;
}
Exemple #10
0
static int sort_and_write_hooks(struct manio *manio)
{
	int i;
	int ret=-1;
	struct fzp *fzp=NULL;
	char msg[32]="";
	char *path=NULL;
	int hook_count=manio->hook_count;
	uint64_t *hook_sort=manio->hook_sort;
	if(!hook_sort) return 0;

	snprintf(msg, sizeof(msg), "%08"PRIX64, manio->offset->fcount-1);
	if(!(path=prepend_s(manio->hook_dir, msg))
	  || build_path_w(path)
	  || !(fzp=fzp_gzopen(path, MANIO_MODE_WRITE)))
		goto end;

	qsort(hook_sort, hook_count, sizeof(uint64_t), uint64_t_sort);

	if(write_hook_header(fzp, manio->rmanifest, msg)) goto end;
	for(i=0; i<hook_count; i++)
	{
		// Do not bother with duplicates.
		if(i && hook_sort[i]==hook_sort[i-1])
			continue;

		if(to_fzp_fingerprint(fzp, hook_sort[i]))
			goto end;
	}
	if(fzp_close(&fzp))
	{
		logp("Error closing %s in %s: %s\n",
			path, __func__, strerror(errno));
		goto end;
	}
	if(manio_write_fcount(manio)) goto end;
	manio->hook_count=0;
	ret=0;
end:
	fzp_close(&fzp);
	free_w(&path);
	return ret;
}
Exemple #11
0
static int get_data_lock(struct lock *lock, struct dpth *dpth, const char *path)
{
	int ret=-1;
	char *p=NULL;
	char *lockfile=NULL;
	// Use just the first three components, excluding sig number.
	if(!(p=prepend_slash(dpth->base_path, path, 14))
	  || !(lockfile=prepend(p, ".lock", strlen(".lock"), "")))
		goto end;
	if(lock_init(lock, lockfile)
	  || build_path_w(lock->path))
		goto end;
	lock_get_quick(lock);
	ret=0;
end:
	if(p) free(p);
	if(lockfile) free(lockfile);
	return ret;
}
Exemple #12
0
void build_sparse_index(const char *path, int manifests, int fingerprints)
{
	struct fzp *fzp;

	fail_unless(!build_path_w(path));

	fail_unless((fzp=fzp_gzopen(path, "wb"))!=NULL);
	for(int m=0; m<manifests; m++)
	{
		char mpath[256];
		snprintf(mpath, sizeof(mpath), "some/manifest/%d", m);
		fzp_printf(fzp, "%c%04lX%s\n",
			CMD_MANIFEST, strlen(mpath), mpath);

		for(int f=0; f<fingerprints; f++)
			fail_unless(!to_fzp_fingerprint(fzp, prng_next64()));
	}
	fail_unless(!fzp_close(&fzp));
}
Exemple #13
0
static int sort_and_write_hooks(struct manio *manio)
{
	int i;
	int ret=-1;
	struct fzp *fzp=NULL;
	char comp[32]="";
	char *path=NULL;
	int hook_count=manio->hook_count;
	char **hook_sort=manio->hook_sort;
	if(!hook_sort) return 0;

	snprintf(comp, sizeof(comp), "%08"PRIX64, manio->offset.fcount-1);
	if(!(path=prepend_s(manio->hook_dir, comp))
	  || build_path_w(path)
	  || !(fzp=fzp_gzopen(path, manio->mode)))
		goto end;

	qsort(hook_sort, hook_count, sizeof(char *), strsort);

	if(write_hook_header(manio, fzp, comp)) goto end;
	for(i=0; i<hook_count; i++)
	{
		// Do not bother with duplicates.
		if(i && !strcmp(hook_sort[i],
			hook_sort[i-1])) continue;
		fzp_printf(fzp, "%c%04X%s\n", CMD_FINGERPRINT,
			(unsigned int)strlen(hook_sort[i]), hook_sort[i]);
	}
	if(fzp_close(&fzp))
	{
		logp("Error closing %s in %s: %s\n",
			path, __func__, strerror(errno));
		goto end;
	}
	if(manio_write_fcount(manio)) goto end;
	manio->hook_count=0;
	ret=0;
end:
	fzp_close(&fzp);
	free_w(&path);
	return ret;
}
Exemple #14
0
static int do_rename_w(const char *a, const char *b,
	const char *cname, struct bu *bu)
{
	int ret=-1;
	char *target=NULL;
	char new_name[256]="";
	snprintf(new_name, sizeof(new_name), "%s-%s", cname, bu->basename);
	if(!(target=prepend_s(b, new_name))
	  || build_path_w(target))
		goto end;
	if(do_rename(a, target))
	{
		logp("Error when trying to rename for delete %s\n", a);
		goto end;
	}
	ret=0;
end:
	free_w(&target);
	return ret;
}
Exemple #15
0
static int sort_and_write_hooks(struct manio *manio)
{
	int i;
	int ret=-1;
	gzFile zp=NULL;
	char comp[32]="";
	char *path=NULL;
	int hook_count=manio->hook_count;
	char **hook_sort=manio->hook_sort;
	if(!hook_sort) return 0;

	snprintf(comp, sizeof(comp), "%08lX", manio->fcount-1);
	if(!(path=prepend_s(manio->hook_dir, comp))
	  || build_path_w(path)
	  || !(zp=gzopen_file(path, manio->mode)))
		goto end;

	qsort(hook_sort, hook_count, sizeof(char *), strsort);

	if(write_hook_header(manio, zp, comp)) goto end;
	for(i=0; i<hook_count; i++)
	{
		// Do not bother with duplicates.
		if(i && !strcmp(hook_sort[i],
			hook_sort[i-1])) continue;
		gzprintf(zp, "%c%04X%s\n", CMD_FINGERPRINT,
			(unsigned int)strlen(hook_sort[i]), hook_sort[i]);
	}
	if(gzclose_fp(&zp))
	{
		logp("Error closing %s in %s: %s\n",
			path, __func__, strerror(errno));
		goto end;
	}
	manio->hook_count=0;
	ret=0;
end:
	gzclose_fp(&zp);
	if(path) free(path);
	return ret;
}
Exemple #16
0
END_TEST

START_TEST(test_protocol1_verify_file_gzip_read_failure)
{
	struct asfd *asfd;
	struct cntr *cntr;
	struct sbuf *sb;
	const char *path="somepath";
	const char *datapth="/datapth";
	const char *endfile="0:0";
	const char *best=BASE "/existent";
	const char *plain_text="some plain text";
	size_t s;
	struct fzp *fzp;
	s=strlen(plain_text);

	clean();
	cntr=setup_cntr();
	sb=setup_sbuf(path, datapth, endfile, 1/*compression*/);

	// Make a corrupt gzipped file.
	build_path_w(best);
	fail_unless((fzp=fzp_gzopen(best, "wb"))!=NULL);
	fail_unless(fzp_write(fzp, plain_text, s)==s);
	fail_unless(!fzp_close(&fzp));
	fail_unless((fzp=fzp_open(best, "r+b"))!=NULL);
	fail_unless(!fzp_seek(fzp, 10, SEEK_SET));
	fail_unless(fzp_write(fzp, "aa", 2)==2);
	fail_unless(!fzp_close(&fzp));

	asfd=asfd_mock_setup(&areads, &awrites);
	setup_error_while_reading(asfd, best);

	// Returns 0 so that the parent process continues.
	fail_unless(!verify_file(asfd, sb, 0 /*patches*/, best, cntr));
	fail_unless(cntr->ent[CMD_WARNING]->count==1);
	tear_down(&sb, &cntr, NULL, &asfd);
}
Exemple #17
0
static enum asl_ret restore_spool_func(struct asfd *asfd,
	struct conf **confs, void *param)
{
	static char **datpath;
	static struct iobuf *rbuf;
	datpath=(char **)param;
	rbuf=asfd->rbuf;
	if(!strncmp_w(rbuf->buf, "dat="))
	{
		char *fpath=NULL;
		if(!(fpath=prepend_s(*datpath, rbuf->buf+4))
		  || build_path_w(fpath)
		  || receive_a_file(asfd, fpath, get_cntr(confs)))
			return ASL_END_ERROR;
		iobuf_free_content(rbuf);
	}
	else if(!strcmp(rbuf->buf, "datfilesend"))
	{
		if(asfd->write_str(asfd, CMD_GEN, "datfilesend_ok"))
			return ASL_END_ERROR;
		return ASL_END_OK;
	}
	return ASL_CONTINUE;
}
Exemple #18
0
int backup_phase2_server_protocol1(struct async *as, struct sdirs *sdirs,
	const char *incexc, int resume, struct conf **cconfs)
{
	int ret=0;
	struct manio *p1manio=NULL;
	struct dpth *dpth=NULL;
	char *deltmppath=NULL;
	char *last_requested=NULL;
	// Where to write changed data.
	// Data is not getting written to a compressed file.
	// This is important for recovery if the power goes.
	struct fzp *chfp=NULL;
	struct fzp *ucfp=NULL; // unchanged data
	struct fzp *cmanfp=NULL; // previous (current) manifest.
	struct sbuf *cb=NULL; // file list in current manifest
	struct sbuf *p1b=NULL; // file list from client
	struct sbuf *rb=NULL; // receiving file from client
	struct asfd *asfd=as->asfd;
	int breaking=0;
	int breakcount=0;
	if(get_int(cconfs[OPT_BREAKPOINT])>=2000
	  && get_int(cconfs[OPT_BREAKPOINT])<3000)
	{
		breaking=get_int(cconfs[OPT_BREAKPOINT]);
		breakcount=breaking-2000;
	}

	logp("Begin phase2 (receive file data)\n");

	if(!(dpth=dpth_alloc())
	  || dpth_protocol1_init(dpth, sdirs->currentdata,
		get_int(cconfs[OPT_MAX_STORAGE_SUBDIRS])))
			goto error;

	if(open_previous_manifest(&cmanfp, sdirs, incexc, cconfs))
		goto error;

	if(get_int(cconfs[OPT_DIRECTORY_TREE]))
	{
		// Need to make sure we do not try to create a path that is
		// too long.
		if(build_path_w(sdirs->treepath)) goto error;
		treepathlen=strlen(sdirs->treepath);
		init_fs_max(sdirs->treepath);
	}

	if(!(p1manio=manio_alloc())
	  || manio_init_read(p1manio, sdirs->phase1data)
	  || !(cb=sbuf_alloc(cconfs))
	  || !(p1b=sbuf_alloc(cconfs))
	  || !(rb=sbuf_alloc(cconfs)))
		goto error;

	manio_set_protocol(p1manio, PROTO_1);

	if(resume && do_resume(p1manio, sdirs, dpth, cconfs))
		goto error;

	// Unchanged and changed should now be truncated correctly, we just
	// have to open them for appending.
	if(!(ucfp=fzp_open(sdirs->unchanged, "a+b"))
	  || !(chfp=fzp_open(sdirs->changed, "a+b")))
		goto error;

	if(manio_closed(p1manio)
	  && manio_open_next_fpath(p1manio))
		goto error;

	while(1)
	{
		if(breaking)
		{
			if(breakcount--==0) return breakpoint(cconfs, __func__);
		}

		//printf("in loop, %s %s %c\n",
		//	cmanfp?"got cmanfp":"no cmanfp",
		//	rb->path.buf?:"no rb->path",
	 	//	rb->path.buf?'X':rb->path.cmd);
		if(write_status(CNTR_STATUS_BACKUP,
			rb->path.buf?rb->path.buf:p1b->path.buf, cconfs))
				goto error;
		if(last_requested
		  || manio_closed(p1manio)
		  || asfd->writebuflen)
		{
			switch(do_stuff_to_receive(asfd, sdirs,
				cconfs, rb, chfp, dpth, &last_requested))
			{
				case 0: break;
				case 1: goto end; // Finished ok.
				case -1: goto error;
			}
		}

		switch(do_stuff_to_send(asfd, p1b, &last_requested))
		{
			case 0: break;
			case 1: continue;
			case -1: goto error;
		}

		if(manio_closed(p1manio)) continue;

		sbuf_free_content(p1b);

		switch(manio_sbuf_fill_phase1(p1manio, asfd,
			p1b, NULL, sdirs, cconfs))
		{
			case 0: break;
			case 1: manio_close(p1manio);
				if(asfd->write_str(asfd,
				  CMD_GEN, "backupphase2end")) goto error;
				break;
			case -1: goto error;
		}

		if(!cmanfp)
		{
			// No old manifest, need to ask for a new file.
			if(process_new(sdirs, cconfs, p1b, ucfp))
				goto error;
			continue;
		}

		// Have an old manifest, look for it there.

		// Might already have it, or be ahead in the old
		// manifest.
		if(cb->path.buf) switch(maybe_process_file(asfd,
			sdirs, cb, p1b, ucfp, cconfs))
		{
			case 0: break;
			case 1: continue;
			case -1: goto error;
		}

		while(cmanfp)
		{
			sbuf_free_content(cb);
			switch(sbufl_fill(cb, asfd, cmanfp, cconfs))
			{
				case 0: break;
				case 1: fzp_close(&cmanfp);
					if(process_new(sdirs, cconfs, p1b,
						ucfp)) goto error;
					continue;
				case -1: goto error;
			}
			switch(maybe_process_file(asfd, sdirs,
				cb, p1b, ucfp, cconfs))
			{
				case 0: continue;
				case 1: break;
				case -1: goto error;
			}
			break;
		}
	}

error:
	ret=-1;
end:
	if(fzp_close(&chfp))
	{
		logp("error closing %s in %s\n", sdirs->changed, __func__);
		ret=-1;
	}
	if(fzp_close(&ucfp))
	{
		logp("error closing %s in %s\n", sdirs->unchanged, __func__);
		ret=-1;
	}
	free_w(&deltmppath);
	sbuf_free(&cb);
	sbuf_free(&p1b);
	sbuf_free(&rb);
	manio_free(&p1manio);
	fzp_close(&cmanfp);
	dpth_free(&dpth);
	if(!ret) unlink(sdirs->phase1data);

	logp("End phase2 (receive file data)\n");

	return ret;
}
Exemple #19
0
int champ_chooser_server(struct sdirs *sdirs, struct conf **confs,
	int resume)
{
	int s;
	int ret=-1;
	int len;
	struct asfd *asfd=NULL;
	struct sockaddr_un local;
	struct lock *lock=NULL;
	struct async *as=NULL;
	int started=0;
	struct scores *scores=NULL;
	const char *directory=get_string(confs[OPT_DIRECTORY]);

	if(!(lock=lock_alloc_and_init(sdirs->champlock))
	  || build_path_w(sdirs->champlock))
		goto end;
	lock_get(lock);
	switch(lock->status)
	{
		case GET_LOCK_GOT:
			log_fzp_set(sdirs->champlog, confs);
			logp("Got champ lock for dedup_group: %s\n",
				get_string(confs[OPT_DEDUP_GROUP]));
			break;
		case GET_LOCK_NOT_GOT:
		case GET_LOCK_ERROR:
		default:
			//logp("Did not get champ lock\n");
			goto end;
	}

	if((s=socket(AF_UNIX, SOCK_STREAM, 0))<0)
	{
		logp("socket error in %s: %s\n", __func__, strerror(errno));
		goto end;
	}

	memset(&local, 0, sizeof(struct sockaddr_un));
	local.sun_family=AF_UNIX;
	snprintf(local.sun_path, sizeof(local.sun_path),
		"%s", sdirs->champsock);
	len=strlen(local.sun_path)+sizeof(local.sun_family)+1;
	unlink(sdirs->champsock);
	if(bind(s, (struct sockaddr *)&local, len)<0)
	{
		logp("bind error in %s: %s\n", __func__, strerror(errno));
		goto end;
	}

	if(listen(s, 5)<0)
	{
		logp("listen error in %s: %s\n", __func__, strerror(errno));
		goto end;
	}

	if(!(as=async_alloc())
	  || as->init(as, 0)
	  || !(asfd=setup_asfd(as, "champ chooser main socket", &s,
		/*listen*/"")))
			goto end;
	asfd->fdtype=ASFD_FD_SERVER_LISTEN_MAIN;

	// I think that this is probably the best point at which to run a
	// cleanup job to delete unused data files, because no other process
	// can fiddle with the dedup_group at this point.
	// Cannot do it on a resume, or it will delete files that are
	// referenced in the backup we are resuming.
	if(delete_unused_data_files(sdirs, resume))
		goto end;

	// Load the sparse indexes for this dedup group.
	if(!(scores=champ_chooser_init(sdirs->data)))
		goto end;

	while(1)
	{
		for(asfd=as->asfd->next; asfd; asfd=asfd->next)
		{
			if(!asfd->blist->head
			  || asfd->blist->head->got==BLK_INCOMING) continue;
			if(results_to_fd(asfd)) goto end;
		}

		int removed;

		switch(as->read_write(as))
		{
			case 0:
				// Check the main socket last, as it might add
				// a new client to the list.
				for(asfd=as->asfd->next; asfd; asfd=asfd->next)
				{
					while(asfd->rbuf->buf)
					{
						if(deal_with_client_rbuf(asfd,
							directory, scores))
								goto end;
						// Get as much out of the
						// readbuf as possible.
						if(asfd->parse_readbuf(asfd))
							goto end;
					}
				}
				if(as->asfd->new_client)
				{
					// Incoming client.
					as->asfd->new_client=0;
					if(champ_chooser_new_client(as, confs))
						goto end;
					started=1;
				}
				break;
			default:
				removed=0;
				// Maybe one of the fds had a problem.
				// Find and remove it and carry on if possible.
				for(asfd=as->asfd->next; asfd; )
				{
					struct asfd *a;
					if(!asfd->want_to_remove)
					{
						asfd=asfd->next;
						continue;
					}
					as->asfd_remove(as, asfd);
					logp("%s: disconnected fd %d\n",
						asfd->desc, asfd->fd);
					a=asfd->next;
					asfd_free(&asfd);
					asfd=a;
					removed++;
				}
				if(removed) break;
				// If we got here, there was no fd to remove.
				// It is a fatal error.
				goto end;
		}
				
		if(started && !as->asfd->next)
		{
			logp("All clients disconnected.\n");
			ret=0;
			break;
		}
	}

end:
	logp("champ chooser exiting: %d\n", ret);
	champ_chooser_free(&scores);
	log_fzp_set(NULL, confs);
	async_free(&as);
	asfd_free(&asfd); // This closes s for us.
	close_fd(&s);
	unlink(sdirs->champsock);
// FIX THIS: free asfds.
	lock_release(lock);
	lock_free(&lock);
	return ret;
}
Exemple #20
0
/* Merge two files of sorted dindexes into each other. */
int merge_dindexes(const char *dst, const char *srca, const char *srcb)
{
	int ret=-1;
	struct sbuf *asb=NULL;
	struct sbuf *bsb=NULL;
	struct fzp *azp=NULL;
	struct fzp *bzp=NULL;
	struct fzp *dzp=NULL;
	uint64_t *anew=NULL;
	uint64_t *bnew=NULL;

	if(!(asb=sbuf_alloc(PROTO_2))
	  || (srcb && !(bsb=sbuf_alloc(PROTO_2))))
		goto end;
	if(build_path_w(dst))
		goto end;
	if((srca && !(azp=fzp_gzopen(srca, "rb")))
	  || (srcb && !(bzp=fzp_gzopen(srcb, "rb")))
	  || !(dzp=fzp_gzopen(dst, "wb")))
		goto end;

	while(azp || bzp || anew || bnew)
	{
		if(azp
		  && asb
		  && !anew)
		{
			switch(get_next_dindex(&anew, asb, azp))
			{
				case -1: goto end;
				case 1: fzp_close(&azp); // Finished OK.
			}
		}

		if(bzp
		  && bsb
		  && !bnew)
		{
			switch(get_next_dindex(&bnew, bsb, bzp))
			{
				case -1: goto end;
				case 1: fzp_close(&bzp); // Finished OK.
			}
		}

		if(anew && !bnew)
		{
			if(gzprintf_dindex(dzp, anew)) goto end;
			free_v((void **)&anew);
		}
		else if(!anew && bnew)
		{
			if(gzprintf_dindex(dzp, bnew)) goto end;
			free_v((void **)&bnew);
		}
		else if(!anew && !bnew)
		{
			continue;
		}
		else if(*anew==*bnew)
		{
			// They were the same - write the new one.
			if(gzprintf_dindex(dzp, bnew)) goto end;
			free_v((void **)&anew);
			free_v((void **)&bnew);
		}
		else if(*anew<*bnew)
		{
			if(gzprintf_dindex(dzp, anew)) goto end;
			free_v((void **)&anew);
		}
		else
		{
			if(gzprintf_dindex(dzp, bnew)) goto end;
			free_v((void **)&bnew);
		}
	}

	if(fzp_close(&dzp))
	{
		logp("Error closing %s in %s\n", tmpfile, __func__);
		goto end;
	}

	ret=0;
end:
	fzp_close(&azp);
	fzp_close(&bzp);
	fzp_close(&dzp);
	sbuf_free(&asb);
	sbuf_free(&bsb);
	free_v((void **)&anew);
	free_v((void **)&bnew);
	return ret;
}
Exemple #21
0
static
#endif
int merge_sparse_indexes(const char *dst, const char *srca, const char *srcb)
{
	int fcmp;
	int ret=-1;
	struct sbuf *asb=NULL;
	struct sbuf *bsb=NULL;
	uint64_t *afingerprints=NULL;
	uint64_t *bfingerprints=NULL;
	size_t aflen=0;
	size_t bflen=0;
	struct fzp *azp=NULL;
	struct fzp *bzp=NULL;
	struct fzp *dzp=NULL;
	struct hooks *anew=NULL;
	struct hooks *bnew=NULL;
	char *apath=NULL;
	char *bpath=NULL;

	if(!(asb=sbuf_alloc(PROTO_2))
	  || (srcb && !(bsb=sbuf_alloc(PROTO_2))))
		goto end;
	if(build_path_w(dst))
		goto end;
	if((srca && !(azp=fzp_gzopen(srca, "rb")))
	  || (srcb && !(bzp=fzp_gzopen(srcb, "rb")))
	  || !(dzp=fzp_gzopen(dst, "wb")))
		goto end;

	while(azp || bzp || anew || bnew)
	{
		if(azp
		  && asb
		  && !anew)
		{
			switch(get_next_set_of_hooks(&anew, asb, azp,
				&apath, &afingerprints, &aflen))
			{
				case -1: goto end;
				case 1: fzp_close(&azp); // Finished OK.
			}
		}

		if(bzp
		  && bsb
		  && !bnew)
		{
			switch(get_next_set_of_hooks(&bnew, bsb, bzp,
				&bpath, &bfingerprints, &bflen))
			{
				case -1: goto end;
				case 1: fzp_close(&bzp); // Finished OK.
			}
		}

		if(anew && !bnew)
		{
			if(gzprintf_hooks(dzp, anew)) goto end;
			hooks_free(&anew);
		}
		else if(!anew && bnew)
		{
			if(gzprintf_hooks(dzp, bnew)) goto end;
			hooks_free(&bnew);
		}
		else if(!anew && !bnew)
		{
			continue;
		}
		else if(!(fcmp=hookscmp(anew, bnew)))
		{
			// They were the same - write the new one.
			if(gzprintf_hooks(dzp, bnew)) goto end;
			hooks_free(&anew);
			hooks_free(&bnew);
		}
		else if(fcmp<0)
		{
			if(gzprintf_hooks(dzp, anew)) goto end;
			hooks_free(&anew);
		}
		else
		{
			if(gzprintf_hooks(dzp, bnew)) goto end;
			hooks_free(&bnew);
		}
	}

	if(fzp_close(&dzp))
	{
		logp("Error closing %s in %s\n", tmpfile, __func__);
		goto end;
	}

	ret=0;
end:
	fzp_close(&azp);
	fzp_close(&bzp);
	fzp_close(&dzp);
	sbuf_free(&asb);
	sbuf_free(&bsb);
	hooks_free(&anew);
	hooks_free(&bnew);
	free_v((void **)&afingerprints);
	free_v((void **)&bfingerprints);
	free_w(&apath);
	free_w(&bpath);
	return ret;
}