/*
 * Copyright (C) 2010 Karel Zak <kzak@redhat.com>
 *
 * This file may be redistributed under the terms of the
 * GNU Lesser General Public License.
 */

/**
 * SECTION: update
 * @title: Tables update
 * @short_description: userspace mount information management
 *
 * The struct libmnt_update provides an abstraction to manage mount options in
 * userspace independently of system configuration. This low-level API works on
 * systems both with and without /etc/mtab. On systems without the regular /etc/mtab
 * file, the userspace mount options (e.g. user=) are stored in the /run/mount/utab
 * file.
 *
 * It's recommended to use high-level struct libmnt_context API.
 */
#include <sys/file.h>
#include <fcntl.h>
#include <signal.h>

#include "mountP.h"
#include "mangle.h"
#include "pathnames.h"

struct libmnt_update {
	char		*target;
	struct libmnt_fs *fs;
	char		*filename;
	unsigned long	mountflags;
	int		userspace_only;
	int		ready;

	struct libmnt_table *mountinfo;
};

static int set_fs_root(struct libmnt_update *upd, struct libmnt_fs *fs, unsigned long mountflags);
static int utab_new_entry(struct libmnt_update *upd, struct libmnt_fs *fs, unsigned long mountflags);

/**
 * mnt_new_update:
 *
 * Returns: newly allocated update handler
 */
struct libmnt_update *mnt_new_update(void)
{
	struct libmnt_update *upd;

	upd = calloc(1, sizeof(*upd));
	if (!upd)
		return NULL;

	DBG(UPDATE, ul_debugobj(upd, "allocate"));
	return upd;
}

/**
 * mnt_free_update:
 * @upd: update
 *
 * Deallocates struct libmnt_update handler.
 */
void mnt_free_update(struct libmnt_update *upd)
{
	if (!upd)
		return;

	DBG(UPDATE, ul_debugobj(upd, "free"));

	mnt_unref_fs(upd->fs);
	mnt_unref_table(upd->mountinfo);
	free(upd->target);
	free(upd->filename);
	free(upd);
}

/*
 * Returns 0 on success, <0 in case of error.
 */
int mnt_update_set_filename(struct libmnt_update *upd, const char *filename,
			    int userspace_only)
{
	const char *path = NULL;
	int rw = 0;

	if (!upd)
		return -EINVAL;

	/* filename explicitly defined */
	if (filename) {
		char *p = strdup(filename);
		if (!p)
			return -ENOMEM;

		upd->userspace_only = userspace_only;
		free(upd->filename);
		upd->filename = p;
	}

	if (upd->filename)
		return 0;

	/* detect tab filename -- /etc/mtab or /run/mount/utab
	 */
#ifdef USE_LIBMOUNT_SUPPORT_MTAB
	mnt_has_regular_mtab(&path, &rw);
#endif
	if (!rw) {
		path = NULL;
		mnt_has_regular_utab(&path, &rw);
		if (!rw)
			return -EACCES;
		upd->userspace_only = TRUE;
	}
	upd->filename = strdup(path);
	if (!upd->filename)
		return -ENOMEM;

	return 0;
}

/**
 * mnt_update_get_filename:
 * @upd: update
 *
 * This function returns the file name (e.g. /etc/mtab) of the up-dated file.
 *
 * Returns: pointer to filename that will be updated or NULL in case of error.
 */
const char *mnt_update_get_filename(struct libmnt_update *upd)
{
	return upd ? upd->filename : NULL;
}

/**
 * mnt_update_is_ready:
 * @upd: update handler
 *
 * Returns: 1 if entry described by @upd is successfully prepared and will be
 * written to the mtab/utab file.
 */
int mnt_update_is_ready(struct libmnt_update *upd)
{
	return upd ? upd->ready : FALSE;
}

