Exemplo n.º 1
0
/* shared_val1 = --unused-- */
enum backup_state_ret
restore_state_complete_v1 (struct backup_info *info, void *data, unsigned size, unsigned *consumed)
{
	if (size > 0)
	{
		fprintf (stderr, "Extra blocks at end of restore???");
	}

	if (info->state != bsComplete)
	{
/* Go ahead and print it to stderr - this is really a development message */
		fprintf (stderr, "State machine missing states\n");
	}

	if (restore_cleanup_parts (info) < 0)
		return bsError;
	if (restore_make_swap (info) < 0)
		return bsError;
	if (restore_fixup_vol_list (info) < 0)
		return bsError;
	if (restore_fixup_zone_maps (info) < 0)
		return bsError;

	mfsvol_cleanup (info->vols);
	info->vols = 0;
	info->mfs = mfs_init (info->devs[0].devname, info->ndevs > 1? info->devs[1].devname: NULL, O_RDWR);
	if (!info->mfs || mfs_has_error (info->mfs))
		return bsError;
	if (restore_fudge_inodes (info) < 0)
		return bsError;
	if (restore_fudge_transactions (info) < 0)
		return bsError;

#if HAVE_SYNC
/* Make sure changes are committed to disk */
	sync ();
#endif

	return bsNextState;
}
Exemplo n.º 2
0
int mainloop(struct fuse_args *args,const char* mp,int mt,int fg) {
	struct fuse_session *se;
	struct fuse_chan *ch;
	struct rlimit rls;
	int piped[2];
	char s;
	int err;
	int i;
	md5ctx ctx;
	uint8_t md5pass[16];

	if (mfsopts.passwordask && mfsopts.password==NULL && mfsopts.md5pass==NULL) {
		mfsopts.password = getpass("MFS Password:"******"bad md5 definition (md5 should be given as 32 hex digits)\n");
				return 1;
			}
			p++;
			if (*p>='0' && *p<='9') {
				md5pass[i]+=(*p-'0');
			} else if (*p>='a' && *p<='f') {
				md5pass[i]+=(*p-'a'+10);
			} else if (*p>='A' && *p<='F') {
				md5pass[i]+=(*p-'A'+10);
			} else {
				fprintf(stderr,"bad md5 definition (md5 should be given as 32 hex digits)\n");
				return 1;
			}
			p++;
		}
		if (*p) {
			fprintf(stderr,"bad md5 definition (md5 should be given as 32 hex digits)\n");
			return 1;
		}
		memset(mfsopts.md5pass,0,strlen(mfsopts.md5pass));
	}

	if (mfsopts.delayedinit) {
		fs_init_master_connection(mfsopts.bindhost,mfsopts.masterhost,mfsopts.masterport,mfsopts.meta,mp,mfsopts.subfolder,(mfsopts.password||mfsopts.md5pass)?md5pass:NULL,mfsopts.donotrememberpassword,1);
	} else {
		if (fs_init_master_connection(mfsopts.bindhost,mfsopts.masterhost,mfsopts.masterport,mfsopts.meta,mp,mfsopts.subfolder,(mfsopts.password||mfsopts.md5pass)?md5pass:NULL,mfsopts.donotrememberpassword,0)<0) {
			return 1;
		}
	}
	memset(md5pass,0,16);

	if (fg==0) {
		openlog(STR(APPNAME), LOG_PID | LOG_NDELAY , LOG_DAEMON);
	} else {
#if defined(LOG_PERROR)
		openlog(STR(APPNAME), LOG_PID | LOG_NDELAY | LOG_PERROR, LOG_USER);
#else
		openlog(STR(APPNAME), LOG_PID | LOG_NDELAY, LOG_USER);
#endif
	}

	i = mfsopts.nofile;
	while (1) {
		rls.rlim_cur = i;
		rls.rlim_max = i;
		if (setrlimit(RLIMIT_NOFILE,&rls)<0) {
			i /= 2;
			if (i<1000) {
				break;
			}
		} else {
			break;
		}
	}
	if (i != (int)(mfsopts.nofile)) {
		fprintf(stderr,"can't set open file limit to %d\n",mfsopts.nofile);
		if (i>=1000) {
			fprintf(stderr,"open file limit set to: %d\n",i);
		}
	}

	setpriority(PRIO_PROCESS,getpid(),mfsopts.nice);
