Skip to content

Commit

Permalink
feat: busybox image
Browse files Browse the repository at this point in the history
  • Loading branch information
fightinggg committed Jun 1, 2021
1 parent 9e0e3ac commit 1d55e73
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 37 deletions.
115 changes: 81 additions & 34 deletions src/main.cpp
@@ -1,6 +1,14 @@
#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <sched.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/mount.h>
#include <sys/stat.h>
#include <sys/syscall.h>
#include <sys/wait.h>
#include <unistd.h>

Expand All @@ -15,24 +23,31 @@
#include "utils/StringUtils.hpp"

using namespace std;
#define FIBER_STACK 8192
#define FIBER_STACK 81920
String busyBoxDir = "/root/src/busybox";

String getErr() {
char s[100];
sprintf(s, "(%d)%s", errno, strerror(errno));
return String(s);
}

void prepareContainer(RunParam *runParam) {
// create cpu subsystem
char cmd[128];
Vector<String> cmdList = {"cd /sys/fs/cgroup/cpu ", "&& mkdir %s ",
"&& cd %s ", "&& echo %d > cpu.cfs_quota_us ",
"&& echo 50000 > cpu.cfs_period_us "};
sprintf(cmd, StringUtils::join(cmdList).data(),
sprintf(cmd, StringUtils::join(cmdList, " ").data(),
runParam->getContainerId().data(), runParam->getContainerId().data(),
int(runParam->getCpus() * 50000));
system(cmd);

// create memory subsystem
cmdList = {"cd /sys/fs/cgroup/memory ", "&& mkdir %s ",
"&& cd %s ", "&& echo %d > memory.limit_in_bytes ",
"&& echo %d > memory.memsw.limit_in_bytes "};
sprintf(cmd, StringUtils::join(cmdList).data(),
cmdList = {"cd /sys/fs/cgroup/memory ", "&& mkdir %s ", "&& cd %s ",
"&& echo %d > memory.limit_in_bytes ",
"&& echo %d > memory.memsw.limit_in_bytes "};
sprintf(cmd, StringUtils::join(cmdList, " ").data(),
runParam->getContainerId().data(), runParam->getContainerId().data(),
int(runParam->getMemory()), int(runParam->getMemorySwap()));
system(cmd);
Expand All @@ -52,39 +67,58 @@ int doContainer(void *param) {
runParam->getContainerId().data());
system(cmd);

// mount proc system
// mount proc system, then container could not find others process
if (mount("proc", "/proc", "proc", MS_NOEXEC | MS_NOSUID | MS_NODEV, NULL)) {
cerr << "mount proc error" << endl;
exit(-1);
}

if (runParam->getImage() == "centos") {
vector<String> v = runParam->getExec();

switch (v.size()) {
case 0:
cerr << "no params ???" << endl;
exit(-1);
case 1:
execlp(v[0].data(), nullptr);
break;
case 2:
execlp(v[0].data(), v[1].data(), NULL);
break;
case 3:
execlp(v[0].data(), v[1].data(), v[2].data(), NULL);
break;
case 4:
execlp(v[0].data(), v[1].data(), v[2].data(), v[3].data(), NULL);
break;
default:
cerr << "too many params, only four params support" << endl;
exit(-1);
}
cerr << "exec error: " << endl;
// mount busyBox 1. change workdir
if (chdir(busyBoxDir.data())) {
cerr << "chdir to busyBoxDir error" << endl;
exit(-1);
}
// mount busyBox 2. mount busyBox
if (mount(busyBoxDir.data(), busyBoxDir.data(), "bind", MS_BIND | MS_REC,
NULL)) {
cerr << "mount busyBox error" << endl;
exit(-1);
}
String privotRootName = ".pivot_root" + runParam->getContainerId();
String privotRoot = busyBoxDir + "/" + privotRootName;
// mount busyBox 3. mkdir put_old
if (mkdir(privotRoot.data(), S_IRWXU | S_IRWXG | S_IRWXO)) {
cerr << "mkdir privotRoot error" << endl;
exit(-1);
}
// mount busyBox 4. privot_root()
if (syscall(SYS_pivot_root, busyBoxDir.data(), privotRoot.data())) {
cerr << "privot_root error" << endl;
exit(-1);
}
// mount busyBox 5. to dir /
if (chdir("/")) {
cerr << "chdir to / error" << endl;
exit(-1);
}
// mount busyBox 6. unmount .privot_root
if (umount2(("/" + privotRootName).data(), MNT_DETACH)) {
cerr << "unmount .pivot_root error " << getErr() << endl;
exit(-1);
}
// mount busyBox 7. delete dir
if (rmdir(("/" + privotRootName).data())) {
cerr << "rm .pivot_root error " << getErr() << endl;
exit(-1);
}

if (runParam->getImage() == "busybox") {
vector<String> v = runParam->getExec();
cout << "container begin: " << StringUtils::join(v, " ") << endl;
return system(StringUtils::join(v, " ").data());
} else {
cerr << "could not find image '" << runParam->getImage() << "'" << endl;
cerr << "could not find image '" << runParam->getImage()
<< "', you can use image 'busybox'" << endl;
exit(-1);
}
}
Expand All @@ -100,6 +134,19 @@ int main(int argc, char *argv[]) {
prepareContainer((RunParam *)param);
int pid = clone(doContainer, (char *)stack + FIBER_STACK, containerFlag,
param); //创建子线程
waitpid(pid, NULL, 0);
cout << "container exit, thanks for using pocker " << endl;
int sonStatus;
if (waitpid(pid, &sonStatus, 0) != pid) {
cerr << "container error " << getErr() << endl;
exit(-1);
}
if (WIFEXITED(sonStatus)) {
printf("container exited, status=%d\n", WEXITSTATUS(sonStatus));
} else if (WIFSIGNALED(sonStatus)) {
printf("container killed by signal %d\n", WTERMSIG(sonStatus));
} else if (WIFSTOPPED(sonStatus)) {
printf("container stopped by signal %d\n", WSTOPSIG(sonStatus));
} else if (WIFCONTINUED(sonStatus)) {
printf("container continued\n");
}
cout << " thanks for using pocker" << endl;
}
7 changes: 4 additions & 3 deletions src/utils/StringUtils.hpp
Expand Up @@ -3,10 +3,11 @@

class StringUtils {
public:
static String join(const Vector<String>&strings) {
static String join(const Vector<String>& strings, String split) {
String res;
for (String s : strings) {
res += s;
for (int i = 0; i < strings.size(); i++) {
res += strings[i];
if (i != 0) res += split;
}
return res;
}
Expand Down

0 comments on commit 1d55e73

Please sign in to comment.