/**
 * mnt_update_set_fs:
 * @upd: update handler
 * @mountflags: MS_* flags
 * @target: umount target, must be NULL for mount
 * @fs: mount filesystem description, must be NULL for umount
 *
 * Returns: <0 in case on error, 0 on success, 1 if update is unnecessary.
 */
int mnt_update_set_fs(struct libmnt_update *upd, unsigned long mountflags,
		      const char *target, struct libmnt_fs *fs)
{
	int rc;

	if (!upd)
		return -EINVAL;
	if ((mountflags & MS_MOVE) && (!fs || !mnt_fs_get_srcpath(fs)))
		return -EINVAL;
	if (target && fs)
		return -EINVAL;

	DBG(UPDATE, ul_debugobj(upd,
			"resetting FS [target=%s, flags=0x%08lx]",
			target, mountflags));
	if (fs) {
		DBG(UPDATE, ul_debugobj(upd, "FS template:"));
		DBG(UPDATE, mnt_fs_print_debug(fs, stderr));
	}

	mnt_unref_fs(upd->fs);
	free(upd->target);
	upd->ready = FALSE;
	upd->fs = NULL;
	upd->target = NULL;
	upd->mountflags = 0;

	if (mountflags & MS_PROPAGATION)
		return 1;

	upd->mountflags = mountflags;

	rc = mnt_update_set_filename(upd, NULL, 0);
	if (rc) {
		DBG(UPDATE, ul_debugobj(upd, "no writable file available [rc=%d]", rc));
		return rc;	/* error or no file available (rc = 1) */
	}
	if (target) {
		upd->target = strdup(target);
		if (!upd->target)
			return -ENOMEM;

	} else if (fs) {
		if (upd->userspace_only && !(mountflags & MS_MOVE)) {
			rc = utab_new_entry(upd, fs, mountflags);
			if (rc)
				return rc;
		} else {
			upd->fs = mnt_copy_mtab_fs(fs);
			if (!upd->fs)
				return -ENOMEM;

		}
	}


	DBG(UPDATE, ul_debugobj(upd, "ready"));
	upd->ready = TRUE;
	return 0;
}

/**
 * mnt_update_get_fs:
 * @upd: update
 *
 * Returns: update filesystem entry or NULL
 */
struct libmnt_fs *mnt_update_get_fs(struct libmnt_update *upd)
{
	return upd ? upd->fs : NULL;
}

/**
 * mnt_update_get_mflags:
 * @upd: update
 *
 * Returns: mount flags as was set by mnt_update_set_fs()
 */
unsigned long mnt_update_get_mflags(struct libmnt_update *upd)
{
	return upd ? upd->mountflags : 0;
}

/**
 * mnt_update_force_rdonly:
 * @upd: update
 * @rdonly: is read-only?
 *
 * Returns: 0 on success and negative number in case of error.
 */
int mnt_update_force_rdonly(struct libmnt_update *upd, int rdonly)
{
	int rc = 0;

	if (!upd || !upd->fs)
		return -EINVAL;

	if (rdonly && (upd->mountflags & MS_RDONLY))
		return 0;
	if (!rdonly && !(upd->mountflags & MS_RDONLY))
		return 0;

	if (!upd->userspace_only) {
		/* /etc/mtab -- we care about VFS options there */
		const char *o = mnt_fs_get_options(upd->fs);
		char *n = o ? strdup(o) : NULL;

		if (n)
			mnt_optstr_remove_option(&n, rdonly ? "rw" : "ro");
		if (!mnt_optstr_prepend_option(&n, rdonly ? "ro" : "rw", NULL))
			rc = mnt_fs_set_options(upd->fs, n);

		free(n);
	}

	if (rdonly)
		upd->mountflags &= ~MS_RDONLY;
	else
		upd->mountflags |= MS_RDONLY;

	return rc;
}


/*
 * Allocates an utab entry (upd->fs) for mount/remount. This function should be
 * called *before* mount(2) syscall. The @fs is used as a read-only template.
 *
 * Returns: 0 on success, negative number on error, 1 if utab's update is
 *          unnecessary.
 */
