Commit 33a50cfd authored by Andrey Vagin's avatar Andrey Vagin Committed by Pavel Emelyanov

mount: detect the newinstance option for devpts (v2)

The devpts instance was mounted w/o the newinstance option if,
the device number is equal to the root /dev/pts.

I think this condition is strong enough to not mount devpts in a
temporary place.

v2: move the host.bla-bla-bla in kerndat.c
Signed-off-by: 's avatarAndrey Vagin <avagin@openvz.org>
Reviewed-by: 's avatarCyrill Gorcunov <gorcunov@openvz.org>
Signed-off-by: 's avatarPavel Emelyanov <xemul@parallels.com>
parent 963f8a06
......@@ -29,4 +29,8 @@
# define SOCKFS_MAGIC 0x534f434b
#endif
#ifndef DEVPTS_SUPER_MAGIC
#define DEVPTS_SUPER_MAGIC 0x1cd1
#endif
#endif /* __CR_FS_MAGIC_H__ */
......@@ -21,4 +21,7 @@ extern int tcp_max_rshare;
extern int kern_last_cap;
extern u64 zero_page_pfn;
struct stat;
extern struct stat *kerndat_get_devpts_stat(void);
#endif /* __CR_KERNDAT_H__ */
......@@ -9,6 +9,7 @@
#include "log.h"
#include "bug.h"
#include "kerndat.h"
#include "fs-magic.h"
#include "mem.h"
#include "compiler.h"
#include "sysctl.h"
......@@ -52,6 +53,32 @@ static int kerndat_get_shmemdev(void)
return 0;
}
struct stat *kerndat_get_devpts_stat()
{
static struct stat st = {};
struct statfs fst;
if (st.st_dev != 0)
return &st;
if (statfs("/dev/pts", &fst)) {
pr_perror("Unable to statefs /dev/pts");
return NULL;
}
if (fst.f_type != DEVPTS_SUPER_MAGIC) {
pr_err("devpts isn't mount on the host\n");
return NULL;
}
/* The root /dev/pts is mounted w/o newinstance, isn't it? */
if (stat("/dev/pts", &st)) {
pr_perror("Unable to stat /dev/pts");
return NULL;
}
return &st;
}
/*
* Check whether pagemap reports soft dirty bit. Kernel has
* this functionality under CONFIG_MEM_SOFT_DIRTY option.
......
......@@ -24,6 +24,7 @@
#include "image.h"
#include "namespaces.h"
#include "protobuf.h"
#include "kerndat.h"
#include "protobuf/mnt.pb-c.h"
/*
......@@ -578,6 +579,46 @@ out:
return NULL;
}
/* Is it mounted w or w/o the newinstance option */
static int devpts_dump(struct mount_info *pm)
{
static const char newinstance[] = ",newinstance";
struct stat *host_st;
struct stat st;
DIR *fdir = NULL;
char *buf;
int len;
host_st = kerndat_get_devpts_stat();
if (host_st == NULL)
return -1;
fdir = open_mountpoint(pm);
if (fdir == NULL)
return -1;
if (fstat(dirfd(fdir), &st)) {
pr_perror("Unable to statfs %d:%s",
pm->mnt_id, pm->mountpoint);
close_mountpoint(fdir);
return -1;
}
close_mountpoint(fdir);
if (host_st->st_dev == st.st_dev)
return 0;
len = strlen(pm->options);
buf = xrealloc(pm->options, len + sizeof(newinstance));
if (buf == NULL)
return -1;
memcpy(buf, newinstance, sizeof(newinstance));
pm->options = buf;
return 0;
}
static int tmpfs_dump(struct mount_info *pm)
{
int ret = -1;
......@@ -694,6 +735,7 @@ static struct fstype fstypes[] = {
.restore = tmpfs_restore,
}, {
.name = "devpts",
.dump = devpts_dump,
.code = FSTYPE__DEVPTS,
}, {
.name = "simfs",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment