Logo Search packages:      
Sourcecode: schroot version File versions  Download package

void session::setup_chroot ( chroot::ptr session_chroot,
chroot::setup_type  setup_type 
) [private]

Setup a chroot. This runs all of the commands in setup.d or run.d.

The environment variables CHROOT_NAME, CHROOT_DESCRIPTION, CHROOT_LOCATION, AUTH_USER and AUTH_VERBOSITY are set for use in setup scripts. See schroot-setup(5) for a complete list.

An error will be thrown on failure.

Parameters:
session_chroot the chroot to setup. This must be present in the chroot list and the chroot configuration object.
setup_type the type of setup to perform.

Definition at line 440 of file sbuild-session.cc.

References sbuild::environment::add(), chroot_status, exec(), sbuild::chroot::EXEC_START, sbuild::chroot::EXEC_STOP, sbuild::auth::get_user(), sbuild::auth::get_verbosity(), OPERATION_AUTOMATIC, OPERATION_BEGIN, OPERATION_END, OPERATION_RECOVER, OPERATION_RUN, session_id, session_operation, sbuild::chroot::SETUP_RECOVER, sbuild::chroot::SETUP_START, sbuild::chroot::SETUP_STOP, sbuild::auth::VERBOSITY_NORMAL, sbuild::auth::VERBOSITY_QUIET, sbuild::auth::VERBOSITY_VERBOSE, and wait_for_child().

Referenced by run_impl().

{
  assert(!session_chroot->get_name().empty());

  if (!((this->session_operation == OPERATION_BEGIN &&
       setup_type == chroot::SETUP_START) ||
      (this->session_operation == OPERATION_RECOVER &&
       setup_type == chroot::SETUP_RECOVER) ||
      (this->session_operation == OPERATION_END &&
       setup_type == chroot::SETUP_STOP) ||
      (this->session_operation == OPERATION_RUN &&
       (setup_type == chroot::EXEC_START ||
        setup_type == chroot::EXEC_STOP)) ||
      (this->session_operation == OPERATION_AUTOMATIC &&
       (setup_type == chroot::SETUP_START ||
        setup_type == chroot::SETUP_STOP  ||
        setup_type == chroot::EXEC_START   ||
        setup_type == chroot::EXEC_STOP))))
    return;

  if (((setup_type == chroot::SETUP_START   ||
      setup_type == chroot::SETUP_RECOVER ||
      setup_type == chroot::SETUP_STOP) &&
       session_chroot->get_run_setup_scripts() == false) ||
      ((setup_type == chroot::EXEC_START ||
      setup_type == chroot::EXEC_STOP) &&
       session_chroot->get_run_exec_scripts() == false))
    return;

  if (setup_type == chroot::SETUP_START)
    this->chroot_status = true;

  try
    {
      session_chroot->setup_lock(setup_type, true);
    }
  catch (chroot::error const& e)
    {
      this->chroot_status = false;
      try
      {
        // Release lock, which also removes session metadata.
        session_chroot->setup_lock(setup_type, false);
      }
      catch (chroot::error const& ignore)
      {
      }
      format fmt(_("Chroot setup failed to lock chroot: %1%"));
      fmt % e.what();
      throw error(fmt);
    }

  std::string setup_type_string;
  if (setup_type == chroot::SETUP_START)
    setup_type_string = "setup-start";
  else if (setup_type == chroot::SETUP_RECOVER)
    setup_type_string = "setup-recover";
  else if (setup_type == chroot::SETUP_STOP)
    setup_type_string = "setup-stop";
  else if (setup_type == chroot::EXEC_START)
    setup_type_string = "exec-start";
  else if (setup_type == chroot::EXEC_STOP)
    setup_type_string = "exec-stop";

  std::string chroot_status_string;
  if (this->chroot_status)
    chroot_status_string = "ok";
  else
    chroot_status_string = "fail";

  string_list arg_list;
  arg_list.push_back(RUN_PARTS); // Run run-parts(8)
  if (get_verbosity() == auth::VERBOSITY_VERBOSE)
    arg_list.push_back("--verbose");
  arg_list.push_back("--lsbsysinit");
  arg_list.push_back("--exit-on-error");
  if (setup_type == chroot::SETUP_STOP ||
      setup_type == chroot::EXEC_STOP)
    arg_list.push_back("--reverse");
  format arg_fmt1("--arg=%1%");
  arg_fmt1 % setup_type_string;
  arg_list.push_back(arg_fmt1.str());
  format arg_fmt2("--arg=%1%");
  arg_fmt2 % chroot_status_string;
  arg_list.push_back(arg_fmt2.str());
  if (setup_type == chroot::SETUP_START ||
      setup_type == chroot::SETUP_RECOVER ||
      setup_type == chroot::SETUP_STOP)
    arg_list.push_back(SCHROOT_CONF_SETUP_D); // Setup directory
  else
    arg_list.push_back(SCHROOT_CONF_EXEC_D); // Run directory

  /* Get a complete list of environment variables to set.  We need to
     query the chroot here, since this can vary depending upon the
     chroot type. */
  environment env;
  session_chroot->setup_env(env);
  env.add("AUTH_USER", get_user());
  {
    const char *verbosity = NULL;
    switch (get_verbosity())
      {
      case auth::VERBOSITY_QUIET:
      verbosity = "quiet";
      break;
      case auth::VERBOSITY_NORMAL:
      verbosity = "normal";
      break;
      case auth::VERBOSITY_VERBOSE:
      verbosity = "verbose";
      break;
      default:
      log_debug(DEBUG_CRITICAL) << format(_("Invalid verbosity level: %1%, falling back to \"normal\""))
        % static_cast<int>(get_verbosity())
                 << endl;
      verbosity = "normal";
      break;
      }
    env.add("AUTH_VERBOSITY", verbosity);
  }

  env.add("MOUNT_DIR", SCHROOT_MOUNT_DIR);
  env.add("LIBEXEC_DIR", SCHROOT_LIBEXEC_DIR);
  env.add("PID", getpid());
  env.add("SESSION_ID", this->session_id);

  int exit_status = 0;
  pid_t pid;

  if ((pid = fork()) == -1)
    {
      this->chroot_status = false;
      format fmt(_("Failed to fork child: %1%"));
      fmt % strerror(errno);
      throw error(fmt);
    }
  else if (pid == 0)
    {
      // The setup scripts don't use our syslog fd.
      closelog();

      chdir("/");
      /* This is required to ensure the scripts run with uid=0 and gid=0,
       otherwise setuid programs such as mount(8) will fail.  This
       should always succeed, because our euid=0 and egid=0.*/
      setuid(0);
      setgid(0);
      initgroups("root", 0);
      if (exec (arg_list[0], arg_list, env))
      {
        log_error() << format(_("Could not exec \"%1%\": %2%"))
          % arg_list[0] % strerror(errno)
                  << endl;
        exit (EXIT_FAILURE);
      }
      exit (EXIT_FAILURE); /* Should never be reached. */
    }
  else
    {
      wait_for_child(pid, exit_status);
    }

  try
    {
      session_chroot->setup_lock(setup_type, false);
    }
  catch (chroot::error const& e)
    {
      this->chroot_status = false;
      format fmt(_("Chroot setup failed to unlock chroot: %1%"));
      fmt % e.what();
      throw error(fmt);
    }

  if (exit_status != 0)
    {
      this->chroot_status = false;
      format fmt(_("Chroot setup failed during chroot \"%1%\" stage"));
      fmt % setup_type_string;
      throw error(fmt);
    }
}


Generated by  Doxygen 1.6.0   Back to index