static int utab_new_entry(struct libmnt_update *upd, struct libmnt_fs *fs,
			  unsigned long mountflags)
{
	int rc = 0;
	const char *o, *a;
	char *u = NULL;

	assert(fs);
	assert(upd);
	assert(upd->fs == NULL);
	assert(!(mountflags & MS_MOVE));

	DBG(UPDATE, ul_debug("prepare utab entry"));

	o = mnt_fs_get_user_options(fs);
	a = mnt_fs_get_attributes(fs);
	upd->fs = NULL;

	if (o) {
		/* remove non-mtab options */
		rc = mnt_optstr_get_options(o, &u,
				mnt_get_builtin_optmap(MNT_USERSPACE_MAP),
				MNT_NOMTAB);
		if (rc)
			goto err;
	}

	if (!u && !a) {
		DBG(UPDATE, ul_debug("utab entry unnecessary (no options)"));
		return 1;
	}

	/* allocate the entry */
	upd->fs = mnt_copy_fs(NULL, fs);
	if (!upd->fs) {
		rc = -ENOMEM;
		goto err;
	}

	rc = mnt_fs_set_options(upd->fs, u);
	if (rc)
		goto err;
	rc = mnt_fs_set_attributes(upd->fs, a);
	if (rc)
		goto err;

	if (!(mountflags & MS_REMOUNT)) {
		rc = set_fs_root(upd, fs, mountflags);
		if (rc)
			goto err;
	}

	free(u);
	DBG(UPDATE, ul_debug("utab entry OK"));
	return 0;
err:
	free(u);
	mnt_unref_fs(upd->fs);
	upd->fs = NULL;
	return rc;
}

/*
 * Sets fs-root and fs-type to @upd->fs according to the @fs template and
 * @mountfalgs. For MS_BIND mountflag it reads information about the source
 * filesystem from /proc/self/mountinfo.
 */
static int set_fs_root(struct libmnt_update *upd, struct libmnt_fs *fs,
		       unsigned long mountflags)
{
	struct libmnt_fs *src_fs;
	char *fsroot = NULL;
	const char *src, *fstype;
	int rc = 0;

	DBG(UPDATE, ul_debug("setting FS root"));

	assert(upd);
	assert(upd->fs);
	assert(fs);

	fstype = mnt_fs_get_fstype(fs);

	if (mountflags & MS_BIND) {
		if (!upd->mountinfo)
			upd->mountinfo = mnt_new_table_from_file(_PATH_PROC_MOUNTINFO);
		src = mnt_fs_get_srcpath(fs);
		if (src) {
			 rc = mnt_fs_set_bindsrc(upd->fs, src);
			 if (rc)
				 goto err;
		}

	} else if (fstype && (strcmp(fstype, "btrfs") == 0 || strcmp(fstype, "auto") == 0)) {
		if (!upd->mountinfo)
			upd->mountinfo = mnt_new_table_from_file(_PATH_PROC_MOUNTINFO);
	}

	src_fs = mnt_table_get_fs_root(upd->mountinfo, fs,
					mountflags, &fsroot);
	if (src_fs) {
		src = mnt_fs_get_srcpath(src_fs);
		rc = mnt_fs_set_source(upd->fs, src);
		if (rc)
			goto err;

		mnt_fs_set_fstype(upd->fs, mnt_fs_get_fstype(src_fs));
	}

	upd->fs->root = fsroot;
	return 0;
err:
	free(fsroot);
	return rc;
}

/* mtab and fstab update -- returns zero on success
 */
static int fprintf_mtab_fs(FILE *f, struct libmnt_fs *fs)
{
	const char *o, *src, *fstype, *comm;
	char *m1, *m2, *m3, *m4;
	int rc;

	assert(fs);
	assert(f);

	comm = mnt_fs_get_comment(fs);
	src = mnt_fs_get_source(fs);
	fstype = mnt_fs_get_fstype(fs);
	o = mnt_fs_get_options(fs);

	m1 = src ? mangle(src) : "none";
	m2 = mangle(mnt_fs_get_target(fs));
	m3 = fstype ? mangle(fstype) : "none";
	m4 = o ? mangle(o) : "rw";

	if (m1 && m2 && m3 && m4) {
		if (comm)
			fputs(comm, f);
		rc = fprintf(f, "%s %s %s %s %d %d\n",
				m1, m2, m3, m4,
				mnt_fs_get_freq(fs),
				mnt_fs_get_passno(fs));
		if (rc > 0)
			rc = 0;
	} else
		rc = -ENOMEM;

	if (src)
		free(m1);
	free(m2);
	if (fstype)
		free(m3);
	if (o)
		free(m4);

	return rc;
}

static int fprintf_utab_fs(FILE *f, struct libmnt_fs *fs)
{
	char *p;
	int rc = 0;

	if (!fs || !f)
		return -EINVAL;

	p = mangle(mnt_fs_get_source(fs));
	if (p) {
		rc = fprintf(f, "SRC=%s ", p);
		free(p);
	}
	if (rc >= 0) {
		p = mangle(mnt_fs_get_target(fs));
		if (p) {
			rc = fprintf(f, "TARGET=%s ", p);
			free(p);
		}
	}
	if (rc >= 0) {
		p = mangle(mnt_fs_get_root(fs));
		if (p) {
			rc = fprintf(f, "ROOT=%s ", p);
			free(p);
		}
	}
	if (rc >= 0) {
		p = mangle(mnt_fs_get_bindsrc(fs));
		if (p) {
			rc = fprintf(f, "BINDSRC=%s ", p);
			free(p);
		}
	}
	if (rc >= 0) {
		p = mangle(mnt_fs_get_attributes(fs));
		if (p) {
			rc = fprintf(f, "ATTRS=%s ", p);
			free(p);
		}
	}
	if (rc >= 0) {
		p = mangle(mnt_fs_get_user_options(fs));
		if (p) {
			rc = fprintf(f, "OPTS=%s", p);
			free(p);
		}
	}
	if (rc >= 0)
		rc = fprintf(f, "\n");

	if (rc > 0)
		rc = 0;	/* success */
	return rc;
}

static int update_table(struct libmnt_update *upd, struct libmnt_table *tb)
{
	FILE *f;
	int rc, fd;
	char *uq = NULL;

	if (!tb || !upd->filename)
		return -EINVAL;

	DBG(UPDATE, ul_debugobj(upd, "%s: updating", upd->filename));

	fd = mnt_open_uniq_filename(upd->filename, &uq);
	if (fd < 0)
		return fd;	/* error */

	f = fdopen(fd, "w" UL_CLOEXECSTR);
	if (f) {
		struct stat st;
		struct libmnt_iter itr;
		struct libmnt_fs *fs;

		mnt_reset_iter(&itr, MNT_ITER_FORWARD);

		if (tb->comms && mnt_table_get_intro_comment(tb))
			fputs(mnt_table_get_intro_comment(tb), f);

		while(mnt_table_next_fs(tb, &itr, &fs) == 0) {
			if (upd->userspace_only)
				rc = fprintf_utab_fs(f, fs);
			else
				rc = fprintf_mtab_fs(f, fs);
			if (rc) {
				DBG(UPDATE, ul_debugobj(upd,
					"%s: write entry failed: %m", uq));
				goto leave;
			}
		}
		if (tb->comms && mnt_table_get_trailing_comment(tb))
			fputs(mnt_table_get_trailing_comment(tb), f);

		if (fflush(f) != 0) {
			rc = -errno;
			DBG(UPDATE, ul_debugobj(upd, "%s: fflush failed: %m", uq));
			goto leave;
		}

		rc = fchmod(fd, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) ? -errno : 0;

		if (!rc && stat(upd->filename, &st) == 0)
			/* Copy uid/gid from the present file before renaming. */
			rc = fchown(fd, st.st_uid, st.st_gid) ? -errno : 0;

		fclose(f);
		f = NULL;

		if (!rc)
			rc = rename(uq, upd->filename) ? -errno : 0;
	} else {
		rc = -errno;
		close(fd);
	}

leave:
	if (f)
		fclose(f);

	unlink(uq);	/* be paranoid */
	free(uq);
	DBG(UPDATE, ul_debugobj(upd, "%s: done [rc=%d]", upd->filename, rc));
	return rc;
}

