Пример #1
0
/*! This will test the functionality of S_block_steal_and_lock() when S_gpool's
 *  superblock list is empty. */
void block_1(void)
{
  int ret;
  struct block * block;
  struct superblock * superblock;

  /* ---- UNIT ---- */
  block = S_block_steal_and_lock();

  /* ---- ASSERTIONS ---- */
  assert(block);
  superblock = S_block_2superblock(block);
  assert(superblock == S_gpool.head);
  assert(block != superblock->head);
  assert(block->next == superblock->head);

  /* ---- CLEANUP ---- */
  LOCK_LET(&(block->lock));
  ret = lock_free(&(block->lock));
  assert(!ret);
  ret = lock_free(&(superblock->lock));
  assert(!ret);
  ret = CALL_SYS_FREE(superblock, SUPERBLOCK_SIZE);
  assert(SYS_FREE_FAIL != ret);
  S_gpool.head = NULL;
}
Пример #2
0
/*! Destroy a superblock's block list and each block's vma list. */
static void
S_superblock_list_destroy(struct superblock * const superblock)
{
  int ret;
  size_t i;
  struct block * block;

  /* Destroy superblock's block list. */
  superblock->head = (struct block*)((char*)superblock+BLOCK_SIZE);
  block = superblock->head;
  for (i=0; i<SUPERBLOCK_CTR_FULL; ++i) {
    block->head = (struct vm_area*)((char*)block+sizeof(struct block));
    if (SUPERBLOCK_CTR_FULL-1 == i) {
      block->next = NULL;
    }
    else {
      block->next = (struct block*)((char*)block+BLOCK_SIZE);
    }

    /* Destroy block's lock. */
    ret = lock_free(&(block->lock));
    assert(!ret);

    /* Accumulate block wait counter. */
    superblock->blctr += block->lctr;

    block = block->next;
  }
}
Пример #3
0
/**
 * Destroys an initialized queue (i.e. free queue and alloc queue) in task queue
 * @param tq    tq to index
 * @param idx   index of queue to destroy in tq
 */
static void tq_queue_destroy(taskQ_t* tq, unsigned int idx)
{
    int             j;
    uintptr_t       chksum;

    assert (idx < tq->num_queues);

    tq_empty_queue(tq->queues[idx]);
    tq_free_queue(tq->queues[idx]);

    tq_empty_queue(tq->free_queues[idx]);
    tq_free_queue(tq->free_queues[idx]);

    /* free all lock data associated with queue */
    chksum = 0;
    for (j = 0; j < tq->num_threads; j++) {
        chksum += (uintptr_t)tq->locks[idx].per_thread[j];
        lock_free_per_thread(tq->locks[idx].per_thread[j]);
    }

    lock_free (tq->locks[idx].parent);

    phoenix_mem_free (tq->locks[idx].per_thread);
    tq->locks[idx].per_thread = NULL;
}
Пример #4
0
char *dpth_mk(struct dpth *dpth)
{
	static char save_path[32];
	static struct lock *lock=NULL;
	while(1)
	{
		snprintf(save_path, sizeof(save_path), "%04X/%04X/%04X/%04X",
			dpth->prim, dpth->seco, dpth->tert, dpth->sig);
		if(!dpth->need_data_lock) return save_path;

		if(!lock && !(lock=lock_alloc())) goto error;
		if(get_data_lock(lock, dpth, save_path)) goto error;
		switch(lock->status)
		{
			case GET_LOCK_GOT: break;
			case GET_LOCK_NOT_GOT:
				// Increment and try again.
				if(dpth_incr(dpth)) goto error;
				continue;
			case GET_LOCK_ERROR:
			default:
				goto error;
		}

		dpth->need_data_lock=0; // Got it.
		if(add_lock_to_list(dpth, lock, save_path)) goto error;
		lock=NULL;
		return save_path;
	}
error:
	lock_free(&lock);
	return NULL;
}
Пример #5
0
static int merge_into_global_sparse(const char *sparse, const char *global)
{
	int ret=-1;
	char *tmpfile=NULL;
	struct stat statp;
	struct lock *lock=NULL;
	const char *globalsrc=NULL;
	
	if(!(tmpfile=get_global_sparse_tmp(global)))
		goto end;

	if(!(lock=try_to_get_sparse_lock(global)))
		goto end;

	if(!lstat(global, &statp)) globalsrc=global;

	if(merge_sparse_indexes(tmpfile, globalsrc, sparse))
		goto end;

	// FIX THIS: nasty race condition needs to be recoverable.
	if(do_rename(tmpfile, global)) goto end;

	ret=0;
end:
	lock_release(lock);
	lock_free(&lock);
	free_w(&tmpfile);
	return ret;
}
Пример #6
0
/*! This will test the functionality of S_superblock_get_and_lock() when S_gpool's
 *  superblock list is empty. */
