Roger Leigh <[EMAIL PROTECTED]> writes:

> dchroot has support for switching between PER_LINUX and PER_LINUX32
> personalities.  schroot should also provide this support (it's
> currently provided via the command-prefix option, but more explicit
> support would be useful).

I looked at Jeff Bailey's patch for dchroot, and the attached patch
introduces preliminary support for different process execution
domains.  You can then set the personality in the config file:

personality=linux
personality=linux32
personality=svr4
personality=xenix

etc.

It defaults to "linux" on Linux, and "undefined" on non-Linux kernels.

I don't have an amd64 system for testing, however.  Could anyone with
a suitable biarch system possibly give it a try?  (If you run dchroot,
run 'dchroot --config > schroot.conf' to dump a new schroot.conf.)


It now shows the personality (with a deliberate error):

$ schroot/schroot -i -c stable
W: sid-block chroot: personality "linux31" is unknown.
I: Valid personalities: bsd, hpux, irix32, irix64, irixn32, iscr4, linux, 
linux32, linux_32bit, osf4, osr5, riscos, scorvr3, solaris, sunos, svr4, 
undefined, uw7, wysev386, xenix
  --- Chroot ---
  Name                  sarge
  Description           Debian sarge (stable)
  Type                  plain
  Priority              2
  Groups                sbuild
  Root Groups           root sbuild
  Aliases               stable
  Run Setup Scripts     true
  Run Execution Scripts true
  Session Managed       true
  Personality           linux
  Location              /srv/chroot/sarge


Regards,
Roger

-- 
Roger Leigh
                Printing on GNU/Linux?  http://gutenprint.sourceforge.net/
                Debian GNU/Linux        http://www.debian.org/
                GPG Public Key: 0x25BFB848.  Please sign and encrypt your mail.
Index: schroot/sbuild-session.cc
===================================================================
--- schroot/sbuild-session.cc	(revision 708)
+++ schroot/sbuild-session.cc	(working copy)
@@ -30,6 +30,10 @@
 #include <string.h>
 #include <unistd.h>
 
+#ifdef __linux__
+#include <sys/personality.h>
+#endif
+
 #include <syslog.h>
 
 #include <boost/format.hpp>
@@ -668,6 +672,17 @@
       exit (EXIT_FAILURE);
     }
 
+#ifdef __linux__
+  /* Set the process execution domain. */
+  if (personality (session_chroot->get_persona()) < 0)
+    {
+      log_error() << format(_("Could not set personality to '%1%': %2%"))
+	% session_chroot->get_persona() % strerror(errno)
+		  << endl;
+      exit (EXIT_FAILURE);
+    }
+#endif
+
   /* Enter the chroot */
   if (chdir (location.c_str()))
     {
Index: schroot/sbuild-chroot.cc
===================================================================
--- schroot/sbuild-chroot.cc	(revision 708)
+++ schroot/sbuild-chroot.cc	(working copy)
@@ -23,13 +23,124 @@
 
 #include <algorithm>
 #include <cerrno>
+#include <map>
+#include <set>
+#include <utility>
 #include <ext/stdio_filebuf.h>
 
+#ifdef __linux__
+#include <sys/personality.h>
+#endif
+
 #include <boost/format.hpp>
 
 using boost::format;
 using namespace sbuild;
 
+namespace
+{
+  std::map<int,std::string> personalities;
+
+  void
+  setup_personalities () __attribute__ ((constructor));
+
+  void
+  setup_personalities ()
+  {
+    personalities.insert(std::pair<int,std::string>(-1, "undefined"));
+#ifdef __linux__
+    personalities.insert(std::pair<int,std::string>(PER_LINUX, "linux"));
+    personalities.insert(std::pair<int,std::string>(PER_LINUX_32BIT, "linux_32bit"));
+    personalities.insert(std::pair<int,std::string>(PER_SVR4, "svr4"));
+    personalities.insert(std::pair<int,std::string>(PER_SCOSVR3, "scorvr3"));
+    personalities.insert(std::pair<int,std::string>(PER_OSR5, "osr5"));
+    personalities.insert(std::pair<int,std::string>(PER_WYSEV386, "wysev386"));
+    personalities.insert(std::pair<int,std::string>(PER_ISCR4, "iscr4"));
+    personalities.insert(std::pair<int,std::string>(PER_BSD, "bsd"));
+    personalities.insert(std::pair<int,std::string>(PER_SUNOS, "sunos"));
+    personalities.insert(std::pair<int,std::string>(PER_XENIX, "xenix"));
+    personalities.insert(std::pair<int,std::string>(PER_LINUX32, "linux32"));
+    personalities.insert(std::pair<int,std::string>(PER_IRIX32, "irix32"));
+    personalities.insert(std::pair<int,std::string>(PER_IRIXN32, "irixn32"));
+    personalities.insert(std::pair<int,std::string>(PER_IRIX64, "irix64"));
+    personalities.insert(std::pair<int,std::string>(PER_RISCOS, "riscos"));
+    personalities.insert(std::pair<int,std::string>(PER_SOLARIS, "solaris"));
+    personalities.insert(std::pair<int,std::string>(PER_UW7, "uw7"));
+    personalities.insert(std::pair<int,std::string>(PER_HPUX, "hpux"));
+    personalities.insert(std::pair<int,std::string>(PER_OSF4, "osf4"));
+    personalities.insert(std::pair<int,std::string>(PER_OSF4, "osf4"));
+#endif
+  }
+
+  /**
+   * Find a personality by name.
+   *
+   * @param persona the personality to find.
+   * @returns the personality number, -1 if the personality was
+   * undefined, or -2 if the personality was unknown (not found).
+   */
+  int
+  find_personality (std::string const& persona)
+  {
+    for (std::map<int,std::string>::const_iterator pos = personalities.begin();
+	 pos != personalities.end();
+	 ++pos)
+      if (pos->second == persona)
+	return pos->first;
+
+    return -2;
+  }
+
+  /**
+   * Find a personality by number.
+   *
+   * @param persona the personality to find.
+   * @returns the personality name, "undefined" if the personality was
+   * not defined, or ""unknown" if the personality was not found.
+   */
+  std::string const&
+  find_personality (int persona)
+  {
+    static const std::string undefined("undefined");
+    static const std::string unknown("unknown");
+
+    std::map<int,std::string>::const_iterator pos =
+      personalities.find(persona);
+
+    if (pos != personalities.end())
+      return pos->second;
+
+    return unknown;
+  }
+
+  /**
+   * Print a list of the available personalities.
+   *
+   * @param stream the stream to output to.
+   */
+  void
+  print_personalities (std::ostream& stream)
+  {
+    std::set<std::string> sorted_names;
+
+    for (std::map<int,std::string>::const_iterator pos = personalities.begin();
+	 pos != personalities.end();
+	 ++pos)
+      sorted_names.insert(pos->second);
+
+    for (std::set<std::string>::const_iterator spos = sorted_names.begin();
+	 spos != sorted_names.end();
+	 ++spos)
+      {
+	stream << *spos;
+	std::set<std::string>::const_iterator stpos = spos;
+	if (++stpos != sorted_names.end())
+	  stream << ", ";
+      }
+  }
+
+}
+
 sbuild::chroot::chroot ():
   name(),
   description(),
@@ -43,7 +154,12 @@
   active(false),
   run_setup_scripts(false),
   run_exec_scripts(false),
-  command_prefix()
+  command_prefix(),
+#ifdef __linux__
+  persona(find_personality("linux"))
+#else
+  persona(find_personality("undefined"))
+#endif
 {
 }
 
@@ -239,7 +355,19 @@
   this->command_prefix = command_prefix;
 }
 
+int
+sbuild::chroot::get_persona () const
+{
+  return this->persona;
+}
+
 void
+sbuild::chroot::set_persona (int persona)
+{
+  this->persona = persona;
+}
+
+void
 sbuild::chroot::setup_env (environment& env)
 {
   env.add("CHROOT_TYPE", get_chroot_type());
@@ -352,6 +480,8 @@
   if (!get_command_prefix().empty())
     stream << format_details(_("Command Prefix"), get_command_prefix());
 
+  stream << format_details(_("Personality"), find_personality(get_persona()));
+
   /* Non user-settable properties are listed last. */
   if (!get_location().empty())
     stream << format_details(_("Location"),
@@ -412,6 +542,9 @@
   string_list const& command_prefix = get_command_prefix();
   keyfile.set_list_value(this->name, "command-prefix",
 			 command_prefix.begin(), command_prefix.end());
+
+  keyfile.set_value(this->name, "personality",
+		    find_personality(get_persona()));
 }
 
 void
@@ -484,6 +617,27 @@
 			     keyfile::PRIORITY_OPTIONAL,
 			     command_prefix))
     set_command_prefix(command_prefix);
+
+  std::string persona;
+  if (keyfile.get_value(this->name, "personality",
+			keyfile::PRIORITY_OPTIONAL,
+			persona))
+    {
+      int persona_id = find_personality(persona);
+      if (persona_id < -1)
+	{
+	  std::ostringstream plist;
+	  print_personalities(plist);
+
+	  log_warning()
+	    << format(_("%1% chroot: personality \"%2%\" is unknown.\n"))
+	    % this->name % persona;
+	  log_info()
+	    << format(_("Valid personalities: %1%\n")) % plist.str();
+	}
+
+      set_persona(persona_id);
+    }
 }
 
 /*
Index: schroot/sbuild-chroot.h
===================================================================
--- schroot/sbuild-chroot.h	(revision 708)
+++ schroot/sbuild-chroot.h	(working copy)
@@ -342,6 +342,22 @@
     set_command_prefix (string_list const& command_prefix);
 
     /**
+     * Get the process execution domain for the chroot.
+     *
+     * @returns the command prefix.
+     */
+    int
+    get_persona () const;
+
+    /**
+     * Set the process execution domain for the chroot.
+     *
+     * @param persona the command prefix.
+     */
+    void
+    set_persona (int persona);
+
+    /**
      * Get the type of the chroot.
      *
      * @returns the chroot type.
@@ -527,6 +543,8 @@
     bool          run_exec_scripts;
     /// Command prefix.
     string_list   command_prefix;
+    /// Process execution domain (Linux only).
+    int           persona;
   };
 
 }

Attachment: pgpy6Qm0QbXf4.pgp
Description: PGP signature

Reply via email to