/**
 * mnt_table_write_file
 * @tb: parsed file (e.g. fstab)
 * @file: target
 *
 * This function writes @tb to @file.
 *
 * Returns: 0 on success, negative number on error.
 */
int mnt_table_write_file(struct libmnt_table *tb, FILE *file)
{
	int rc = 0;
	struct libmnt_iter itr;
	struct libmnt_fs *fs;

	if (tb->comms && mnt_table_get_intro_comment(tb))
		fputs(mnt_table_get_intro_comment(tb), file);

	mnt_reset_iter(&itr, MNT_ITER_FORWARD);
	while(mnt_table_next_fs(tb, &itr, &fs) == 0) {
		rc = fprintf_mtab_fs(file, fs);
		if (rc)
			return rc;
	}
	if (tb->comms && mnt_table_get_trailing_comment(tb))
		fputs(mnt_table_get_trailing_comment(tb), file);

	if (fflush(file) != 0)
		rc = -errno;

	DBG(TAB, ul_debugobj(tb, "write file done [rc=%d]", rc));
	return rc;
}

/**
 * mnt_table_replace_file
 * @tb: parsed file (e.g. fstab)
 * @filename: target
 *
 * This function replaces @file by the new content from @tb.
 *
 * Returns: 0 on success, negative number on error.
 */
int mnt_table_replace_file(struct libmnt_table *tb, const char *filename)
{
	int fd, rc = 0;
	FILE *f;
	char *uq = NULL;

	DBG(TAB, ul_debugobj(tb, "%s: replacing", filename));

	fd = mnt_open_uniq_filename(filename, &uq);
	if (fd < 0)
		return fd;	/* error */

	f = fdopen(fd, "w" UL_CLOEXECSTR);
	if (f) {
		struct stat st;

		mnt_table_write_file(tb, f);

		if (fflush(f) != 0) {
			rc = -errno;
			DBG(UPDATE, ul_debug("%s: fflush failed: %m", uq));
			goto leave;
		}

		rc = fchmod(fd, S_IRUSR|S_IWUSR|S_IRGRP|S_IROTH) ? -errno : 0;

		if (!rc && stat(filename, &st) == 0)
			/* Copy uid/gid from the present file before renaming. */
			rc = fchown(fd, st.st_uid, st.st_gid) ? -errno : 0;

		fclose(f);
		f = NULL;

		if (!rc)
			rc = rename(uq, filename) ? -errno : 0;
	} else {
		rc = -errno;
		close(fd);
	}

leave:
	if (f)
		fclose(f);
	unlink(uq);
	free(uq);

	DBG(TAB, ul_debugobj(tb, "replace done [rc=%d]", rc));
	return rc;
}

static int add_file_entry(struct libmnt_table *tb, struct libmnt_update *upd)
{
	struct libmnt_fs *fs;

	assert(upd);

	fs = mnt_copy_fs(NULL, upd->fs);
	if (!fs)
		return -ENOMEM;

	mnt_table_add_fs(tb, fs);
	mnt_unref_fs(fs);

	return update_table(upd, tb);
}

