예제 #1
0
/**
 * mnt_table_parse_mtab:
 * @tb: table
 * @filename: overwrites default (/etc/mtab or $LIBMOUNT_MTAB) or NULL
 *
 * This function parses /etc/mtab or /proc/self/mountinfo +
 * /run/mount/utabs or /proc/mounts.
 *
 * See also mnt_table_set_parser_errcb().
 *
 * Returns: 0 on success or negative number in case of error.
 */
int mnt_table_parse_mtab(struct libmnt_table *tb, const char *filename)
{
	int rc;
	const char *utab = NULL;
	struct libmnt_table *u_tb;

	assert(tb);

	if (mnt_has_regular_mtab(&filename, NULL)) {

		DBG(TAB, mnt_debug_h(tb, "force %s usage", filename));

		rc = mnt_table_parse_file(tb, filename);
		if (!rc)
			return 0;
		filename = NULL;	/* failed */
	}

	/*
	 * useless /etc/mtab
	 * -- read kernel information from /proc/self/mountinfo
	 */
	tb->fmt = MNT_FMT_MOUNTINFO;
	rc = mnt_table_parse_file(tb, _PATH_PROC_MOUNTINFO);
	if (rc) {
		/* hmm, old kernel? ...try /proc/mounts */
		tb->fmt = MNT_FMT_MTAB;
		return mnt_table_parse_file(tb, _PATH_PROC_MOUNTS);
	}

	if (mnt_table_get_nents(tb) == 0)
		return 0;			/* empty, ignore utab */
	/*
	 * try to read the user specific information from /run/mount/utabs
	 */
	utab = mnt_get_utab_path();
	if (!utab || is_file_empty(utab))
		return 0;

	u_tb = mnt_new_table();
	if (!u_tb)
		return -ENOMEM;

	u_tb->fmt = MNT_FMT_UTAB;
	mnt_table_set_parser_fltrcb(u_tb, tb->fltrcb, tb->fltrcb_data);

	if (mnt_table_parse_file(u_tb, utab) == 0) {
		struct libmnt_fs *u_fs;
		struct libmnt_iter itr;

		mnt_reset_iter(&itr, MNT_ITER_BACKWARD);

		/*  merge user options into mountinfo from the kernel */
		while(mnt_table_next_fs(u_tb, &itr, &u_fs) == 0)
			mnt_table_merge_user_fs(tb, u_fs);
	}

	mnt_unref_table(u_tb);
	return 0;
}
예제 #2
0
/**
 * mnt_table_parse_mtab:
 * @tb: table
 * @filename: overwrites default (/etc/mtab or $LIBMOUNT_MTAB) or NULL
 *
 * This function parses /etc/mtab or /proc/self/mountinfo +
 * /run/mount/utabs or /proc/mounts.
 *
 * See also mnt_table_set_parser_errcb().
 *
 * Returns: 0 on success or negative number in case of error.
 */
int mnt_table_parse_mtab(struct libmnt_table *tb, const char *filename)
{
	int rc;
	const char *utab = NULL;

	if (mnt_has_regular_mtab(&filename, NULL)) {

		DBG(TAB, mnt_debug_h(tb, "force %s usage", filename));

		rc = mnt_table_parse_file(tb, filename);
		if (!rc)
			return 0;
		filename = NULL;	/* failed */
	}

	/*
	 * useless /etc/mtab
	 * -- read kernel information from /proc/self/mountinfo
	 */
	tb->fmt = MNT_FMT_MOUNTINFO;
	rc = mnt_table_parse_file(tb, _PATH_PROC_MOUNTINFO);
	if (rc) {
		/* hmm, old kernel? ...try /proc/mounts */
		tb->fmt = MNT_FMT_MTAB;
		return mnt_table_parse_file(tb, _PATH_PROC_MOUNTS);
	}

	/*
	 * try to read user specific information from /run/mount/utabs
	 */
	utab = mnt_get_utab_path();
	if (utab) {
		struct libmnt_table *u_tb = __mnt_new_table_from_file(utab, MNT_FMT_UTAB);

		if (u_tb) {
			struct libmnt_fs *u_fs;
			struct libmnt_iter itr;

			mnt_reset_iter(&itr, MNT_ITER_BACKWARD);

			/*  merge user options into mountinfo from kernel */
			while(mnt_table_next_fs(u_tb, &itr, &u_fs) == 0)
				mnt_table_merge_user_fs(tb, u_fs);

			mnt_free_table(u_tb);
		}
	}
	return 0;
}
예제 #3
0
/**
 * mnt_table_parse_fstab:
 * @tb: table
 * @filename: overwrites default (/etc/fstab or $LIBMOUNT_FSTAB) or NULL
 *
 * This function parses /etc/fstab and appends new lines to the @tab. If the
 * @filename is a directory then mnt_table_parse_dir() is called.
 *
 * See also mnt_table_set_parser_errcb().
 *
 * Returns: 0 on success or negative number in case of error.
 */
