hyperstart中运行的pod的核心数据结构如下所示:

struct hyper_pod {
struct hyper_interface *iface;
struct hyper_route *rt;
struct portmapping_white_list *portmap_white_lists;
char **dns;
struct list_head containers;
struct list_head exec_head;
char *hostname;
char *share_tag;
int init_pid;
uint32_t i_num;
uint32_t r_num;
uint32_t d_num;
/* how many containers are running */
uint32_t remains;
int req_destroy;
int efd;
};

  

1、static int hyper_start_pod(char *json, int length):

  该函数首先调用hyper_parse_pod(pod, json, length),将从runv传入的json数据解析用来填充pod,pod为指向全局变量global_pod的指针。之后,再调用hyper_setup_pod(pod)进行容器创建之前的准备工作,最后调用hyper_start_containers(pod)进行容器的创建和启动的工作。

2、static int hyper_setup_pod(struct hyper_pod *pod):

  该函数首先创建了一个目录"/tmp/hyper/proc",之后再依次调用hyper_setup_network(pod),hyper_setup_dns(pod),hyper_setup_shared(pod),hyper_setup_portmapping(pod),hyper_setup_pod_init(pod)进行pod的初始化工作。其中我们先主要关注hyper_setup_shared和hyper_setup_pod_init的工作。

3、static int hyper_setup_shared(struct hyper_pod *pod):

  该函数的作用就是将容器的镜像挂载到SHARE_DIR(/tmp/hyper/shared)。当hypervisor为QEMU时,该函数的操作简化的来看,就是将宿主机的/var/run/hyper/vm-ID/share_dir目录挂载到SHARE_DIR下。此时,rootfs在SHARE_DIR/container-ID/之下。

4、static int hyper_setup_pod_init(struct hyper_pod *pod):

  该函数的主要作用是调用clone创建一个pod进程,其中的主要逻辑如下:

  int flag = CLONE_NEWPID | CLONE_NEWNS | CLONE_NEWIPC | CLONE_NEWUTS

  struct hyper_pod_arg arg = {.pod = NULL, .ctl_pipe = {-1, -1}, .pod = pod}

  pod->init_pid = clone(hyper_pod_init, stack + stacksize , flags, &arg)

5、static int hyper_pod_init(void *data):

  该函数的工作主要用于为SIGCHLD设置信号处理函数,重新挂载/proc目录,最后重新设置pod的hostname,最后无限等待用于处理SIGCHLD。

hyperstart中container的核心数据结构如下:

struct hyper_container {
struct list_head list;
struct hyper_exec exec;
int ns;
uint32_t code; // configs
char *id;
char *rootfs;
char *image;
char *scsiaddr;
char *fstype;
struct volume *vols;
struct fsmap *maps;
struct sysctl *sys;
struct port *ports;
int vols_num;
int maps_num;
int sys_num;
int ports_num;
int initialize;
};

  

6、static int hyper_start_containers(struct hyper_pod *pod):

  该函数的作用就是根据pod内container的配置信息创建container,并且在其中运行process。主要的内容为遍历pod中的container,执行hyper_setup_container(c, pod)和hyper_run_process(&c->exec)。

7、int hyper_setup_container(struct hyper_container *container, struct hyper_pod *pod):

  该函数首先通过hyper_setup_container_portmapping(container, pod)和hyper_setup_pty(container),为container设置port mapping和pty,之后再调用pid = clone(hyper_setup_container_rootfs, stack + stacksize, flags, &arg) (注:flag = CLONE_NEWNS | SIGCHLD)创建容器进程。最后获取容器的mount namespace fd:

  sprintf(path, "/proc/%s/ns/mnt", pid);

  container->ns = open(path, O_RDONLY | O_CLOEXEC);

8、static int hyper_setup_container_rootfs(void *data):

(1)、该函数首先等待父进程打开容器进程的container->ns,之后调用hyper_enter_sandbox(arg->pod, -1),利用setns进入pod->init_pid的PID,UTS,IPC namespace,之后再fork一个子进程。(对pod->init_pid的操作不应该是在pod的PID namespace之外么?但现在是在pod 的 pid namespace中,并且已经重新挂载了/proc)

(2)、之后,两个mount命令,将根目录的模式设置为MS_PRIVATE和MS_SLAVE。接着设置root目录为"/tmp/hyper/container-id/root/",然后将SHARE_DIR挂载到root目录,此时容器的根文件系统挂载完成。之后,将当前目录切换到容器的根目录

