libmount: add post-mount checks to detect ro/rw
Signed-off-by: Karel Zak <kzak@redhat.com>
This commit is contained in:
parent
8b470b20d7
commit
f9906424d4
|
@ -289,8 +289,7 @@ int mnt_context_setup_loopdev(struct libmnt_context *cxt)
|
|||
* mount planned read-write, but loopdev is read-only,
|
||||
* let's fix mount options...
|
||||
*/
|
||||
cxt->mountflags |= MS_RDONLY;
|
||||
|
||||
mnt_context_set_mflags(cxt, cxt->mountflags | MS_RDONLY);
|
||||
|
||||
/* we have to keep the device open until mount(1),
|
||||
* otherwise it will auto-cleared by kernel
|
||||
|
|
|
@ -455,10 +455,6 @@ static int do_mount(struct libmnt_context *cxt, const char *try_type)
|
|||
rc = mnt_fs_set_fstype(fs, try_type);
|
||||
}
|
||||
|
||||
/* TODO: check if the result is really read-only/read-write
|
||||
* and if necessary update cxt->mountflags
|
||||
*/
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
||||
|
@ -591,6 +587,7 @@ int mnt_context_prepare_mount(struct libmnt_context *cxt)
|
|||
int mnt_context_do_mount(struct libmnt_context *cxt)
|
||||
{
|
||||
const char *type;
|
||||
int res;
|
||||
|
||||
assert(cxt);
|
||||
assert(cxt->fs);
|
||||
|
@ -607,9 +604,40 @@ int mnt_context_do_mount(struct libmnt_context *cxt)
|
|||
|
||||
type = mnt_fs_get_fstype(cxt->fs);
|
||||
if (type)
|
||||
return do_mount(cxt, NULL);
|
||||
res = do_mount(cxt, NULL);
|
||||
else
|
||||
res = do_mount_by_pattern(cxt, cxt->fstype_pattern);
|
||||
|
||||
return do_mount_by_pattern(cxt, cxt->fstype_pattern);
|
||||
if (mnt_context_get_status(cxt)
|
||||
&& !(cxt->flags & MNT_FL_FAKE)
|
||||
&& !cxt->helper) {
|
||||
/*
|
||||
* Mounted by mount(2), do some post-mount checks
|
||||
*
|
||||
* Kernel allows to use MS_RDONLY for bind mounts, but the
|
||||
* read-only request could be silently ignored. Check it to
|
||||
* avoid 'ro' in mtab and 'rw' in /proc/mounts.
|
||||
*/
|
||||
if ((cxt->mountflags & MS_BIND)
|
||||
&& (cxt->mountflags & MS_RDONLY)
|
||||
&& !mnt_is_readonly(mnt_context_get_target(cxt)))
|
||||
|
||||
mnt_context_set_mflags(cxt,
|
||||
cxt->mountflags & ~MS_RDONLY);
|
||||
|
||||
|
||||
/* Kernel can silently add MS_RDONLY flag when mounting file
|
||||
* system that does not have write support. Check this to avoid
|
||||
* 'ro' in /proc/mounts and 'rw' in mtab.
|
||||
*/
|
||||
if (!(cxt->mountflags & (MS_RDONLY | MS_PROPAGATION | MS_MOVE))
|
||||
&& mnt_is_readonly(mnt_context_get_target(cxt)))
|
||||
|
||||
mnt_context_set_mflags(cxt,
|
||||
cxt->mountflags | MS_RDONLY);
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -129,6 +129,8 @@ extern int mnt_run_test(struct libmnt_test *tests, int argc, char *argv[]);
|
|||
extern int endswith(const char *s, const char *sx);
|
||||
extern int startswith(const char *s, const char *sx);
|
||||
|
||||
extern int mnt_is_readonly(const char *path);
|
||||
|
||||
extern int mnt_parse_offset(const char *str, size_t len, uintmax_t *res);
|
||||
|
||||
extern int mnt_chdir_to_parent(const char *target, char **filename);
|
||||
|
|
|
@ -145,6 +145,41 @@ err:
|
|||
return rc;
|
||||
}
|
||||
|
||||
/*
|
||||
* Check if @path is on read-only filesystem independently on file permissions.
|
||||
*/
|
||||
int mnt_is_readonly(const char *path)
|
||||
{
|
||||
if (access(path, W_OK) == 0)
|
||||
return 0;
|
||||
if (errno == EROFS)
|
||||
return 1;
|
||||
if (errno != EACCES)
|
||||
return 0;
|
||||
|
||||
#ifdef HAVE_FUTIMENS
|
||||
/*
|
||||
* access(2) returns EACCES on read-only FS:
|
||||
*
|
||||
* - for set-uid application if one component of the path is not
|
||||
* accessible for the current rUID. (Note that euidaccess(2) does not
|
||||
* check for EROFS at all).
|
||||
*
|
||||
* - for read-write filesystem with read-only VFS node (aka -o remount,ro,bind)
|
||||
*/
|
||||
{
|
||||
struct timespec times[2];
|
||||
|
||||
times[0].tv_nsec = UTIME_NOW; /* atime */
|
||||
times[1].tv_nsec = UTIME_OMIT; /* mtime */
|
||||
|
||||
if (utimensat(AT_FDCWD, path, times, 0) == -1)
|
||||
return errno == EROFS;
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* mnt_mangle:
|
||||
* @str: string
|
||||
|
|
Loading…
Reference in New Issue