Exemple #1
0
int partition_stat_get(partition_stat_t *stat)
{
    FILE *mnt_file     = NULL;
    struct mntent *mnt = NULL;
    struct statfs fsbuf;

    bzero(stat, sizeof(partition_stat_t));

    mnt_file = setmntent(MTAB_FILE, "r");
    if (NULL == mnt_file) {
        log_error("setmntext failed.");
        return 0;
    }

    while (NULL != (mnt = getmntent(mnt_file))) {
        if (stat->count >= MAX_PARTITIOn_COUNT) {
            log_warn("partition count >= %d.", MAX_PARTITIOn_COUNT);
            break;
        }

        if(strncmp(mnt->mnt_fsname, "/", 1)) {
            continue;
        }

        strncpy(stat->partitions[stat->count].fs_name, mnt->mnt_fsname + 5, MAX_FS_NAME_SIZE - 1);
        strncpy(stat->partitions[stat->count].mnt_dir, mnt->mnt_dir, MAX_MNT_DIR_SIZE - 1);

        if (!statfs(mnt->mnt_dir, &fsbuf)) {
            stat->partitions[stat->count].type   = fsbuf.f_type;
            stat->partitions[stat->count].bsize  = fsbuf.f_bsize;
            stat->partitions[stat->count].blocks = fsbuf.f_blocks;
            stat->partitions[stat->count].bfree  = fsbuf.f_bfree;
            stat->partitions[stat->count].bavail = fsbuf.f_bavail;
            stat->partitions[stat->count].status = disk_status(mnt->mnt_dir);
        }
        else {
            log_error("statfs for %s failed, %s.", mnt->mnt_dir); 
            stat->partitions[stat->count].status = PARTITION_STATUS_ERROR;
        }

        stat->partitions[stat->count].total_size         = (fsbuf.f_bsize/1024) * (fsbuf.f_blocks/1024); 
        stat->partitions[stat->count].nonroot_total_size = 
            (fsbuf.f_bsize/1024) * ((fsbuf.f_blocks - fsbuf.f_bfree + fsbuf.f_bavail)/1024);
        stat->partitions[stat->count].used_size          = (fsbuf.f_bsize/1024) * ((fsbuf.f_blocks - fsbuf.f_bfree)/1024);
        stat->partitions[stat->count].avail_size         = (fsbuf.f_bsize/1024) * (fsbuf.f_bavail/1024);

        if (stat->partitions[stat->count].nonroot_total_size != 0) {
            stat->partitions[stat->count].usage = 
                (float)stat->partitions[stat->count].used_size/(float)stat->partitions[stat->count].nonroot_total_size;
        }
        else {
            stat->partitions[stat->count].usage = 0;
        }

        stat->nonroot_total_size += stat->partitions[stat->count].nonroot_total_size;
        stat->total_size         += stat->partitions[stat->count].total_size;
        stat->used_size          += stat->partitions[stat->count].used_size;
        stat->avail_size         += stat->partitions[stat->count].avail_size;

        stat->count++;
    }

    stat->usage = (float)stat->used_size/(float)stat->nonroot_total_size;
    endmntent(mnt_file);

    return 1;
}
int init_ctl_channel(const char *name, int verb)
{
	char buf[PATH_MAX];
	struct statfs st;
	int old_transport = 0;

        (void) verb;
        if (0) goto out; /* just to defeat gcc warnings */

	/* Before trying to open the control channel, make sure it
	 * isn't already open. */
	close_ctl_channel();

#ifdef HAVE_OPENAT
        if (relay_basedir_fd >= 0) {
                strncpy(buf, CTL_CHANNEL_NAME, PATH_MAX);
                control_channel = openat_cloexec(relay_basedir_fd,
						 CTL_CHANNEL_NAME, O_RDWR, 0);
                dbug(2, "Opened %s (%d)\n", CTL_CHANNEL_NAME, control_channel);

                /* NB: Extra real-id access check as below */
                if (faccessat(relay_basedir_fd, CTL_CHANNEL_NAME, R_OK|W_OK, 0) != 0){
                        close(control_channel);
                        return -5;
                }
                if (control_channel >= 0)
                        goto out; /* It's OK to bypass the [f]access[at] check below,
                                     since this would only occur the *second* time 
                                     staprun tries this gig, or within unprivileged stapio. */
        }
        /* PR14245, NB: we fall through to /sys ... /proc searching,
           in case the relay_basedir_fd option wasn't given (i.e., for
           early in staprun), or if errors out for some reason. */
#endif

	if (statfs("/sys/kernel/debug", &st) == 0 && (int)st.f_type == (int)DEBUGFS_MAGIC) {
                /* PR14245: allow subsequent operations, and if
                   necessary, staprun->stapio forks, to reuse an fd for 
                   directory lookups (even if some parent directories have
                   perms 0700. */
#ifdef HAVE_OPENAT
                if (! sprintf_chk(buf, "/sys/kernel/debug/systemtap/%s", name)) {
                        relay_basedir_fd = open (buf, O_DIRECTORY | O_RDONLY);
                        /* If this fails, we don't much care; the
                           negative return value will just keep us
                           looking up by name again next time. */
                        /* NB: we don't plan to close this fd, so that we can pass
                           it across staprun->stapio fork/execs. */
                }
#endif
		if (sprintf_chk(buf, "/sys/kernel/debug/systemtap/%s/%s", 
                                name, CTL_CHANNEL_NAME))
			return -1;
	} else {
		old_transport = 1;
		if (sprintf_chk(buf, "/proc/systemtap/%s/%s", name, CTL_CHANNEL_NAME))
			return -2;
	}

	control_channel = open_cloexec(buf, O_RDWR, 0);
	dbug(2, "Opened %s (%d)\n", buf, control_channel);

	/* NB: Even if open() succeeded with effective-UID permissions, we
	 * need the access() check to make sure real-UID permissions are also
	 * sufficient.  When we run under the setuid staprun, effective and
	 * real UID may not be the same.  Specifically, we want to prevent 
         * a local stapusr from trying to attach to a different stapusr's module.
	 *
	 * The access() is done *after* open() to avoid any TOCTOU-style race
	 * condition.  We believe it's probably safe either way, as the file
	 * we're trying to access connot be modified by a typical user, but
	 * better safe than sorry.
	 */
#ifdef HAVE_OPENAT
        if (control_channel >= 0 && relay_basedir_fd >= 0) {
                if (faccessat (relay_basedir_fd, CTL_CHANNEL_NAME, R_OK|W_OK, 0) == 0)
                        goto out;
                /* else fall through */
        }
#endif
	if (control_channel >= 0 && access(buf, R_OK|W_OK) != 0) {
		close(control_channel);
		return -5;
	}

out:
	if (control_channel < 0) {
                err(_("Cannot attach to module %s control channel; not running?\n"),
                    name);
		return -3;
	}
	return old_transport;
}
TEST(sys_vfs, statfs) {
  struct statfs sb;
  ASSERT_EQ(0, statfs("/proc", &sb));
  Check(sb);
}
static int local_statfs(FsContext *s, const char *path, struct statfs *stbuf)
{
   return statfs(rpath(s, path), stbuf);
}
Exemple #5
0
int
do_move(char *from, char *to)
{
	struct stat sb, fsb;
	char modep[15];

	/* Source path must exist (symlink is OK). */
	if (lstat(from, &fsb)) {
		warn("%s", from);
		return (1);
	}

	/*
	 * (1)	If the destination path exists, the -f option is not specified
	 *	and either of the following conditions are true:
	 *
	 *	(a) The permissions of the destination path do not permit
	 *	    writing and the standard input is a terminal.
	 *	(b) The -i option is specified.
	 *
	 *	the mv utility shall write a prompt to standard error and
	 *	read a line from standard input.  If the response is not
	 *	affirmative, mv shall do nothing more with the current
	 *	source file...
	 */
	if (!fflg && !access(to, F_OK)) {
		int ask = 1;
		int ch, first;

		if (iflg && !access(from, F_OK)) {
			(void)fprintf(stderr, "overwrite %s? ", to);
		} else if (stdin_ok && access(to, W_OK) && !stat(to, &sb)) {
			strmode(sb.st_mode, modep);
			(void)fprintf(stderr, "override %s%s%s/%s for %s? ",
			    modep + 1, modep[9] == ' ' ? "" : " ",
			    user_from_uid(sb.st_uid, 0),
			    group_from_gid(sb.st_gid, 0), to);
		} else
			ask = 0;
		if (ask) {
			first = ch = getchar();
			while (ch != '\n' && ch != EOF)
				ch = getchar();
			if (first != 'y' && first != 'Y')
				return (0);
		}
	}

	/*
	 * (2)	If rename() succeeds, mv shall do nothing more with the
	 *	current source file.  If it fails for any other reason than
	 *	EXDEV, mv shall write a diagnostic message to the standard
	 *	error and do nothing more with the current source file.
	 *
	 * (3)	If the destination path exists, and it is a file of type
	 *	directory and source_file is not a file of type directory,
	 *	or it is a file not of type directory, and source file is
	 *	a file of type directory, mv shall write a diagnostic
	 *	message to standard error, and do nothing more with the
	 *	current source file...
	 */
	if (!rename(from, to))
		return (0);

	if (errno != EXDEV) {
		warn("rename %s to %s", from, to);
		return (1);
	}

	/* Disallow moving a mount point. */
	if (S_ISDIR(fsb.st_mode)) {
		struct statfs sfs;
		char path[MAXPATHLEN];

		if (realpath(from, path) == NULL) {
			warnx("cannot resolve %s", from);
			return (1);
		}
		if (!statfs(path, &sfs) && !strcmp(path, sfs.f_mntonname)) {
			warnx("cannot rename a mount point");
			return (1);
		}
	}

	/*
	 * (4)	If the destination path exists, mv shall attempt to remove it.
	 *	If this fails for any reason, mv shall write a diagnostic
	 *	message to the standard error and do nothing more with the
	 *	current source file...
	 */
	if (!lstat(to, &sb)) {
		if ((S_ISDIR(sb.st_mode)) ? rmdir(to) : unlink(to)) {
			warn("can't remove %s", to);
			return (1);
		}
	}

	/*
	 * (5)	The file hierarchy rooted in source_file shall be duplicated
	 *	as a file hierarchy rooted in the destination path...
	 */
	return (S_ISREG(fsb.st_mode) ?
	    fastcopy(from, to, &fsb) : copy(from, to));
}
Exemple #6
0
/* Unit should be a power-of-2 (e.g. 1024 to report kilobytes) or 1 (to report bytes) */
static ulong getdiskspace(const char* path, ulong unit, BOOL freespace)
{
#if defined(_WIN32)
	char			root[16];
	DWORD			TotalNumberOfClusters;
	DWORD			NumberOfFreeClusters;
	DWORD			BytesPerSector;
	DWORD			SectorsPerCluster;
	ULARGE_INTEGER	avail;
	ULARGE_INTEGER	size;
	static HINSTANCE hK32;
	GetDiskFreeSpaceEx_t GetDiskFreeSpaceEx;

	if(hK32 == NULL)
		hK32 = LoadLibrary("KERNEL32");
	GetDiskFreeSpaceEx
		= (GetDiskFreeSpaceEx_t)GetProcAddress(hK32,"GetDiskFreeSpaceExA");

	if (GetDiskFreeSpaceEx!=NULL) {	/* Windows 95-OSR2 or later */
		if(!GetDiskFreeSpaceEx(
			path,		/* pointer to the directory name */
			&avail,		/* receives the number of bytes on disk avail to the caller */
			&size,		/* receives the number of bytes on disk */
			NULL))		/* receives the free bytes on disk */
			return(0);

		if(freespace)
			size=avail;

		if(unit>1)
			size.QuadPart=Int64ShrlMod32(size.QuadPart,bit_num(unit));

#if defined(_ANONYMOUS_STRUCT)
		if(size.HighPart)
#else
		if(size.u.HighPart)
#endif
			return(0xffffffff);	/* 4GB max */

#if defined(_ANONYMOUS_STRUCT)
		return(size.LowPart);
#else
		return(size.u.LowPart);
#endif
	}

	/* Windows 95 (old way), limited to 2GB */
	sprintf(root,"%.3s",path);
	if(!GetDiskFreeSpace(
		root,					/* pointer to root path */
		(PDWORD)&SectorsPerCluster,		/* pointer to sectors per cluster */
		(PDWORD)&BytesPerSector,		/* pointer to bytes per sector */
		(PDWORD)&NumberOfFreeClusters,	/* pointer to number of free clusters */
		(PDWORD)&TotalNumberOfClusters  /* pointer to total number of clusters */
		))
		return(0);

	if(freespace)
		TotalNumberOfClusters = NumberOfFreeClusters;
	if(unit>1)
		TotalNumberOfClusters/=unit;
	return(TotalNumberOfClusters*SectorsPerCluster*BytesPerSector);


#elif defined(__solaris__) || (defined(__NetBSD_Version__) && (__NetBSD_Version__ >= 300000000 /* NetBSD 3.0 */))

	struct statvfs fs;
	unsigned long blocks;

    if (statvfs(path, &fs) < 0)
    	return 0;

	if(freespace)
		blocks=fs.f_bavail;
	else
		blocks=fs.f_blocks;

	if(unit>1)
		blocks/=unit;
    return fs.f_bsize * blocks;

/* statfs is also used under FreeBSD (Though it *supports* statvfs() now too) */
#elif defined(__GLIBC__) || defined(BSD)

	struct statfs fs;
	unsigned long blocks;

    if (statfs(path, &fs) < 0)
    	return 0;

	if(freespace)
		blocks=fs.f_bavail;
	else
		blocks=fs.f_blocks;

	if(unit>1)
		blocks/=unit;
    return fs.f_bsize * blocks;

#else

	fprintf(stderr,"\n*** !Missing getfreediskspace implementation ***\n");
	return(0);

#endif
}
Exemple #7
0
int
main(int argc, char *argv[])
{
	struct stat stbuf;
	struct statfs *mntbuf;
	long mntsize;
	int ch, i;
	int width, maxwidth;
	char *mntpt;

	if (pledge("stdio rpath", NULL) == -1)
		err(1, "pledge");

	while ((ch = getopt(argc, argv, "hiklnPt:")) != -1)
		switch (ch) {
		case 'h':
			hflag = 1;
			kflag = 0;
			break;
		case 'i':
			iflag = 1;
			break;
		case 'k':
			kflag = 1;
			hflag = 0;
			break;
		case 'l':
			lflag = 1;
			break;
		case 'n':
			nflag = 1;
			break;
		case 'P':
			Pflag = 1;
			break;
		case 't':
			if (typelist != NULL)
				errx(1, "only one -t option may be specified.");
			maketypelist(optarg);
			break;
		default:
			usage();
		}
	argc -= optind;
	argv += optind;

	if ((iflag || hflag) && Pflag) {
		warnx("-h and -i are incompatible with -P");
		usage();
	}

	mntsize = getmntinfo(&mntbuf, MNT_NOWAIT);
	if (mntsize == 0)
		err(1, "retrieving information on mounted file systems");

	if (!*argv) {
		mntsize = regetmntinfo(&mntbuf, mntsize);
	} else {
		mntbuf = calloc(argc, sizeof(struct statfs));
		if (mntbuf == NULL)
			err(1, NULL);
		mntsize = 0;
		for (; *argv; argv++) {
			if (stat(*argv, &stbuf) < 0) {
				if ((mntpt = getmntpt(*argv)) == 0) {
					warn("%s", *argv);
					continue;
				}
			} else if (S_ISCHR(stbuf.st_mode) || S_ISBLK(stbuf.st_mode)) {
				if (!raw_df(*argv, &mntbuf[mntsize]))
					++mntsize;
				continue;
			} else
				mntpt = *argv;
			/*
			 * Statfs does not take a `wait' flag, so we cannot
			 * implement nflag here.
			 */
			if (!statfs(mntpt, &mntbuf[mntsize]))
				if (lflag && (mntbuf[mntsize].f_flags & MNT_LOCAL) == 0)
					warnx("%s is not a local file system",
					    *argv);
				else if (!selected(mntbuf[mntsize].f_fstypename))
					warnx("%s mounted as a %s file system",
					    *argv, mntbuf[mntsize].f_fstypename);
				else
					++mntsize;
			else
				warn("%s", *argv);
		}
	}

	if (mntsize) {
		maxwidth = 11;
		for (i = 0; i < mntsize; i++) {
			width = strlen(mntbuf[i].f_mntfromname);
			if (width > maxwidth)
				maxwidth = width;
		}

		if (Pflag)
			posixprint(mntbuf, mntsize, maxwidth);
		else
			bsdprint(mntbuf, mntsize, maxwidth);
	}

	return (mntsize ? 0 : 1);
}
Exemple #8
0
int
main(int argc, char *argv[])
{
	struct stat stbuf;
	struct statfs statfsbuf, totalbuf;
	struct maxwidths maxwidths;
	struct statfs *mntbuf;
	const char *fstype;
	char *mntpath, *mntpt;
	const char **vfslist;
	int i, mntsize;
	int ch, rv;

	fstype = "ufs";

	memset(&totalbuf, 0, sizeof(totalbuf));
	totalbuf.f_bsize = DEV_BSIZE;
	strlcpy(totalbuf.f_mntfromname, "total", MNAMELEN);
	vfslist = NULL;
	while ((ch = getopt(argc, argv, "abcgHhiklmnPt:T")) != -1)
		switch (ch) {
		case 'a':
			aflag = 1;
			break;
		case 'b':
				/* FALLTHROUGH */
		case 'P':
			/*
			 * POSIX specifically discusses the behavior of
			 * both -k and -P. It states that the blocksize should
			 * be set to 1024. Thus, if this occurs, simply break
			 * rather than clobbering the old blocksize.
			 */
			if (kflag)
				break;
			setenv("BLOCKSIZE", "512", 1);
			hflag = 0;
			break;
		case 'c':
			cflag = 1;
			break;
		case 'g':
			setenv("BLOCKSIZE", "1g", 1);
			hflag = 0;
			break;
		case 'H':
			hflag = UNITS_SI;
			break;
		case 'h':
			hflag = UNITS_2;
			break;
		case 'i':
			iflag = 1;
			break;
		case 'k':
			kflag++;
			setenv("BLOCKSIZE", "1024", 1);
			hflag = 0;
			break;
		case 'l':
			if (vfslist != NULL)
				errx(1, "-l and -t are mutually exclusive.");
			vfslist = makevfslist(makenetvfslist());
			lflag = 1;
			break;
		case 'm':
			setenv("BLOCKSIZE", "1m", 1);
			hflag = 0;
			break;
		case 'n':
			nflag = 1;
			break;
		case 't':
			if (lflag)
				errx(1, "-l and -t are mutually exclusive.");
			if (vfslist != NULL)
				errx(1, "only one -t option may be specified");
			fstype = optarg;
			vfslist = makevfslist(optarg);
			break;
		case 'T':
			Tflag = 1;
			break;
		case '?':
		default:
			usage();
		}
	argc -= optind;
	argv += optind;

	rv = 0;
	if (!*argv) {
		/* everything (modulo -t) */
		mntsize = getmntinfo(&mntbuf, MNT_NOWAIT);
		mntsize = regetmntinfo(&mntbuf, mntsize, vfslist);
	} else {
		/* just the filesystems specified on the command line */
		mntbuf = malloc(argc * sizeof(*mntbuf));
		if (mntbuf == 0)
			err(1, "malloc()");
		mntsize = 0;
		/* continued in for loop below */
	}

	/* iterate through specified filesystems */
	for (; *argv; argv++) {
		if (stat(*argv, &stbuf) < 0) {
			if ((mntpt = getmntpt(*argv)) == 0) {
				warn("%s", *argv);
				rv = 1;
				continue;
			}
		} else if (S_ISCHR(stbuf.st_mode)) {
			if ((mntpt = getmntpt(*argv)) == 0) {
				mdev.fspec = *argv;
				mntpath = strdup("/tmp/df.XXXXXX");
				if (mntpath == NULL) {
					warn("strdup failed");
					rv = 1;
					continue;
				}
				mntpt = mkdtemp(mntpath);
				if (mntpt == NULL) {
					warn("mkdtemp(\"%s\") failed", mntpath);
					rv = 1;
					free(mntpath);
					continue;
				}
				if (mount(fstype, mntpt, MNT_RDONLY,
				    &mdev) != 0) {
					warn("%s", *argv);
					rv = 1;
					(void)rmdir(mntpt);
					free(mntpath);
					continue;
				} else if (statfs(mntpt, &statfsbuf) == 0) {
					statfsbuf.f_mntonname[0] = '\0';
					prtstat(&statfsbuf, &maxwidths);
					if (cflag)
						addstat(&totalbuf, &statfsbuf);
				} else {
					warn("%s", *argv);
					rv = 1;
				}
				(void)unmount(mntpt, 0);
				(void)rmdir(mntpt);
				free(mntpath);
				continue;
			}
		} else
			mntpt = *argv;

		/*
		 * Statfs does not take a `wait' flag, so we cannot
		 * implement nflag here.
		 */
		if (statfs(mntpt, &statfsbuf) < 0) {
			warn("%s", mntpt);
			rv = 1;
			continue;
		}

		/*
		 * Check to make sure the arguments we've been given are
		 * satisfied.  Return an error if we have been asked to
		 * list a mount point that does not match the other args
		 * we've been given (-l, -t, etc.).
		 */
		if (checkvfsname(statfsbuf.f_fstypename, vfslist)) {
			rv = 1;
			continue;
		}

		/* the user asked for it, so ignore the ignore flag */
		statfsbuf.f_flags &= ~MNT_IGNORE;

		/* add to list */
		mntbuf[mntsize++] = statfsbuf;
	}

	bzero(&maxwidths, sizeof(maxwidths));
	for (i = 0; i < mntsize; i++) {
		if (aflag || (mntbuf[i].f_flags & MNT_IGNORE) == 0) {
			update_maxwidths(&maxwidths, &mntbuf[i]);
			if (cflag)
				addstat(&totalbuf, &mntbuf[i]);
		}
	}
	for (i = 0; i < mntsize; i++)
		if (aflag || (mntbuf[i].f_flags & MNT_IGNORE) == 0)
			prtstat(&mntbuf[i], &maxwidths);
	if (cflag)
		prtstat(&totalbuf, &maxwidths);
	return (rv);
}
Exemple #9
0
RTR3DECL(int) RTFsQueryType(const char *pszFsPath, PRTFSTYPE penmType)
{
    *penmType = RTFSTYPE_UNKNOWN;

    /*
     * Validate input.
     */
    AssertPtrReturn(pszFsPath, VERR_INVALID_POINTER);
    AssertReturn(*pszFsPath, VERR_INVALID_PARAMETER);

    /*
     * Convert the path and query the stats.
     * We're simply return the device id.
     */
    char const *pszNativeFsPath;
    int rc = rtPathToNative(&pszNativeFsPath, pszFsPath, NULL);
    if (RT_SUCCESS(rc))
    {
        struct stat Stat;
        if (!stat(pszNativeFsPath, &Stat))
        {
#if defined(RT_OS_LINUX)
            FILE *mounted = setmntent("/proc/mounts", "r");
            if (!mounted)
                mounted = setmntent("/etc/mtab", "r");
            if (mounted)
            {
                char            szBuf[1024];
                struct stat     mntStat;
                struct mntent   mntEnt;
                while (getmntent_r(mounted, &mntEnt, szBuf, sizeof(szBuf)))
                {
                    if (!stat(mntEnt.mnt_dir, &mntStat))
                    {
                        if (mntStat.st_dev == Stat.st_dev)
                        {
                            if (!strcmp("ext4", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_EXT4;
                            else if (!strcmp("ext3", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_EXT3;
                            else if (!strcmp("ext2", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_EXT2;
                            else if (!strcmp("jfs", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_JFS;
                            else if (!strcmp("xfs", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_XFS;
                            else if (   !strcmp("vfat", mntEnt.mnt_type)
                                     || !strcmp("msdos", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_FAT;
                            else if (!strcmp("ntfs", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_NTFS;
                            else if (!strcmp("hpfs", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_HPFS;
                            else if (!strcmp("ufs", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_UFS;
                            else if (!strcmp("tmpfs", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_TMPFS;
                            else if (!strcmp("hfsplus", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_HFS;
                            else if (!strcmp("udf", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_UDF;
                            else if (!strcmp("iso9660", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_ISO9660;
                            else if (!strcmp("smbfs", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_SMBFS;
                            else if (!strcmp("cifs", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_CIFS;
                            else if (!strcmp("nfs", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_NFS;
                            else if (!strcmp("nfs4", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_NFS;
                            else if (!strcmp("sysfs", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_SYSFS;
                            else if (!strcmp("proc", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_PROC;
                            else if (   !strcmp("fuse", mntEnt.mnt_type)
                                     || !strncmp("fuse.", mntEnt.mnt_type, 5)
                                     || !strcmp("fuseblk", mntEnt.mnt_type))
                                *penmType = RTFSTYPE_FUSE;
                            else
                            {
                                /* sometimes there are more than one entry for the same partition */
                                continue;
                            }
                            break;
                        }
                    }
                }
                endmntent(mounted);
            }

#elif defined(RT_OS_SOLARIS)
            if (!strcmp("zfs", Stat.st_fstype))
                *penmType = RTFSTYPE_ZFS;
            else if (!strcmp("ufs", Stat.st_fstype))
                *penmType = RTFSTYPE_UFS;
            else if (!strcmp("nfs", Stat.st_fstype))
                *penmType = RTFSTYPE_NFS;

#elif defined(RT_OS_DARWIN) || defined(RT_OS_FREEBSD)
            struct statfs statfsBuf;
            if (!statfs(pszNativeFsPath, &statfsBuf))
            {
                if (!strcmp("hfs", statfsBuf.f_fstypename))
                    *penmType = RTFSTYPE_HFS;
                else if (   !strcmp("fat", statfsBuf.f_fstypename)
                         || !strcmp("msdos", statfsBuf.f_fstypename))
                    *penmType = RTFSTYPE_FAT;
                else if (!strcmp("ntfs", statfsBuf.f_fstypename))
                    *penmType = RTFSTYPE_NTFS;
                else if (!strcmp("autofs", statfsBuf.f_fstypename))
                    *penmType = RTFSTYPE_AUTOFS;
                else if (!strcmp("devfs", statfsBuf.f_fstypename))
                    *penmType = RTFSTYPE_DEVFS;
                else if (!strcmp("nfs", statfsBuf.f_fstypename))
                    *penmType = RTFSTYPE_NFS;
                else if (!strcmp("ufs", statfsBuf.f_fstypename))
                    *penmType = RTFSTYPE_UFS;
                else if (!strcmp("zfs", statfsBuf.f_fstypename))
                    *penmType = RTFSTYPE_ZFS;
            }
            else
                rc = RTErrConvertFromErrno(errno);
#endif
        }
        else
            rc = RTErrConvertFromErrno(errno);
        rtPathFreeNative(pszNativeFsPath, pszFsPath);
    }

    return rc;
}
Exemple #10
0
static int pgfuse_statfs( const char *path, struct statvfs *buf )
{
	PgFuseData *data = (PgFuseData *)fuse_get_context( )->private_data;
	PGconn *conn;
	int64_t blocks_total, blocks_used, blocks_free, blocks_avail;
	int64_t files_total, files_used, files_free, files_avail;
	int res;
	int i;
	size_t nof_locations = MAX_TABLESPACE_OIDS;
	char *location[MAX_TABLESPACE_OIDS];
	FILE *mtab;
	struct mntent *m;
	struct mntent mnt;
	char strings[MTAB_BUFFER_SIZE];
	char *prefix;
	int prefix_len;

	if( data->verbose ) {
		syslog( LOG_INFO, "Statfs called on '%s', thread #%u",
			data->mountpoint, THREAD_ID );
	}
		
	memset( buf, 0, sizeof( struct statvfs ) );
	
	ACQUIRE( conn );
        PSQL_BEGIN( conn );

	/* blocks */

	res = psql_get_tablespace_locations( conn, location, &nof_locations, data->verbose );
	if( res < 0 ) {
		PSQL_ROLLBACK( conn ); RELEASE( conn );
		return res;
	}

	/* transform them and especially resolve symlinks */
	for( i = 0; i < nof_locations; i++ ) {
		char *old_path = location[i];
		char *new_path = realpath( old_path, NULL );
		if( new_path == NULL ) {
			/* do nothing, most likely a permission problem */
			syslog( LOG_ERR, "realpath for '%s' failed: %s,  pgfuse mount point '%s', thread #%u",
				old_path, strerror( errno ), data->mountpoint, THREAD_ID );
		} else {
			location[i] = new_path;
			free( old_path );
		}
	}
	
	blocks_free = INT64_MAX;
	blocks_avail = INT64_MAX;
	
	/* iterate over mount entries and try to match to the tablespace locations */
	mtab = setmntent( MTAB_FILE, "r" );
	while( ( m = getmntent_r( mtab, &mnt, strings, sizeof( strings ) ) ) != NULL ) {
		struct statfs fs;
		
		/* skip filesystems without mount point */
		if( mnt.mnt_dir == NULL ) continue;
		
		/* skip filesystems which are not a prefix of one of the tablespace locations */
		prefix = NULL;
		prefix_len = 0;
		for( i = 0; i < nof_locations; i++ ) {
			if( strncmp( mnt.mnt_dir, location[i], strlen( mnt.mnt_dir ) ) == 0 ) {
				if( strlen( mnt.mnt_dir ) > prefix_len ) {
					prefix_len = strlen( mnt.mnt_dir );
					prefix = strdup( mnt.mnt_dir );
					blocks_free = INT64_MAX;
					blocks_avail = INT64_MAX;
				}
			}
		}
		if( prefix == NULL ) continue;
		
		/* get data of file system */
		res = statfs( prefix, &fs );
		if( res < 0 ) {
			syslog( LOG_ERR, "statfs on '%s' failed: %s,  pgfuse mount point '%s', thread #%u",
				prefix,	strerror( errno ), data->mountpoint, THREAD_ID );
			return res;
		}

		if( data->verbose ) {
			syslog( LOG_DEBUG, "Checking mount point '%s' for free disk space, now %jd, was %jd, pgfuse mount point '%s', thread #%u",
				prefix,	fs.f_bfree, blocks_free, data->mountpoint, THREAD_ID );
		}

		/* take the smallest available disk space free (worst case the first one
		 * to overflow one of the tablespaces)
		 */
		if( fs.f_bfree * fs.f_frsize < blocks_free * data->block_size ) {
			blocks_free = fs.f_bfree * fs.f_frsize / data->block_size;
		}
		if( fs.f_bavail * fs.f_frsize < blocks_avail * data->block_size ) {
			blocks_avail = fs.f_bavail * fs.f_frsize / data->block_size;
		}
				
		if( prefix ) free( prefix );
	}
	endmntent( mtab );
	
	for( i = 0; i < nof_locations; i++ ) {
		if( location[i] ) free( location[i] );
	}
			
	blocks_used = psql_get_fs_blocks_used( conn );	
	if( blocks_used < 0 ) {
                PSQL_ROLLBACK( conn ); RELEASE( conn );
		return blocks_used;
	}
            
	blocks_total = blocks_avail + blocks_used;
	blocks_free = blocks_avail;
	
	/* inodes */

	/* no restriction on the number of files storable, we could
	   add some limits later */
	files_total = INT64_MAX;
	
	files_used = psql_get_fs_files_used( conn );
	if( files_used < 0 ) {
                PSQL_ROLLBACK( conn ); RELEASE( conn );
		return files_used;
	}
	
	files_free = files_total - files_used;
	files_avail = files_free;

	if( data->verbose ) {
		syslog( LOG_DEBUG, "Stats for '%s' are (%jd blocks total, %jd used, %jd free, "
			"%"PRId64" inodes total, %"PRId64" inodes used, %"PRId64" inodes free, thread #%u",
			data->mountpoint, 
			blocks_total, blocks_used, blocks_free,
			files_total, files_used, files_free,
			THREAD_ID );
	}
	
	/* fill statfs structure */
	
	/* Note: blocks have to be retrning as units of f_frsize
	 * f_favail, f_fsid and f_flag are currently ignored by FUSE ? */
	buf->f_bsize = data->block_size;
	buf->f_frsize = data->block_size;
	buf->f_blocks = blocks_total;
	buf->f_bfree = blocks_free;
	buf->f_bavail = blocks_avail;
	buf->f_files = files_total;
	buf->f_ffree = files_free;
	buf->f_favail = files_avail;
	buf->f_fsid =  0x4FE3A364;
	if( data->read_only ) {
		buf->f_flag |= ST_RDONLY;
	}
	buf->f_namemax = MAX_FILENAME_LENGTH;

	PSQL_COMMIT( conn ); RELEASE( conn );
	
	return 0;
}
Exemple #11
0
void
netsnmp_fsys_arch_load( void )
{
    int  ret  = 0;
    uint size = 0;

    struct vmount *aixmnt, *aixcurr;
    char          *path;
    struct statfs  stat_buf;
    netsnmp_fsys_info *entry;
    char               tmpbuf[1024];

    /*
     * Retrieve information about the currently mounted filesystems...
     */
    ret = mntctl(MCTL_QUERY, sizeof(uint), &size);
    if ( ret != 0 || size<=0 ) {
        snmp_log_perror( "initial mntctl failed" );
        return;
    }

    aixmnt = (struct vmount *)malloc( size );
    if ( aixmnt == NULL ) {
        snmp_log_perror( "cannot allocate memory for mntctl data" );
        return;
    }

    ret = mntctl(MCTL_QUERY, size, aixmnt );
    if ( ret <= 0 ) {
        free(aixmnt);
        snmp_log_perror( "main mntctl failed" );
        return;
    }
    aixcurr = aixmnt;


    /*
     * ... and insert this into the filesystem container.
     */

    for ( aixcurr  = aixmnt;
         (aixcurr-aixmnt) >= size;
          aixcurr  = (char*)aixcurr + aixcurr->vmt_length ) {

        path = vmt2dataptr( aixcurr, VMT_OBJECT );
        entry = netsnmp_fsys_by_path( path, NETSNMP_FS_FIND_CREATE );
        if (!entry) {
            continue;
        }

        strncpy( entry->path,   path,    sizeof( entry->path   ));
        strncpy( entry->device, vmt2dataptr( aixcurr, VMT_STUB),
                                         sizeof( entry->device ));
        entry->type   = _fsys_type( aixcurr->vmt_gfstype );

        if (!(entry->type & _NETSNMP_FS_TYPE_SKIP_BIT))
            entry->flags |= NETSNMP_FS_FLAG_ACTIVE;

        if ( _fsys_remote( entry->device, entry->type, vmt2dataptr( aixcurr, VMT_HOST) ))
            entry->flags |= NETSNMP_FS_FLAG_REMOTE;
        if ( aixcurr->vmt_flags & MNT_READONLY )
            entry->flags |= NETSNMP_FS_FLAG_RONLY;
        /*
         *  The root device is presumably bootable.
         *  Other partitions probably aren't!
         */
        if ((entry->path[0] == '/') &&
            (entry->path[1] == '\0'))
            entry->flags |= NETSNMP_FS_FLAG_BOOTABLE;

        /*
         *  XXX - identify removeable disks
         */

        /*
         *  Optionally skip retrieving statistics for remote mounts
         */
        if ( (entry->flags & NETSNMP_FS_FLAG_REMOTE) &&
            netsnmp_ds_get_boolean(NETSNMP_DS_APPLICATION_ID,
                                   NETSNMP_DS_AGENT_SKIPNFSINHOSTRESOURCES))
            continue;

        if ( statfs( entry->path, &stat_buf ) < 0 ) {
            snprintf( tmpbuf, sizeof(tmpbuf), "Cannot statfs %s\n", entry->path );
            snmp_log_perror( tmpbuf );
            continue;
        }
        entry->units =  stat_buf.f_bsize;
        entry->size  =  stat_buf.f_blocks;
        entry->used  = (stat_buf.f_blocks - stat_buf.f_bfree);
        entry->avail =  stat_buf.f_bavail;
        entry->inums_total = stat_buf.f_files;
        entry->inums_avail = stat_buf.f_ffree;
        netsnmp_fsys_calculate32(entry);
    }
    free(aixmnt);
    aixmnt  = NULL;
    aixcurr = NULL;
}
Exemple #12
0
/*
 ADIO_FileSysType_fncall - determines the file system type for a given file 
 using a system-dependent function call

Input Parameters:
. filename - pointer to file name character array

Output Parameters:
. fstype - location in which to store file system type (ADIO_XXX)
. error_code - location in which to store error code

 MPI_SUCCESS is stored in the location pointed to by error_code on success.

 This function is used by MPI_File_open() and MPI_File_delete() to determine 
 file system type.  Most other functions use the type which is stored when the 
 file is opened.
 */
static void ADIO_FileSysType_fncall(char *filename, int *fstype, int *error_code)
{
#ifndef ROMIO_NTFS
    char *dir;
    int err;
#endif
#if (defined(HPUX) || defined(SPPUX) || defined(IRIX) || defined(SOLARIS) || defined(AIX) || defined(DEC) || defined(CRAY))
    struct statvfs vfsbuf;
#endif
#if (defined(LINUX) || defined(FREEBSD) || defined(tflops))
    struct statfs fsbuf;
#endif
#ifdef PARAGON
    struct estatfs ebuf;
#endif
#ifdef SX4
    struct stat sbuf;
#endif

    *error_code = MPI_SUCCESS;

#if (defined(HPUX) || defined(SPPUX) || defined(IRIX) || defined(SOLARIS) || defined(AIX) || defined(DEC) || defined(CRAY))
    do {
	err = statvfs(filename, &vfsbuf);
    } while (err && (errno == ESTALE));

    if (err && (errno == ENOENT)) {
	ADIO_FileSysType_parentdir(filename, &dir);
	err = statvfs(dir, &vfsbuf);
	free(dir);
    }

    if (err) *error_code = MPI_ERR_UNKNOWN;
    else {
	/* FPRINTF(stderr, "%s\n", vfsbuf.f_basetype); */
	if (!strncmp(vfsbuf.f_basetype, "nfs", 3)) *fstype = ADIO_NFS;
	else {
# if (defined(HPUX) || defined(SPPUX))
#    ifdef HFS
	    *fstype = ADIO_HFS;
#    else
            *fstype = ADIO_UFS;
#    endif
# else
	    if (!strncmp(vfsbuf.f_basetype, "xfs", 3)) *fstype = ADIO_XFS;
	    else if (!strncmp(vfsbuf.f_basetype, "piofs", 4)) *fstype = ADIO_PIOFS;
	    else *fstype = ADIO_UFS;
# endif
	}
    }
#elif defined(LINUX)
    do {
	err = statfs(filename, &fsbuf);
    } while (err && (errno == ESTALE));

    if (err && (errno == ENOENT)) {
	ADIO_FileSysType_parentdir(filename, &dir);
	err = statfs(dir, &fsbuf);
	free(dir);
    }

    if (err) *error_code = MPI_ERR_UNKNOWN;
    else {
	/* FPRINTF(stderr, "%d\n", fsbuf.f_type);*/
	if (fsbuf.f_type == NFS_SUPER_MAGIC) *fstype = ADIO_NFS;
# ifdef ROMIO_PVFS
	else if (fsbuf.f_type == PVFS_SUPER_MAGIC) *fstype = ADIO_PVFS;
# endif
	else *fstype = ADIO_UFS;
    }
#elif (defined(FREEBSD) && defined(HAVE_MOUNT_NFS))
    do {
	err = statfs(filename, &fsbuf);
    } while (err && (errno == ESTALE));

    if (err && (errno == ENOENT)) {
	ADIO_FileSysType_parentdir(filename, &dir);
	err = statfs(dir, &fsbuf);
	free(dir);
    }

    if (err) *error_code = MPI_ERR_UNKNOWN;
    else {
# if (__FreeBSD_version>300004)
	if ( !strncmp("nfs",fsbuf.f_fstypename,3) ) *fstype = ADIO_NFS;
# else
	if (fsbuf.f_type == MOUNT_NFS) *fstype = ADIO_NFS;
# endif
	else *fstype = ADIO_UFS;
    }
#elif defined(PARAGON)
    do {
	err = statpfs(filename, &ebuf, 0, 0);
    } while (err && (errno == ESTALE));

    if (err && (errno == ENOENT)) {
	ADIO_FileSysType_parentdir(filename, &dir);
	err = statpfs(dir, &ebuf, 0, 0);
	free(dir);
    }

    if (err) *error_code = MPI_ERR_UNKNOWN;
    else {
	if (ebuf.f_type == MOUNT_NFS) *fstype = ADIO_NFS;
	else if (ebuf.f_type == MOUNT_PFS) *fstype = ADIO_PFS;
	else *fstype = ADIO_UFS;
    }
#elif defined(tflops)
    do {
	err = statfs(filename, &fsbuf);
    } while (err && (errno == ESTALE));

    if (err && (errno == ENOENT)) {
	ADIO_FileSysType_parentdir(filename, &dir);
	err = statfs(dir, &fsbuf);
	free(dir);
    }

    if (err) *error_code = MPI_ERR_UNKNOWN;
    else {
	if (fsbuf.f_type == MOUNT_NFS) *fstype = ADIO_NFS;
	else if (fsbuf.f_type == MOUNT_PFS) *fstype = ADIO_PFS;
	else *fstype = ADIO_UFS;
    }
#elif defined(SX4)
    do {
	err = stat(filename, &sbuf);
    } while (err && (errno == ESTALE));

    if (err && (errno == ENOENT)) {
	ADIO_FileSysType_parentdir(filename, &dir);
	err = stat(dir, &sbuf);
	free(dir);
    }
    
    if (err) *error_code = MPI_ERR_UNKNOWN;
    else {
	if (!strcmp(sbuf.st_fstype, "nfs")) *fstype = ADIO_NFS;
	else *fstype = ADIO_SFS;
    }
#else
    /* on other systems, make NFS the default */
# ifdef ROMIO_NTFS
    *fstype = ADIO_NTFS;
# else
    *fstype = ADIO_NFS;   
# endif
    *error_code = MPI_SUCCESS;
#endif
}
/* this is umount replacement to mnt_context_apply_fstab(), use
 * mnt_context_tab_applied() to check result.
 */
static int lookup_umount_fs(struct libmnt_context *cxt)
{
	const char *tgt;
	struct stat st;
	struct libmnt_fs *fs = NULL;
	int rc = 0;

	assert(cxt);
	assert(cxt->fs);

	tgt = mnt_fs_get_target(cxt->fs);
	if (!tgt) {
		DBG(CXT, ul_debugobj(cxt, "umount: undefined target"));
		return -EINVAL;
	}

	/*
	 * Let's try to avoid mountinfo usage at all to minimize performance
	 * degradation. Don't forget that kernel has to compose *whole*
	 * mountinfo about all mountpoints although we look for only one entry.
	 *
	 * All we need is fstype and to check if there is no userspace mount
	 * options for the target (e.g. helper=udisks to call /sbin/umount.udisks).
	 *
	 * So, let's use statfs() if possible (it's bad idea for --lazy/--force
	 * umounts as target is probably unreachable NFS, also for --detach-loop
	 * as this additionally needs to know the name of the loop device).
	 */
	if (!mnt_context_is_restricted(cxt)
	    && *tgt == '/'
	    && !(cxt->flags & MNT_FL_HELPER)
	    && !mnt_context_mtab_writable(cxt)
	    && !mnt_context_is_force(cxt)
	    && !mnt_context_is_lazy(cxt)
	    && !mnt_context_is_loopdel(cxt)
	    && mnt_stat_mountpoint(tgt, &st) == 0 && S_ISDIR(st.st_mode)
	    && !has_utab_entry(cxt, tgt)) {

		const char *type = mnt_fs_get_fstype(cxt->fs);

		/* !mnt_context_mtab_writable(cxt) && has_utab_entry() verified that there
		 * is no stuff in utab, so disable all mtab/utab related actions */
		mnt_context_disable_mtab(cxt, TRUE);

		if (!type) {
			struct statfs vfs;
			if (statfs(tgt, &vfs) == 0)
				type = mnt_statfs_get_fstype(&vfs);
			if (type) {
				rc = mnt_fs_set_fstype(cxt->fs, type);
				if (rc)
					return rc;
			}
		}
		if (type) {
			DBG(CXT, ul_debugobj(cxt,
				"umount: mountinfo unnecessary [type=%s]", type));
			return 0;
		}
	}

	rc = mnt_context_find_umount_fs(cxt, tgt, &fs);
	if (rc < 0)
		return rc;

	if (rc == 1 || !fs) {
		DBG(CXT, ul_debugobj(cxt, "umount: cannot find '%s' in mtab", tgt));
		return 0;	/* this is correct! */
	}

	if (fs != cxt->fs) {
		/* copy from mtab to our FS description
		 */
		mnt_fs_set_source(cxt->fs, NULL);
		mnt_fs_set_target(cxt->fs, NULL);

		if (!mnt_copy_fs(cxt->fs, fs)) {
			DBG(CXT, ul_debugobj(cxt, "umount: failed to copy FS"));
			return -errno;
		}
		DBG(CXT, ul_debugobj(cxt, "umount: mtab applied"));
	}

	cxt->flags |= MNT_FL_TAB_APPLIED;
	return rc;
}
/**
 * Setup the CVMX_SHARED data section to be shared across
 * all processors running this application. A memory mapped
 * region is allocated using shm_open and mmap. The current
 * contents of the CVMX_SHARED section are copied into the
 * region. Then the new region is remapped to replace the
 * existing CVMX_SHARED data.
 *
 * This function will display a message and abort the
 * application under any error conditions. The Linux tmpfs
 * filesystem must be mounted under /dev/shm.
 */
static void setup_cvmx_shared(void)
{
    const char *SHM_NAME = "cvmx_shared";
    unsigned long shared_size = &__cvmx_shared_end - &__cvmx_shared_start;
    int fd;

    /* If there isn't and shared data we can skip all this */
    if (shared_size)
    {
        printf("CVMX_SHARED: %p-%p\n", &__cvmx_shared_start, &__cvmx_shared_end);

#ifdef __UCLIBC__
	const char *defaultdir = "/dev/shm/";
	struct statfs f;
	char shm_name[30];
	int pid;
	/* The canonical place is /dev/shm. */ 
	if (statfs (defaultdir, &f) == 0)
	{
	    pid = getpid();
	    sprintf (shm_name, "%s%s-%d", defaultdir, SHM_NAME, pid);
	}
	else
	{
	    perror("/dev/shm is not mounted");
	    exit(-1);
	}

	/* shm_open(), shm_unlink() are not implemented in uClibc. Do the 
	   same thing using open() and close() system calls.  */
	fd = open (shm_name, O_RDWR | O_CREAT | O_TRUNC, 0);

	if (fd < 0)
	{
	    perror("Failed to open CVMX_SHARED(shm_name)");
	    exit(errno);
	}
	
	unlink (shm_name);
#else
        /* Open a new shared memory region for use as CVMX_SHARED */
        fd = shm_open(SHM_NAME, O_RDWR | O_CREAT | O_TRUNC, 0);
        if (fd <0)
        {
            perror("Failed to setup CVMX_SHARED(shm_open)");
            exit(errno);
        }

        /* We don't want the file on the filesystem. Immediately unlink it so
            another application can create its own shared region */
        shm_unlink(SHM_NAME);
#endif

        /* Resize the region to match the size of CVMX_SHARED */
        ftruncate(fd, shared_size);

        /* Map the region into some random location temporarily so we can
            copy the shared data to it */
        void *ptr = mmap(NULL, shared_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
        if (ptr == NULL)
        {
            perror("Failed to setup CVMX_SHARED(mmap copy)");
            exit(errno);
        }

        /* Copy CVMX_SHARED to the new shared region so we don't lose
            initializers */
        memcpy(ptr, &__cvmx_shared_start, shared_size);
        munmap(ptr, shared_size);

        /* Remap the shared region to replace the old CVMX_SHARED region */
        ptr = mmap(&__cvmx_shared_start, shared_size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_FIXED, fd, 0);
        if (ptr == NULL)
        {
            perror("Failed to setup CVMX_SHARED(mmap final)");
            exit(errno);
        }

        /* Once mappings are setup, the file handle isn't needed anymore */
        close(fd);
    }
}
Exemple #15
0
int nandroid_backup(const char* backup_path)
{
    nandroid_backup_bitfield = 0;
    ui_set_background(BACKGROUND_ICON_INSTALLING);
    refresh_default_backup_handler();
    
    if (ensure_path_mounted(backup_path) != 0) {
        return print_and_error("Can't mount backup path.\n");
    }
    
    Volume* volume = volume_for_path(backup_path);
    if (NULL == volume)
        return print_and_error("Unable to find volume for backup path.\n");
    if (is_data_media_volume_path(volume->mount_point))
        volume = volume_for_path("/data");
    int ret;
    struct statfs s;
    if (NULL != volume) {
        if (0 != (ret = statfs(volume->mount_point, &s)))
            return print_and_error("Unable to stat backup path.\n");
        uint64_t bavail = s.f_bavail;
        uint64_t bsize = s.f_bsize;
        uint64_t sdcard_free = bavail * bsize;
        uint64_t sdcard_free_mb = sdcard_free / (uint64_t)(1024 * 1024);
        ui_print("SD Card space free: %lluMB\n", sdcard_free_mb);
        if (sdcard_free_mb < 150)
            ui_print("There may not be enough free space to complete backup... continuing...\n");
    }
    char tmp[PATH_MAX];
    ensure_directory(backup_path);

    if (backup_boot && 0 != (ret = nandroid_backup_partition(backup_path, "/boot")))
        return ret;

    if (backup_recovery && 0 != (ret = nandroid_backup_partition(backup_path, "/recovery")))
        return ret;

    Volume *vol = volume_for_path("/wimax");
    if (backup_wimax && vol != NULL && 0 == stat(vol->device, &s))
    {
        char serialno[PROPERTY_VALUE_MAX];
        ui_print("Backing up WiMAX...\n");
        serialno[0] = 0;
        property_get("ro.serialno", serialno, "");
        sprintf(tmp, "%s/wimax.%s.img", backup_path, serialno);
        ret = backup_raw_partition(vol->fs_type, vol->device, tmp);
        if (0 != ret)
            return print_and_error("Error while dumping WiMAX image!\n");
    }

    //2 copies of efs are made: tarball and raw backup
    if (backup_efs) {
        //first backup in raw format, returns 0 on success (or if skipped), else 1
        if (0 != custom_backup_raw_handler(backup_path, "/efs")) {
            ui_print("EFS raw image backup failed! Trying tar backup...\n");
        }
        //second backup in tar format
        sprintf(tmp, "%s/efs_tar", backup_path);
        ensure_directory(tmp);
        if (0 != (ret = nandroid_backup_partition(tmp, "/efs")))
            return ret;
    }
    
    if (backup_modem) {
        if (0 != (ret = nandroid_backup_partition(backup_path, "/modem")))
            return ret;
    }

    if (backup_system && 0 != (ret = nandroid_backup_partition(backup_path, "/system")))
        return ret;


    if (is_custom_backup && backup_preload) {
        if (0 != (ret = nandroid_backup_partition(backup_path, "/preload"))) {
            ui_print("Failed to backup /preload!\n");
            return ret;
        }
    }
    else if (!is_custom_backup
#ifdef PHILZ_TOUCH_RECOVERY
                && nandroid_add_preload
#endif
            )
    {
        if (0 != (ret = nandroid_backup_partition(backup_path, "/preload"))) {
            ui_print("Failed to backup preload! Try to disable it.\n");
            ui_print("Skipping /preload...\n");
            //return ret;
        }
    }

    if (backup_data && 0 != (ret = nandroid_backup_partition(backup_path, "/data")))
        return ret;

    if (has_datadata()) {
        if (backup_data && 0 != (ret = nandroid_backup_partition(backup_path, "/datadata")))
            return ret;
    }

    if (is_data_media() || 0 != stat("/sdcard/.android_secure", &s)) {
        ui_print("No /sdcard/.android_secure found. Skipping backup of applications on external storage.\n");
    }
    else {
        if (backup_data && 0 != (ret = nandroid_backup_partition_extended(backup_path, "/sdcard/.android_secure", 0)))
            return ret;
    }

    if (backup_cache && 0 != (ret = nandroid_backup_partition_extended(backup_path, "/cache", 0)))
        return ret;

    if (backup_sdext) {
        vol = volume_for_path("/sd-ext");
        if (vol == NULL || 0 != stat(vol->device, &s))
        {
            ui_print("No sd-ext found. Skipping backup of sd-ext.\n");
        }
        else
        {
            if (0 != ensure_path_mounted("/sd-ext"))
                ui_print("Could not mount sd-ext. sd-ext backup may not be supported on this device. Skipping backup of sd-ext.\n");
            else if (0 != (ret = nandroid_backup_partition(backup_path, "/sd-ext")))
                return ret;
        }
    }

#ifdef PHILZ_TOUCH_RECOVERY
    if (enable_md5sum)
#endif
    {
        ui_print("Generating md5 sum...\n");
        sprintf(tmp, "nandroid-md5.sh %s", backup_path);
        if (0 != (ret = __system(tmp))) {
            ui_print("Error while generating md5 sum!\n");
            return ret;
        }
    }

    sprintf(tmp, "chmod -R 777 %s ; chmod -R u+r,u+w,g+r,g+w,o+r,o+w /sdcard/clockworkmod ; chmod u+x,g+x,o+x /sdcard/clockworkmod/backup ; chmod u+x,g+x,o+x /sdcard/clockworkmod/blobs", backup_path);
    __system(tmp);
    sync();
    ui_set_background(BACKGROUND_ICON_NONE);
    ui_reset_progress();
    ui_print("\nBackup complete!\n");
    return 0;
}
Exemple #16
0
/*
 ADIO_FileSysType_fncall - determines the file system type for a given file 
 using a system-dependent function call

Input Parameters:
. filename - pointer to file name character array

Output Parameters:
. fstype - location in which to store file system type (ADIO_XXX)
. error_code - location in which to store error code

 MPI_SUCCESS is stored in the location pointed to by error_code on success.

 This function is used by MPI_File_open() and MPI_File_delete() to determine 
 file system type.  Most other functions use the type which is stored when the 
 file is opened.
 */
static void ADIO_FileSysType_fncall(char *filename, int *fstype, int *error_code)
{
#ifndef ROMIO_NTFS
    char *dir;
    int err;
#endif

#ifdef ROMIO_HAVE_STRUCT_STATVFS_WITH_F_BASETYPE
    struct statvfs vfsbuf;
#endif
#ifdef HAVE_STRUCT_STATFS
    struct statfs fsbuf;
#endif
#ifdef ROMIO_HAVE_STRUCT_STAT_WITH_ST_FSTYPE
    struct stat sbuf;
#endif
    static char myname[] = "ADIO_RESOLVEFILETYPE_FNCALL";

    *error_code = MPI_SUCCESS;

#ifdef ROMIO_HAVE_STRUCT_STATVFS_WITH_F_BASETYPE
    do {
	err = statvfs(filename, &vfsbuf);
    } while (err && (errno == ESTALE));

    if (err && (errno == ENOENT)) {
	/* ENOENT may be returned in two cases:
	 * 1) no directory entry for "filename"
	 * 2) "filename" is a dangling symbolic link
	 *
	 * ADIO_FileSysType_parentdir tries to deal with both cases.
	 */
	ADIO_FileSysType_parentdir(filename, &dir);
	err = statvfs(dir, &vfsbuf);

	ADIOI_Free(dir);
    }

    /* --BEGIN ERROR HANDLING-- */
    if (err) {
	*error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
					   myname, __LINE__, MPI_ERR_NO_SUCH_FILE,
					   "**filename", "**filename %s", filename);
	return;
    }
    /* --END ERROR HANDLING-- */

    /* FPRINTF(stderr, "%s\n", vfsbuf.f_basetype); */
    if (!strncmp(vfsbuf.f_basetype, "nfs", 3)) {
	*fstype = ADIO_NFS;
	return;
    }
    if (!strncmp(vfsbuf.f_basetype, "xfs", 3)) {
	*fstype = ADIO_XFS;
	return;
    }

# ifdef ROMIO_UFS
    /* if UFS support is enabled, default to that */
    *fstype = ADIO_UFS;
    return;
# endif

    /* --BEGIN ERROR HANDLING-- */
    *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
				       myname, __LINE__, MPI_ERR_NO_SUCH_FILE,
				       "**filename", "**filename %s", filename);
    /* --END ERROR HANDLING-- */
#endif /* STATVFS APPROACH */

#if defined(HAVE_STRUCT_STATFS) && defined(HAVE_STATFS)
    do {
	err = statfs(filename, &fsbuf);
    } while (err && (errno == ESTALE));

    if (err && (errno == ENOENT)) {
	ADIO_FileSysType_parentdir(filename, &dir);
	err = statfs(dir, &fsbuf);
	ADIOI_Free(dir);
    }

    /* --BEGIN ERROR HANDLING-- */
    if (err) {
    	*error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
					   myname, __LINE__, MPI_ERR_NO_SUCH_FILE,
					   "**filename", "**filename %s", filename);
	return;
    }
    /* --END ERROR HANDLING-- */

# ifdef ROMIO_HAVE_STRUCT_STATFS_WITH_F_FSTYPENAME
    if ( !strncmp("nfs",fsbuf.f_fstypename,3) ) {
	*fstype = ADIO_NFS;
	return;
    }
# endif

#  ifdef ROMIO_BGL 
    /* BlueGene is a special case: all file systems are AD_BGL, except for
     * certain exceptions */
    *fstype = ADIO_BGL;
    check_for_lockless_exceptions(fsbuf.f_type, fstype);
    *error_code = MPI_SUCCESS;
    return;
#  endif

    /* FPRINTF(stderr, "%d\n", fsbuf.f_type);*/
# ifdef NFS_SUPER_MAGIC
    if (fsbuf.f_type == NFS_SUPER_MAGIC) {
	*fstype = ADIO_NFS;
	return;
    }
# endif

/*#if defined(LINUX) && defined(ROMIO_LUSTRE)*/
#ifdef ROMIO_LUSTRE
#define LL_SUPER_MAGIC 0x0BD00BD0
    if (fsbuf.f_type == LL_SUPER_MAGIC) {
	*fstype = ADIO_LUSTRE;
	return;
    }
# endif

# ifdef PAN_KERNEL_FS_CLIENT_SUPER_MAGIC
    if (fsbuf.f_type == PAN_KERNEL_FS_CLIENT_SUPER_MAGIC) {
	*fstype = ADIO_PANFS;
	return;
    }
# endif

# ifdef MOUNT_NFS
    if (fsbuf.f_type == MOUNT_NFS) {
	*fstype = ADIO_NFS;
	return;
    }
# endif

# ifdef MOUNT_PFS
    if (fsbuf.f_type == MOUNT_PFS) {
	*fstype = ADIO_PFS;
	return;
    }
# endif

# ifdef PVFS_SUPER_MAGIC
    if (fsbuf.f_type == PVFS_SUPER_MAGIC) {
	*fstype = ADIO_PVFS;
	return;
    }
# endif

# ifdef PVFS2_SUPER_MAGIC
    if (fsbuf.f_type == PVFS2_SUPER_MAGIC) {
	*fstype = ADIO_PVFS2;
	return;
    }
# endif

# ifdef ROMIO_UFS
    /* if UFS support is enabled, default to that */
    *fstype = ADIO_UFS;
    return;
# endif
    /* --BEGIN ERROR HANDLING-- */
    *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
				       myname, __LINE__, MPI_ERR_NO_SUCH_FILE,
				       "**filename", "**filename %s", filename);
    /* --END ERROR HANDLING-- */
#endif /* STATFS APPROACH */

#ifdef ROMIO_HAVE_STRUCT_STAT_WITH_ST_FSTYPE
    do {
	err = stat(filename, &sbuf);
    } while (err && (errno == ESTALE));

    if (err && (errno == ENOENT)) {
	ADIO_FileSysType_parentdir(filename, &dir);
	err = stat(dir, &sbuf);
	ADIOI_Free(dir);
    }
    
    if (err) {
    	/* --BEGIN ERROR HANDLING-- */
    	*error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
				           myname, __LINE__, MPI_ERR_NO_SUCH_FILE,
				           "**filename", "**filename %s", filename);
    	/* --END ERROR HANDLING-- */
	return;
    }
    else {
	if (!strcmp(sbuf.st_fstype, "nfs")) *fstype = ADIO_NFS;
	else *fstype = ADIO_SFS; /* assuming SX4 for now */
    }
#endif /* STAT APPROACH */

#ifdef ROMIO_NTFS
    ADIOI_UNREFERENCED_ARG(filename);
    ADIOI_UNREFERENCED_ARG(error_code);
    *fstype = ADIO_NTFS; /* only supported FS on Windows */
#elif defined(ROMIO_NFS)
    *fstype = ADIO_NFS;
#elif defined(ROMIO_UFS)
    *fstype = ADIO_UFS;
#else
    /* --BEGIN ERROR HANDLING-- */
    *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
				       myname, __LINE__, MPI_ERR_NO_SUCH_FILE,
				       "**filename", "**filename %s", filename);
    /* --END ERROR HANDLING-- */
#endif
}
Exemple #17
0
int nandroid_restore_partition_extended(const char* backup_path, const char* mount_point, int umount_when_finished) {
    int ret = 0;
    char* name = basename(mount_point);

    nandroid_restore_handler restore_handler = NULL;
    const char *filesystems[] = { "yaffs2", "ext2", "ext3", "ext4", "vfat", "rfs", NULL };
    const char* backup_filesystem = NULL;
    Volume *vol = volume_for_path(mount_point);
    const char *device = NULL;
    if (vol != NULL)
        device = vol->device;

    char tmp[PATH_MAX];
    sprintf(tmp, "%s/%s.img", backup_path, name);
    struct stat file_info;
    if (0 != (ret = statfs(tmp, &file_info))) {
        // can't find the backup, it may be the new backup format?
        // iterate through the backup types
        printf("couldn't find old .img format\n");
        char *filesystem;
        int i = 0;
        while ((filesystem = filesystems[i]) != NULL) {
            sprintf(tmp, "%s/%s.%s.img", backup_path, name, filesystem);
            if (0 == (ret = statfs(tmp, &file_info))) {
                backup_filesystem = filesystem;
                restore_handler = unyaffs_wrapper;
                break;
            }
            sprintf(tmp, "%s/%s.%s.tar", backup_path, name, filesystem);
            if (0 == (ret = statfs(tmp, &file_info))) {
                backup_filesystem = filesystem;
                restore_handler = tar_extract_wrapper;
                break;
            }
            sprintf(tmp, "%s/%s.%s.dup", backup_path, name, filesystem);
            if (0 == (ret = statfs(tmp, &file_info))) {
                backup_filesystem = filesystem;
                restore_handler = dedupe_extract_wrapper;
                break;
            }
            i++;
        }

        if (backup_filesystem == NULL || restore_handler == NULL) {
            //ui_print("%s.img not found. Skipping restore of %s.\n", name, mount_point);
            ui_print("No %s backup found(img, tar, dup). Skipping restore of %s.\n", name, mount_point);
            return 0;
        }
        else {
            printf("Found new backup image: %s\n", tmp);
        }

        // If the fs_type of this volume is "auto" or mount_point is /data
        // and is_data_media, let's revert
        // to using a rm -rf, rather than trying to do a
        // ext3/ext4/whatever format.
        // This is because some phones (like DroidX) will freak out if you
        // reformat the /system or /data partitions, and not boot due to
        // a locked bootloader.
        // Other devices, like the Galaxy Nexus, XOOM, and Galaxy Tab 10.1
        // have a /sdcard symlinked to /data/media.
        // Or of volume does not exist (.android_secure), just rm -rf.
        if (vol == NULL || 0 == strcmp(vol->fs_type, "auto"))
            backup_filesystem = NULL;
        if (0 == strcmp(vol->mount_point, "/data") && is_data_media())
            backup_filesystem = NULL;
    }

    ensure_directory(mount_point);

    int callback = stat("/sdcard/clockworkmod/.hidenandroidprogress", &file_info) != 0;
    compute_archive_stats(tmp);

    ui_print("Restoring %s...\n", name);
    if (backup_filesystem == NULL) {
        if (0 != (ret = format_volume(mount_point))) {
            ui_print("Error while formatting %s!\n", mount_point);
            return ret;
        }
    }
    else if (0 != (ret = format_device(device, mount_point, backup_filesystem))) {
        ui_print("Error while formatting %s!\n", mount_point);
        return ret;
    }

    if (0 != (ret = ensure_path_mounted(mount_point))) {
        ui_print("Can't mount %s!\n", mount_point);
        return ret;
    }

    if (restore_handler == NULL)
        restore_handler = get_restore_handler(mount_point);
    if (restore_handler == NULL) {
        ui_print("Error finding an appropriate restore handler.\n");
        return -2;
    }
    if (0 != (ret = restore_handler(tmp, mount_point, callback))) {
        ui_print("Error while restoring %s!\n", mount_point);
        return ret;
    }

    if (umount_when_finished) {
        ensure_path_unmounted(mount_point);
    }
    
    return 0;
}
Exemple #18
0
bool proc_probe(pid_t pid, proc_t * const pproc)
{
    assert(pproc);

    /* Validating procfs */
    struct statfs sb;
    if ((statfs(PROCFS, &sb) < 0) || (sb.f_type != PROC_SUPER_MAGIC))
    {
		return false;
    }

    /* Validating process stat */
    char buffer[4096];

    sprintf(buffer, PROCFS "/%d/stat", pid);
    if (access(buffer, R_OK | F_OK) < 0)
    {
		return false;
    }

    /* Grab stat information in one read */
    int fd = open(buffer, O_RDONLY);
    int len = read(fd, buffer, sizeof(buffer) - 1);
    close(fd);
    buffer[len] = '\0';

    /* Extract interested information */
    int offset = 0;
    char * token = buffer;
    do
    {
        switch (offset++)
        {
        case  0:           /* pid */
            sscanf(token, "%d", &pproc->pid);
            break;
        case  1:           /* comm */
            break;
        case  2:           /* state */
            sscanf(token, "%c", &pproc->state);
            break;
        case  3:           /* ppid */
            sscanf(token, "%d", &pproc->ppid);
            break;
        case  4:           /* pgrp */
        case  5:           /* session */
        case  6:           /* tty_nr */
        case  7:           /* tty_pgrp */
            break;
        case  8:           /* flags */
            break;
        case  9:           /* min_flt */
        case 10:           /* cmin_flt */
        case 11:           /* maj_flt */
        case 12:           /* cmaj_flt */
            break;
        case 13:           /* utime */
            sscanf(token, "%lu", &pproc->tm.tms_utime);
            break;
        case 14:           /* stime */
            sscanf(token, "%lu", &pproc->tm.tms_stime);
            break;
        case 15:           /* cutime */
            sscanf(token, "%ld", &pproc->tm.tms_cutime);
            break;
        case 16:           /* cstime */
            sscanf(token, "%ld", &pproc->tm.tms_cstime);
            break;
        case 17:           /* priority */
        case 18:           /* nice */
        case 19:           /* 0 */
        case 20:           /* it_real_value */
        case 21:           /* start_time */
            break;
        case 22:           /* vsize */
            sscanf(token, "%lu", &pproc->vsize);
            break;
        case 23:           /* rss */
        case 24:           /* rlim_rss */
        case 25:           /* start_code */
        case 26:           /* end_code */
        case 27:           /* start_stack */
        case 28:           /* esp */
        case 29:           /* eip */
        case 30:           /* pending_signal */
        case 31:           /* blocked_signal */
        case 32:           /* sigign */
        case 33:           /* sigcatch */
        case 34:           /* wchan */
        case 35:           /* nswap */
        case 36:           /* cnswap */
        case 37:           /* exit_signal */
        case 38:           /* processor */
        default:
            break;
        }
    } while (strsep(&token, " ") != NULL);

    /* Must be the parent process in order to probe registers and floating point
       registers; and the status of target process must be 'T' (aka traced) */
    if ((pproc->ppid != getpid()) || (toupper(pproc->state) != 'T'))
    {
		return false;
    }

    /* Inspect process registers */
    /* General purpose registers */
    if (ptrace(PTRACE_GETREGS, pid, NULL, (void *)&pproc->regs) < 0)
    {
		return false;
    }

	/* Inspect floating point registers */
    /* Floating point registers */
    if (ptrace(PTRACE_GETFPREGS, pid, NULL, (void *)&pproc->fpregs) < 0)
    {
		return false;
    }
	return true;
}
Exemple #19
0
/*
 ADIO_FileSysType_fncall - determines the file system type for a given file
 using a system-dependent function call

Input Parameters:
. filename - pointer to file name character array

Output Parameters:
. fstype - location in which to store file system type (ADIO_XXX)
. error_code - location in which to store error code

 MPI_SUCCESS is stored in the location pointed to by error_code on success.

 This function is used by MPI_File_open() and MPI_File_delete() to determine 
 file system type.  Most other functions use the type which is stored when the 
 file is opened.
 */
static void ADIO_FileSysType_fncall(const char *filename, int *fstype, int *error_code)
{
#if defined (ROMIO_HAVE_STRUCT_STATVFS_WITH_F_BASETYPE) || defined (HAVE_STRUCT_STATFS) || defined (ROMIO_HAVE_STRUCT_STAT_WITH_ST_FSTYPE)
    int err;
#endif

#ifdef ROMIO_HAVE_STRUCT_STATVFS_WITH_F_BASETYPE
    struct statvfs vfsbuf;
#endif
#ifdef HAVE_STRUCT_STATFS
    struct statfs fsbuf;
#endif
#ifdef ROMIO_HAVE_STRUCT_STAT_WITH_ST_FSTYPE
    struct stat sbuf;
#endif
    static char myname[] = "ADIO_RESOLVEFILETYPE_FNCALL";

/* NFS can get stuck and end up returing ESTALE "forever" */
#define MAX_ESTALE_RETRY 10000
    int retry_cnt;

    *error_code = MPI_SUCCESS;

#ifdef ROMIO_HAVE_STRUCT_STATVFS_WITH_F_BASETYPE
    /* rare: old solaris machines */
    retry_cnt=0;
    do {
	err = statvfs(filename, &vfsbuf);
    } while (err && (errno == ESTALE) && retry_cnt++ < MAX_ESTALE_RETRY);

    if (err) {
	/* ENOENT may be returned in two cases:
	 * 1) no directory entry for "filename"
	 * 2) "filename" is a dangling symbolic link
	 *
	 * ADIO_FileSysType_parentdir tries to deal with both cases.
	 */
	if (errno == ENOENT) {
	    char *dir;
	    ADIO_FileSysType_parentdir(filename, &dir);
	    err = statvfs(dir, &vfsbuf);

	    ADIOI_Free(dir);
	}
	else {
	    *error_code = ADIOI_Err_create_code(myname, filename, errno);
	    if(*error_code != MPI_SUCCESS) return;
	}
    }

    /* --BEGIN ERROR HANDLING-- */
    if (err) {
	*error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
					   myname, __LINE__, MPI_ERR_NO_SUCH_FILE,
					   "**filename", "**filename %s", filename);
	return;
    }
    /* --END ERROR HANDLING-- */

    /* FPRINTF(stderr, "%s\n", vfsbuf.f_basetype); */
    if (!strncmp(vfsbuf.f_basetype, "nfs", 3)) {
	*fstype = ADIO_NFS;
	return;
    }
    if (!strncmp(vfsbuf.f_basetype, "xfs", 3)) {
	*fstype = ADIO_XFS;
	return;
    }

# ifdef ROMIO_UFS
    /* if UFS support is enabled, default to that */
    *fstype = ADIO_UFS;
    return;
# endif

    /* --BEGIN ERROR HANDLING-- */
    *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
				       myname, __LINE__, MPI_ERR_NO_SUCH_FILE,
				       "**filename", "**filename %s", filename);
    /* --END ERROR HANDLING-- */
#endif /* STATVFS APPROACH */

#if defined(HAVE_STRUCT_STATFS) && defined(HAVE_STATFS)
    /* common automagic fs-detection logic for any modern POSX-compliant
     * environment */
    retry_cnt = 0;
    do {
	err = statfs(filename, &fsbuf);
    } while (err && (errno == ESTALE) && retry_cnt++ < MAX_ESTALE_RETRY);

    if (err) {
	if(errno == ENOENT) {
	    char *dir;
	    ADIO_FileSysType_parentdir(filename, &dir);
	    err = statfs(dir, &fsbuf);
	    ADIOI_Free(dir);
	}
	else {
	    *error_code = ADIOI_Err_create_code(myname, filename, errno);
	    if(*error_code != MPI_SUCCESS) return;
	}
    }

    /* --BEGIN ERROR HANDLING-- */
    if (err) {
    	*error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
					   myname, __LINE__, MPI_ERR_NO_SUCH_FILE,
					   "**filename", "**filename %s", filename);
	return;
    }
    /* --END ERROR HANDLING-- */

# ifdef ROMIO_HAVE_STRUCT_STATFS_WITH_F_FSTYPENAME
    /* uncommon: maybe only on Darwin ? */
    if ( !strncmp("nfs",fsbuf.f_fstypename,3) ) {
	*fstype = ADIO_NFS;
	return;
    }
# endif


#ifdef ROMIO_GPFS
    if (fsbuf.f_type == GPFS_SUPER_MAGIC) {
	*fstype = ADIO_GPFS;
	return;
    }
#endif

    /* FPRINTF(stderr, "%d\n", fsbuf.f_type);*/
# ifdef NFS_SUPER_MAGIC
    if (fsbuf.f_type == NFS_SUPER_MAGIC) {
	*fstype = ADIO_NFS;
	return;
    }
# endif

#ifdef ROMIO_LUSTRE
# ifndef LL_SUPER_MAGIC
#  define LL_SUPER_MAGIC 0x0BD00BD0
# endif
    if (fsbuf.f_type == LL_SUPER_MAGIC) {
	*fstype = ADIO_LUSTRE;
	return;
    }
#endif

# ifdef PAN_KERNEL_FS_CLIENT_SUPER_MAGIC
    if (fsbuf.f_type == PAN_KERNEL_FS_CLIENT_SUPER_MAGIC) {
	*fstype = ADIO_PANFS;
	return;
    }
# endif

# ifdef MOUNT_NFS
    if (fsbuf.f_type == MOUNT_NFS) {
	*fstype = ADIO_NFS;
	return;
    }
# endif

# ifdef MOUNT_PFS
    if (fsbuf.f_type == MOUNT_PFS) {
	*fstype = ADIO_PFS;
	return;
    }
# endif

# ifdef PVFS_SUPER_MAGIC
    if (fsbuf.f_type == PVFS_SUPER_MAGIC) {
	*fstype = ADIO_PVFS;
	return;
    }
# endif

# ifdef PVFS2_SUPER_MAGIC
    if (fsbuf.f_type == PVFS2_SUPER_MAGIC) {
	*fstype = ADIO_PVFS2;
	return;
    }
# endif

# ifdef XFS_SUPER_MAGIC
    if (fsbuf.f_type == XFS_SUPER_MAGIC) {
	    *fstype = ADIO_XFS;
	    return;
    }
# endif

# ifdef ROMIO_UFS
    /* if UFS support is enabled, default to that */
    *fstype = ADIO_UFS;
    return;
# endif
    /* --BEGIN ERROR HANDLING-- */
    *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
				       myname, __LINE__, MPI_ERR_NO_SUCH_FILE,
				       "**filename", "**filename %s", filename);
    /* --END ERROR HANDLING-- */
#endif /* STATFS APPROACH */

#ifdef ROMIO_HAVE_STRUCT_STAT_WITH_ST_FSTYPE
    /* rare: maybe old NEC SX or SGI IRIX machines */
    retry_cnt = 0;
    do {
	err = stat(filename, &sbuf);
    } while (err && (errno == ESTALE) && retry_cnt++ < MAX_ESTALE_RETRY);

    if (err) {
	if(errno == ENOENT) {
	    char *dir;
	    ADIO_FileSysType_parentdir(filename, &dir);
	    err = stat(dir, &sbuf);
	    ADIOI_Free(dir);
	}
	else{
	    *error_code = ADIOI_Err_create_code(myname, filename, errno);
	    if(*error_code != MPI_SUCCESS) return;
	}
    }
    
    if (err) {
    	/* --BEGIN ERROR HANDLING-- */
    	*error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
				           myname, __LINE__, MPI_ERR_NO_SUCH_FILE,
				           "**filename", "**filename %s", filename);
    	/* --END ERROR HANDLING-- */
	return;
    }
    else {
	if (!strcmp(sbuf.st_fstype, "nfs")) *fstype = ADIO_NFS;
	else *fstype = ADIO_SFS; /* assuming SX4 for now */
    }
#endif /* STAT APPROACH */

#ifdef ROMIO_NTFS
    ADIOI_UNREFERENCED_ARG(filename);
    ADIOI_UNREFERENCED_ARG(error_code);
    *fstype = ADIO_NTFS; /* only supported FS on Windows */
#elif defined(ROMIO_NFS)
    *fstype = ADIO_NFS;
#elif defined(ROMIO_UFS)
    *fstype = ADIO_UFS;
#else
    /* --BEGIN ERROR HANDLING-- */
    *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE,
				       myname, __LINE__, MPI_ERR_NO_SUCH_FILE,
				       "**filename", "**filename %s", filename);
    /* --END ERROR HANDLING-- */
#endif
}
int nandroid_backup(const char* backup_path)
{
    ui_set_background(BACKGROUND_ICON_INSTALLING);
    
    if (ensure_path_mounted("/sdcard") != 0)
        return print_and_error("Can't mount /sdcard\n");
    
    int ret;
    struct statfs s;
    if (0 != (ret = statfs("/sdcard", &s)))
        return print_and_error("Unable to stat /sdcard\n");
    uint64_t bavail = s.f_bavail;
    uint64_t bsize = s.f_bsize;
    uint64_t sdcard_free = bavail * bsize;
    uint64_t sdcard_free_mb = sdcard_free / (uint64_t)(1024 * 1024);
    ui_print("SD Card space free: %lluMB\n", sdcard_free_mb);
    if (sdcard_free_mb < 150)
        ui_print("There may not be enough free space to complete backup... continuing...\n");
    
    char tmp[PATH_MAX];
    sprintf(tmp, "mkdir -p %s", backup_path);
    __system(tmp);

    if (0 != (ret = nandroid_backup_partition(backup_path, "/boot")))
        return ret;

    if (0 != (ret = nandroid_backup_partition(backup_path, "/recovery")))
        return ret;

    Volume *vol = volume_for_path("/wimax");
    if (vol != NULL && 0 == stat(vol->device, &s))
    {
        char serialno[PROPERTY_VALUE_MAX];
        ui_print("Backing up WiMAX...\n");
        serialno[0] = 0;
        property_get("ro.serialno", serialno, "");
        sprintf(tmp, "%s/wimax.%s.img", backup_path, serialno);
        ret = backup_raw_partition(vol->fs_type, vol->device, tmp);
        if (0 != ret)
            return print_and_error("Error while dumping WiMAX image!\n");
    }

    if (0 != (ret = nandroid_backup_partition(backup_path, "/system")))
        return ret;

    if (0 != (ret = nandroid_backup_partition(backup_path, "/data")))
        return ret;

    if (has_datadata()) {
        if (0 != (ret = nandroid_backup_partition(backup_path, "/datadata")))
            return ret;
    }

    if (0 != stat("/sdcard/.android_secure", &s))
    {
        ui_print("No /sdcard/.android_secure found. Skipping backup of applications on external storage.\n");
    }
    else
    {
        if (0 != (ret = nandroid_backup_partition_extended(backup_path, "/sdcard/.android_secure", 0)))
            return ret;
    }

    if (0 != (ret = nandroid_backup_partition_extended(backup_path, "/cache", 0)))
        return ret;
#ifdef RECOVERY_HAVE_SD_EXT
    vol = volume_for_path("/sd-ext");
    if (vol == NULL || 0 != stat(vol->device, &s))
    {
        ui_print("No sd-ext found. Skipping backup of sd-ext.\n");
    }
    else
    {
        if (0 != ensure_path_mounted("/sd-ext"))
            ui_print("Could not mount sd-ext. sd-ext backup may not be supported on this device. Skipping backup of sd-ext.\n");
        else if (0 != (ret = nandroid_backup_partition(backup_path, "/sd-ext")))
            return ret;
    }
#endif
    ui_print("Generating md5 sum...\n");
    sprintf(tmp, "nandroid-md5.sh %s", backup_path);
    if (0 != (ret = __system(tmp))) {
        ui_print("Error while generating md5 sum!\n");
        return ret;
    }
    
    sync();
    ui_set_background(BACKGROUND_ICON_NONE);
    ui_reset_progress();
    ui_print("\nBackup complete!\n");
    return 0;
}
Exemple #21
0
struct mount_entry *
read_file_system_list (bool need_fs_type)
{
  struct mount_entry *mount_list;
  struct mount_entry *me;
  struct mount_entry **mtail = &mount_list;

#ifdef MOUNTED_LISTMNTENT
  {
    struct tabmntent *mntlist, *p;
    struct mntent *mnt;
    struct mount_entry *me;

    /* the third and fourth arguments could be used to filter mounts,
       but Crays doesn't seem to have any mounts that we want to
       remove. Specifically, automount create normal NFS mounts.
       */

    if (listmntent (&mntlist, KMTAB, NULL, NULL) < 0)
      return NULL;
    for (p = mntlist; p; p = p->next) {
      mnt = p->ment;
      me = xmalloc (sizeof *me);
      me->me_devname = xstrdup (mnt->mnt_fsname);
      me->me_mountdir = xstrdup (mnt->mnt_dir);
      me->me_type = xstrdup (mnt->mnt_type);
      me->me_type_malloced = 1;
      me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
      me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
      me->me_dev = -1;
      *mtail = me;
      mtail = &me->me_next;
    }
    freemntlist (mntlist);
  }
#endif

#ifdef MOUNTED_GETMNTENT1 /* GNU/Linux, 4.3BSD, SunOS, HP-UX, Dynix, Irix.  */
  {
    struct mntent *mnt;
    char *table = MOUNTED;
    FILE *fp;

    fp = setmntent (table, "r");
    if (fp == NULL)
      return NULL;

    while ((mnt = getmntent (fp)))
      {
        me = malloc (sizeof *me);
        me->me_devname = strdup (mnt->mnt_fsname);
        me->me_mountdir = strdup (mnt->mnt_dir);
        me->me_type = strdup (mnt->mnt_type);
        me->me_type_malloced = 1;
        me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
        me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
        me->me_dev = dev_from_mount_options (mnt->mnt_opts);

        /* Add to the linked list. */
        *mtail = me;
        mtail = &me->me_next;
      }

    if (endmntent (fp) == 0)
      goto free_then_fail;
  }
#endif /* MOUNTED_GETMNTENT1. */

#ifdef MOUNTED_GETMNTINFO        /* 4.4BSD.  */
  {
    struct statfs *fsp;
    int entries;

    entries = getmntinfo (&fsp, MNT_NOWAIT);
    if (entries < 0)
      return NULL;
    for (; entries-- > 0; fsp++)
      {
        me = malloc (sizeof *me);
        me->me_devname = strdup (fsp->f_mntfromname);
        me->me_mountdir = strdup (fsp->f_mntonname);
#if defined(__macosx__)
        me->me_type = fsp->f_fstypename;
#else
        me->me_type = fsp->fs_typename;
#endif 
        me->me_type_malloced = 0;
        me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
        me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
        me->me_dev = (dev_t) -1;        /* Magic; means not known yet. */

        /* Add to the linked list. */
        *mtail = me;
        mtail = &me->me_next;
      }
  }
#endif /* MOUNTED_GETMNTINFO */

#ifdef MOUNTED_GETMNTINFO2        /* NetBSD 3.0.  */
  {
    struct statvfs *fsp;
    int entries;

    entries = getmntinfo (&fsp, MNT_NOWAIT);
    if (entries < 0)
      return NULL;
    for (; entries-- > 0; fsp++)
      {
        me = xmalloc (sizeof *me);
        me->me_devname = xstrdup (fsp->f_mntfromname);
        me->me_mountdir = xstrdup (fsp->f_mntonname);
        me->me_type = xstrdup (fsp->f_fstypename);
        me->me_type_malloced = 1;
        me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
        me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
        me->me_dev = (dev_t) -1;        /* Magic; means not known yet. */

        /* Add to the linked list. */
        *mtail = me;
        mtail = &me->me_next;
      }
  }
#endif /* MOUNTED_GETMNTINFO2 */

#ifdef MOUNTED_GETMNT                /* Ultrix.  */
  {
    int offset = 0;
    int val;
    struct fs_data fsd;

    while (errno = 0,
           0 < (val = getmnt (&offset, &fsd, sizeof (fsd), NOSTAT_MANY,
                              (char *) 0)))
      {
        me = xmalloc (sizeof *me);
        me->me_devname = xstrdup (fsd.fd_req.devname);
        me->me_mountdir = xstrdup (fsd.fd_req.path);
        me->me_type = gt_names[fsd.fd_req.fstype];
        me->me_type_malloced = 0;
        me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
        me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
        me->me_dev = fsd.fd_req.dev;

        /* Add to the linked list. */
        *mtail = me;
        mtail = &me->me_next;
      }
    if (val < 0)
      goto free_then_fail;
  }
#endif /* MOUNTED_GETMNT. */

#if defined MOUNTED_FS_STAT_DEV /* BeOS */
  {
    /* The next_dev() and fs_stat_dev() system calls give the list of
       all file systems, including the information returned by statvfs()
       (fs type, total blocks, free blocks etc.), but without the mount
       point. But on BeOS all file systems except / are mounted in the
       rootfs, directly under /.
       The directory name of the mount point is often, but not always,
       identical to the volume name of the device.
       We therefore get the list of subdirectories of /, and the list
       of all file systems, and match the two lists.  */

    DIR *dirp;
    struct rootdir_entry
      {
        char *name;
        dev_t dev;
        ino_t ino;
        struct rootdir_entry *next;
      };
    struct rootdir_entry *rootdir_list;
    struct rootdir_entry **rootdir_tail;
    int32 pos;
    dev_t dev;
    fs_info fi;

    /* All volumes are mounted in the rootfs, directly under /. */
    rootdir_list = NULL;
    rootdir_tail = &rootdir_list;
    dirp = opendir ("/");
    if (dirp)
      {
        struct dirent *d;

        while ((d = readdir (dirp)) != NULL)
          {
            char *name;
            struct stat statbuf;

            if (strcmp (d->d_name, "..") == 0)
              continue;

            if (strcmp (d->d_name, ".") == 0)
              name = strdup ("/");
            else
              {
                name = malloc (1 + strlen (d->d_name) + 1);
                name[0] = '/';
                strcpy (name + 1, d->d_name);
              }

            if (lstat (name, &statbuf) >= 0 && S_ISDIR (statbuf.st_mode))
              {
                struct rootdir_entry *re = malloc (sizeof *re);
                re->name = name;
                re->dev = statbuf.st_dev;
                re->ino = statbuf.st_ino;

                /* Add to the linked list.  */
                *rootdir_tail = re;
                rootdir_tail = &re->next;
              }
            else
              free (name);
          }
        closedir (dirp);
      }
    *rootdir_tail = NULL;

    for (pos = 0; (dev = next_dev (&pos)) >= 0; )
      if (fs_stat_dev (dev, &fi) >= 0)
        {
          /* Note: fi.dev == dev. */
          struct rootdir_entry *re;

          for (re = rootdir_list; re; re = re->next)
            if (re->dev == fi.dev && re->ino == fi.root)
              break;

          me = malloc (sizeof *me);
          me->me_devname = strdup (fi.device_name[0] != '\0' ? fi.device_name : fi.fsh_name);
          me->me_mountdir = strdup (re != NULL ? re->name : fi.fsh_name);
          me->me_type = strdup (fi.fsh_name);
          me->me_type_malloced = 1;
          me->me_dev = fi.dev;
          me->me_dummy = 0;
          me->me_remote = (fi.flags & B_FS_IS_SHARED) != 0;

          /* Add to the linked list. */
          *mtail = me;
          mtail = &me->me_next;
        }
    *mtail = NULL;

    while (rootdir_list != NULL)
      {
        struct rootdir_entry *re = rootdir_list;
        rootdir_list = re->next;
        free (re->name);
        free (re);
      }
  }
#endif /* MOUNTED_FS_STAT_DEV */

#if defined MOUNTED_GETFSSTAT        /* __alpha running OSF_1 */
  {
    int numsys, counter;
    size_t bufsize;
    struct statfs *stats;

    numsys = getfsstat ((struct statfs *)0, 0L, MNT_NOWAIT);
    if (numsys < 0)
      return (NULL);
    if (SIZE_MAX / sizeof *stats <= numsys)
      xalloc_die ();

    bufsize = (1 + numsys) * sizeof *stats;
    stats = xmalloc (bufsize);
    numsys = getfsstat (stats, bufsize, MNT_NOWAIT);

    if (numsys < 0)
      {
        free (stats);
        return (NULL);
      }

    for (counter = 0; counter < numsys; counter++)
      {
        me = xmalloc (sizeof *me);
        me->me_devname = xstrdup (stats[counter].f_mntfromname);
        me->me_mountdir = xstrdup (stats[counter].f_mntonname);
        me->me_type = xstrdup (FS_TYPE (stats[counter]));
        me->me_type_malloced = 1;
        me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
        me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
        me->me_dev = (dev_t) -1;        /* Magic; means not known yet. */

        /* Add to the linked list. */
        *mtail = me;
        mtail = &me->me_next;
      }

    free (stats);
  }
#endif /* MOUNTED_GETFSSTAT */

#if defined MOUNTED_FREAD || defined MOUNTED_FREAD_FSTYP /* SVR[23].  */
  {
    struct mnttab mnt;
    char *table = "/etc/mnttab";
    FILE *fp;

    fp = fopen (table, "r");
    if (fp == NULL)
      return NULL;

    while (fread (&mnt, sizeof mnt, 1, fp) > 0)
      {
        me = xmalloc (sizeof *me);
# ifdef GETFSTYP                        /* SVR3.  */
        me->me_devname = xstrdup (mnt.mt_dev);
# else
        me->me_devname = xmalloc (strlen (mnt.mt_dev) + 6);
        strcpy (me->me_devname, "/dev/");
        strcpy (me->me_devname + 5, mnt.mt_dev);
# endif
        me->me_mountdir = xstrdup (mnt.mt_filsys);
        me->me_dev = (dev_t) -1;        /* Magic; means not known yet. */
        me->me_type = "";
        me->me_type_malloced = 0;
# ifdef GETFSTYP                        /* SVR3.  */
        if (need_fs_type)
          {
            struct statfs fsd;
            char typebuf[FSTYPSZ];

            if (statfs (me->me_mountdir, &fsd, sizeof fsd, 0) != -1
                && sysfs (GETFSTYP, fsd.f_fstyp, typebuf) != -1)
              {
                me->me_type = xstrdup (typebuf);
                me->me_type_malloced = 1;
              }
          }
# endif
        me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
        me->me_remote = ME_REMOTE (me->me_devname, me->me_type);

        /* Add to the linked list. */
        *mtail = me;
        mtail = &me->me_next;
      }

    if (ferror (fp))
      {
        /* The last fread() call must have failed.  */
        int saved_errno = errno;
        fclose (fp);
        errno = saved_errno;
        goto free_then_fail;
      }

    if (fclose (fp) == EOF)
      goto free_then_fail;
  }
#endif /* MOUNTED_FREAD || MOUNTED_FREAD_FSTYP.  */

#ifdef MOUNTED_GETMNTTBL        /* DolphinOS goes its own way.  */
  {
    struct mntent **mnttbl = getmnttbl (), **ent;
    for (ent=mnttbl;*ent;ent++)
      {
        me = xmalloc (sizeof *me);
        me->me_devname = xstrdup ( (*ent)->mt_resource);
        me->me_mountdir = xstrdup ( (*ent)->mt_directory);
        me->me_type = xstrdup ((*ent)->mt_fstype);
        me->me_type_malloced = 1;
        me->me_dummy = ME_DUMMY (me->me_devname, me->me_type);
        me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
        me->me_dev = (dev_t) -1;        /* Magic; means not known yet. */

        /* Add to the linked list. */
        *mtail = me;
        mtail = &me->me_next;
      }
    endmnttbl ();
  }
#endif

#ifdef MOUNTED_GETMNTENT2        /* SVR4.  */
  {
    struct mnttab mnt;
    char *table = MNTTAB;
    FILE *fp;
    int ret;
    int lockfd = -1;

# if defined F_RDLCK && defined F_SETLKW
    /* MNTTAB_LOCK is a macro name of our own invention; it's not present in
       e.g. Solaris 2.6.  If the SVR4 folks ever define a macro
       for this file name, we should use their macro name instead.
       (Why not just lock MNTTAB directly?  We don't know.)  */
#  ifndef MNTTAB_LOCK
#   define MNTTAB_LOCK "/etc/.mnttab.lock"
#  endif
    lockfd = open (MNTTAB_LOCK, O_RDONLY);
    if (0 <= lockfd)
      {
        struct flock flock;
        flock.l_type = F_RDLCK;
        flock.l_whence = SEEK_SET;
        flock.l_start = 0;
        flock.l_len = 0;
        while (fcntl (lockfd, F_SETLKW, &flock) == -1)
          if (errno != EINTR)
            {
              int saved_errno = errno;
              close (lockfd);
              errno = saved_errno;
              return NULL;
            }
      }
    else if (errno != ENOENT)
      return NULL;
# endif

    errno = 0;
    fp = fopen (table, "r");
    if (fp == NULL)
      ret = errno;
    else
      {
        while ((ret = getmntent (fp, &mnt)) == 0)
          {
            me = xmalloc (sizeof *me);
            me->me_devname = xstrdup (mnt.mnt_special);
            me->me_mountdir = xstrdup (mnt.mnt_mountp);
            me->me_type = xstrdup (mnt.mnt_fstype);
            me->me_type_malloced = 1;
            me->me_dummy = MNT_IGNORE (&mnt) != 0;
            me->me_remote = ME_REMOTE (me->me_devname, me->me_type);
            me->me_dev = dev_from_mount_options (mnt.mnt_mntopts);

            /* Add to the linked list. */
            *mtail = me;
            mtail = &me->me_next;
          }

        ret = fclose (fp) == EOF ? errno : 0 < ret ? 0 : -1;
      }

    if (0 <= lockfd && close (lockfd) != 0)
      ret = errno;

    if (0 <= ret)
      {
        errno = ret;
        goto free_then_fail;
      }
  }
#endif /* MOUNTED_GETMNTENT2.  */

#ifdef MOUNTED_VMOUNT                /* AIX.  */
  {
    int bufsize;
    char *entries, *thisent;
    struct vmount *vmp;
    int n_entries;
    int i;

    /* Ask how many bytes to allocate for the mounted file system info.  */
    if (mntctl (MCTL_QUERY, sizeof bufsize, (struct vmount *) &bufsize) != 0)
      return NULL;
    entries = xmalloc (bufsize);

    /* Get the list of mounted file systems.  */
    n_entries = mntctl (MCTL_QUERY, bufsize, (struct vmount *) entries);
    if (n_entries < 0)
      {
        int saved_errno = errno;
        free (entries);
        errno = saved_errno;
        return NULL;
      }

    for (i = 0, thisent = entries;
         i < n_entries;
         i++, thisent += vmp->vmt_length)
      {
        char *options, *ignore;

        vmp = (struct vmount *) thisent;
        me = xmalloc (sizeof *me);
        if (vmp->vmt_flags & MNT_REMOTE)
          {
            char *host, *dir;

            me->me_remote = 1;
            /* Prepend the remote dirname.  */
            host = thisent + vmp->vmt_data[VMT_HOSTNAME].vmt_off;
            dir = thisent + vmp->vmt_data[VMT_OBJECT].vmt_off;
            me->me_devname = xmalloc (strlen (host) + strlen (dir) + 2);
            strcpy (me->me_devname, host);
            strcat (me->me_devname, ":");
            strcat (me->me_devname, dir);
          }
        else
          {
            me->me_remote = 0;
            me->me_devname = xstrdup (thisent +
                                      vmp->vmt_data[VMT_OBJECT].vmt_off);
          }
        me->me_mountdir = xstrdup (thisent + vmp->vmt_data[VMT_STUB].vmt_off);
        me->me_type = xstrdup (fstype_to_string (vmp->vmt_gfstype));
        me->me_type_malloced = 1;
        options = thisent + vmp->vmt_data[VMT_ARGS].vmt_off;
        ignore = strstr (options, "ignore");
        me->me_dummy = (ignore
                        && (ignore == options || ignore[-1] == ',')
                        && (ignore[sizeof "ignore" - 1] == ','
                            || ignore[sizeof "ignore" - 1] == '\0'));
        me->me_dev = (dev_t) -1; /* vmt_fsid might be the info we want.  */

        /* Add to the linked list. */
        *mtail = me;
        mtail = &me->me_next;
      }
    free (entries);
  }
#endif /* MOUNTED_VMOUNT. */

  *mtail = NULL;
  return mount_list;


 free_then_fail:
  {
    int saved_errno = errno;
    *mtail = NULL;

    while (mount_list)
      {
        me = mount_list->me_next;
        free (mount_list->me_devname);
        free (mount_list->me_mountdir);
        if (mount_list->me_type_malloced)
          free (mount_list->me_type);
        free (mount_list);
        mount_list = me;
      }

    errno = saved_errno;
    return NULL;
  }
}
Exemple #22
0
/*
 * get_tmp_disk - Return the total size of temporary file system on
 *    this system
 * Input: tmp_disk - buffer for the disk space size
 *        tmp_fs - pathname of the temporary file system to status,
 *		   defaults to "/tmp"
 * Output: tmp_disk - filled in with disk space size in MB, zero if error
 *         return code - 0 if no error, otherwise errno
 */
extern int
get_tmp_disk(uint32_t *tmp_disk, char *tmp_fs)
{
	int error_code = 0;

#if defined(HAVE_STATVFS)
	struct statvfs stat_buf;
	uint64_t total_size = 0;
	char *tmp_fs_name = tmp_fs;

	*tmp_disk = 0;
	total_size = 0;

	if (tmp_fs_name == NULL)
		tmp_fs_name = "/tmp";
	if (statvfs(tmp_fs_name, &stat_buf) == 0) {
		total_size = stat_buf.f_blocks * stat_buf.f_frsize;
		total_size /= 1024 * 1024;
	}
	else if (errno != ENOENT) {
		error_code = errno;
		error ("get_tmp_disk: error %d executing statvfs on %s",
			errno, tmp_fs_name);
	}
	*tmp_disk += (uint32_t)total_size;

#elif defined(HAVE_STATFS)
	struct statfs stat_buf;
	long   total_size;
	float page_size;
	char *tmp_fs_name = tmp_fs;

	*tmp_disk = 0;
	total_size = 0;
	page_size = (sysconf(_SC_PAGE_SIZE) / 1048576.0); /* MG per page */

	if (tmp_fs_name == NULL)
		tmp_fs_name = "/tmp";
#if defined (__sun)
	if (statfs(tmp_fs_name, &stat_buf, 0, 0) == 0) {
#else
	if (statfs(tmp_fs_name, &stat_buf) == 0) {
#endif
		total_size = (long)stat_buf.f_blocks;
	}
	else if (errno != ENOENT) {
		error_code = errno;
		error ("get_tmp_disk: error %d executing statfs on %s",
			errno, tmp_fs_name);
	}

	*tmp_disk += (uint32_t)(total_size * page_size);
#else
	*tmp_disk = 1;
#endif
	return error_code;
}

extern int get_up_time(uint32_t *up_time)
{
#if defined(HAVE_AIX) || defined(__sun) || defined(__APPLE__) || defined(__NetBSD__) || defined(__FreeBSD__)
	clock_t tm;
	struct tms buf;

	tm = times(&buf);
	if (tm == (clock_t) -1) {
		*up_time = 0;
		return errno;
	}

	*up_time = tm / sysconf(_SC_CLK_TCK);
#elif defined(__CYGWIN__)
	FILE *uptime_file;
	char buffer[128];
	char* _uptime_path = "/proc/uptime";

	if (!(uptime_file = fopen(_uptime_path, "r"))) {
		error("get_up_time: error %d opening %s", errno, _uptime_path);
		return errno;
	}

	if (fgets(buffer, sizeof(buffer), uptime_file))
		*up_time = atoi(buffer);

	fclose(uptime_file);
#else
	/* NOTE for Linux: The return value of times() may overflow the
	 * possible range of type clock_t. There is also an offset of
	 * 429 million seconds on some implementations. We just use the
	 * simpler sysinfo() function instead. */
	struct sysinfo info;

	if (sysinfo(&info) < 0) {
		*up_time = 0;
		return errno;
	}


	if (conf->boot_time) {
		/* Make node look like it rebooted when slurmd started */
		static uint32_t orig_uptime = 0;
		if (orig_uptime == 0)
			orig_uptime = info.uptime;
		*up_time = info.uptime - orig_uptime;
	} else {
		*up_time = info.uptime;
	}
#endif
	return 0;
}
Exemple #23
0
static void init_selinuxmnt(void)
{
	char *buf=NULL, *p;
	FILE *fp=NULL;
	struct statfs sfbuf;
	int rc;
	size_t len;
	ssize_t num;
	int exists = 0;

	if (selinux_mnt)
		return;

	/* We check to see if the preferred mount point for selinux file
	 * system has a selinuxfs. */
	do {
		rc = statfs(SELINUXMNT, &sfbuf);
	} while (rc < 0 && errno == EINTR);
	if (rc == 0) {
		if ((uint32_t)sfbuf.f_type == (uint32_t)SELINUX_MAGIC) {
			selinux_mnt = strdup(SELINUXMNT);
			return;
		}
	} 

	/* Drop back to detecting it the long way. */
	fp = fopen("/proc/filesystems", "r");
	if (!fp)
		return;

	__fsetlocking(fp, FSETLOCKING_BYCALLER);
	while ((num = getline(&buf, &len, fp)) != -1) {
		if (strstr(buf, "selinuxfs")) {
			exists = 1;
			break;
		}
	}

	if (!exists) 
		goto out;

	fclose(fp);

	/* At this point, the usual spot doesn't have an selinuxfs so
	 * we look around for it */
	fp = fopen("/proc/mounts", "r");
	if (!fp)
		goto out;

	__fsetlocking(fp, FSETLOCKING_BYCALLER);
	while ((num = getline(&buf, &len, fp)) != -1) {
		char *tmp;
		p = strchr(buf, ' ');
		if (!p)
			goto out;
		p++;
		tmp = strchr(p, ' ');
		if (!tmp)
			goto out;
		if (!strncmp(tmp + 1, "selinuxfs ", 10)) {
			*tmp = '\0';
			break;
		}
	}

	/* If we found something, dup it */
	if (num > 0)
		selinux_mnt = strdup(p);

      out:
	free(buf);
	if (fp)
		fclose(fp);
	return;
}
int nandroid_backup(const char* backup_path)
{
    nandroid_backup_bitfield = 0;
    ui_set_background(BACKGROUND_ICON_INSTALLING);
    refresh_default_backup_handler();

    if (ensure_path_mounted(backup_path) != 0) {
        return print_and_error("无法挂载备份时需要的存储器.\n");
    }

    Volume* volume = volume_for_path(backup_path);
    if (NULL == volume)
        return print_and_error("找不到备份需要的存储器.\n");
    if (is_data_media_volume_path(volume->mount_point))
        volume = volume_for_path("/data");
    int ret;
    struct statfs s;
    if (NULL != volume) {
        if (0 != (ret = statfs(volume->mount_point, &s)))
            return print_and_error("找不到备份路径,因此无法开始.\n");
        uint64_t bavail = s.f_bavail;
        uint64_t bsize = s.f_bsize;
        uint64_t sdcard_free = bavail * bsize;
        uint64_t sdcard_free_mb = sdcard_free / (uint64_t)(1024 * 1024);
        ui_print("SD Card space free: %lluMB\n", sdcard_free_mb);
        if (sdcard_free_mb < 150)
            ui_print("可能是你的机器空间不足了,继续中...\n");
    }
    char tmp[PATH_MAX];
    ensure_directory(backup_path);

    if (0 != (ret = nandroid_backup_partition(backup_path, "/boot")))
        return ret;

    if (0 != (ret = nandroid_backup_partition(backup_path, "/uboot")))
        return ret;

    if (0 != (ret = nandroid_backup_partition(backup_path, "/recovery")))
        return ret;

    Volume *vol = volume_for_path("/wimax");
    if (vol != NULL && 0 == stat(vol->device, &s))
    {
        char serialno[PROPERTY_VALUE_MAX];
        ui_print("正在备份WiMAX...\n");
        serialno[0] = 0;
        property_get("ro.serialno", serialno, "");
        sprintf(tmp, "%s/wimax.%s.img", backup_path, serialno);
        ret = backup_raw_partition(vol->fs_type, vol->device, tmp);
        if (0 != ret)
            return print_and_error("打包或生成WiMAX镜像失败\n");
    }

    if (0 != (ret = nandroid_backup_partition(backup_path, "/system")))
        return ret;

    if (0 != (ret = nandroid_backup_partition(backup_path, "/data")))
        return ret;

    if (has_datadata()) {
        if (0 != (ret = nandroid_backup_partition(backup_path, "/datadata")))
            return ret;
    }

    if (is_data_media() || 0 != stat("/sdcard/.android_secure", &s)) {
        ui_print("没找到 /sdcard/.android_secure. 跳过外部程序备份.\n");
    }
    else {
        if (0 != (ret = nandroid_backup_partition_extended(backup_path, "/sdcard/.android_secure", 0)))
            return ret;
    }

    if (0 != (ret = nandroid_backup_partition_extended(backup_path, "/cache", 0)))
        return ret;

    vol = volume_for_path("/sd-ext");
    if (vol == NULL || 0 != stat(vol->device, &s))
    {
        ui_print("没找到SD-EXT,因此跳过该处备份.\n");
    }
    else
    {
        if (0 != ensure_path_mounted("/sd-ext"))
            ui_print("没法挂载SD-EXT,可能是你的机器不支持该选项,跳过该部分的备份\n");
        else if (0 != (ret = nandroid_backup_partition(backup_path, "/sd-ext")))
            return ret;
    }

    ui_print("生成md5 校验值...\n");
    sprintf(tmp, "nandroid-md5.sh %s", backup_path);
    if (0 != (ret = __system(tmp))) {
        ui_print("MD5校验值生成失败\n");
        return ret;
    }

    sprintf(tmp, "cp /tmp/recovery.log %s/recovery.log", backup_path);
    __system(tmp);

    sprintf(tmp, "chmod -R 777 %s ; chmod -R u+r,u+w,g+r,g+w,o+r,o+w /sdcard/clockworkmod ; chmod u+x,g+x,o+x /sdcard/clockworkmod/backup ; chmod u+x,g+x,o+x /sdcard/clockworkmod/blobs", backup_path);
    __system(tmp);
    sync();
    ui_set_background(BACKGROUND_ICON_NONE);
    ui_reset_progress();
    ui_print("\n备份完成!\n");
    return 0;
}
inline int getAccess(int accType, struct stat *buffer, char *p_path)
{

    struct statfs fsbuffer;
    int idType;

    if(! buffer)
	return BTA_FS_CO_FAIL;

    //idType= (buffer->st_uid== BT_UID) ? 1 : (buffer->st_uid== BT_GID) ? 2 : 3;
    if(buffer->st_uid == BT_UID)
        idType = 1;
    else if(buffer->st_gid == BT_GID ||
            buffer->st_gid == AID_SYSTEM ||
            buffer->st_gid == AID_MISC ||
            buffer->st_gid == AID_SDCARD_RW)
        idType = 2;
    else idType = 3;

    if(statfs(p_path, &fsbuffer)==0)
    {
        if(fsbuffer.f_type == FAT_FS)
	    return BTA_FS_CO_OK;
    }
    else {
        return BTA_FS_CO_FAIL;
    }

    switch(accType) {
        case 4:
	if(idType== 1) {	//Id is User Id
	   if(buffer-> st_mode & S_IRUSR)
	       return BTA_FS_CO_OK;
	}
	else if(idType==2) {   //Id is Group Id
	    if(buffer-> st_mode & S_IRGRP)
	       return BTA_FS_CO_OK;
	}
	else {			//Id is Others
	    if(buffer-> st_mode & S_IROTH)
	       return BTA_FS_CO_OK;
	}
	break;

	case 6:
	if(idType== 1) {	//Id is User Id
	   if((buffer-> st_mode & S_IRUSR) && (buffer-> st_mode & S_IWUSR))
	       return BTA_FS_CO_OK;
	}
	else if(idType==2) {   //Id is Group Id
	    if((buffer-> st_mode & S_IRGRP) && (buffer-> st_mode & S_IWGRP))
	       return BTA_FS_CO_OK;
	}
	else {			//Id is Others
	    if((buffer-> st_mode & S_IROTH) && (buffer-> st_mode & S_IWOTH))
	       return BTA_FS_CO_OK;
	}
	break;

	default:
	return BTA_FS_CO_OK;
    }
    BTIF_TRACE_DEBUG("*************FTP- Access Failed **********");
    return BTA_FS_CO_EACCES;
}
int nandroid_restore_partition_extended(const char* backup_path, const char* mount_point, int umount_when_finished) {
    int ret = 0;
    char* name = basename(mount_point);

    nandroid_restore_handler restore_handler = NULL;
    const char *filesystems[] = { "yaffs2", "ext2", "ext3", "ext4", "vfat", "rfs", NULL };
    const char* backup_filesystem = NULL;
    Volume *vol = volume_for_path(mount_point);
    const char *device = NULL;
    if (vol != NULL)
        device = vol->device;

    char tmp[PATH_MAX];
    sprintf(tmp, "%s/%s.img", backup_path, name);
    struct stat file_info;
    if (strcmp(backup_path, "-") == 0) {
        if (vol)
            backup_filesystem = vol->fs_type;
        restore_handler = tar_extract_wrapper;
        strcpy(tmp, "/proc/self/fd/0");
    }
    else if (0 != (ret = statfs(tmp, &file_info))) {
        // can't find the backup, it may be the new backup format?
        // iterate through the backup types
        printf("找不到默认\n");
        char *filesystem;
        int i = 0;
        while ((filesystem = filesystems[i]) != NULL) {
            sprintf(tmp, "%s/%s.%s.img", backup_path, name, filesystem);
            if (0 == (ret = statfs(tmp, &file_info))) {
                backup_filesystem = filesystem;
                restore_handler = unyaffs_wrapper;
                break;
            }
            sprintf(tmp, "%s/%s.%s.tar", backup_path, name, filesystem);
            if (0 == (ret = statfs(tmp, &file_info))) {
                backup_filesystem = filesystem;
                restore_handler = tar_extract_wrapper;
                break;
            }
            sprintf(tmp, "%s/%s.%s.dup", backup_path, name, filesystem);
            if (0 == (ret = statfs(tmp, &file_info))) {
                backup_filesystem = filesystem;
                restore_handler = dedupe_extract_wrapper;
                break;
            }
            i++;
        }

        if (backup_filesystem == NULL || restore_handler == NULL) {
            ui_print("%s.镜像没找到,因此跳过该处恢复. %s.\n", name, mount_point);
            return 0;
        }
        else {
            printf("找到新的可恢复镜像: %s\n", tmp);
        }
    }

    // If the fs_type of this volume is "auto" or mount_point is /data
    // and is_data_media, let's revert
    // to using a rm -rf, rather than trying to do a
    // ext3/ext4/whatever format.
    // This is because some phones (like DroidX) will freak out if you
    // reformat the /system or /data partitions, and not boot due to
    // a locked bootloader.
    // Other devices, like the Galaxy Nexus, XOOM, and Galaxy Tab 10.1
    // have a /sdcard symlinked to /data/media.
    // Or of volume does not exist (.android_secure), just rm -rf.
    if (vol == NULL || 0 == strcmp(vol->fs_type, "auto"))
        backup_filesystem = NULL;
    if (0 == strcmp(vol->mount_point, "/data") && is_data_media())
        backup_filesystem = NULL;

    ensure_directory(mount_point);

    int callback = stat("/sdcard/clockworkmod/.hidenandroidprogress", &file_info) != 0;

    ui_print("正在恢复 %s...\n", name);
    if (backup_filesystem == NULL) {
        if (0 != (ret = format_volume(mount_point))) {
            ui_print("格式化下列分区失败 %s!\n", mount_point);
            return ret;
        }
    }
    else if (0 != (ret = format_device(device, mount_point, backup_filesystem))) {
        ui_print("格式化下列分区失败 %s!\n", mount_point);
        return ret;
    }

    if (0 != (ret = ensure_path_mounted(mount_point))) {
        ui_print("挂载下列分区失败 %s!\n", mount_point);
        return ret;
    }

    if (restore_handler == NULL)
        restore_handler = get_restore_handler(mount_point);

    // override restore handler for undump
    if (strcmp(backup_path, "-") == 0) {
        restore_handler = tar_undump_wrapper;
    }

    if (restore_handler == NULL) {
        ui_print("找不到合适的方案\n");
        return -2;
    }

    if (0 != (ret = restore_handler(tmp, mount_point, callback))) {
        ui_print("恢复失败: %s!\n", mount_point);
        return ret;
    }

    if (umount_when_finished) {
        ensure_path_unmounted(mount_point);
    }

    return 0;
}
Exemple #27
0
int eDVBServiceRecord::doRecord()
{
	int err = doPrepare();
	if (err)
	{
		m_error = errTuneFailed;
		m_event((iRecordableService*)this, evRecordFailed);
		return err;
	}
	
	if (!m_tuned)
		return 0; /* try it again when we are tuned in */
	
	if (!m_record && m_tuned && !m_streaming && !m_simulate)
	{
#if defined(__sh__) 
		int flags = O_WRONLY|O_CREAT|O_LARGEFILE;
		struct statfs sbuf;
#endif
		eDebug("Recording to %s...", m_filename.c_str());
		::remove(m_filename.c_str());
#if defined(__sh__)
		//nit2005, we must creat a file for statfs
 		int fd = ::open(m_filename.c_str(), O_WRONLY|O_CREAT|O_LARGEFILE, 0644);
		::close(fd);
		if (statfs(m_filename.c_str(), &sbuf) < 0) 
		{ 
			eDebug("eDVBServiceRecord - can't get fs type assuming none NFS!"); 
		} else 
		{ 
			if (sbuf.f_type == EXT3_SUPER_MAGIC) 
				eDebug("eDVBServiceRecord - Ext2/3/4 Filesystem\n"); 
			else 
			if (sbuf.f_type == NFS_SUPER_MAGIC) 
			{ 
				eDebug("eDVBServiceRecord - NFS Filesystem; add O_DIRECT to flags\n"); 
				flags |= O_DIRECT; 
			} 
			else 
			if (sbuf.f_type == USBDEVICE_SUPER_MAGIC) 
				eDebug("eDVBServiceRecord - USB Device\n"); 
			else 
			if (sbuf.f_type == SMB_SUPER_MAGIC) 
				eDebug("eDVBServiceRecord - SMBs Device\n"); 
			else 
			if (sbuf.f_type == MSDOS_SUPER_MAGIC) 
				eDebug("eDVBServiceRecord - MSDOS Device\n"); 
		} 

		fd = ::open(m_filename.c_str(), flags, 0644); 
#else
		int fd = ::open(m_filename.c_str(), O_WRONLY|O_CREAT|O_LARGEFILE, 0644);
#endif
		if (fd == -1)
		{
			eDebug("eDVBServiceRecord - can't open recording file!");
			m_error = errOpenRecordFile;
			m_event((iRecordableService*)this, evRecordFailed);
			return errOpenRecordFile;
		}

			/* turn off kernel caching strategies */
		posix_fadvise(fd, 0, 0, POSIX_FADV_RANDOM);

		ePtr<iDVBDemux> demux;
		if (m_service_handler.getDataDemux(demux))
		{
			eDebug("eDVBServiceRecord - NO DEMUX available!");
			m_error = errNoDemuxAvailable;
			m_event((iRecordableService*)this, evRecordFailed);
			return errNoDemuxAvailable;
		}
		demux->createTSRecorder(m_record);
		if (!m_record)
		{
			eDebug("eDVBServiceRecord - no ts recorder available.");
			m_error = errNoTsRecorderAvailable;
			m_event((iRecordableService*)this, evRecordFailed);
			return errNoTsRecorderAvailable;
		}
		m_record->setTargetFD(fd);
		m_record->setTargetFilename(m_filename.c_str());
		m_record->connectEvent(slot(*this, &eDVBServiceRecord::recordEvent), m_con_record_event);

		m_target_fd = fd;
	}
	
	if (m_streaming)
	{
		m_state = stateRecording;
		eDebug("start streaming...");
	} else
	{
		eDebug("start recording...");

		eDVBServicePMTHandler::program program;
		if (m_service_handler.getProgramInfo(program))
			eDebug("getting program info failed.");
		else
		{
			std::set<int> pids_to_record;

			pids_to_record.insert(0); // PAT

			if (program.pmtPid != -1)
				pids_to_record.insert(program.pmtPid); // PMT

			int timing_pid = -1, timing_pid_type = -1;

			eDebugNoNewLine("RECORD: have %d video stream(s)", program.videoStreams.size());
			if (!program.videoStreams.empty())
			{
				eDebugNoNewLine(" (");
				for (std::vector<eDVBServicePMTHandler::videoStream>::const_iterator
					i(program.videoStreams.begin()); 
					i != program.videoStreams.end(); ++i)
				{
					pids_to_record.insert(i->pid);
					
					if (timing_pid == -1)
					{
						timing_pid = i->pid;
						timing_pid_type = i->type;
					}
					
					if (i != program.videoStreams.begin())
							eDebugNoNewLine(", ");
					eDebugNoNewLine("%04x", i->pid);
				}
				eDebugNoNewLine(")");
			}
			eDebugNoNewLine(", and %d audio stream(s)", program.audioStreams.size());
			if (!program.audioStreams.empty())
			{
				eDebugNoNewLine(" (");
				for (std::vector<eDVBServicePMTHandler::audioStream>::const_iterator
					i(program.audioStreams.begin()); 
					i != program.audioStreams.end(); ++i)
				{
					pids_to_record.insert(i->pid);
	
					if (timing_pid == -1)
					{
						timing_pid = i->pid;
						timing_pid_type = -1;
					}
				
					if (i != program.audioStreams.begin())
						eDebugNoNewLine(", ");
					eDebugNoNewLine("%04x", i->pid);
				}
				eDebugNoNewLine(")");
			}
			if (!program.subtitleStreams.empty())
			{
				eDebugNoNewLine(" (");
				for (std::vector<eDVBServicePMTHandler::subtitleStream>::const_iterator
					i(program.subtitleStreams.begin());
					i != program.subtitleStreams.end(); ++i)
				{
					pids_to_record.insert(i->pid);
	
					if (i != program.subtitleStreams.begin())
						eDebugNoNewLine(", ");
					eDebugNoNewLine("%04x", i->pid);
				}
				eDebugNoNewLine(")");
			}
			eDebugNoNewLine(", and the pcr pid is %04x", program.pcrPid);
			if (program.pcrPid != 0x1fff)
				pids_to_record.insert(program.pcrPid);
			eDebug(", and the text pid is %04x", program.textPid);
			if (program.textPid != -1)
				pids_to_record.insert(program.textPid); // Videotext

				/* find out which pids are NEW and which pids are obsolete.. */
			std::set<int> new_pids, obsolete_pids;

			std::set_difference(pids_to_record.begin(), pids_to_record.end(), 
					m_pids_active.begin(), m_pids_active.end(),
					std::inserter(new_pids, new_pids.begin()));

			std::set_difference(
					m_pids_active.begin(), m_pids_active.end(),
					pids_to_record.begin(), pids_to_record.end(), 
					std::inserter(obsolete_pids, obsolete_pids.begin())
					);
			
			for (std::set<int>::iterator i(new_pids.begin()); i != new_pids.end(); ++i)
			{
				eDebug("ADD PID: %04x", *i);
				m_record->addPID(*i);
			}

			for (std::set<int>::iterator i(obsolete_pids.begin()); i != obsolete_pids.end(); ++i)
			{
				eDebug("REMOVED PID: %04x", *i);
				m_record->removePID(*i);
			}

			if (timing_pid != -1)
				m_record->setTimingPID(timing_pid, timing_pid_type);

			m_pids_active = pids_to_record;

			if (m_state != stateRecording)
			{
				m_record->start();
				m_state = stateRecording;
			}
		}
	}
	m_error = 0;
	m_event((iRecordableService*)this, evRecordRunning);
	return 0;
}
int
run_attr_tests (char *testfile)
{
        int             ret = -1;
        char            *res = NULL;
        struct stat     buf;
        struct statfs   sbuf;
        struct statvfs  svbuf;

        assert (testfile);

        fprintf (stdout, "Testing chmod");
        ret = chmod (testfile, 0);
        check_err (ret, "chmod", 2);

        fprintf (stdout, "Testing chown");
        ret = chown (testfile, 0, 0);
        check_err (ret, "chown", 2);

        fprintf (stdout, "Testing link");
        ret = link (testfile, testfile);
        check_err (ret, "link", 2);

        fprintf (stdout, "Testing rename");
        ret = rename (testfile, testfile);
        check_err (ret, "rename", 2);

        fprintf (stdout, "Testing utimes");
        ret = utimes (testfile, NULL);
        check_err (ret, "utimes", 2);

        fprintf (stdout, "Testing utime");
        ret = utime (testfile, NULL);
        check_err (ret, "utime", 2);

        fprintf (stdout, "Testing unlink");
        ret = unlink (testfile);
        check_err (ret, "unlink", 2);

        fprintf (stdout, "Testing symlink");
        ret = symlink (testfile, testfile);
        check_err (ret, "symlink", 2);

        fprintf (stdout, "Testing readlink");
        ret = readlink (testfile, testfile, 0);
        check_err (ret, "readlink", 2);

        fprintf (stdout, "Testing realpath");
        ret = 0;
        res = realpath ((const char *)testfile, testfile);
        if (!res)
                ret = -1;
        check_err (ret, "realpath", 2);

        fprintf (stdout, "Testing stat");
        ret = stat (testfile, &buf);
        check_err (ret, "stat", 1);

        fprintf (stdout, "Testing lstat");
        ret = lstat (testfile, &buf);
        check_err (ret, "lstat", 1);

        fprintf (stdout, "Testing statfs");
        ret = statfs (testfile, &sbuf);
        check_err (ret, "statfs", 2);

        fprintf (stdout, "Testing statvfs");
        ret = statvfs (testfile, &svbuf);
        check_err (ret, "statvfs", 1);

        fprintf (stdout, "Testing getxattr");
        ret = getxattr (testfile, NULL, NULL, 0);
        check_err (ret, "getxattr", 2);

        fprintf (stdout, "Testing lgetxattr");
        ret = lgetxattr (testfile, NULL, NULL, 0);
        check_err (ret, "lgetxattr", 1);

        fprintf (stdout, "Testing lchown");
        ret = lchown (testfile, 0, 0);
        check_err (ret, "lchown", 2);
        return 0;
}
bool 
proc_probe(pid_t pid, int opt, proc_t * const pproc)
{
    FUNC_BEGIN("proc_probe(%d,%d,%p)", pid, opt, pproc);
    
    assert(pproc);
    
    /* Validating procfs */
    struct statfs sb;
    if ((statfs(PROCFS, &sb) < 0) || (sb.f_type != PROC_SUPER_MAGIC))
    {
        WARNING("procfs missing or invalid");
        FUNC_RET(false, "proc_probe()");
    }
    
    /* Validating process stat */
    char buffer[4096];
    
    sprintf(buffer, PROCFS "/%d/stat", pid);
    if (access(buffer, R_OK | F_OK) < 0)
    {
        WARNING("procfs entries missing or invalid");
        FUNC_RET(false, "proc_probe()");
    }
    
    /* Grab stat information in one read */
    int fd = open(buffer, O_RDONLY);
    int len = read(fd, buffer, sizeof(buffer) - 1);
    close(fd);
    buffer[len] = '\0';
    
    /* Extract interested information */
    int offset = 0;
    char * token = buffer;
    do
    {
        switch (offset++)
        {
        case  0:           /* pid */
            sscanf(token, "%d", &pproc->pid);
            break;
        case  1:           /* comm */
            break;
        case  2:           /* state */
            sscanf(token, "%c", &pproc->state);
            break;
        case  3:           /* ppid */
            sscanf(token, "%d", &pproc->ppid);
            break;
        case  4:           /* pgrp */
        case  5:           /* session */
        case  6:           /* tty_nr */
        case  7:           /* tty_pgrp */
            break;
        case  8:           /* flags */
            sscanf(token, "%lu", &pproc->flags);
            break;
        case  9:           /* min_flt */
        case 10:           /* cmin_flt */
        case 11:           /* maj_flt */
        case 12:           /* cmaj_flt */
            break;
        case 13:           /* utime */
            sscanf(token, "%lu", &pproc->tm.tms_utime);
            break;
        case 14:           /* stime */
            sscanf(token, "%lu", &pproc->tm.tms_stime);
            break;
        case 15:           /* cutime */
            sscanf(token, "%ld", &pproc->tm.tms_cutime);
            break;
        case 16:           /* cstime */
            sscanf(token, "%ld", &pproc->tm.tms_cstime);
            break;
        case 17:           /* priority */
        case 18:           /* nice */
        case 19:           /* 0 */
        case 20:           /* it_real_value */
        case 21:           /* start_time */
            break;
        case 22:           /* vsize */
            sscanf(token, "%lu", &pproc->vsize);
            break;
        case 23:           /* rss */
            sscanf(token, "%ld", &pproc->rss);
            break;
        case 24:           /* rlim_rss */
        case 25:           /* start_code */
        case 26:           /* end_code */
        case 27:           /* start_stack */
        case 28:           /* esp */
        case 29:           /* eip */
        case 30:           /* pending_signal */
        case 31:           /* blocked_signal */
        case 32:           /* sigign */
        case 33:           /* sigcatch */
        case 34:           /* wchan */
        case 35:           /* nswap */
        case 36:           /* cnswap */
        case 37:           /* exit_signal */
        case 38:           /* processor */
        default:
            break;
        }
    } while (strsep(&token, " ") != NULL);
    DBG("proc.pid            % 10d", pproc->pid);
    DBG("proc.ppid           % 10d", pproc->ppid);
    DBG("proc.state                   %c", pproc->state);
    DBG("proc.flags          0x%08lx", pproc->flags);
    DBG("proc.utime          %010lu", pproc->tm.tms_utime);
    DBG("proc.stime          %010lu", pproc->tm.tms_stime);
    DBG("proc.cutime         % 10ld", pproc->tm.tms_cutime);
    DBG("proc.cstime         % 10ld", pproc->tm.tms_cstime);
    DBG("proc.vsize          %010lu", pproc->vsize);
    DBG("proc.rss            % 10ld", pproc->rss);
        
    /* Must be the parent process in order to probe registers and floating point
       registers; and the status of target process must be 'T' (aka traced) */
    if ((pproc->ppid != getpid()) || (pproc->state != 'T'))
    {
        FUNC_RET((opt == PROBE_STAT), "proc_probe()");
    }

    /* Inspect process registers */
    #ifdef __linux__
    if (opt & PROBE_REGS)
    {
        /* General purpose registers */
        if (ptrace(PTRACE_GETREGS, pid, NULL, (void *)&pproc->regs) < 0)
        {
            WARNING("ptrace:PTRACE_GETREGS");
            FUNC_RET(false, "proc_probe()");
        }
        DBG("regs.ebx            0x%08lx", pproc->regs.ebx);
        DBG("regs.ecx            0x%08lx", pproc->regs.ecx);
        DBG("regs.edx            0x%08lx", pproc->regs.edx);
        DBG("regs.esi            0x%08lx", pproc->regs.esi);
        DBG("regs.edi            0x%08lx", pproc->regs.edi);
        DBG("regs.ebp            0x%08lx", pproc->regs.ebp);
        DBG("regs.eax            0x%08lx", pproc->regs.eax);
        DBG("regs.xds            0x%08lx", pproc->regs.xds);
        DBG("regs.xes            0x%08lx", pproc->regs.xes);
        DBG("regs.xfs            0x%08lx", pproc->regs.xfs);
        DBG("regs.xgs            0x%08lx", pproc->regs.xgs);
        DBG("regs.orig_eax       0x%08lx", pproc->regs.orig_eax);
        DBG("regs.eip            0x%08lx", pproc->regs.eip);
        DBG("regs.xcs            0x%08lx", pproc->regs.xcs);
        DBG("regs.eflags         0x%08lx", pproc->regs.eflags);
        DBG("regs.esp            0x%08lx", pproc->regs.esp);
        DBG("regs.xss            0x%08lx", pproc->regs.xss);
        
        /* Current instruction */
        pproc->op = ptrace(PTRACE_PEEKDATA, pid, (void *)pproc->regs.eip, 
                           NULL);
        if (errno != 0)
        {
            WARNING("ptrace:PTRACE_PEEKDATA");
            FUNC_RET(false, "proc_probe()");
        }
        DBG("proc.op             0x%08x", pproc->op);
    }
    #endif /* __linux__ */

    /* Inspect floating point registers */
    #ifdef __linux__
    if (opt & PROBE_FPREGS)
    {
        /* Floating point registers */
        if (ptrace(PTRACE_GETFPREGS, pid, NULL, (void *)&pproc->fpregs) < 0)
        {
            WARNING("ptrace:PTRACE_GETFPREGS");
            FUNC_RET(false, "proc_probe()");
        }
        DBG("fpregs.cwd          0x%08lx", pproc->fpregs.cwd);
        DBG("fpregs.swd          0x%08lx", pproc->fpregs.swd);
        DBG("fpregs.twd          0x%08lx", pproc->fpregs.twd);
        DBG("fpregs.fip          0x%08lx", pproc->fpregs.fip);
        DBG("fpregs.fcs          0x%08lx", pproc->fpregs.fcs);
        DBG("fpregs.fos          0x%08lx", pproc->fpregs.fos);
        DBG("fpregs.st_space     0x%08lx 0x%08lx 0x%08lx 0x%08lx",
            pproc->fpregs.st_space[ 0], pproc->fpregs.st_space[ 1],
            pproc->fpregs.st_space[ 2], pproc->fpregs.st_space[ 3]);
        DBG("                    0x%08lx 0x%08lx 0x%08lx 0x%08lx",
            pproc->fpregs.st_space[ 4], pproc->fpregs.st_space[ 5],
            pproc->fpregs.st_space[ 6], pproc->fpregs.st_space[ 7]);
        DBG("                    0x%08lx 0x%08lx 0x%08lx 0x%08lx",
            pproc->fpregs.st_space[ 8], pproc->fpregs.st_space[ 9],
            pproc->fpregs.st_space[10], pproc->fpregs.st_space[11]);
        DBG("                    0x%08lx 0x%08lx 0x%08lx 0x%08lx", 
            pproc->fpregs.st_space[12], pproc->fpregs.st_space[13],
            pproc->fpregs.st_space[14], pproc->fpregs.st_space[15]);
        DBG("                    0x%08lx 0x%08lx 0x%08lx 0x%08lx", 
            pproc->fpregs.st_space[16], pproc->fpregs.st_space[17],
            pproc->fpregs.st_space[18], pproc->fpregs.st_space[19]);
    }
    #endif /* __linux__ */
    
    FUNC_RET(true, "proc_probe()");
}
int convert_mtd_device(const char *root, const char* fs_list)
{
    static char* headers[] = {  "Converting Menu",
                                "",
    							NULL,
                                NULL
    };

    static char* confirm_convert  = "Confirm convert?";
    static char* confirm = "Yes - Convert";

    const char* root_fs = get_type_internal_fs(root);
    headers[2] = root;

    typedef char* string;
    string tfs[NUM_FILESYSTEMS] = { "rfs", "ext4" };
    static string options[NUM_FILESYSTEMS*2 + 1 + 1];
    int sel_fs[NUM_FILESYSTEMS*2 + 1 + 1];

	int i,j=0;
	// with backup
	for (i=0; i<NUM_FILESYSTEMS; i++) {
    	if (fs_list[i] == '*') {
    		if (strcmp(tfs[i], root_fs)) {
    			sel_fs[j] = i;
    			options[j] = (string)malloc(32);
    			sprintf(options[j++], "to %s with backup", tfs[i]);
    		}
    	}
    	else break;
    }
    options[j++] = "";

	// without backup
	for (i=0; i<NUM_FILESYSTEMS; i++) {
    	if (fs_list[i] == '*') {
    		if (strcmp(tfs[i], root_fs)) {
    			sel_fs[j] = i;
    			options[j] = (string)malloc(32);
    			sprintf(options[j++], "to %s through format", tfs[i]);
    		}
    	}
    	else break;
    }
    options[j] = NULL;

    int chosen_item = get_menu_selection(headers, options, 0);
    if (chosen_item == GO_BACK)
        return 1;

    if (chosen_item < i) {
        // with backup
        if (!confirm_selection(confirm_convert, confirm))
            return 1;

    	ui_set_background(BACKGROUND_ICON_INSTALLING);
        ui_show_indeterminate_progress();

    	// mount $root
    	if (0 != ensure_root_path_mounted(root)) {
    		ui_print("Can't mount %s for backup\n", root);
    		return -1;
    	}

    	// check size of $root
    	struct statfs stat_root;
    	if (0 != statfs(get_mount_point_for_root(root), &stat_root)) {
    		ui_print("Can't get size of %s\n", root);
    		return -1;
    	}

    	// mount SDCARD
    	if (0 != ensure_root_path_mounted("SDCARD:")) {
    		ui_print("Can't mount sdcard for backup\n", root);
    		return -1;
    	}

    	// check size SD
    	struct statfs stat_sd;
    	if (0 != statfs(get_mount_point_for_root("SDCARD:"), &stat_sd)) {
    		ui_print("Can't get size of sdcard\n");
    		return -1;
    	}

        uint64_t root_fsize = (uint64_t)(stat_root.f_blocks-stat_root.f_bfree)*(uint64_t)stat_root.f_bsize;
        uint64_t sd_free_size = (uint64_t)stat_sd.f_bfree*(uint64_t)stat_sd.f_bsize;
        ui_print("SD free: %lluMB / need: %lluMB\n", sd_free_size/(1024*1024), root_fsize/(1024*1024));
        if (root_fsize > sd_free_size) {
        	ui_print("Can't backup need: %lluMB on SD\n", root_fsize/(1024*1024));
        	return -1;
        }

    	// create folder for backup [/sdcard/ebrecovery/tmp] [mkdir -p /sdcard/ebrecovery/tmp]
    	if (0 != __system("mkdir -p /sdcard/ebrecovery/tmp")) {
    		ui_print("Can't create tmp folder for backup\n");
    		return -1;
    	}

        ui_show_progress(0.3, root_fsize*30/(140*1024*1024));

    	// backup
    	ui_print("Backuping %s...\n", root);
    	char br_exec[256];
    	sprintf(br_exec, "tar -c --exclude=*RFS_LOG.LO* -f /sdcard/ebrecovery/tmp/ctmp.tar %s", get_mount_point_for_root(root)+1);
    	if (0 != __system(br_exec)) {
    		ui_print("Can't create backup file\n");
    		return -1;
    	}

    	// check size of backup file > sizeof($root)?
    	// set new FS
    	ui_print("Change fs type %s -> %s\n", get_type_internal_fs(root), tfs[sel_fs[chosen_item]]);
    	if (0 != set_type_internal_fs(root, tfs[sel_fs[chosen_item]])) {
    		ui_print("Error change type of file system to %s for %s\n", tfs[sel_fs[chosen_item]], root);
    		return -1;
    	}

    	// format $root
        ui_show_progress(0.05, 10);
        ui_print("Formatting %s...\n", root);
        if (0 != format_root_device(root)) {
    		ui_print("Error format %s\n", root);
    		return -1;
        }

        // mount $root
    	if (0 != ensure_root_path_mounted(root)) {
    		ui_print("Can't mount %s for backup\n", root);
    		return -1;
    	}

    	// restore $root
        ui_show_progress(0.65, root_fsize*500/(140*1024*1024));
    	ui_print("Restoring %s...\n", root);
    	if (0 != __system("tar -x -f /sdcard/ebrecovery/tmp/ctmp.tar")) {
    		ui_print("Can't restore backup file\n");
    		return -1;
    	}

    	// check size of $root ?
    	// delete temp backup files (delete tmp folder)
        ui_show_indeterminate_progress();
    	if (0 != __system("rm /sdcard/ebrecovery/tmp/ctmp.tar")) {
    		ui_print("Can't remove backup file\n");
    		return -1;
    	}

        return 0;
    }
    else {
    	// without
        if (!confirm_selection(confirm_convert, confirm))
            return 1;
    	// change file system to new
    	ui_print("Change fs type %s -> %s\n", get_type_internal_fs(root), tfs[sel_fs[chosen_item]]);
    	if (0 != set_type_internal_fs(root, tfs[sel_fs[chosen_item]])) {
    		ui_print("Error change type of file system to %s for %s\n", tfs[sel_fs[chosen_item]], root);
    		return -1;
    	}
    	// format
        ui_set_background(BACKGROUND_ICON_INSTALLING);
        ui_show_indeterminate_progress();
        ui_print("Formatting %s...\n", root);
        return format_root_device(root);
    }

    return -1;
}