(3)、调用函数container_setup_init_layer(container, setup_dns),对/etc, /etc/resolv.conf,/etc/hosts,/etc/hostname进行重新创建,并且将/proc/mounts重新链接到/etc/mtab。相当于创建了docker中的init-layer。之后再调用container_setup_modules,container_setup_volumes,container_setup_dns进行rootfs的初始化工作

(4)、调用chroot(".")和chdir("/")

(5)、调用container_setup_sysctl(container)和container_setup_workdir(container),根据配置文件队/proc/sys/进行配置,然后进入容器的workdir

hyperstart中exec的核心数据结构如下所示:

struct hyper_exec {

  struct list_head    list;
  struct hyper_pod    *pod;
  struct hyper_event   stdinev;
  struct hyper_event   stdoutev;
  struct hyper_event   stderrev;
  int          pid;
  int          ptyno;   int          init;
  int          ptyfd;
  uint8_t        close_stdin_request;
  uint8_t        code;
  uint8_t        exit;
  uint8_t        ref;
  char         *container_id;
  char         *user;
  char         *group;
  char         **additional_groups;
  int          nr_additional_groups;
  struct env       *envs;
  int          envs_num;
  char         **argv;
  int          argc;
  int          tty;
  uint64_t        seq;
  uint64_t        errseq;
  char          *workdir;
}

  

9、int hyper_run_process(struct hyper_exec *exec)

  ...

  struct stdio_config io = {-1, -1,-1, -1,-1, -1}

  ...

  hyper_setup_stdio(exec, &io)

  pipe2(pipe, O_CLOEXEC)

  pid = fork()

  if (pid == 0) {

    hyper_do_exec_cmd(exec, pipe[1], &io)
  }

  hyper_get_type(pipe[0], &type)

  hyper_setup_stdio_events(exec, &io)  // 和容器建立IO

  exec->pid = type

  list_add_tail(&exec->list, &exec->pod->exec_head)

  exec->ref++

  ....

10、static int hyper_do_exec_cmd(struct hyper_exec *exec, int pipe, struct stdio_config *io)

  hyper_enter_sandbox(exec->pod, pipe) -> enter pidns of pod init

  c = hyper_find_container(exec->pod, exec->container_id)

  setns(c->ns, CLONE_NEWNS)

  chdir("/")

  hyper_setup_env(c->exec.envs, c->exec.envs_num)

  setenv("HOME", "/root", 1)

  setenv("HOSTNAME", exec->pod->hostname, 1)

  if (exec->tty) {

    setenv("TERM", "xterm", 1)
  } else {

    unsetenv("TERM")

  }

  hyper_exec_process(exec, io)

11、static void hyper_exec_process(struct hyper_exec *exec, struct stdio_config *io)

  sigprocmask(SIG_SETMASK, &orig_mask, NULL)

  exec->workdir && chdir(exec->workdir)

  hyper_setup_exec_user(exec)

  hyper_setup_exec_env(exec->envs, exec->envs)

  setsid()

  hyper_install_process_stdio(exec, io)

  execvp(exec->argv[0], exec->argv)