static int update_add_entry(struct libmnt_update *upd, struct libmnt_lock *lc)
{
	struct libmnt_table *tb;
	int rc = 0;

	assert(upd);
	assert(upd->fs);

	DBG(UPDATE, ul_debugobj(upd, "%s: add entry", upd->filename));

	if (lc)
		rc = mnt_lock_file(lc);
	if (rc)
		return -MNT_ERR_LOCK;

	tb = __mnt_new_table_from_file(upd->filename,
			upd->userspace_only ? MNT_FMT_UTAB : MNT_FMT_MTAB, 1);
	if (tb)
		rc = add_file_entry(tb, upd);
	if (lc)
		mnt_unlock_file(lc);

	mnt_unref_table(tb);
	return rc;
}

static int update_remove_entry(struct libmnt_update *upd, struct libmnt_lock *lc)
{
	struct libmnt_table *tb;
	int rc = 0;

	assert(upd);
	assert(upd->target);

	DBG(UPDATE, ul_debugobj(upd, "%s: remove entry", upd->filename));

	if (lc)
		rc = mnt_lock_file(lc);
	if (rc)
		return -MNT_ERR_LOCK;

	tb = __mnt_new_table_from_file(upd->filename,
			upd->userspace_only ? MNT_FMT_UTAB : MNT_FMT_MTAB, 1);
	if (tb) {
		struct libmnt_fs *rem = mnt_table_find_target(tb, upd->target, MNT_ITER_BACKWARD);
		if (rem) {
			mnt_table_remove_fs(tb, rem);
			rc = update_table(upd, tb);
		}
	}
	if (lc)
		mnt_unlock_file(lc);

	mnt_unref_table(tb);
	return rc;
}

static int update_modify_target(struct libmnt_update *upd, struct libmnt_lock *lc)
{
	struct libmnt_table *tb = NULL;
	int rc = 0;

	assert(upd);
	DBG(UPDATE, ul_debugobj(upd, "%s: modify target", upd->filename));

	if (lc)
		rc = mnt_lock_file(lc);
	if (rc)
		return -MNT_ERR_LOCK;

	tb = __mnt_new_table_from_file(upd->filename,
			upd->userspace_only ? MNT_FMT_UTAB : MNT_FMT_MTAB, 1);
	if (tb) {
		struct libmnt_fs *cur = mnt_table_find_target(tb,
				mnt_fs_get_srcpath(upd->fs), MNT_ITER_BACKWARD);
		if (cur) {
			rc = mnt_fs_set_target(cur, mnt_fs_get_target(upd->fs));
			if (!rc)
				rc = update_table(upd, tb);
		}
	}

	if (lc)
		mnt_unlock_file(lc);

	mnt_unref_table(tb);
	return rc;
}

static int update_modify_options(struct libmnt_update *upd, struct libmnt_lock *lc)
{
	struct libmnt_table *tb = NULL;
	int rc = 0;
	struct libmnt_fs *fs;

	assert(upd);
	assert(upd->fs);

	DBG(UPDATE, ul_debugobj(upd, "%s: modify options", upd->filename));

	fs = upd->fs;

	if (lc)
		rc = mnt_lock_file(lc);
	if (rc)
		return -MNT_ERR_LOCK;

	tb = __mnt_new_table_from_file(upd->filename,
			upd->userspace_only ? MNT_FMT_UTAB : MNT_FMT_MTAB, 1);
	if (tb) {
		struct libmnt_fs *cur = mnt_table_find_target(tb,
					mnt_fs_get_target(fs),
					MNT_ITER_BACKWARD);
		if (cur) {
			if (upd->userspace_only)
				rc = mnt_fs_set_attributes(cur,	mnt_fs_get_attributes(fs));
			if (!rc)
				rc = mnt_fs_set_options(cur, mnt_fs_get_options(fs));
			if (!rc)
				rc = update_table(upd, tb);
		} else
			rc = add_file_entry(tb, upd);	/* not found, add new */
	}

	if (lc)
		mnt_unlock_file(lc);

	mnt_unref_table(tb);
	return rc;
}

