summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Maiolino <cmaiolino@redhat.com>2012-01-16 12:29:49 -0500
committerJeff Layton <jlayton@samba.org>2012-01-16 12:29:49 -0500
commitf46dd7661cfb87257c95081fc2071c934bfbbb16 (patch)
treea20eab75598acdfdd8113eaf8fb2eb5801d72a06
parent80682b216fed9ea52e1498890eb248567aba2a06 (diff)
downloadcifs-utils-f46dd7661cfb87257c95081fc2071c934bfbbb16.tar.gz
cifs-utils-f46dd7661cfb87257c95081fc2071c934bfbbb16.tar.bz2
cifs-utils-f46dd7661cfb87257c95081fc2071c934bfbbb16.zip
mount.cifs: Properly update mtab during remount
During a remount of a cifs filesystem, the mtab file is not properly updated, which leads to a doubled entry of the same filesystem in the /etc/mtab file. This patch adds a new function del_mtab() which is called before the add_mtab() in case the fs is being remounted. The del_mtab() function will delete from the mtab, the old entry from the filesystem which is being remounted, and then, calls add_mtab() to add an updated entry to the mtab file. Signed-off-by: Carlos Maiolino <cmaiolino@redhat.com>
-rw-r--r--mount.cifs.c99
1 files changed, 98 insertions, 1 deletions
diff --git a/mount.cifs.c b/mount.cifs.c
index 147f7fc..af071c1 100644
--- a/mount.cifs.c
+++ b/mount.cifs.c
@@ -42,6 +42,7 @@
#include <fcntl.h>
#include <limits.h>
#include <paths.h>
+#include <libgen.h>
#include <sys/mman.h>
#include <sys/wait.h>
#ifdef HAVE_LIBCAP_NG
@@ -161,6 +162,7 @@
#define OPT_BKUPUID 30
#define OPT_BKUPGID 31
+#define MNT_TMP_FILE "/.mtab.cifs.XXXXXX"
/* struct for holding parsed mount info for use by privleged process */
struct parsed_mount_info {
@@ -1624,6 +1626,94 @@ add_mtab_exit:
return rc;
}
+static int
+del_mtab(char *mountpoint)
+{
+ int tmprc, rc = 0;
+ FILE *mnttmp, *mntmtab;
+ struct mntent *mountent;
+ char *mtabfile, *mtabdir, *mtabtmpfile;
+
+ mtabfile = strdup(MOUNTED);
+ mtabdir = dirname(mtabfile);
+ mtabdir = realloc(mtabdir, strlen(mtabdir) + strlen(MNT_TMP_FILE) + 2);
+ if (!mtabdir) {
+ fprintf(stderr, "del_mtab: cannot determine current mtab path");
+ rc = EX_FILEIO;
+ goto del_mtab_exit;
+ }
+
+ mtabtmpfile = strcat(mtabdir, MNT_TMP_FILE);
+ if (!mtabtmpfile) {
+ fprintf(stderr, "del_mtab: cannot allocate memory to tmp file");
+ rc = EX_FILEIO;
+ goto del_mtab_exit;
+ }
+
+ atexit(unlock_mtab);
+ rc = lock_mtab();
+ if (rc) {
+ fprintf(stderr, "del_mtab: cannot lock mtab");
+ rc = EX_FILEIO;
+ goto del_mtab_exit;
+ }
+
+ mtabtmpfile = mktemp(mtabtmpfile);
+ if (!mtabtmpfile) {
+ fprintf(stderr, "del_mtab: cannot setup tmp file destination");
+ rc = EX_FILEIO;
+ goto del_mtab_exit;
+ }
+
+ mntmtab = setmntent(MOUNTED, "r");
+ if (!mntmtab) {
+ fprintf(stderr, "del_mtab: could not update mount table\n");
+ rc = EX_FILEIO;
+ goto del_mtab_exit;
+ }
+
+ mnttmp = setmntent(mtabtmpfile, "w");
+ if (!mnttmp) {
+ fprintf(stderr, "del_mtab: could not update mount table\n");
+ endmntent(mntmtab);
+ rc = EX_FILEIO;
+ goto del_mtab_exit;
+ }
+
+ while ((mountent = getmntent(mntmtab)) != NULL) {
+ if (!strcmp(mountent->mnt_dir, mountpoint))
+ continue;
+ rc = addmntent(mnttmp, mountent);
+ if (rc) {
+ fprintf(stderr, "del_mtab: unable to add mount entry to mtab\n");
+ rc = EX_FILEIO;
+ goto del_mtab_error;
+ }
+ }
+
+ endmntent(mntmtab);
+
+ tmprc = my_endmntent(mnttmp, 0);
+ if (tmprc) {
+ fprintf(stderr, "del_mtab: error %d detected on close of tmp file\n", tmprc);
+ rc = EX_FILEIO;
+ goto del_mtab_error;
+ }
+
+ rename(mtabtmpfile, MOUNTED);
+
+del_mtab_exit:
+ unlock_mtab();
+ free(mtabdir);
+ return rc;
+
+del_mtab_error:
+ if (unlink(mtabtmpfile))
+ fprintf(stderr, "del_mtab: failed to delete tmp file - %s\n",
+ strerror(errno));
+ goto del_mtab_exit;
+}
+
/* have the child drop root privileges */
static int
drop_child_privs(void)
@@ -2021,8 +2111,15 @@ mount_retry:
}
do_mtab:
- if (!parsed_info->nomtab && !mtab_unusable())
+ if (!parsed_info->nomtab && !mtab_unusable()) {
+ if (parsed_info->flags & MS_REMOUNT) {
+ rc = del_mtab(mountpoint);
+ if (rc)
+ goto mount_exit;
+ }
+
rc = add_mtab(orig_dev, mountpoint, parsed_info->flags, fstype);
+ }
mount_exit:
if (parsed_info) {