Пример #1
0
int datapoint_read(datapoint_t* p, int fd)
{
        if ((timestamp_read(&p->t, fd) != 0) 
            || (value_read(&p->v, fd) != 0))
                return -1;
    
        return 0;
}
Пример #2
0
static int check_interval(
	struct strlist *interval,
	const char *cname,
	const char *ctimestamp,
	time_t time_now)
{
	char *cp;
	long min_time;
	long seconds=0;
	char tstmp[64]="";
	char min_time_buf[64]="";

	if((seconds=get_interval_in_seconds(interval->path, cname))<0)
		return -1;
	if(timestamp_read(ctimestamp, tstmp, sizeof(tstmp)))
	{
		logp("Could not read timestamp %s\n", ctimestamp);
		return 0; // Backup now.
	}

	min_time=timestamp_to_long(tstmp)+seconds;
	strftime(min_time_buf, sizeof(min_time_buf),
		DEFAULT_TIMESTAMP_FORMAT, localtime(&min_time));
	cp=strchr(tstmp, ' ');
	if(cp)
		cp++;
	else
		cp=tstmp;

	logp("Last backup: %s\n", cp);
	logp("Next after : %s (interval %s)\n", min_time_buf, interval->path);

	if(min_time < time_now)
		return 0;
	return 1;
}
Пример #3
0
int backup_phase4_server_burp1(struct sdirs *sdirs, struct conf *cconf)
{
	int ret=-1;
	struct stat statp;
	ssize_t len=0;
	char realcurrent[256]="";
	unsigned long bno=0;
	int hardlinked_current=0;
	char tstmp[64]="";
	int previous_backup=0;
	struct fdirs *fdirs=NULL;

	if((len=readlink(sdirs->current, realcurrent, sizeof(realcurrent)-1))<0)
		len=0;
	realcurrent[len]='\0';

	if(!(fdirs=fdirs_alloc())
	  || fdirs_init(fdirs, sdirs, realcurrent))
		goto end;

	if(set_logfp(fdirs->logpath, cconf))
		goto end;

	logp("Begin phase4 (shuffle files)\n");

	if(write_status(STATUS_SHUFFLING, NULL, cconf))
		goto end;

	if(!lstat(sdirs->current, &statp)) // Had a previous backup.
	{
		previous_backup++;

		if(lstat(fdirs->hlinkedcurrent, &statp))
		{
			hardlinked_current=0;
			logp("Previous backup is not a hardlinked_archive\n");
			logp(" will generate reverse deltas\n");
		}
		else
		{
			hardlinked_current=1;
			logp("Previous backup is a hardlinked_archive\n");
			logp(" will not generate reverse deltas\n");
		}

		// If current was not a hardlinked_archive, need to duplicate
		// it.
		if(!hardlinked_current && lstat(fdirs->currentdup, &statp))
		{
			// Have not duplicated the current backup yet.
			if(!lstat(fdirs->currentduptmp, &statp))
			{
				logp("Removing previous directory: %s\n",
					fdirs->currentduptmp);
				if(recursive_delete(fdirs->currentduptmp,
					NULL, 1 /* del files */))
				{
					logp("Could not delete %s\n",
						fdirs->currentduptmp);
					goto end;
				}
			}
			logp("Duplicating current backup.\n");
			if(recursive_hardlink(sdirs->current,
				fdirs->currentduptmp, cconf)
			// The rename race condition is of no consequence here
			// because currentdup does not exist.
			  || do_rename(fdirs->currentduptmp, fdirs->currentdup))
				goto end;
		}
	}

	if(timestamp_read(fdirs->timestamp, tstmp, sizeof(tstmp)))
	{
		logp("could not read timestamp file: %s\n",
			fdirs->timestamp);
		goto end;
	}
	// Get the backup number.
	bno=strtoul(tstmp, NULL, 10);

	// Determine whether the new backup should be a hardlinked
	// archive or not, from the conf and the backup number...
	if(need_hardlinked_archive(cconf, bno))
	{
		// Create a file to indicate that the previous backup
		// does not have others depending on it.
		FILE *hfp=NULL;
		if(!(hfp=open_file(fdirs->hlinked, "wb"))) goto end;

		// Stick the next backup timestamp in it. It might
		// be useful one day when wondering when the next
		// backup, now deleted, was made.
		fprintf(hfp, "%s\n", tstmp);
		if(close_fp(&hfp))
		{
			logp("error closing hardlinked indication\n");
			goto end;
		}
	}
	else
		unlink(fdirs->hlinked);

	if(atomic_data_jiggle(sdirs, fdirs, hardlinked_current, cconf, bno))
	{
		logp("could not finish up backup.\n");
		goto end;
	}

	if(write_status(STATUS_SHUFFLING, "deleting temporary files", cconf))
		goto end;

	// Remove the temporary data directory, we have now removed
	// everything useful from it.
	recursive_delete(fdirs->datadirtmp, NULL, 1 /* del files */);

	// Clean up the currentdata directory - this is now the 'old'
	// currentdata directory. Any files that were deleted from
	// the client will be left in there, so call recursive_delete
	// with the option that makes it not delete files.
	// This will have the effect of getting rid of unnecessary
	// directories.
	sync(); // try to help CIFS
	recursive_delete(fdirs->currentdupdata, NULL, 0 /* do not del files */);

	// Rename the old current to something that we know to delete.
	if(previous_backup && !hardlinked_current)
	{
		if(deleteme_move(sdirs->client,
			fdirs->fullrealcurrent, realcurrent, cconf)
		// I have tested that potential race conditions on the
		// rename() are automatically recoverable here.
		  || do_rename(fdirs->currentdup, fdirs->fullrealcurrent))
			goto end;
	}

	if(deleteme_maybe_delete(cconf, sdirs->client))
		goto end;

	cntr_stats_to_file(cconf->cntr, sdirs->finishing, ACTION_BACKUP);

	logp("End phase4 (shuffle files)\n");

	ret=0;
end:
	fdirs_free(fdirs);
	return ret;
}