/**
 * mnt_update_table:
 * @upd: update
 * @lc: lock or NULL
 *
 * High-level API to update /etc/mtab (or private /run/mount/utab file).
 *
 * The @lc lock is optional and will be created if necessary. Note that
 * an automatically created lock blocks all signals.
 *
 * See also mnt_lock_block_signals() and mnt_context_get_lock().
 *
 * Returns: 0 on success, negative number on error.
 */
int mnt_update_table(struct libmnt_update *upd, struct libmnt_lock *lc)
{
	struct libmnt_lock *lc0 = lc;
	int rc = -EINVAL;

	if (!upd || !upd->filename)
		return -EINVAL;
	if (!upd->ready)
		return 0;

	DBG(UPDATE, ul_debugobj(upd, "%s: update tab", upd->filename));
	if (upd->fs) {
		DBG(UPDATE, mnt_fs_print_debug(upd->fs, stderr));
	}
	if (!lc) {
		lc = mnt_new_lock(upd->filename, 0);
		if (lc)
			mnt_lock_block_signals(lc, TRUE);
	}
	if (lc && upd->userspace_only)
		mnt_lock_use_simplelock(lc, TRUE);	/* use flock */

	if (!upd->fs && upd->target)
		rc = update_remove_entry(upd, lc);	/* umount */
	else if (upd->mountflags & MS_MOVE)
		rc = update_modify_target(upd, lc);	/* move */
	else if (upd->mountflags & MS_REMOUNT)
		rc = update_modify_options(upd, lc);	/* remount */
	else if (upd->fs)
		rc = update_add_entry(upd, lc);	/* mount */

	upd->ready = FALSE;
	DBG(UPDATE, ul_debugobj(upd, "%s: update tab: done [rc=%d]",
				upd->filename, rc));
	if (lc != lc0)
		 mnt_free_lock(lc);
	return rc;
}

int mnt_update_already_done(struct libmnt_update *upd, struct libmnt_lock *lc)
{
	struct libmnt_table *tb = NULL;
	struct libmnt_lock *lc0 = lc;
	int rc = 0;

	if (!upd || !upd->filename || (!upd->fs && !upd->target))
		return -EINVAL;

	DBG(UPDATE, ul_debugobj(upd, "%s: checking for previous update", upd->filename));

	if (!lc) {
		lc = mnt_new_lock(upd->filename, 0);
		if (lc)
			mnt_lock_block_signals(lc, TRUE);
	}
	if (lc && upd->userspace_only)
		mnt_lock_use_simplelock(lc, TRUE);	/* use flock */
	if (lc) {
		rc = mnt_lock_file(lc);
		if (rc) {
			rc = -MNT_ERR_LOCK;
			goto done;
		}
	}

	tb = __mnt_new_table_from_file(upd->filename,
			upd->userspace_only ? MNT_FMT_UTAB : MNT_FMT_MTAB, 1);
	if (lc)
		mnt_unlock_file(lc);
	if (!tb)
		goto done;

	if (upd->fs) {
		/* mount */
		const char *tgt = mnt_fs_get_target(upd->fs);
		const char *src = mnt_fs_get_bindsrc(upd->fs) ?
					mnt_fs_get_bindsrc(upd->fs) :
					mnt_fs_get_source(upd->fs);

		if (mnt_table_find_pair(tb, src, tgt, MNT_ITER_BACKWARD)) {
			DBG(UPDATE, ul_debugobj(upd, "%s: found %s %s",
						upd->filename, src, tgt));
			rc = 1;
		}
	} else if (upd->target) {
		/* umount */
		if (!mnt_table_find_target(tb, upd->target, MNT_ITER_BACKWARD)) {
			DBG(UPDATE, ul_debugobj(upd, "%s: not-found (umounted) %s",
						upd->filename, upd->target));
			rc = 1;
		}
	}

	mnt_unref_table(tb);
done:
	if (lc && lc != lc0)
		mnt_free_lock(lc);
	DBG(UPDATE, ul_debugobj(upd, "%s: previous update check done [rc=%d]",
				upd->filename, rc));
	return rc;
}


