mcexec: support for /proc mounted by mcoverlayfs

This commit is contained in:
Yoichi Umezawa
2015-12-14 14:47:05 +09:00
parent bb81f84709
commit 20deed09f0
3 changed files with 143 additions and 1 deletions

View File

@ -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

View File

@ -16,5 +16,5 @@ clean:
install:
mkdir -p -m 755 $(BINDIR)
install -m 755 mcexec $(BINDIR)
install -m 4755 mcexec $(BINDIR)

View File

@ -59,6 +59,8 @@
#include <semaphore.h>
#include <signal.h>
#include <sys/signalfd.h>
#include <sys/mount.h>
#include <linux/version.h>
#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