hyperstart 容器创建流程分析的更多相关文章

  1. openstack之虚拟机创建流程分析

    这篇博文静静的呆在草稿箱大半年了.假设不是由于某些原因被问到,以及由于忽略它而导致的损失,否则我也不知道什么时候会将它完毕.感谢这段时间经历的挫折,让我知道不足.希望你能给我更大的决心! 本文试图具体 ...

  2. Spring源码解析02:Spring IOC容器之XmlBeanFactory启动流程分析和源码解析

    一. 前言 Spring容器主要分为两类BeanFactory和ApplicationContext,后者是基于前者的功能扩展,也就是一个基础容器和一个高级容器的区别.本篇就以BeanFactory基 ...

  3. Spring源码解析 | 第二篇:Spring IOC容器之XmlBeanFactory启动流程分析和源码解析

    一. 前言 Spring容器主要分为两类BeanFactory和ApplicationContext,后者是基于前者的功能扩展,也就是一个基础容器和一个高级容器的区别.本篇就以BeanFactory基 ...

  4. 上层应用与wpa_supplicant,wpa_supplicant与kernel 相关socket创建交互分析

    单独拿出来,分析以下上层应用与wpa_supplicant   wpa_supplicant与kernel 的socket交互. 关联上层应用与wpa_supplicant的socket的创建.连接流 ...

  5. Spring IOC 容器源码分析 - 创建原始 bean 对象

    1. 简介 本篇文章是上一篇文章(创建单例 bean 的过程)的延续.在上一篇文章中,我们从战略层面上领略了doCreateBean方法的全过程.本篇文章,我们就从战术的层面上,详细分析doCreat ...

  6. Spring IOC 容器源码分析 - 创建单例 bean 的过程

    1. 简介 在上一篇文章中,我比较详细的分析了获取 bean 的方法,也就是getBean(String)的实现逻辑.对于已实例化好的单例 bean,getBean(String) 方法并不会再一次去 ...

  7. SpringBoot启动流程分析(六):IoC容器依赖注入

    SpringBoot系列文章简介 SpringBoot源码阅读辅助篇: Spring IoC容器与应用上下文的设计与实现 SpringBoot启动流程源码分析: SpringBoot启动流程分析(一) ...

  8. SpringBoot启动流程分析(四):IoC容器的初始化过程

    SpringBoot系列文章简介 SpringBoot源码阅读辅助篇: Spring IoC容器与应用上下文的设计与实现 SpringBoot启动流程源码分析: SpringBoot启动流程分析(一) ...

  9. SpringBoot框架——从SpringBoot看IoC容器初始化流程之方法分析

    目录 一.概观Spring Boot 二.Spring Boot应用初始化 2.1 初始化入口 2.2 SpringApplication的run方法 2.3 方法分析 三.容器创建与初始化 3.1 ...

随机推荐

  1. 开源的javascript实现页面打印功能,兼容所有的浏览器(情况属实)

    这篇文章完全是属于技术文章,也是记录一下自己在项目当中遇到的坑爹问题啊,因为是B/S的程序,所以打印功能还是必须要有的,对于打印我选择了一个js插件,发现非常的简单和方便,所以这里拿出来和大家分享一下 ...

  2. spring的懒加载

    在spring的IOC容器中,可以通过设置<beans default-lazy-init="XXX"></beans>来设置是否为懒加载模式,懒加载的意思 ...

  3. 泛函编程(8)-数据结构-Tree

    上节介绍了泛函数据结构List及相关的泛函编程函数设计使用,还附带了少许多态类型(Polymorphic Type)及变形(Type Variance)的介绍.有关Polymorphism的详细介绍会 ...

  4. Linux服务器时间同步方法

    一般稍微大点的项目都会部署到好几台服务器做集群,同一个应用可能部署到几台服务器上,而处理业务中必须让不同的服务器上时间保持一致,这就需要进行服务器间的时间同步.我的做法是: 1,选择其中一台对外网开放 ...

  5. php学习笔记:文件的上传(包含设置文件的上传大小限制)

    今天写的是文件上传,前几天自学的正规则又忘记了,用了很笨的方法去判断格式,直接上代码: <?php /** * Created by PhpStorm. * User: Administrato ...

  6. Linux chmod命令详解

    Linux chmod命令详解 chmod----改变一个或多个文件的存取模式(mode)   chmod [options] mode files   只能文件属主或特权用户才能使用该功能来改变文件 ...

  7. winform(无边框窗体与timer)

    一.无边框窗体 1.控制按钮如何制作就是放置可以点击的控件,不局限于使用按钮或是什么别的,只要放置的控件可以点击能触发点击事件就可以了 做的好看一点,就是鼠标移入(pictureBox1_MouseE ...

  8. StackOverflow Update: 560M Pageviews A Month, 25 Servers, And It's All About Performance

    http://highscalability.com/blog/2014/7/21/stackoverflow-update-560m-pageviews-a-month-25-servers-and ...

  9. javascript --- 只继承于原型

    正如上次所述,,出于效率考虑,我们应该尽可能的将一些可重用的属性和方法添加到原型中去. 如果养成了这个好习惯,我们仅仅依靠原型就能顺利的完成继承关系的构建了. 毕竟采用new her()方法将her的 ...

  10. SQL注入技术专题—由浅入深【精华聚合贴】

    SQL注入技术专题—由浅入深[精华聚合贴] 不管用什么语言编写的Web应用,它们都用一个共同点,具有交互性并且多数是数据库驱动.在网络中,数据库驱动的Web应用随处可见,由此而存在的SQL注入是影响企 ...