#ifdef TEST_PROGRAM

static int update(const char *target, struct libmnt_fs *fs, unsigned long mountflags)
{
	int rc;
	struct libmnt_update *upd;

	DBG(UPDATE, ul_debug("update test"));

	upd = mnt_new_update();
	if (!upd)
		return -ENOMEM;

	rc = mnt_update_set_fs(upd, mountflags, target, fs);
	if (rc == 1) {
		/* update is unnecessary */
		rc = 0;
		goto done;
	}
	if (rc) {
		fprintf(stderr, "failed to set FS\n");
		goto done;
	}

	/* [... mount(2) call should be here...]  */

	rc = mnt_update_table(upd, NULL);
done:
	mnt_free_update(upd);
	return rc;
}

static int test_add(struct libmnt_test *ts, int argc, char *argv[])
{
	struct libmnt_fs *fs = mnt_new_fs();
	int rc;

	if (argc < 5 || !fs)
		return -1;
	mnt_fs_set_source(fs, argv[1]);
	mnt_fs_set_target(fs, argv[2]);
	mnt_fs_set_fstype(fs, argv[3]);
	mnt_fs_set_options(fs, argv[4]);

	rc = update(NULL, fs, 0);
	mnt_unref_fs(fs);
	return rc;
}

static int test_remove(struct libmnt_test *ts, int argc, char *argv[])
{
	if (argc < 2)
		return -1;
	return update(argv[1], NULL, 0);
}

static int test_move(struct libmnt_test *ts, int argc, char *argv[])
{
	struct libmnt_fs *fs = mnt_new_fs();
	int rc;

	if (argc < 3)
		return -1;
	mnt_fs_set_source(fs, argv[1]);
	mnt_fs_set_target(fs, argv[2]);

	rc = update(NULL, fs, MS_MOVE);

	mnt_unref_fs(fs);
	return rc;
}

static int test_remount(struct libmnt_test *ts, int argc, char *argv[])
{
	struct libmnt_fs *fs = mnt_new_fs();
	int rc;

	if (argc < 3)
		return -1;
	mnt_fs_set_target(fs, argv[1]);
	mnt_fs_set_options(fs, argv[2]);

	rc = update(NULL, fs, MS_REMOUNT);
	mnt_unref_fs(fs);
	return rc;
}

static int test_replace(struct libmnt_test *ts, int argc, char *argv[])
{
	struct libmnt_fs *fs = mnt_new_fs();
	struct libmnt_table *tb = mnt_new_table();
	int rc;

	if (argc < 3)
		return -1;

	mnt_table_enable_comments(tb, TRUE);
	mnt_table_parse_fstab(tb, NULL);

	mnt_fs_set_source(fs, argv[1]);
	mnt_fs_set_target(fs, argv[2]);
	mnt_fs_append_comment(fs, "# this is new filesystem\n");

	mnt_table_add_fs(tb, fs);
	mnt_unref_fs(fs);

	rc = mnt_table_replace_file(tb, mnt_get_fstab_path());
	mnt_unref_table(tb);
	return rc;
}

int main(int argc, char *argv[])
{
	struct libmnt_test tss[] = {
	{ "--add",    test_add,     "<src> <target> <type> <options>  add a line to mtab" },
	{ "--remove", test_remove,  "<target>                      MS_REMOUNT mtab change" },
	{ "--move",   test_move,    "<old_target>  <target>        MS_MOVE mtab change" },
	{ "--remount",test_remount, "<target>  <options>           MS_REMOUNT mtab change" },
	{ "--replace",test_replace, "<src> <target>                Add a line to LIBMOUNT_FSTAB and replace the original file" },
	{ NULL }
	};

	return mnt_run_test(tss, argc, argv);
}

#endif /* TEST_PROGRAM */