void superblock_1(void)
{
  int ret;
  size_t ictr, jctr;
  struct vm_area * vma;
  struct block * block;
  struct superblock * superblock;

  /* ---- UNIT ---- */
  superblock = S_superblock_get_and_lock();

  /* ---- ASSERTIONS ---- */
  assert(superblock);
  assert(superblock == S_gpool.head);
  assert(NULL == superblock->prev);
  assert(NULL == superblock->next);
  for (ictr=0,block=superblock->head; block; block=block->next,++ictr) {
    assert(ictr < SUPERBLOCK_CTR_FULL);

    for (jctr=0,vma=block->head; vma; vma=vma->vm_next,++jctr) {
      assert(jctr < BLOCK_CTR_FULL);
    }
    assert(jctr == BLOCK_CTR_FULL);
  }
  assert(ictr == SUPERBLOCK_CTR_FULL);

  /* ---- CLEANUP ---- */
  LOCK_LET(&(superblock->lock));
  ret = lock_free(&(superblock->lock));
  assert(!ret);
  ret = CALL_SYS_FREE(superblock, SUPERBLOCK_SIZE);
  assert(SYS_FREE_FAIL != ret);
  S_gpool.head = NULL;
}
Пример #7
0
Файл: lock.c Проект: grke/burp
struct lock *lock_alloc_and_init(const char *path)
{
	struct lock *lock;
	if(!(lock=lock_alloc()) || lock_init(lock, path))
		lock_free(&lock);
	return lock;
}
Пример #8
0
void lock_component_free(spdid_t spd, unsigned long lock_id)
{
	struct meta_lock *l;
	spdid_t spdid = cos_spd_id();

	if (sched_component_take(spdid)) return;
	l = lock_find(lock_id, spd);
	if (sched_component_release(spdid)) return;

	if (l) lock_free(l);

	return;
}
Пример #9
0
/**
 * @brief ggs_event_free
 *
 * GGS event free.
 *
 * @param event Event.
 */
static void ggs_event_free(GGSEvent *event)
{
	event->loop = false;
	shutdown(event->socket,  SHUT_RDWR);
#ifdef _WIN32
	closesocket(event->socket);
	WSACleanup();
#else
	close(event->socket);
#endif
	thread_join(event->thread);
	free(event->buffer);
	lock_free(event);
}
Пример #10
0
/*! Free a superblock with no used blocks. */
static void
S_superblock_unlock_and_put(struct superblock * const superblock)
{
  int ret;

  /* Lock S_gpool. */
  LOCK_GET(&(S_gpool.lock), S_gpool.lctr);

  /* Remove superblock from S_gpool's superblock list. */
  if (S_gpool.head == superblock) {
    S_gpool.head = superblock->next;
  }
  else {
    superblock->prev->next = superblock->next;
  }
  if (NULL != superblock->next) {
    superblock->next->prev = superblock->prev;
  }

  /* Unlock S_gpool. */
  LOCK_LET(&(S_gpool.lock));

  /* Unlock superblock. */
  LOCK_LET(&(superblock->lock));

  /* Free superblock's lock. */
  ret = lock_free(&(superblock->lock));
  assert(!ret);

  /* Destroy superblock's block list. */
  S_superblock_list_destroy(superblock);

  /* Lock S_gpool. */
  LOCK_GET(&(S_gpool.lock), S_gpool.lctr);

  /* Accumulate superblock's block wait counter. */
  S_gpool.blctr += superblock->blctr;
  /* Accumulate superblock's wait counter. */
  S_gpool.slctr += superblock->lctr;

  /* Unlock S_gpool. */
  LOCK_LET(&(S_gpool.lock));

  /* Release back to system. */
  ret = CALL_SYS_FREE(superblock, SUPERBLOCK_SIZE);
  assert(SYS_FREE_FAIL != ret);

  DBG_LOG(stderr, "put superblock %p-%p\n", (void*)superblock,\
    (void*)((char*)superblock+SUPERBLOCK_SIZE));
}
Пример #11
0
Файл: lock.c Проект: grke/burp
void locks_release_and_free(struct lock **locklist)
{
	struct lock *l;
	struct lock *head;
	if(!locklist) return;
	head=*locklist;
	while(head)
	{
		l=head;
		head=head->next;
		lock_release(l);
		lock_free(&l);
	}
	*locklist=NULL;
}
Пример #12
0
void
vma_gpool_free(void)
{
  int ret;

  /* TODO Until superblock_* cache unused superblocks, this is unnecessary if we
   * say that applications must free all memory they allocate. */
#if 0
  while (S_gpool.head) {
    S_superblock_unlock_and_put(S_gpool.head);
  }
#endif

  ret = lock_free(&(S_gpool.lock));
  assert(!ret);
}
Пример #13
0
static int release_and_move_to_next_in_list(struct dpth *dpth)
{
	int ret=0;
	struct dpth_lock *next=NULL;

	// Try to release (and unlink) the lock even if close_fp failed, just
	// to be tidy.
	if(close_fp(&dpth->fp)) ret=-1;
	if(lock_release(dpth->head->lock)) ret=-1;
	lock_free(&dpth->head->lock);

	next=dpth->head->next;
	if(dpth->head==dpth->tail) dpth->tail=next;
	dpth_lock_free(dpth->head);
	dpth->head=next;
	return ret;
}
Пример #14
0
void
shutdown_daemons(void)
{
    AFS_STATCNT(shutdown_daemons);
    if (afs_cold_shutdown) {
	afs_brsDaemons = brsInit = 0;
	rxepoch_checked = afs_nbrs = 0;
	memset(afs_brs, 0, sizeof(afs_brs));
	memset(&afs_xbrs, 0, sizeof(afs_lock_t));
	afs_brsWaiters = 0;
#ifdef AFS_AIX41_ENV
	lock_free(&afs_asyncbuf_lock);
	unpin(&afs_asyncbuf, sizeof(struct buf *));
	unpin(&afs_asyncbuf_cv, sizeof(afs_int32));
	afs_initbiod = 0;
#endif
    }
}
Пример #15
0
/**
 * @brief Free a message event.
 *
 * @param event Event.
 */