int mnt_table_parse_fstab(struct libmnt_table *tb, const char *filename)
{
	struct stat st;
	int rc = 0;

	assert(tb);

	if (!tb)
		return -EINVAL;
	if (!filename)
		filename = mnt_get_fstab_path();

	if (!filename || stat(filename, &st))
		return -EINVAL;

	tb->fmt = MNT_FMT_FSTAB;

	if (S_ISREG(st.st_mode))
		rc = mnt_table_parse_file(tb, filename);
	else if (S_ISDIR(st.st_mode))
		rc = mnt_table_parse_dir(tb, filename);
	else
		rc = -EINVAL;

	return rc;
}
예제 #4
0
/**
 * mnt_table_parse_swaps:
 * @tb: table
 * @filename: overwrites default (/proc/swaps or $LIBMOUNT_SWAPS) or NULL
 *
 * This function parses /proc/swaps and appends new lines to the @tab.
 *
 * See also mnt_table_set_parser_errcb().
 *
 * Returns: 0 on success or negative number in case of error.
 */
int mnt_table_parse_swaps(struct libmnt_table *tb, const char *filename)
{
	if (!tb)
		return -EINVAL;
	if (!filename) {
		filename = mnt_get_swaps_path();
		if (!filename)
			return -EINVAL;
	}

	tb->fmt = MNT_FMT_SWAPS;

	return mnt_table_parse_file(tb, filename);
}
예제 #5
0
파일: eject.c 프로젝트: bdwalton/util-linux
/*
 * See if device has been mounted by looking in mount table.  If so, set
 * device name and mount point name, and return 1, otherwise return 0.
 */
static int device_get_mountpoint(char **devname, char **mnt)
{
	struct libmnt_fs *fs;
	int rc;

	*mnt = NULL;

	if (!mtab) {
		mtab = mnt_new_table();
		if (!mtab)
			err(EXIT_FAILURE, _("failed to initialize libmount table"));

		cache = mnt_new_cache();
		mnt_table_set_cache(mtab, cache);

		if (p_option)
			rc = mnt_table_parse_file(mtab, _PATH_PROC_MOUNTINFO);
		else
			rc = mnt_table_parse_mtab(mtab, NULL);
		if (rc)
			err(EXIT_FAILURE, _("failed to parse mount table"));
	}

	fs = mnt_table_find_source(mtab, *devname, MNT_ITER_BACKWARD);
	if (!fs) {
		/* maybe 'devname' is mountpoint rather than a real device */
		fs = mnt_table_find_target(mtab, *devname, MNT_ITER_BACKWARD);
		if (fs) {
			free(*devname);
			*devname = xstrdup(mnt_fs_get_source(fs));
		}
	}

	if (fs) {
		*mnt = xstrdup(mnt_fs_get_target(fs));
		/* We'll call umount(), so remove the filesystem from the table
		 * to avoid duplicate results in the next device_get_mountpoint()
		 * call */
		mnt_free_fs(fs);
	}
	return *mnt ? 0 : -1;
}
예제 #6
0
struct libmnt_table *__mnt_new_table_from_file(const char *filename, int fmt)
{
	struct libmnt_table *tb;
	struct stat st;

	assert(filename);
	if (!filename)
		return NULL;
	if (stat(filename, &st))
		return NULL;
	tb = mnt_new_table();
	if (tb) {
		tb->fmt = fmt;
		if (mnt_table_parse_file(tb, filename) != 0) {
			mnt_unref_table(tb);
			tb = NULL;
		}
	}
	return tb;
}
예제 #7
0
struct libmnt_table *__mnt_new_table_from_file(const char *filename, int fmt)
{
	struct libmnt_table *tb;
	struct stat st;

	if (!filename)
		return NULL;
	if (stat(filename, &st))
		return NULL;
	tb = mnt_new_table();
	if (tb) {
		DBG(TAB, ul_debugobj(tb, "new tab for file: %s", filename));
		tb->fmt = fmt;
		if (mnt_table_parse_file(tb, filename) != 0) {
			mnt_unref_table(tb);
			tb = NULL;
		}
	}
	return tb;
}
예제 #8
0
/* Check if there is something important in the utab file. The parsed utab is
 * stored in context->utab and deallocated by mnt_free_context().
 *
 * This function exists to avoid (if possible) /proc/self/mountinfo usage, so
 * don't use thigs like mnt_resolve_target(), mnt_context_get_mtab() etc here.
 * See lookup_umount_fs() for more details.
 */
static int has_utab_entry(struct libmnt_context *cxt, const char *target)
{
	struct libmnt_cache *cache = NULL;
	struct libmnt_fs *fs;
	struct libmnt_iter itr;
	char *cn = NULL;
	int rc = 0;

	assert(cxt);

	if (!cxt->utab) {
		const char *path = mnt_get_utab_path();

		if (!path || is_file_empty(path))
			return 0;
		cxt->utab = mnt_new_table();
		if (!cxt->utab)
			return 0;
		cxt->utab->fmt = MNT_FMT_UTAB;
		if (mnt_table_parse_file(cxt->utab, path))
			return 0;
	}

	/* paths in utab are canonicalized */
	cache = mnt_context_get_cache(cxt);
	cn = mnt_resolve_path(target, cache);
	mnt_reset_iter(&itr, MNT_ITER_BACKWARD);

	while (mnt_table_next_fs(cxt->utab, &itr, &fs) == 0) {
		if (mnt_fs_streq_target(fs, cn)) {
			rc = 1;
			break;
		}
	}

	if (!cache)
		free(cn);

	return rc;
}
예제 #9
0
파일: eject.c 프로젝트: Berrrry/util-linux
/*
 * See if device has been mounted by looking in mount table.  If so, set
 * device name and mount point name, and return 1, otherwise return 0.
 */
