diff --git a/arch/x86/tools/mcreboot-smp-x86.sh.in b/arch/x86/tools/mcreboot-smp-x86.sh.in index 4e886dbc..786254e2 100644 --- a/arch/x86/tools/mcreboot-smp-x86.sh.in +++ b/arch/x86/tools/mcreboot-smp-x86.sh.in @@ -22,6 +22,9 @@ mem="512M@0" cpus="" ihk_ikc_irq_core=0 +kernel_release=`uname -r` +enable_mcoverlay=`if [[ ${kernel_release} =~ ^4.* ]]; then echo "yes"; fi` + if [ "$cpus" == "" ]; then # Get the number of CPUs on NUMA node 0 @@ -38,6 +41,16 @@ if [ "`lsmod | grep mcctrl`" != "" ]; then if ! rmmod mcctrl; then echo "error: removing mcctrl"; exit; fi fi +# Remove mcoverlay if loaded +if [ "$enable_mcoverlay" != "" ]; then + if [ "`lsmod | grep mcoverlay`" != "" ]; then + if [ "`cat /proc/mounts | grep /tmp/mcos/mcos0_proc`" != "" ]; then umount -l /tmp/mcos/mcos0_proc; fi + if [ "`cat /proc/mounts | grep /tmp/mcos`" != "" ]; then umount -l /tmp/mcos; fi + if [ -e /tmp/mcos ]; then rm -rf /tmp/mcos; fi + if ! rmmod mcoverlay; then echo "error: removing mcoverlay"; exit; fi + fi +fi + # Load IHK if not loaded if [ "`lsmod | grep ihk`" == "" ]; then if ! insmod ${KMODDIR}/ihk.ko; then echo "error: loading ihk"; exit; fi; @@ -96,3 +109,19 @@ if ! ${SBINDIR}/ihkosctl 0 kargs hidos; then echo "error: setting kernel argumen if ! ${SBINDIR}/ihkosctl 0 boot; then echo "error: booting"; exit; fi if ! insmod ${KMODDIR}/mcctrl.ko; then echo "error: inserting mcctrl.ko"; exit; fi if ! chown `logname` /dev/mcd* /dev/mcos*; then echo "error: chowning device files"; exit; fi + +if [ "$enable_mcoverlay" != "" ]; then + if ! insmod ${KMODDIR}/mcoverlay.ko; then echo "error: inserting mcoverlay.ko"; exit; fi + while [ ! -e /proc/mcos0 ] + do + sleep 1 + done + if [ ! -e /tmp/mcos ]; then mkdir -p /tmp/mcos; fi + if ! mount -t tmpfs tmpfs /tmp/mcos; then echo "error: mount /tmp/mcos"; exit; fi + if [ ! -e /tmp/mcos/mcos0_proc ]; then mkdir -p /tmp/mcos/mcos0_proc; fi + if [ ! -e /tmp/mcos/mcos0_proc_upper ]; then mkdir -p /tmp/mcos/mcos0_proc_upper; fi + if [ ! -e /tmp/mcos/mcos0_proc_work ]; then mkdir -p /tmp/mcos/mcos0_proc_work; fi + if ! mount -t mcoverlay mcoverlay -o lowerdir=/proc/mcos0:/proc,upperdir=/tmp/mcos/mcos0_proc_upper,workdir=/tmp/mcos/mcos0_proc_work,nocopyupw,nofscheck /tmp/mcos/mcos0_proc; then echo "error: mount /tmp/mcos/mcos0_proc"; exit; fi + mount --make-rprivate /proc +fi + diff --git a/executer/user/Makefile.in b/executer/user/Makefile.in index 330f448e..4ba92524 100644 --- a/executer/user/Makefile.in +++ b/executer/user/Makefile.in @@ -16,5 +16,5 @@ clean: install: mkdir -p -m 755 $(BINDIR) - install -m 755 mcexec $(BINDIR) + install -m 4755 mcexec $(BINDIR) diff --git a/executer/user/mcexec.c b/executer/user/mcexec.c index 13b1100d..6fa966e2 100644 --- a/executer/user/mcexec.c +++ b/executer/user/mcexec.c @@ -59,6 +59,8 @@ #include #include #include +#include +#include #include "../include/uprotocol.h" //#define DEBUG @@ -1073,6 +1075,80 @@ void init_worker_threads(int fd) pthread_barrier_wait(&init_ready); } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,0,0) +#define READ_BUFSIZE 1024 +static int isunshare(void) +{ + int err = 0; + int ret; + int fd; + char proc_path[PATH_MAX]; + ssize_t len_read; + char buf_read[READ_BUFSIZE + 1]; + char *buf_read_off; + char *buf_find; + char buf_cmp[READ_BUFSIZE + 1]; + char *buf_cmp_off; + ssize_t len_copy; + + snprintf(proc_path, sizeof(proc_path), "/proc/%d/mounts", getpid()); + fd = open(proc_path, O_RDONLY); + if (fd < 0) { + fprintf(stderr, "Error: Failed to open %s.\n", proc_path); + return -1; + } + + buf_cmp_off = buf_cmp; + while (1) { + len_read = read(fd, buf_read, READ_BUFSIZE); + if (len_read == -1) { + fprintf(stderr, "Error: Failed to read.\n"); + err = -1; + break; + } + + buf_read_off = buf_read; + while (1) { + if ((len_read - (buf_read_off - buf_read)) <= 0) { + break; + } + buf_find = memchr(buf_read_off, '\n', + len_read - (buf_read_off - buf_read)); + if (buf_find) { + len_copy = buf_find - buf_read_off; + } else { + len_copy = len_read - (buf_read_off - buf_read); + } + memcpy(buf_cmp_off, buf_read_off, len_copy); + *(buf_cmp_off + len_copy) = '\0'; + + if (buf_find) { + buf_read_off = buf_read_off + len_copy + 1; + buf_cmp_off = buf_cmp; + ret = strncmp(buf_cmp, "mcoverlay /proc ", 16); + if (!ret) { + err = 1; + break; + } + } else { + buf_read_off = buf_read_off + len_copy; + buf_cmp_off = buf_cmp_off + len_copy; + break; + } + } + + if (err == 1 || len_read == 0) { + break; + } + } + + close(fd); + + __dprintf("err=%d\n", err); + return err; +} +#endif + #define MCK_RLIMIT_AS 0 #define MCK_RLIMIT_CORE 1 #define MCK_RLIMIT_CPU 2 @@ -1217,6 +1293,39 @@ int main(int argc, char **argv) ++optind; } +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,0,0) + __dprintf("mcoverlay enable\n"); + char mcos_procdir[PATH_MAX]; + + error = isunshare(); + if (error == 0) { + if (unshare(CLONE_NEWNS)) { + fprintf(stderr, "Error: Failed to unshare. (%s)\n", + strerror(errno)); + return 1; + } + + sprintf(mcos_procdir, "/tmp/mcos/mcos%d_proc", mcosid); + if (mount(mcos_procdir, "/proc", NULL, MS_BIND, NULL)) { + fprintf(stderr, "Error: Failed to mount. (%s)\n", + strerror(errno)); + return 1; + } + } else if (error == -1) { + return 1; + } +#else + __dprintf("mcoverlay disable\n"); +#endif + + __dprintf("before seteuid(): uid=%d, euid=%d\n", getuid(), geteuid()); + if (seteuid(getuid())) { + fprintf(stderr, "Error: Failed to seteuid. (%s)\n", + strerror(errno)); + return 1; + } + __dprintf("after seteuid(): uid=%d, euid=%d\n", getuid(), geteuid()); + sprintf(dev, "/dev/mcos%d", mcosid); /* No more arguments? */ @@ -1567,6 +1676,9 @@ chgpath(char *in, char *buf) char *fn = in; struct stat sb; +#if LINUX_VERSION_CODE >= KERNEL_VERSION(4,0,0) + if(!strcmp(fn, "/sys/devices/system/cpu/online")){ +#else if (!strncmp(fn, "/proc/self/", 11)){ sprintf(buf, "/proc/mcos%d/%d/%s", mcosid, getpid(), fn + 11); fn = buf; @@ -1576,6 +1688,7 @@ chgpath(char *in, char *buf) fn = buf; } else if(!strcmp(fn, "/sys/devices/system/cpu/online")){ +#endif fn = "/admin/fs/attached/files/sys/devices/system/cpu/online"; } else