void event_free(Event *event)
{
	int i;

	spin_lock(event);

	for (i = 0; i < event->size; ++i) {
		free(event->ring[i]);
	}
	event->first = 0;
	event->end = 0;
	free(event->ring);

	lock_free(event);
	condition_free(event);

	spin_unlock(event);
	spin_free(event);
}
Пример #16
0
void sdirs_free_content(struct sdirs *sdirs)
{
        free_w(&sdirs->base);
        free_w(&sdirs->dedup);
        free_w(&sdirs->champlock);
        free_w(&sdirs->champsock);
        free_w(&sdirs->champlog);
        free_w(&sdirs->data);
        free_w(&sdirs->clients);
        free_w(&sdirs->client);

        free_w(&sdirs->working);
        free_w(&sdirs->rworking);
        free_w(&sdirs->finishing);
        free_w(&sdirs->current);
        free_w(&sdirs->currenttmp);
        free_w(&sdirs->deleteme);

        free_w(&sdirs->timestamp);
        free_w(&sdirs->changed);
        free_w(&sdirs->unchanged);
	free_w(&sdirs->manifest);
	free_w(&sdirs->rmanifest);
        free_w(&sdirs->cmanifest);
	free_w(&sdirs->phase1data);

	free_w(&sdirs->lockdir);
	lock_free(&sdirs->lock);

	// Burp1 directories.
	free_w(&sdirs->currentdata);
	free_w(&sdirs->datadirtmp);
	free_w(&sdirs->phase2data);
	free_w(&sdirs->unchangeddata);
	free_w(&sdirs->cincexc);
	free_w(&sdirs->deltmppath);
	free_w(&sdirs->treepath);
}
Пример #17
0
void sdirs_free(struct sdirs *sdirs)
{
	if(!sdirs) return;

        if(sdirs->base) free(sdirs->base);
        if(sdirs->dedup) free(sdirs->dedup);
        if(sdirs->champlock) free(sdirs->champlock);
        if(sdirs->champsock) free(sdirs->champsock);
        if(sdirs->champlog) free(sdirs->champlog);
        if(sdirs->data) free(sdirs->data);
        if(sdirs->clients) free(sdirs->clients);
        if(sdirs->client) free(sdirs->client);

        if(sdirs->working) free(sdirs->working);
        if(sdirs->finishing) free(sdirs->finishing);
        if(sdirs->current) free(sdirs->current);

        if(sdirs->timestamp) free(sdirs->timestamp);
        if(sdirs->changed) free(sdirs->changed);
        if(sdirs->unchanged) free(sdirs->unchanged);
        if(sdirs->cmanifest) free(sdirs->cmanifest);
	if(sdirs->phase1data) free(sdirs->phase1data);

	if(sdirs->lockdir) free(sdirs->lockdir);
	lock_free(&sdirs->lock);

	// Legacy directories
	if(sdirs->currentdata) free(sdirs->currentdata);
	if(sdirs->manifest) free(sdirs->manifest);
	if(sdirs->datadirtmp) free(sdirs->datadirtmp);
	if(sdirs->phase2data) free(sdirs->phase2data);
	if(sdirs->unchangeddata) free(sdirs->unchangeddata);
	if(sdirs->cincexc) free(sdirs->cincexc);
	if(sdirs->deltmppath) free(sdirs->deltmppath);

	free(sdirs);
	sdirs=NULL;
}
Пример #18
0
/**
 * Initialize a queue for a given index in the task queue
 * @return zero on failure, nonzero on success
 */
static int tq_queue_init(taskQ_t* tq, unsigned int idx)
{
    int     j;

    assert (idx < tq->num_queues);

    tq->queues[idx] = tq_alloc_queue();
    if (tq->queues[idx] == NULL) return 0;

    tq->free_queues[idx] = tq_alloc_queue();
    if (tq->free_queues[idx] == NULL) goto fail_free_queue;

    tq->locks[idx].parent = lock_alloc();

    tq->locks[idx].per_thread = (mr_lock_t *)phoenix_mem_calloc(
        tq->num_threads, sizeof(mr_lock_t));
    if (tq->locks[idx].per_thread == NULL) goto fail_priv_alloc;

    tq->locks[idx].chksum = 0;
    for (j = 0; j < tq->num_threads; ++j) {
        mr_lock_t   per_thread;
        per_thread = lock_alloc_per_thread(tq->locks[idx].parent);
        tq->locks[idx].per_thread[j] = per_thread;
        tq->locks[idx].chksum += (uintptr_t)per_thread;
    }

    return 1;

fail_priv_alloc:
    lock_free(tq->locks[idx].parent);
    tq_free_queue(tq->free_queues[idx]);
    tq->free_queues[idx] = NULL;
fail_free_queue:
    tq_free_queue(tq->queues[idx]);
    tq->queues[idx] = NULL;

    return 0;
}
Пример #19
0
static void do_fork(int child_exit_early)
{
	switch(fork())
	{
		case -1: fail_unless(0==1);
			break;
		case 0: // Child.
		{
			struct lock *lock;
			lock=lock_alloc_and_init(lockfile);
			lock_get_quick(lock);
			if(!child_exit_early)
			{
				sleep(2);
				lock_release(lock);
				lock_free(&lock);
			}
			exit(0);
		}
		default: break;
	}
	// Parent.
}
Пример #20
0
static int merge_into_global_sparse(const char *sparse, const char *global,
	struct conf **confs)
{
	int ret=-1;
	char *tmpfile=NULL;
	struct stat statp;
	char *lockfile=NULL;
	struct lock *lock=NULL;
	const char *globalsrc=NULL;
	
	if(!(tmpfile=prepend_n(global, "tmp", strlen("tmp"), ".")))
		goto end;

	// Get a lock before messing with the global sparse index.
	if(!(lockfile=prepend_n(global, "lock", strlen("lock"), "."))
	  || !(lock=lock_alloc_and_init(lockfile)))
		goto end;

	if(try_to_get_lock(lock)) goto end;

	if(!lstat(global, &statp)) globalsrc=global;

	if(merge_sparse_indexes(sparse, globalsrc, tmpfile, confs))
		goto end;

	// FIX THIS: nasty race condition needs to be recoverable.
	if(do_rename(tmpfile, global)) goto end;

	ret=0;
end:
	lock_release(lock);
	lock_free(&lock);
	if(lockfile) free(lockfile);
	if(tmpfile) free(tmpfile);
	return ret;
}
Пример #21
0
static void tear_down(struct lock **lock, struct lock **locklist)
{
	lock_free(lock);
	locks_release_and_free(locklist);
	alloc_check();
}
Пример #22
0
	/*}}}*/
};