static int device_get_mountpoint(char **devname, char **mnt)
{
	struct libmnt_fs *fs;
	int rc;

	*mnt = NULL;

	if (!mtab) {
		struct libmnt_cache *cache;

		mtab = mnt_new_table();
		if (!mtab)
			err(EXIT_FAILURE, _("failed to initialize libmount table"));

		cache = mnt_new_cache();
		mnt_table_set_cache(mtab, cache);
		mnt_unref_cache(cache);

		if (p_option)
			rc = mnt_table_parse_file(mtab, _PATH_PROC_MOUNTINFO);
		else
			rc = mnt_table_parse_mtab(mtab, NULL);
		if (rc)
			err(EXIT_FAILURE, _("failed to parse mount table"));
	}

	fs = mnt_table_find_source(mtab, *devname, MNT_ITER_BACKWARD);
	if (!fs) {
		/* maybe 'devname' is mountpoint rather than a real device */
		fs = mnt_table_find_target(mtab, *devname, MNT_ITER_BACKWARD);
		if (fs) {
			free(*devname);
			*devname = xstrdup(mnt_fs_get_source(fs));
		}
	}

	if (fs)
		*mnt = xstrdup(mnt_fs_get_target(fs));
	return *mnt ? 0 : -1;
}
예제 #10
0
/* default filename is /proc/self/mountinfo
 */
int __mnt_table_parse_mtab(struct libmnt_table *tb, const char *filename,
			   struct libmnt_table *u_tb)
{
	int rc = 0, priv_utab = 0;

	assert(tb);

	if (filename)
		DBG(TAB, ul_debugobj(tb, "%s reuested as mtab", filename));

#ifdef USE_LIBMOUNT_SUPPORT_MTAB
	if (mnt_has_regular_mtab(&filename, NULL)) {

		DBG(TAB, ul_debugobj(tb, "force mtab usage [filename=%s]", filename));

		rc = mnt_table_parse_file(tb, filename);

		/*
		 * If @filename forces us to read from /proc then also read
		 * utab file to merge userspace mount options.
		 */
		if (rc == 0 && is_mountinfo(tb))
			goto read_utab;

		if (!rc)
			return 0;
		filename = NULL;	/* failed */
	} else
		filename = NULL;	/* mtab useless */
#endif

	if (!filename || strcmp(filename, _PATH_PROC_MOUNTINFO) == 0) {
		filename = _PATH_PROC_MOUNTINFO;
		tb->fmt = MNT_FMT_MOUNTINFO;
		DBG(TAB, ul_debugobj(tb, "mtab parse: #1 read mountinfo"));
	} else
		tb->fmt = MNT_FMT_GUESS;

	rc = mnt_table_parse_file(tb, filename);
	if (rc) {
		/* hmm, old kernel? ...try /proc/mounts */
		tb->fmt = MNT_FMT_MTAB;
		return mnt_table_parse_file(tb, _PATH_PROC_MOUNTS);
	}

	if (!is_mountinfo(tb))
		return 0;
#ifdef USE_LIBMOUNT_SUPPORT_MTAB
read_utab:
#endif
	DBG(TAB, ul_debugobj(tb, "mtab parse: #2 read utab"));

	if (mnt_table_get_nents(tb) == 0)
		return 0;			/* empty, ignore utab */
	/*
	 * try to read the user specific information from /run/mount/utabs
	 */
	if (!u_tb) {
		const char *utab = mnt_get_utab_path();

		if (!utab || is_file_empty(utab))
			return 0;

		u_tb = mnt_new_table();
		if (!u_tb)
			return -ENOMEM;

		u_tb->fmt = MNT_FMT_UTAB;
		mnt_table_set_parser_fltrcb(u_tb, tb->fltrcb, tb->fltrcb_data);

		rc = mnt_table_parse_file(u_tb, utab);
		priv_utab = 1;
	}

	DBG(TAB, ul_debugobj(tb, "mtab parse: #3 merge utab"));

	if (rc == 0) {
		struct libmnt_fs *u_fs;
		struct libmnt_iter itr;

		mnt_reset_iter(&itr, MNT_ITER_BACKWARD);

		/*  merge user options into mountinfo from the kernel */
		while(mnt_table_next_fs(u_tb, &itr, &u_fs) == 0)
			mnt_table_merge_user_fs(tb, u_fs);
	}


	if (priv_utab)
		mnt_unref_table(u_tb);
	return 0;
}