#ifdef MFS_USE_MEMLOCK
	if (mfsopts.memlock) {
		rls.rlim_cur = RLIM_INFINITY;
		rls.rlim_max = RLIM_INFINITY;
		if (setrlimit(RLIMIT_MEMLOCK,&rls)<0) {
			mfsopts.memlock=0;
		}
	}
#endif

	piped[0] = piped[1] = -1;
	if (fg==0) {
		if (pipe(piped)<0) {
			fprintf(stderr,"pipe error\n");
			return 1;
		}
		err = fork();
		if (err<0) {
			fprintf(stderr,"fork error\n");
			return 1;
		} else if (err>0) {
			close(piped[1]);
			err = read(piped[0],&s,1);
			if (err==0) {
				s=1;
			}
			return s;
		}
		close(piped[0]);
		s=1;
	}


#ifdef MFS_USE_MEMLOCK
	if (mfsopts.memlock) {
		if (mlockall(MCL_CURRENT|MCL_FUTURE)==0) {
			syslog(LOG_NOTICE,"process memory was successfully locked in RAM");
		}
	}
#endif

/* glibc malloc tuning */
#ifdef MFS_USE_MALLOPT
	if (mfsopts.limitarenas) {
		if (!getenv("MALLOC_ARENA_MAX")) {
			syslog(LOG_NOTICE,"setting glibc malloc arena max to 8");
			mallopt(M_ARENA_MAX, mfsopts.limitarenas);
		}
		if (!getenv("MALLOC_ARENA_TEST")) {
			syslog(LOG_NOTICE,"setting glibc malloc arena test to 1");
			mallopt(M_ARENA_TEST, 1);
		}
	} else {
		syslog(LOG_NOTICE,"setting glibc malloc arenas turned off");
	}
#endif /* glibc malloc tuning */

	syslog(LOG_NOTICE,"monotonic clock function: %s",monotonic_method());
	syslog(LOG_NOTICE,"monotonic clock speed: %"PRIu32" ops / 10 mili seconds",monotonic_speed());

	conncache_init(200);
	chunkloc_cache_init();
	symlink_cache_init();
	negentry_cache_init(mfsopts.negentrycacheto);
//	dir_cache_init();
	fs_init_threads(mfsopts.ioretries);
	if (masterproxy_init(mfsopts.proxyhost)<0) {
		fs_term();
//		dir_cache_term();
		negentry_cache_term();
		symlink_cache_term();
		chunkloc_cache_term();
		return 1;
	}

//	fs_term();
//	negentry_cache_term();
//	symlink_cache_term();
//	chunkloc_cache_term();
//	return 1;

	if (mfsopts.meta==0) {
		csdb_init();
		delay_init();
		read_data_init(mfsopts.readaheadsize*1024*1024,mfsopts.readaheadleng,mfsopts.readaheadtrigger,mfsopts.ioretries);
		write_data_init(mfsopts.writecachesize*1024*1024,mfsopts.ioretries);
	}

 	ch = fuse_mount(mp, args);
	if (ch==NULL) {
		fprintf(stderr,"error in fuse_mount\n");
		if (piped[1]>=0) {
			if (write(piped[1],&s,1)!=1) {
				fprintf(stderr,"pipe write error\n");
			}
			close(piped[1]);
		}
		if (mfsopts.meta==0) {
			write_data_term();
			read_data_term();
			delay_term();
			csdb_term();
		}
		masterproxy_term();
		fs_term();
//		dir_cache_term();
		negentry_cache_term();
		symlink_cache_term();
		chunkloc_cache_term();
		return 1;
	}

	if (mfsopts.meta) {
		mfs_meta_init(mfsopts.debug,mfsopts.entrycacheto,mfsopts.attrcacheto);
		se = fuse_lowlevel_new(args, &mfs_meta_oper, sizeof(mfs_meta_oper), (void*)piped);
	} else {
		mfs_init(mfsopts.debug,mfsopts.keepcache,mfsopts.direntrycacheto,mfsopts.entrycacheto,mfsopts.attrcacheto,mfsopts.xattrcacheto,mfsopts.groupscacheto,mfsopts.mkdircopysgid,mfsopts.sugidclearmode,1,mfsopts.fsyncbeforeclose,mfsopts.noxattrs,mfsopts.noposixlocks,mfsopts.nobsdlocks); //mfsopts.xattraclsupport);
		se = fuse_lowlevel_new(args, &mfs_oper, sizeof(mfs_oper), (void*)piped);
	}
	if (se==NULL) {
		fuse_unmount(mp,ch);
		fprintf(stderr,"error in fuse_lowlevel_new\n");
		portable_usleep(100000);	// time for print other error messages by FUSE
		if (piped[1]>=0) {
			if (write(piped[1],&s,1)!=1) {
				fprintf(stderr,"pipe write error\n");
			}
			close(piped[1]);
		}
		if (mfsopts.meta==0) {
			write_data_term();
			read_data_term();
			delay_term();
			csdb_term();
		}
		masterproxy_term();
		fs_term();
//		dir_cache_term();
		negentry_cache_term();
		symlink_cache_term();
		chunkloc_cache_term();
		return 1;
	}

//	fprintf(stderr,"check\n");
	fuse_session_add_chan(se, ch);

	if (fuse_set_signal_handlers(se)<0) {
		fprintf(stderr,"error in fuse_set_signal_handlers\n");
		fuse_session_remove_chan(ch);
		fuse_session_destroy(se);
		fuse_unmount(mp,ch);
		if (piped[1]>=0) {
			if (write(piped[1],&s,1)!=1) {
				fprintf(stderr,"pipe write error\n");
			}
			close(piped[1]);
		}
		if (mfsopts.meta==0) {
			write_data_term();
			read_data_term();
			delay_term();
			csdb_term();
		}
		masterproxy_term();
		fs_term();
//		dir_cache_term();
		negentry_cache_term();
		symlink_cache_term();
		chunkloc_cache_term();
		return 1;
	}

	if (mfsopts.debug==0 && fg==0) {
		setsid();
		setpgid(0,getpid());
		if ((i = open("/dev/null", O_RDWR, 0)) != -1) {
			(void)dup2(i, STDIN_FILENO);
			(void)dup2(i, STDOUT_FILENO);
			(void)dup2(i, STDERR_FILENO);
			if (i>2) close (i);
		}
	}

	if (mt) {
		err = fuse_session_loop_mt(se);
	} else {
		err = fuse_session_loop(se);
	}
	if (err) {
		if (piped[1]>=0) {
			if (write(piped[1],&s,1)!=1) {
				syslog(LOG_ERR,"pipe write error: %s",strerr(errno));
			}
			close(piped[1]);
		}
	}
	fuse_remove_signal_handlers(se);
	fuse_session_remove_chan(ch);
	fuse_session_destroy(se);
	fuse_unmount(mp,ch);
	if (mfsopts.meta==0) {
		write_data_term();
		read_data_term();
		delay_term();
		csdb_term();
	}
	masterproxy_term();
	fs_term();
