Example #1
0
/*
 * Given a full path to a file, translate into a dataset name and a relative
 * path within the dataset.  'dataset' must be at least MAXNAMELEN characters,
 * and 'relpath' must be at least MAXPATHLEN characters.  We also pass a stat64
 * buffer, which we need later to get the object ID.
 */
static int
parse_pathname(const char *inpath, char *dataset, char *relpath,
    struct stat64 *statbuf)
{
	struct extmnttab mp;
	FILE *fp;
	int match;
	const char *rel;
	char fullpath[MAXPATHLEN];

	compress_slashes(inpath, fullpath);

	if (fullpath[0] != '/') {
		(void) fprintf(stderr, "invalid object '%s': must be full "
		    "path\n", fullpath);
		usage();
		return (-1);
	}

	if (strlen(fullpath) >= MAXPATHLEN) {
		(void) fprintf(stderr, "invalid object; pathname too long\n");
		return (-1);
	}

	if (stat64(fullpath, statbuf) != 0) {
		(void) fprintf(stderr, "cannot open '%s': %s\n",
		    fullpath, strerror(errno));
		return (-1);
	}

	if ((fp = fopen(MNTTAB, "r")) == NULL) {
		(void) fprintf(stderr, "cannot open /etc/mnttab\n");
		return (-1);
	}

	match = 0;
	while (getextmntent(fp, &mp, sizeof (mp)) == 0) {
		if (makedev(mp.mnt_major, mp.mnt_minor) == statbuf->st_dev) {
			match = 1;
			break;
		}
	}

	if (!match) {
		(void) fprintf(stderr, "cannot find mountpoint for '%s'\n",
		    fullpath);
		return (-1);
	}

	if (strcmp(mp.mnt_fstype, MNTTYPE_ZFS) != 0) {
		(void) fprintf(stderr, "invalid path '%s': not a ZFS "
		    "filesystem\n", fullpath);
		return (-1);
	}

	if (strncmp(fullpath, mp.mnt_mountp, strlen(mp.mnt_mountp)) != 0) {
		(void) fprintf(stderr, "invalid path '%s': mountpoint "
		    "doesn't match path\n", fullpath);
		return (-1);
	}

	(void) strcpy(dataset, mp.mnt_special);

	rel = fullpath + strlen(mp.mnt_mountp);
	if (rel[0] == '/')
		rel++;
	(void) strcpy(relpath, rel);

	return (0);
}
Example #2
0
/*
 * Given a full path to a file, translate into a dataset name and a relative
 * path within the dataset.  'dataset' must be at least MAXNAMELEN characters,
 * and 'relpath' must be at least MAXPATHLEN characters.  We also pass a stat
 * buffer, which we need later to get the object ID.
 */
static int
parse_pathname(const char *inpath, char *dataset, char *relpath,
    struct stat *statbuf)
{
	struct extmnttab mp;
	FILE *fp;
	int match;
	const char *rel;
	char fullpath[MAXPATHLEN];

	compress_slashes(inpath, fullpath);

	if (fullpath[0] != '/') {
		(void) fprintf(stderr, "invalid object '%s': must be full "
		    "path\n", fullpath);
		usage();
		return (-1);
	}

	if (strlen(fullpath) >= MAXPATHLEN) {
		(void) fprintf(stderr, "invalid object; pathname too long\n");
		return (-1);
	}

	if (stat(fullpath, statbuf) != 0) {
		(void) fprintf(stderr, "cannot open '%s': %s\n",
		    fullpath, strerror(errno));
		return (-1);
	}

#ifdef HAVE_SETMNTENT
	if ((fp = setmntent(MNTTAB, "r")) == NULL) {
#else
	if ((fp = fopen(MNTTAB, "r")) == NULL) {
#endif
		(void) fprintf(stderr, "cannot open /etc/mtab\n");
		return (-1);
	}

	match = 0;
	while (getextmntent(fp, &mp, sizeof (mp)) == 0) {
		if (makedev(mp.mnt_major, mp.mnt_minor) == statbuf->st_dev) {
			match = 1;
			break;
		}
	}

	if (!match) {
		(void) fprintf(stderr, "cannot find mountpoint for '%s'\n",
		    fullpath);
		return (-1);
	}

	if (strcmp(mp.mnt_fstype, MNTTYPE_ZFS) != 0) {
		(void) fprintf(stderr, "invalid path '%s': not a ZFS "
		    "filesystem\n", fullpath);
		return (-1);
	}

	if (strncmp(fullpath, mp.mnt_mountp, strlen(mp.mnt_mountp)) != 0) {
		(void) fprintf(stderr, "invalid path '%s': mountpoint "
		    "doesn't match path\n", fullpath);
		return (-1);
	}

	(void) strcpy(dataset, mp.mnt_special);

	rel = fullpath + strlen(mp.mnt_mountp);
	if (rel[0] == '/')
		rel++;
	(void) strcpy(relpath, rel);

	return (0);
}
#endif

//From FreeBSD
static int
parse_pathname(const char *inpath, char *dataset, char *relpath,
    struct stat *statbuf)
{
        struct statfs sfs;
        const char *rel;
        char fullpath[MAXPATHLEN];

        compress_slashes(inpath, fullpath);

        if (fullpath[0] != '/') {
                (void) fprintf(stderr, "invalid object '%s': must be full "
                    "path\n", fullpath);
                usage();
                return (-1);
        }

        if (strlen(fullpath) >= MAXPATHLEN) {
                (void) fprintf(stderr, "invalid object; pathname too long\n");
                return (-1);
        }

        if (stat(fullpath, statbuf) != 0) {
                (void) fprintf(stderr, "cannot open '%s': %s\n",
                    fullpath, strerror(errno));
                return (-1);
        }

        if (statfs(fullpath, &sfs) == -1) {
                (void) fprintf(stderr, "cannot find mountpoint for '%s': %s\n",
                    fullpath, strerror(errno));
                return (-1);
        }

        if (strcmp(sfs.f_fstypename, MNTTYPE_ZFS) != 0) {
                (void) fprintf(stderr, "invalid path '%s': not a ZFS "
                    "filesystem\n", fullpath);
                return (-1);
        }

        if (strncmp(fullpath, sfs.f_mntonname, strlen(sfs.f_mntonname)) != 0) {
                (void) fprintf(stderr, "invalid path '%s': mountpoint "
                    "doesn't match path\n", fullpath);
                return (-1);
        }

        (void) strcpy(dataset, sfs.f_mntfromname);

        rel = fullpath + strlen(sfs.f_mntonname);
        if (rel[0] == '/')
                rel++;
        (void) strcpy(relpath, rel);

        return (0);
}

/*
 * Convert from a (dataset, path) pair into a (objset, object) pair.  Note that
 * we grab the object number from the inode number, since looking this up via
 * libzpool is a real pain.
 */
/* ARGSUSED */
static int
object_from_path(const char *dataset, const char *path, struct stat *statbuf,
    zinject_record_t *record)
{
	objset_t *os;
	int err;

	/*
	 * Before doing any libzpool operations, call sync() to ensure that the
	 * on-disk state is consistent with the in-core state.
	 */
	sync();

	err = dmu_objset_own(dataset, DMU_OST_ZFS, B_TRUE, B_FALSE, FTAG, &os);
	if (err != 0) {
		(void) fprintf(stderr, "cannot open dataset '%s': %s\n",
		    dataset, strerror(err));
		return (-1);
	}

	record->zi_objset = dmu_objset_id(os);
	record->zi_object = statbuf->st_ino;

	dmu_objset_disown(os, B_FALSE, FTAG);

	return (0);
}