Re: [PATCH] mount.cifs: Properly update mtab during remount

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Thu, 29 Dec 2011 09:00:57 -0200
Carlos Maiolino <cmaiolino@xxxxxxxxxx> wrote:

> > > 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@xxxxxxxxxx>
> > > ---
> > >  mount.cifs.c |   81 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
> > >  1 files changed, 81 insertions(+), 0 deletions(-)
> > > 
> > > diff --git a/mount.cifs.c b/mount.cifs.c
> > > index 147f7fc..6535b40 100644
> > > --- a/mount.cifs.c
> > > +++ b/mount.cifs.c
> > > @@ -161,6 +161,7 @@
> > >  #define OPT_BKUPUID    30
> > >  #define OPT_BKUPGID    31
> > >  
> > > +#define MNT_TMP_PATH "/tmp/mtab.tmp"
> > >  
> > >  /* struct for holding parsed mount info for use by privleged process */
> > >  struct parsed_mount_info {
> > > @@ -1624,6 +1625,81 @@ add_mtab_exit:
> > >  	return rc;
> > >  }
> > >  
> > > +static int
> > > +del_mtab(char *devname, char *mountpoint)
> > > +{
> > > +	int fd, tmprc, rc = 0;
> > > +	FILE *mnttmp, *mntmtab;
> > > +	struct mntent *mountent;
> > > +	struct stat statbuf;
> > > +
> > > +	rc = lock_mtab();
> > > +	if(rc) {
> > > +		fprintf(stderr, "del_mtab: cannot lock mtab");
> > > +		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(MNT_TMP_PATH, "w");
> > > +	if (!mnttmp) {
> > > +		fprintf(stderr, "del_mtab: could not update mount table\n");
> > > +		endmntent(mntmtab);
> > > +		rc = EX_FILEIO;
> > > +		goto del_mtab_exit;
> > > +	}
> > > +
> > > +	fd = fileno(mntmtab);
> > > +	if (fd < 0) {
> > > +		fprintf(stderr, "mntent does not appear to be valid\n");
> > > +		endmntent(mntmtab);
> > > +		endmntent(mnttmp);
> > > +		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, "unable to add mount entry to mtab\n");
> > > +			ftruncate(fd, statbuf.st_size);
> > > +			rc = EX_FILEIO;
> > > +			break;
> > > +		}
> > > +	}
> > > +
> > > +	rc = fstat(fd, &statbuf);
> > > +	if (rc != 0) {
> > > +		fprintf(stderr, "unable to fstat open mtab\n");
> > > +		endmntent(mntmtab);
> > > +		endmntent(mnttmp);
> > > +		rc = EX_FILEIO;
> > > +		goto del_mtab_exit;
> > > +	}
> > > +
> > > +	tmprc = my_endmntent(mntmtab, statbuf.st_size);
> > > +	if (tmprc) {
> > > +		fprintf(stderr, "error %d detected on close of mtab\n", tmprc);
> > > +		rc = EX_FILEIO;
> > > +	}
> > > +	endmntent(mnttmp);
> > > +
> > > +	rename(MNT_TMP_PATH, MOUNTED);
> > 
> > You seem to me making the assumption that MNT_TMP_PATH and MOUNTED are
> > on the same filesystem. That's not necessarily (or even commonly) the
> > case. If you want to do this, you'll probably want to make sure they
> > are on the same filesystem.
> > 
> 
> Hi, I didn't notice rename() shall not cross filesystem boundaries, Would
> be better to set the MNT_TMP_PATH to a file into /etc? Maybe a hidden file
> like /etc/.mtab.tmp?
> 

Well, that assumes that MOUNTED is in /etc, which is usually the case,
but may not always be...

It would probably be better to base MNT_TMP_PATH on MOUNTED itself.
Either add a suffix of some sort to MOUNTED, or use dirname() on
MOUNTED to get the directory.

> > > +	unlink(MNT_TMP_PATH);
> > > +
> > > +del_mtab_exit:
> > > +	unlock_mtab();
> > > +	return rc;
> > > +}
> > > +
> > >  /* have the child drop root privileges */
> > >  static int
> > >  drop_child_privs(void)
> > > @@ -2021,6 +2097,11 @@ mount_retry:
> > >  	}
> > >  
> > >  do_mtab:
> > > +	if(parsed_info->flags & MS_REMOUNT){
> >        ^^^^^^
> >     nit: we try to follow kernel coding style in this code...
> >    
> > > +		rc = del_mtab(orig_dev, mountpoint);
> > > +		if(rc)
> > > +			goto mount_exit;
> > > +	}
> > >  	if (!parsed_info->nomtab && !mtab_unusable())
> > >  		rc = add_mtab(orig_dev, mountpoint, parsed_info->flags, fstype);
> > >  
> > 
> > Patch looks reasonable otherwise. Nice work...
> > 
> > Note too, that remounts in the kernel cifs code are quite broken. It
> > always returns 0 without ever actually changing anything. It would be
> > helpful to fix that as well...
> > 
> I'll add that to my TODO list.
> 
> 
> I'm rewriting the patch with the changes required and should re-send it soon. Thanks
> for the review.
> 


-- 
Jeff Layton <jlayton@xxxxxxxxxx>
--
To unsubscribe from this list: send the line "unsubscribe linux-cifs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Yosemite News]     [Linux Kernel]     [Linux SCSI]

  Powered by Linux