//	dir_cache_term();
	negentry_cache_term();
	symlink_cache_term();
	chunkloc_cache_term();
	return err ? 1 : 0;
}
Exemplo n.º 3
0
int
copy_main (int argc, char **argv)
{
	char source_a[PATH_MAX], source_b[PATH_MAX];
	char dest_a[PATH_MAX], dest_b[PATH_MAX];
	char *tmp;
	struct backup_info *info_b, *info_r;
	int opt, loop, thresh = 0, threshopt = 0;
	unsigned int varsize = 0, swapsize = 0;
	unsigned int bflags = BF_BACKUPVAR, rflags = 0;
	int quiet = 0;
	int bswap = 0;
	int expand = 0;
	int expandscale = 2;

	tivo_partition_direct ();

	while ((opt = getopt (argc, argv, "hqf:L:tTaspxr:v:S:lbBzE")) > 0)
	{
		switch (opt)
		{
		case 'q':
			quiet++;
			break;
		case 's':
			bflags |= BF_SHRINK;
			break;
		case 'E':
			bflags |= BF_TRUNCATED;
			break;
		case 'f':
			if (threshopt)
			{
				fprintf (stderr, "%s: -f and -%c cannot be used together\n", argv[0], threshopt);
				return 1;
			}
			threshopt = loop;
			thresh = strtoul (optarg, &tmp, 10);
			if (*tmp)
			{
				fprintf (stderr, "%s: Non integer argument to -f\n", argv[0]);
				return 1;
			}
			break;
		case 'L':
			if (threshopt)
			{
				fprintf (stderr, "%s: -l and -%c cannot be used together\n", argv[0], threshopt);
				return 1;
			}
			threshopt = loop;
			thresh = strtoul (optarg, &tmp, 10);
			thresh *= 1024 * 2;
			bflags |= BF_THRESHSIZE;
			if (*tmp)
			{
				fprintf (stderr, "%s: Non integer argument to -L\n", argv[0]);
				return 1;
			}
			break;
		case 't':
			bflags |= BF_THRESHTOT;
			break;
		case 'T':
			bflags |= BF_STREAMTOT;
			break;
		case 'a':
			if (threshopt)
			{
				fprintf (stderr, "%s: -a and -%c cannot be used together\n", argv[0], threshopt);
				return 1;
			}
			threshopt = loop;
			thresh = ~0;
			break;

		case 'v':
			bflags &= ~BF_BACKUPVAR;
			varsize = strtoul (optarg, &tmp, 10);
			varsize *= 1024 * 2;
			if (tmp && *tmp)
			{
				fprintf (stderr, "%s: Integer argument expected for -v.\n", argv[0]);
				return 1;
			}
			break;
		case 'S':
			swapsize = strtoul (optarg, &tmp, 10);
			swapsize *= 1024 * 2;
			if (tmp && *tmp)
			{
				fprintf (stderr, "%s: Integer argument expected for -s.\n", argv[0]);
				return 1;
			}
			break;
		case 'z':
			rflags |= RF_ZEROPART;
			break;
		case 'b':
			if (bswap != 0)
			{
				fprintf (stderr, "%s: Only one byte swapping option (-b/-B) allowed.\n", argv[0]);
				return 1;
			}
			bswap = -1;
			break;
		case 'B':
			if (bswap != 0)
			{
				fprintf (stderr, "%s: Only one byte swapping option (-b/-B) allowed.\n", argv[0]);
				return 1;
			}
			bswap = 1;
			break;
		case 'p':
			rflags |= RF_BALANCE;
			break;
		case 'l':
			rflags |= RF_NOFILL;
			break;
		case 'x':
			expand = 1;
			break;
		case 'r':
			expandscale = strtoul (optarg, &tmp, 10);
			if (tmp && *tmp)
			{
				fprintf (stderr, "%s: Integer argument expected for -r.\n", argv[0]);
				return 1;
			}
			if (expandscale < 0 || expandscale > 4)
			{
				fprintf (stderr, "%s: Scale value for -r must be in the range 0 to 4.\n", argv[0]);
				return 1;
			}
			break;
		default:
			copy_usage (argv[0]);
			return 1;
		}
	}

	// Split out the drive names
	source_a[0] = 0;
	source_b[0] = 0;
	dest_a[0] = 0;
	dest_b[0] = 0;

	if (argc - optind < 4)
	{
		if (optind < argc)
		{
			get_drives (argv[optind++], source_a, source_b);
		}
		if (optind < argc)
		{
			get_drives (argv[optind++], dest_a, dest_b);
		}
	}
	else
	{
// Special case for convenience - 2 source and 2 target named
		strcpy (source_a, argv[optind++]);
		strcpy (source_b, argv[optind++]);
		strcpy (dest_a, argv[optind++]);
		strcpy (dest_b, argv[optind++]);
	}

	if (optind < argc || !*source_a || !*dest_a)
	{
		copy_usage (argv[0]);
		return 1;
	}

	if (expand > 0)
		rflags |= RF_NOFILL;

	info_b = init_backup (source_a, source_b, bflags);

	// Try to continue anyway despite error.
	if (bflags & BF_TRUNCATED && backup_has_error (info_b))
	{
		backup_perror (info_b, "WARNING");
		fprintf (stderr, "Attempting copy anyway\n");
		backup_check_truncated_volume (info_b);
		if (info_b && backup_has_error (info_b))
		{
			backup_perror (info_b, "Copy source");
			return 1;
		}
	}

	if (info_b && backup_has_error (info_b))
	{
		backup_perror (info_b, "Copy source");

		fprintf (stderr, "To attempt copy anyway, try again with -E.  -s is implied by -E.\n");
		return 1;
	}

	info_r = init_restore (rflags);
	if (info_r && restore_has_error (info_r))
	{
		restore_perror (info_r, "Copy target");
		return 1;
	}

	if (!info_b || !info_r)
	{
		fprintf (stderr, "%s: Copy failed to start.  Make sure you specified the right\ndevices, and that the drives are not locked.\n", argv[0]);
		return 1;
	}
	else
	{
		unsigned starttime;
		char buf[BUFSIZE];
		unsigned int curcount = 0;
		int nread, nwrit;

		if (threshopt)
			backup_set_thresh (info_b, thresh);

		if (varsize)
			restore_set_varsize (info_r, varsize);
		if (swapsize)
			restore_set_swapsize (info_r, swapsize);
		if (bswap)
			restore_set_bswap (info_r, bswap);

		if (quiet < 2)
			fprintf (stderr, "Scanning source drive.  Please wait a moment.\n");

		if (backup_start (info_b) < 0)
		{
			if (backup_has_error (info_b))
				backup_perror (info_b, "Copy source");
			else
				fprintf (stderr, "Copy source failed.\n");
			return 1;
		}

// Fill the buffer up to start.  Restore needs some information to bootstrap
// the process.
		while (curcount < BUFSIZE && (nread = backup_read (info_b, buf, BUFSIZE - curcount)) > 0)
		{
			curcount += nread;
		}

		if (curcount < BUFSIZE)
		{
			if (backup_has_error (info_b))
				backup_perror (info_b, "Copy source");
			else
				fprintf (stderr, "Copy source failed.\n");
			return 1;
		}

		nread = curcount;

		nwrit = restore_write (info_r, buf, nread);
		if (nwrit < 0)
		{
			if (restore_has_error (info_r))
				restore_perror (info_r, "Copy target");
			else
				fprintf (stderr, "Copy target failed.\n");
			return 1;
		}

		if (restore_trydev (info_r, dest_a, dest_b) < 0)
		{
			if (restore_has_error (info_r))
				restore_perror (info_r, "Copy target");
			else
				fprintf (stderr, "Copy target failed.\n");
			return 1;
		}

		if (restore_start (info_r) < 0)
		{
			if (restore_has_error (info_r))
				restore_perror (info_r, "Copy target");
			else
				fprintf (stderr, "Copy target failed.\n");
			return 1;
		}

		if (restore_write (info_r, buf + nwrit, nread - nwrit) != nread - nwrit)
		{
			if (restore_has_error (info_r))
				restore_perror (info_r, "Copy target");
			else
				fprintf (stderr, "Copy target failed.\n");
			return 1;
		}

		starttime = time (NULL);

		fprintf (stderr, "Starting copy\nSize: %d megabytes\n", info_r->nsectors / 2048);
		while ((curcount = backup_read (info_b, buf, BUFSIZE)) > 0)
		{
			unsigned int prcnt, compr;
			if (restore_write (info_r, buf, curcount) != curcount)
			{
				if (quiet < 1)
					fprintf (stderr, "\n");
				if (restore_has_error (info_r))
					restore_perror (info_r, "Copy source");
				else
					fprintf (stderr, "Copy source failed.\n");
				return 1;
			}
			prcnt = get_percent (info_r->cursector, info_r->nsectors);
			if (quiet < 1)
			{
				unsigned timedelta = time(NULL) - starttime;

				fprintf (stderr, "\rCopying %d of %d mb (%d.%02d%%)", info_r->cursector / 2048, info_r->nsectors / 2048, prcnt / 100, prcnt % 100);

				if (prcnt > 100 && timedelta > 15)
				{
					unsigned ETA = timedelta * (10000 - prcnt) / prcnt;
					fprintf (stderr, " %d mb/sec (ETA %d:%02d:%02d)", info_r->cursector / timedelta / 2048, ETA / 3600, ETA / 60 % 60, ETA % 60);
				}
			}
		}

		if (quiet < 1)
			fprintf (stderr, "\n");

		if (backup_has_error (info_b))
		{
			backup_perror (info_b, "Copy source");
			return 1;
		}

		if (restore_has_error (info_r))
		{
			restore_perror (info_r, "Copy target");
			return 1;
		}
	}

	if (backup_finish (info_b) < 0)
	{
		if (backup_has_error (info_b))
			backup_perror (info_b, "Copy source");
		else
			fprintf (stderr, "Copy source failed.\n");
		return 1;
	}

	if (info_b->back_flags & BF_TRUNCATED)
	{
		fprintf (stderr, "***WARNING***\nCopy was made of an incomplete volume.  While the copy succeeded,\nit is possible there was some required data missing.  Verify your copy.\n");
	}

	if (quiet < 2)
		fprintf (stderr, "Cleaning up target.  Please wait a moment.\n");

	if (restore_finish (info_r) < 0)
	{
		if (restore_has_error (info_r))
			restore_perror (info_r, "Copy target");
		else
			fprintf (stderr, "Copy target failed.\n");
		return 1;
	}

	if (quiet < 2)
		fprintf (stderr, "Copy done!\n");

	if (expand > 0)
	{
		int blocksize = 0x800;
		struct mfs_handle *mfshnd;

		expand = 0;

		mfshnd = mfs_init (dest_a, dest_b, O_RDWR);
		if (!mfshnd)
		{
			fprintf (stderr, "Drive expansion failed.\n");
			return 1;
		}

		if (mfs_has_error (mfshnd))
		{
			mfs_perror (mfshnd, "Target expand");
			return 1;
		}

		while (expandscale-- > 0)
			blocksize *= 2;

		if (tivo_partition_largest_free (dest_a) > 1024 * 1024 * 2)
		{
			if (expand_drive (mfshnd, "/dev/hda", dest_a, blocksize) < 0)
			{
				if (mfs_has_error (mfshnd))
					mfs_perror (mfshnd, "Expand drive A");
				else
					fprintf (stderr, "Drive A expansion failed.\n");
				return 1;
			}
			expand++;
		}

		if (dest_b[0] && tivo_partition_largest_free (dest_b) > 1024 * 1024 * 2)
		{
			if (expand_drive (mfshnd, "/dev/hdb", dest_b, blocksize) < 0)
			{
				if (mfs_has_error (mfshnd))
					mfs_perror (mfshnd, "Expand drive B");
				else
					fprintf (stderr, "Drive B expansion failed.\n");
				return 1;
			}
			expand++;
		}

		if (!expand)
		{
			fprintf (stderr, "Not enough extra space to expand on A drive%s.\n", dest_b[0]? " or B drive": "");
		}
	}

	return 0;
}