static int
usage (const char *pgm) /*{{{*/
{
	fprintf (stderr, "Usage: %s [-L <loglevel>] [-s <socket name>] [-s <reread in seconds>] [-c <config filename>] [-l]\n", pgm);
	return 1;
}/*}}}*/
int
main (int argc, char **argv) /*{{{*/
{
	int	rc;
	char	*ptr;
	char	*sock_name;
	int	reread;
	int	n;
	lock_t	*lock;

	if (ptr = strrchr (argv[0], '/'))
		program = ptr + 1;
	else
		program = argv[0];
	loglevel = "WARNING";
	sock_name = NULL;
	reread = 0;
	cfgfile = NULL;

	while ((n = getopt (argc, argv, "L:s:r:c:l")) != -1)
		switch (n) {
		case 'L':
			loglevel = optarg;
			break;
		case 's':
			if (sock_name)
				free (sock_name);
			if (! (sock_name = strdup (optarg))) {
				fprintf (stderr, "Failed to allocate memory for socket name %s (%m).\n", optarg);
				return 1;
			}
			break;
		case 'r':
			if ((reread = atoi (optarg)) < 1) {
				fprintf (stderr, "Reread value must be at least 1.\n");
				return 1;
			}
			break;
		case 'c':
			if (cfgfile)
				free (cfgfile);
			if (! (cfgfile = strdup (optarg))) {
				fprintf (stderr, "Failed to allocate memory for config.filename %s (%m).\n", optarg);
				return 1;
			}
			break;
		case 'l':
			break;
		default:
			return usage (argv[0]);
		}
	if (optind < argc)
		return usage (argv[0]);
	if (! (lock = lock_alloc (LOCK_PATH))) {
		fprintf (stderr, "Failed to allocate memory for locking (%m).\n");
		return 1;
	}
	if (! lock_lock (lock)) {
		fprintf (stderr, "Instance seems already to run, aborting.\n");
		return 1;
	}

	if ((! sock_name) || (! cfgfile)) {
		const char	*home;

		if (! (home = getenv ("HOME")))
			home = "";
		if (! sock_name) {
			if (! (sock_name = malloc (strlen (home) + sizeof (SOCK_PATH) + 16))) {
				fprintf (stderr, "Failed to allocate socket name %s/%s (%m).\n", home, SOCK_PATH);
				return 1;
			}
			sprintf (sock_name, "unix:%s/%s", home, SOCK_PATH);
		}
		if (! cfgfile) {
			if (! (cfgfile = malloc (strlen (home) + sizeof (CFGFILE) + 1))) {
				fprintf (stderr, "Failed to allocate config.filename %s/%s (%m).\n", home, CFGFILE);
				return 1;
			}
			sprintf (cfgfile, "%s/%s", home, CFGFILE);
		}
	}
	rc = 1;
	umask (0);
	if (smfi_register (bav) == MI_FAILURE)
		fprintf (stderr, "Failed to register filter.\n");
	else if (smfi_setconn (sock_name) == MI_FAILURE)
		fprintf (stderr, "Failed to register socket name \"%s\".\n", sock_name);
	else if (smfi_opensocket (1) == MI_FAILURE)
		fprintf (stderr, "Failed to open socket socket \"%s\".\n", sock_name);
	else {
		if (smfi_main () == MI_FAILURE)
			fprintf (stderr, "Failed to hand over control to milter.\n");
		else
			rc = 0;
	}
	unlink (sock_name);
	lock_unlock (lock);
	lock_free (lock);
	free (sock_name);
	free (cfgfile);
	return rc;
}/*}}}*/
Пример #23
0
int run_bedup(int argc, char *argv[])
{
	int i=1;
	int ret=0;
	int option=0;
	int nonburp=0;
	unsigned int maxlinks=DEF_MAX_LINKS;
	char *groups=NULL;
	char ext[16]="";
	int givenconfigfile=0;
	const char *configfile=NULL;

	configfile=get_config_path();
	snprintf(ext, sizeof(ext), ".bedup.%d", getpid());

	while((option=getopt(argc, argv, "c:dg:hlm:nvV?"))!=-1)
	{
		switch(option)
		{
			case 'c':
				configfile=optarg;
				givenconfigfile=1;
				break;
			case 'd':
				deletedups=1;
				break;
			case 'g':
				groups=optarg;
				break;
			case 'l':
				makelinks=1;
				break;
			case 'm':
				maxlinks=atoi(optarg);
				break;
			case 'n':
				nonburp=1;
				break;
			case 'V':
				printf("%s-%s\n", prog, VERSION);
				return 0;
			case 'v':
				verbose=1;
				break;
			case 'h':
			case '?':
				return usage();
		}
	}

	if(nonburp && givenconfigfile)
	{
		logp("-n and -c options are mutually exclusive\n");
		return 1;
	}
	if(nonburp && groups)
	{
		logp("-n and -g options are mutually exclusive\n");
		return 1;
	}
	if(!nonburp && maxlinks!=DEF_MAX_LINKS)
	{
		logp("-m option is specified via the configuration file in burp mode (max_hardlinks=)\n");
		return 1;
	}
	if(deletedups && makelinks)
	{
		logp("-d and -l options are mutually exclusive\n");
		return 1;
	}
	if(deletedups && !nonburp)
	{
		logp("-d option requires -n option\n");
		return 1;
	}

	if(optind>=argc)
	{
		if(nonburp)
		{
			logp("No directories found after options\n");
			return 1;
		}
	}
	else
	{
		if(!nonburp)
		{
			logp("Do not specify extra arguments.\n");
			return 1;
		}
	}

	if(maxlinks<2)
	{
		logp("The argument to -m needs to be greater than 1.\n");
		return 1;
	}

	if(nonburp)
	{
		// Read directories from command line.
		for(i=optind; i<argc; i++)
		{
			// Strip trailing slashes, for tidiness.
			if(argv[i][strlen(argv[i])-1]=='/')
				argv[i][strlen(argv[i])-1]='\0';
			if(process_dir("", argv[i], ext, maxlinks,
				0 /* not burp mode */, 0 /* level */))
			{
				ret=1;
				break;
			}
		}
	}
	else
	{
		struct conf **globalcs=NULL;
		struct strlist *grouplist=NULL;
		struct lock *globallock=NULL;

		if(groups)
		{
			char *tok=NULL;
			if((tok=strtok(groups, ",\n")))
			{
				do
				{
					if(strlist_add(&grouplist, tok, 1))
					{
						log_out_of_memory(__func__);
						return -1;
					}
				} while((tok=strtok(NULL, ",\n")));
			}
			if(!grouplist)
			{
				logp("unable to read list of groups\n");
				return -1;
			}
		}

		// Read directories from config files, and get locks.
		if(!(globalcs=confs_alloc())) return -1;
		if(confs_init(globalcs)) return -1;
		if(conf_load_global_only(configfile, globalcs)) return 1;
		if(get_e_burp_mode(globalcs[OPT_BURP_MODE])!=BURP_MODE_SERVER)
		{
			logp("%s is not a server config file\n", configfile);
			confs_free(&globalcs);
			return 1;
		}
		logp("Dedup clients from %s\n",
			get_string(globalcs[OPT_CLIENTCONFDIR]));
		maxlinks=get_int(globalcs[OPT_MAX_HARDLINKS]);
		if(grouplist)
		{
			struct strlist *g=NULL;
			logp("in dedup groups:\n");
			for(g=grouplist; g; g=g->next)
				logp("%s\n", g->path);
		}
		else
		{
			char *lockpath=NULL;
			// Only get the global lock when doing a global run.
			// If you are doing individual groups, you are likely
			// to want to do many different dedup jobs and a
			// global lock would get in the way.
			if(!(lockpath=prepend(
				get_string(globalcs[OPT_LOCKFILE]),
				".bedup", ""))
			  || !(globallock=lock_alloc_and_init(lockpath)))
				return 1;
			lock_get(globallock);
			if(globallock->status!=GET_LOCK_GOT)
			{
				logp("Could not get lock %s (%d)\n", lockpath,
					globallock->status);
				free_w(&lockpath);
				return 1;
			}
			logp("Got %s\n", lockpath);
		}
		ret=iterate_over_clients(globalcs, grouplist, ext, maxlinks);
		confs_free(&globalcs);

		lock_release(globallock);
		lock_free(&globallock);
		strlists_free(&grouplist);
	}

	if(!nonburp)
	{
		logp("%d client storages scanned\n", ccount);
	}
	logp("%llu duplicate %s found\n",
		count, count==1?"file":"files");
	logp("%llu bytes %s%s\n",
		savedbytes, (makelinks || deletedups)?"saved":"saveable",
			bytes_to_human(savedbytes));
	return ret;
}
Пример #24
0
static
#endif
int real_main(int argc, char *argv[])
{
	int ret=1;
	int option=0;
	int daemon=1;
	int forking=1;
	int strip=0;
	int randomise=0;
	struct lock *lock=NULL;
	struct conf **confs=NULL;
	int forceoverwrite=0;
	enum action act=ACTION_LIST;
	const char *backup=NULL;
	const char *backup2=NULL;
	char *restoreprefix=NULL;
	char *stripfrompath=NULL;
	const char *regex=NULL;
	const char *browsefile=NULL;
	char *browsedir=NULL;
	const char *conffile=get_conf_path();
	const char *orig_client=NULL;
	const char *logfile=NULL;
	// The orig_client is the original client that the normal client
	// would like to restore from.
#ifndef HAVE_WIN32
	int generate_ca_only=0;
#endif
	int vss_restore=1;
	int test_confs=0;
	enum burp_mode mode;

	log_init(argv[0]);
#ifndef HAVE_WIN32
	if(!strcmp(prog, "bedup"))
		return run_bedup(argc, argv);
	if(!strcmp(prog, "bsigs"))
		return run_bsigs(argc, argv);
#endif

	while((option=getopt(argc, argv, "a:b:c:C:d:fFghil:nq:Qr:s:tvxjz:?"))!=-1)
	{
		switch(option)
		{
			case 'a':
				if(parse_action(&act, optarg)) goto end;
				break;
			case 'b':
				// The diff command may have two backups
				// specified.
				if(!backup2 && backup) backup2=optarg;
				if(!backup) backup=optarg;
				break;
			case 'c':
				conffile=optarg;
				break;
			case 'C':
				orig_client=optarg;
				break;
			case 'd':
				restoreprefix=optarg; // for restores
				browsedir=optarg; // for lists
				break;
			case 'f':
				forceoverwrite=1;
				break;
			case 'F':
				daemon=0;
				break;
			case 'g':
#ifndef HAVE_WIN32
				generate_ca_only=1;
#endif
				break;
			case 'i':
				cmd_print_all();
				ret=0;
				goto end;
			case 'l':
				logfile=optarg;
				break;
			case 'n':
				forking=0;
				break;
			case 'q':
				randomise=atoi(optarg);
				break;
			case 'Q':
				log_force_quiet();
				break;
			case 'r':
				regex=optarg;
				break;
			case 's':
				strip=atoi(optarg);
				break;
			case 'v':
				printf("%s-%s\n", progname(), VERSION);
				ret=0;
				goto end;
			case 'x':
				vss_restore=0;
				break;
			case 't':
				test_confs=1;
				break;
			case 'z':
				browsefile=optarg;
				break;
			case 'h':
			case '?':
			default:
				usage();
				goto end;
		}
	}
	if(optind<argc)
	{
		usage();
		goto end;
	}

	if(act==ACTION_MONITOR)
	{
		// Try to output everything in JSON.
		log_set_json(1);
#ifndef HAVE_WIN32
		// Need to do this so that processes reading stdout get the
		// result of the printfs of logp straight away.
		setlinebuf(stdout);
#endif
	}

	if(!(confs=confs_alloc()))
		goto end;

	if(reload(confs, conffile, 1))
		goto end;

	// Dry run to test config file syntax.
	if(test_confs)
	{
		ret=run_test_confs(confs, orig_client);
		goto end;
	}

	if(!backup) switch(act)
	{
		case ACTION_DELETE:
			logp("No backup specified for deletion.\n");
			goto end;
		case ACTION_RESTORE:
		case ACTION_VERIFY:
		case ACTION_DIFF:
		case ACTION_DIFF_LONG:
			logp("No backup specified. Using the most recent.\n");
			backup="0";
		default:
			break;
	}
	if(!backup2) switch(act)
	{
		case ACTION_DIFF:
		case ACTION_DIFF_LONG:
			logp("No second backup specified. Using file system scan.\n");
			backup2="n"; // For 'next'.
		default:
			break;
	}

	// The logfile option is only used for the status client stuff.
	if(logfile
	  && (act!=ACTION_STATUS
		&& act!=ACTION_STATUS_SNAPSHOT))
			logp("-l <logfile> option obsoleted\n");

	if(orig_client
	  && *orig_client
	  && set_string(confs[OPT_ORIG_CLIENT], orig_client))
		goto end;

	// The random delay needs to happen before the lock is got, otherwise
	// you would never be able to use burp by hand.
	if(randomise) set_int(confs[OPT_RANDOMISE], randomise);
	mode=get_e_burp_mode(confs[OPT_BURP_MODE]);
	if(mode==BURP_MODE_CLIENT
	  && (act==ACTION_BACKUP_TIMED || act==ACTION_TIMER_CHECK))
		random_delay(confs);

	if(mode==BURP_MODE_SERVER
	  && act==ACTION_CHAMP_CHOOSER)
	{
		// These server modes need to run without getting the lock.
	}
	else if(mode==BURP_MODE_CLIENT
	  && (act==ACTION_LIST
		|| act==ACTION_LIST_LONG
		|| act==ACTION_DIFF
		|| act==ACTION_DIFF_LONG
		|| act==ACTION_STATUS
		|| act==ACTION_STATUS_SNAPSHOT
		|| act==ACTION_MONITOR))
	{
		// These client modes need to run without getting the lock.
	}
	else
	{
		const char *lockfile=confs_get_lockfile(confs);
		if(!(lock=lock_alloc_and_init(lockfile)))
			goto end;
		lock_get(lock);
		switch(lock->status)
		{
			case GET_LOCK_GOT: break;
			case GET_LOCK_NOT_GOT:
				logp("Could not get lockfile.\n");
				logp("Another process is probably running,\n");
				goto end;
			case GET_LOCK_ERROR:
			default:
				logp("Could not get lockfile.\n");
				logp("Maybe you do not have permissions to write to %s.\n", lockfile);
				goto end;
		}
	}

	set_int(confs[OPT_OVERWRITE], forceoverwrite);
	set_int(confs[OPT_STRIP], strip);
	set_int(confs[OPT_FORK], forking);
	set_int(confs[OPT_DAEMON], daemon);

	strip_trailing_slashes(&restoreprefix);
	strip_trailing_slashes(&browsedir);
	if(replace_conf_str(confs[OPT_BACKUP], backup)
	  || replace_conf_str(confs[OPT_BACKUP2], backup2)
	  || replace_conf_str(confs[OPT_RESTOREPREFIX], restoreprefix)
	  || replace_conf_str(confs[OPT_STRIP_FROM_PATH], stripfrompath)
	  || replace_conf_str(confs[OPT_REGEX], regex)
	  || replace_conf_str(confs[OPT_BROWSEFILE], browsefile)
	  || replace_conf_str(confs[OPT_BROWSEDIR], browsedir)
	  || replace_conf_str(confs[OPT_MONITOR_LOGFILE], logfile))
		goto end;

	base64_init();
	hexmap_init();

	if(mode==BURP_MODE_SERVER)
	{
#ifdef HAVE_WIN32
		logp("Sorry, server mode is not implemented for Windows.\n");
#else
		ret=server_modes(act,
			conffile, lock, generate_ca_only, confs);
#endif
	}
	else
	{
		ret=client(confs, act, vss_restore);
	}

end:
	lock_release(lock);
	lock_free(&lock);
	confs_free(&confs);
	return ret;
}
Пример #25
0
void	IORWLockFree( IORWLock * lock)
{
    lock_free( lock );
}
Пример #26
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;
}
Пример #27
0
Файл: prog.c Проект: jkniiv/burp
int main (int argc, char *argv[])
{
    int ret=1;
    int option=0;
    int daemon=1;
    int forking=1;
    int strip=0;
    struct lock *lock=NULL;
    struct conf *conf=NULL;
    int forceoverwrite=0;
    enum action act=ACTION_LIST;
    const char *backup=NULL;
    const char *restoreprefix=NULL;
    const char *regex=NULL;
    const char *browsefile=NULL;
    const char *browsedir=NULL;
    const char *conffile=get_conf_path();
    const char *orig_client=NULL;
    // The orig_client is the original client that the normal client
    // would like to restore from.
#ifndef HAVE_WIN32
    const char *sclient=NULL; // Status monitor client to view.
    int generate_ca_only=0;
#endif
    int vss_restore=1;
    int json=0;

    init_log(argv[0]);

    while((option=getopt(argc, argv, "a:b:c:C:d:ghfFil:nr:s:vxjz:?"))!=-1)
    {
        switch(option)
        {
        case 'a':
            if(parse_action(&act, optarg)) goto end;
            break;
        case 'b':
            backup=optarg;
            break;
        case 'c':
            conffile=optarg;
            break;
        case 'C':
            orig_client=optarg;
#ifndef HAVE_WIN32
            sclient=optarg;
#endif
            break;
        case 'd':
            restoreprefix=optarg; // for restores
            browsedir=optarg; // for lists
            break;
        case 'f':
            forceoverwrite=1;
            break;
        case 'F':
            daemon=0;
            break;
        case 'g':
#ifndef HAVE_WIN32
            generate_ca_only=1;
#endif
            break;
        case 'i':
            cmd_print_all();
            ret=0;
            goto end;
        case 'l':
            logp("-l <logfile> option obsoleted\n");
            break;
        case 'n':
            forking=0;
            break;
        case 'r':
            regex=optarg;
            break;
        case 's':
            strip=atoi(optarg);
            break;
        case 'v':
            printf("%s-%s\n", progname(), VERSION);
            ret=0;
            goto end;
        case 'x':
            vss_restore=0;
            break;
        case 'j':
            json=1;
            break;
        case 'z':
            browsefile=optarg;
            break;
        case 'h':
        case '?':
        default:
            usage();
            goto end;
        }
    }
    if(optind<argc)
    {
        usage();
        goto end;
    }

    if(!(conf=conf_alloc()))
        goto end;

    if(reload(conf, conffile,
              1 /* first time */,
              0 /* no oldmax_children setting */,
              0 /* no oldmax_status_children setting */,
              json)) goto end;

    if((act==ACTION_RESTORE || act==ACTION_VERIFY) && !backup)
    {
        logp("No backup specified. Using the most recent.\n");
        backup="0";
    }

    if(act==ACTION_DELETE && !backup)
    {
        logp("No backup specified for deletion.\n");
        goto end;
    }

    if(conf->mode==MODE_CLIENT)
    {
        if(orig_client && *orig_client)
        {
            if(!(conf->orig_client=strdup(orig_client)))
            {
                log_out_of_memory(__func__);
                goto end;
            }
        }
    }

    if(conf->mode==MODE_SERVER
            && (act==ACTION_STATUS
                || act==ACTION_STATUS_SNAPSHOT
                || act==ACTION_CHAMP_CHOOSER))
    {
        // These server modes need to run without getting the lock.
    }
    else
    {
        if(!(lock=lock_alloc_and_init(conf->lockfile)))
            goto end;
        lock_get(lock);
        switch(lock->status)
        {
        case GET_LOCK_GOT:
            break;
        case GET_LOCK_NOT_GOT:
            logp("Could not get lockfile.\n");
            logp("Another process is probably running,\n");
            goto end;
        case GET_LOCK_ERROR:
        default:
            logp("Could not get lockfile.\n");
            logp("Maybe you do not have permissions to write to %s.\n", conf->lockfile);
            goto end;
        }
    }

    conf->overwrite=forceoverwrite;
    conf->strip=strip;
    conf->forking=forking;
    conf->daemon=daemon;
    if(replace_conf_str(backup, &conf->backup)
            || replace_conf_str(restoreprefix, &conf->restoreprefix)
            || replace_conf_str(regex, &conf->regex)
            || replace_conf_str(browsefile, &conf->browsefile)
            || replace_conf_str(browsedir, &conf->browsedir))
        goto end;
    if(conf->mode==MODE_SERVER)
    {
#ifdef HAVE_WIN32
        logp("Sorry, server mode is not implemented for Windows.\n");
#else
        if(act==ACTION_STATUS || act==ACTION_STATUS_SNAPSHOT)
        {
            // We are running on the server machine, being a client
            // of the burp server, getting status information.
            ret=status_client_ncurses(conf, act, sclient);
        }
        else if(act==ACTION_CHAMP_CHOOSER)
        {
            // We are running on the server machine, wanting to
            // be a standalone champion chooser process.
            if(!sclient || !*sclient)
            {
                logp("No client name specified for standalone champion chooser process.\n");
                logp("Try using the '-C' option.\n");
                ret=1;
            }
            else
                ret=champ_chooser_server_standalone(conf,
                                                    sclient);
        }
        else
            ret=server(conf, conffile, lock, generate_ca_only);
#endif
    }
    else
    {
        logp("before client\n");
        ret=client(conf, act, vss_restore, json);
        logp("after client\n");
    }

end:
    lock_release(lock);
    lock_free(&lock);
    conf_free(conf);
    return ret;
}