Как OpenVZ загружается ОС?

Я купил VPS для виртуализации OpenVZ и включил гостевую ОС Debian.

гость /boot DIR пуст. /etc/inittab пустой.

Как выполняется процесс инициализации ОС?

Каково значение reboot для контейнера OpenVZ?

2 ответа

Решение

После исследования я клонирую vzctl инструмент как основная работа по запуску / остановке, выполненная здесь:

git clone https://github.com/OpenVZ/vzctl.git
git clone https://github.com/OpenVZ/libvzctl.git

vzctl использования libvzctl где вы можете найти https://github.com/OpenVZ/libvzctl/blob/master/lib/env.c#L783:

int exec_init(struct start_param *param)
{
   char cid[STR_SIZE];
   char *argv[] = {"init", "-z", "      ", NULL};
   char *envp[] = {"HOME=/", "TERM=linux", cid, NULL};
   char **env;
   int errcode = 0;
   logger(1, 0, "Starting init");

   if (stat_file("/sbin/init") == 0 &&
                   stat_file("/ertc/init") == 0  &&
                   stat_file("/bin/init") == 0)
           errcode = VZCTL_E_BAD_TMPL;

   if (write(param->err_p[1], &errcode, sizeof(errcode)) == -1)
           logger(-1, errno, "exec_init: write(param->err_p[1]");

   snprintf(cid, sizeof(cid), "container="SYSTEMD_CTID_FMT, EID(param->h));
   env = makeenv(envp, &param->h->env_param->misc->ve_env);
   if (env == NULL)
           return VZCTL_E_NOMEM;

   execve("/sbin/init", argv, env);
   execve("/etc/init", argv, env);
   execve("/bin/init", argv, env);
   free_ar_str(env);
   free(env);

   return VZCTL_E_BAD_TMPL;
}

Остановитесь, используя https://github.com/OpenVZ/libvzctl/blob/master/lib/env.c#L103:

int real_env_stop(int stop_mode)
{
  logger(10, 0, "* stop mode %d", stop_mode);
  close_fds(1, -1);
  /* Disable fsync. The fsync will be done by umount() */
  configure_sysctl("/proc/sys/fs/fsync-enable", "0");
  switch (stop_mode) {
  case M_HALT: {
          char *argv[] = {"halt", NULL};
          char *argv_init[] = {"init", "0", NULL};
          execvep(argv[0], argv, NULL);
          execvep(argv_init[0], argv_init, NULL);
          break;
  }
  case M_REBOOT: {
          char *argv[] = {"reboot", NULL};
          execvep(argv[0], argv, NULL);
          break;
  }
  case M_KILL:
          return syscall(__NR_reboot, LINUX_REBOOT_MAGIC1,
                  LINUX_REBOOT_MAGIC2,
                  LINUX_REBOOT_CMD_POWER_OFF, NULL);
  }
  return -1;
}

Перед звонком /sbin/initvzctl сделайте несколько проверок (например, система уже запущена или смонтирована, какой-то файл присутствует и т. д.), остановите, если необходимо, смонтируйте fs, сделайте какой-нибудь изолированный аналог chroot и выполните /sbin/init,

ЗАКЛЮЧЕНИЕ OpenVZ не использует grub/linux-image/initrd из гостевой ОС и сделайте прямой звонок первому, который найдет среди:

"/sbin/init"
"/etc/init"
"/bin/init"

в гостевой ОС. Для остановки он использует один из

halt
init 0
reboot

с гостевой ОС. Инициализация контейнера (безопасность, изоляция, монтирование и т. Д.) Не интересна с точки зрения пользователя для процесса загрузки гостевой ОС.

OpenVZ VPS работает, по сути, как свое изолированное дерево процессов в хост-системе. Как таковой, он не имеет собственного загрузчика или ядра и, как правило, не имеет никаких файлов в /boot,

OpenVZ VPS запускаются при запуске хост-системы /bin/init в специальной среде, такой, что она изолирована от хост-системы, и поэтому она считает себя идентификатором PID 1. Я не совсем уверен в деталях, поскольку Parallels не документировала это ни в каких подробностях.

Пустой или отсутствующий /etc/inittab нормально для системы Linux, использующей systemd init, а не SysV init. Текущие версии Debian по умолчанию используют systemd; это поведение не характерно для OpenVZ.

Я не совсем уверен, как работает reboot в OpenVZ VPS работает, но я предполагаю, что ядро ​​хоста должно иметь специальную обработку для reboot() системный вызов внутри контейнера, который заставляет ядро ​​хоста останавливать или перезапускать контейнер, а не всю систему.

Другие вопросы по тегам