With regard to the /dev/pts issue on "vserver <name> enter" i have ported the
vlogin application from vserver-utils to util-vserver-0.30.210
See also http://list.linux-vserver.org/archive/vserver/msg12117.html
Bene
diff -NurpP util-vserver-0.30.210/scripts/Makefile-files util-vserver-0.30.210-vlogin/scripts/Makefile-files
--- util-vserver-0.30.210/scripts/Makefile-files 2005-04-28 19:45:34.000000000 +0200
+++ util-vserver-0.30.210-vlogin/scripts/Makefile-files 2006-03-04 09:48:30.000000000 +0100
@@ -52,7 +52,8 @@ scripts_pkglib_src_DTA = scripts/functio
scripts/vserver.functions \
scripts/vserver.start \
scripts/vserver.stop \
- scripts/vserver.suexec
+ scripts/vserver.suexec \
+ scripts/vserver.login
scripts_pkglib_gen_DTA = scripts/util-vserver-vars
diff -NurpP util-vserver-0.30.210/scripts/util-vserver-vars.pathsubst util-vserver-0.30.210-vlogin/scripts/util-vserver-vars.pathsubst
--- util-vserver-0.30.210/scripts/util-vserver-vars.pathsubst 2006-01-22 13:24:25.000000000 +0100
+++ util-vserver-0.30.210-vlogin/scripts/util-vserver-vars.pathsubst 2006-03-04 09:55:46.000000000 +0100
@@ -72,6 +72,7 @@ _VDU="$__SBINDIR/vdu"
_VHASHIFY="$__PKGLIBDIR/vhashify"
_VKILL="$__SBINDIR/vkill"
_VLIMIT="$__SBINDIR/vlimit"
+_VLOGIN="$__SBINDIR/vlogin"
_VNAMESPACE="$__SBINDIR/vnamespace"
_VPKG="$__PKGLIBDIR/vpkg"
_VPROCUNHIDE="$__PKGLIBDIR/vprocunhide"
diff -NurpP util-vserver-0.30.210/scripts/vserver util-vserver-0.30.210-vlogin/scripts/vserver
--- util-vserver-0.30.210/scripts/vserver 2005-10-28 20:29:00.000000000 +0200
+++ util-vserver-0.30.210-vlogin/scripts/vserver 2006-03-04 09:47:52.000000000 +0100
@@ -101,6 +101,11 @@ function suexec()
. $__PKGLIBDIR/vserver.suexec
}
+function vlogin()
+{
+ . $__PKGLIBDIR/vserver.login
+}
+
function restart()
{
"[EMAIL PROTECTED]" --sync "$vserver" stop
@@ -220,7 +225,7 @@ case "$2" in
;;
(enter)
getEnterShell "$VSERVER_DIR"
- suexec root "[EMAIL PROTECTED]"
+ vlogin "[EMAIL PROTECTED]"
;;
(running)
isVserverRunning "$VSERVER_DIR"
diff -NurpP util-vserver-0.30.210/scripts/vserver.login util-vserver-0.30.210-vlogin/scripts/vserver.login
--- util-vserver-0.30.210/scripts/vserver.login 1970-01-01 01:00:00.000000000 +0100
+++ util-vserver-0.30.210-vlogin/scripts/vserver.login 2006-03-04 09:46:19.000000000 +0100
@@ -0,0 +1,32 @@
+# $Id: vserver.suexec,v 1.14 2005/07/15 19:01:06 ensc Exp $ --*- sh -*--
+
+# Copyright (C) 2003 Enrico Scholz <[EMAIL PROTECTED]>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; version 2 of the License.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+
+is_stopped=
+isVserverRunning "$VSERVER_DIR" S_CONTEXT || is_stopped=1
+test -z "$is_stopped" || {
+ echo $"'vserver ... suexec' is supported for running vservers only; aborting..." >&2
+ exit 1
+}
+
+generateOptions "$VSERVER_DIR"
+
+pushd "$VSERVER_DIR"/vdir/ >/dev/null
+
+${USE_VNAMESPACE:+$_VNAMESPACE --enter "$S_CONTEXT" -- } \
+${_VLOGIN} -n ${S_CONTEXT} -x ${S_CONTEXT} -- "$@"
+
+popd >/dev/null
diff -NurpP util-vserver-0.30.210/src/Makefile-files util-vserver-0.30.210-vlogin/src/Makefile-files
--- util-vserver-0.30.210/src/Makefile-files 2006-01-22 12:28:00.000000000 +0100
+++ util-vserver-0.30.210-vlogin/src/Makefile-files 2006-03-04 09:34:00.000000000 +0100
@@ -67,6 +67,7 @@ DIETPROGS += src/chcontext-compat \
src/vcontext \
src/vcopy \
src/vkill \
+ src/vlogin \
src/vsched \
src/vshelper-sync \
src/vrsetup \
@@ -141,6 +142,7 @@ sbin_PROGRAMS += src/chbind \
src/vcontext \
src/vlimit \
src/vkill \
+ src/vlogin \
src/vnamespace \
src/vrsetup \
src/vsched \
@@ -201,6 +203,10 @@ src_vkill_LDADD = $(VSERVER_LDADDS)
src_vkill_LDFLAGS = $(VSERVER_LDFLGS)
src_vkill_CPPFLAGS = $(AM_CPPFLAGS) -DLEGACYDIR=\"$(legacydir)\"
+src_vlogin_SOURCES = src/vlogin.c
+src_vlogin_LDADD = $(VSERVER_LDADDS)
+src_vlogin_LDFLAGS = $(VSERVER_LDFLGS)
+
src_vlimit_SOURCES = src/vlimit.c
src_vlimit_LDADD = $(VSERVER_LDADDS)
src_vlimit_LDFLAGS = $(VSERVER_LDFLGS)
diff -NurpP util-vserver-0.30.210/src/vlogin.c util-vserver-0.30.210-vlogin/src/vlogin.c
--- util-vserver-0.30.210/src/vlogin.c 1970-01-01 01:00:00.000000000 +0100
+++ util-vserver-0.30.210-vlogin/src/vlogin.c 2006-03-04 09:56:27.000000000 +0100
@@ -0,0 +1,450 @@
+/***************************************************************************
+ * Copyright 2005 by the vserver-utils team *
+ * See AUTHORS for details *
+ * *
+ * This program is free software; you can redistribute it and/or modify *
+ * it under the terms of the GNU General Public License as published by *
+ * the Free Software Foundation; either version 2 of the License, or *
+ * (at your option) any later version. *
+ * *
+ * This program is distributed in the hope that it will be useful, *
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of *
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
+ * GNU General Public License for more details. *
+ * *
+ * You should have received a copy of the GNU General Public License *
+ * along with this program; if not, write to the *
+ * Free Software Foundation, Inc., *
+ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <getopt.h>
+#include <unistd.h>
+#include <string.h>
+#include <termios.h>
+#include <signal.h>
+#include <sys/wait.h>
+#include <sys/ioctl.h>
+#include <errno.h>
+#include <pty.h>
+
+#include "vserver.h"
+
+#define GLOBAL_CMDS "hV"
+
+#define GLOBAL_CMDS_GETOPT \
+case 'h': \
+ cmd_help(); \
+ break; \
+\
+case 'V': \
+ CMD_VERSION(NAME, DESCR); \
+ break; \
+
+#define DEFAULT_GETOPT \
+default: \
+ printf("Try '%s -h' for more information\n", argv[0]); \
+ exit(EXIT_USAGE); \
+ break; \
+
+
+#define CMD_VERSION(name, desc) do { \
+ printf("%s -- %s\n", name, desc); \
+ printf("This program is part of %s\n\n", PACKAGE_STRING); \
+ printf("Copyright (c) 2005 The vserver-utils Team\n"); \
+ printf("This program is free software; you can redistribute it and/or\n"); \
+ printf("modify it under the terms of the GNU General Public License\n"); \
+ exit(0); \
+} while(0)
+
+/* exit, silent exit, perror exit
+ *
+ * exit code conventions:
+ *
+ * 0 = OK
+ * 1 = Wrong usage
+ * 2 = A command failed
+ * 3 = An opts specific function failed
+ */
+#define EXIT_USAGE 1
+#define EXIT_COMMAND 2
+#define EXIT_OPTS 3
+
+#define EXIT(MSG,RC) { \
+ printf(MSG"; try '%s -h' for more information\n", argv[0]); \
+ exit(RC); \
+}
+
+#define SEXIT(MSG,RC) { \
+ printf(MSG"\n"); \
+ exit(RC); \
+}
+
+#define PEXIT(MSG,RC) { \
+ perror(MSG); \
+ exit(RC); \
+}
+
+#define NAME "vlogin"
+#define DESCR "Context Login"
+
+#define SHORT_OPTS "n:x:"
+
+struct options {
+ nid_t nid;
+ xid_t xid;
+};
+
+#define TS_RESET 0
+#define TS_RAW 1
+
+struct terminal {
+ int fd; /* terminal file descriptor */
+ struct termios term; /* terminal settings */
+ struct winsize ws; /* terminal size */
+ pid_t pid; /* terminal process id */
+ struct termios termo; /* original terminal settings */
+ int state; /* terminal state */
+};
+
+static struct terminal t;
+
+static inline
+void cmd_help()
+{
+ printf("Usage: %s <opts>* [-- <shell> <args>*]\n"
+ "\n"
+ "Available options:\n"
+ " -n <xid> Network Context ID\n"
+ " -x <xid> Context ID\n"
+ "\n",
+ NAME);
+ exit(EXIT_SUCCESS);
+}
+
+/* set terminal to raw mode */
+static
+int terminal_raw(void)
+{
+ struct termios buf;
+
+ /* save original terminal settings */
+ if (tcgetattr(STDIN_FILENO, &t.termo) == -1)
+ return -1;
+
+ buf = t.termo;
+
+ /* echo off
+ ** canonical mode off
+ ** extended input processing off
+ ** signal chars off */
+ buf.c_lflag &= ~(ECHO | ICANON | IEXTEN | ISIG);
+
+ /* no SIGINT on BREAK
+ ** CR-to-NL off
+ ** input parity check off
+ ** don't strip 8th bit on input
+ ** output flow control off */
+ buf.c_iflag &= ~(BRKINT | ICRNL | INPCK | ISTRIP | IXON);
+
+ /* clear size bits
+ ** parity checking off */
+ buf.c_cflag &= ~(CSIZE | PARENB);
+
+ /* set 8 bits/char */
+ buf.c_cflag |= CS8;
+
+ /* output processing off */
+ buf.c_oflag &= ~(OPOST);
+
+ /* 1 byte at a time
+ ** no timer */
+ buf.c_cc[VMIN] = 1;
+ buf.c_cc[VTIME] = 0;
+
+ if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &buf) == -1)
+ return -1;
+
+ t.state = TS_RAW;
+
+ return 0;
+}
+
+/* reset terminal to original state */
+static
+int terminal_reset(void)
+{
+ if (t.state != TS_RAW)
+ return 0;
+
+ if (tcsetattr(STDIN_FILENO, TCSAFLUSH, &t.termo) == -1)
+ return -1;
+
+ t.state = TS_RESET;
+
+ return 0;
+}
+
+/* exit handler */
+static
+void terminal_atexit(void)
+{
+ terminal_reset();
+ printf("\n"); /* for cosmetic reasons */
+}
+
+/* send signal to terminal */
+static
+void terminal_kill(int sig)
+{
+ pid_t pgrp = -1;
+
+ /* try to get process group leader */
+ if (ioctl(t.fd, TIOCGPGRP, &pgrp) >= 0 &&
+ pgrp != -1 &&
+ kill(-pgrp, sig) != -1)
+ return;
+
+ /* fallback using terminal pid */
+ kill(-t.pid, sig);
+}
+
+/* redraw the terminal screen */
+static
+void terminal_redraw(void)
+{
+ /* get winsize from stdin */
+ ioctl(0, TIOCGWINSZ, &t.ws);
+
+ /* set winsize in terminal */
+ ioctl(t.fd, TIOCSWINSZ, &t.ws);
+
+ /* set winsize change signal to terminal */
+ terminal_kill(SIGWINCH);
+}
+
+/* copy terminal activity to user */
+static
+void terminal_activity(void)
+{
+ char buf[64];
+ int len;
+
+ /* read terminal activity */
+ len = read(t.fd, buf, sizeof(buf));
+
+ /* terminal died or strange things happened */
+ if (len == -1)
+ PEXIT("Failed to read from terminal", EXIT_COMMAND);
+
+ /* get the current terminal settings */
+ if (tcgetattr(t.fd, &t.term) == -1)
+ PEXIT("Failed to get terminal attributes", EXIT_COMMAND);
+
+ /* set the current terminal settings */
+ if (tcsetattr(STDIN_FILENO, TCSANOW, &t.term) == -1)
+ PEXIT("Failed to set terminal attributes", EXIT_COMMAND);
+
+ /* write activity to user */
+ if (write(STDOUT_FILENO, buf, len) == -1)
+ PEXIT("Failed to write to stdout", EXIT_COMMAND);
+}
+
+/* copy user activity to terminal */
+static
+void user_activity(void)
+{
+ char buf[64];
+ int len;
+
+ /* read user activity */
+ len = read(STDIN_FILENO, buf, sizeof(buf));
+
+ /* the user process died or strange thins happened */
+ if (len == -1)
+ PEXIT("Failed to read from stdin", EXIT_COMMAND);
+
+ /* write activity to terminal */
+ if (write(t.fd, buf, len) == -1)
+ PEXIT("Failed to write to terminal", EXIT_COMMAND);
+}
+
+/* catch signals */
+static
+void signal_handler(int sig)
+{
+ int status;
+
+ switch(sig) {
+ /* catch interrupt */
+ case SIGINT:
+ terminal_kill(sig);
+ break;
+
+ /* terminal died */
+ case SIGCHLD:
+ wait(&status);
+ exit(status);
+ break;
+
+ /* window size has changed */
+ case SIGWINCH:
+ signal(SIGWINCH, signal_handler);
+ terminal_redraw();
+ break;
+
+ default:
+ exit(0);
+ }
+
+}
+
+int main(int argc, char *argv[])
+{
+ /* init program data */
+ struct options opts = {
+ .nid = 0,
+ .xid = 0,
+ };
+
+ int c;
+
+ /* parse command line */
+ while (1) {
+ c = getopt(argc, argv, GLOBAL_CMDS SHORT_OPTS);
+ if (c == -1) break;
+
+ switch (c) {
+ GLOBAL_CMDS_GETOPT
+
+ case 'n':
+ opts.nid = (nid_t) atoi(optarg);
+ break;
+
+ case 'x':
+ opts.xid = (xid_t) atoi(optarg);
+ break;
+
+ DEFAULT_GETOPT
+ }
+ }
+
+ if (opts.xid == 0)
+ EXIT("Invalid xid", EXIT_USAGE);
+
+ /* enter context */
+ if (opts.nid > 1 && vc_net_migrate(opts.nid) == -1)
+ PEXIT("Failed to migrate to network context", EXIT_COMMAND);
+
+ if (vc_ctx_migrate(opts.xid) == -1)
+ PEXIT("Failed to migrate to context", EXIT_COMMAND);
+
+ /* set terminal to raw mode */
+ atexit(terminal_atexit);
+ if (terminal_raw() == -1)
+ PEXIT("Failed to set terminal to raw mode", EXIT_COMMAND);
+
+ /* fork new pseudo terminal */
+ int slave;
+
+ if (openpty(&t.fd, &slave, NULL, NULL, NULL) == -1)
+ PEXIT("Failed to open new pseudo terminal", EXIT_COMMAND);
+
+ /* chroot to cwd */
+ if (chdir(".") == -1)
+ PEXIT("Failed to chdir to cwd", EXIT_COMMAND);
+
+ if (chroot(".") == -1)
+ PEXIT("Failed to chroot to cwd", EXIT_COMMAND);
+
+ pid_t pid;
+ pid = fork();
+
+ /* setup some signal handlers */
+ signal(SIGINT, signal_handler);
+ signal(SIGCHLD, signal_handler);
+ signal(SIGWINCH, signal_handler);
+
+ if (pid == -1)
+ PEXIT("Failed to fork new pseudo terminal", EXIT_COMMAND);
+
+ if (pid == 0) {
+ /* we don't need the master side of the terminal */
+ close(t.fd);
+
+ /* login_tty() stupid dietlibc doesn't have it */
+ setsid();
+
+ if (ioctl(slave, TIOCSCTTY, NULL) == -1)
+ PEXIT("Failed to set controlling terminal", EXIT_COMMAND);
+
+ dup2(slave, 0);
+ dup2(slave, 1);
+ dup2(slave, 2);
+
+ if (slave > 2)
+ close(slave);
+
+ /* check shell */
+ if (argc > optind) {
+ if (execv(argv[optind], argv+optind) == -1) {
+ PEXIT("Failed to execute shell", EXIT_COMMAND);
+ }
+ }
+ else {
+ if (execl("/bin/sh", "/bin/sh", "-l", NULL) == -1) {
+ PEXIT("Failed to execute default shell", EXIT_COMMAND);
+ }
+ }
+ }
+
+ /* save terminals pid */
+ t.pid = pid;
+
+ /* set process title for ps */
+ int i, len;
+
+ for (i = 1; i < argc; i++) {
+ memset(argv[i], '\0', strlen(argv[i]));
+ }
+
+ len = strlen(argv[0]);
+ memset(argv[0], '\0', len);
+ strncpy(argv[0], "VLOGIN", len);
+
+ /* we want a redraw */
+ terminal_redraw();
+
+ /* main loop */
+ fd_set rfds;
+ int n = 0;
+
+ for(;;) {
+ /* init file descriptors for select */
+ FD_ZERO(&rfds);
+ FD_SET(STDIN_FILENO, &rfds);
+ FD_SET(t.fd, &rfds);
+ n = t.fd;
+
+ /* wait for something to happen */
+ while (select(n + 1, &rfds, NULL, NULL, NULL) == -1) {
+ if (errno == EINTR || errno == EAGAIN) continue;
+ PEXIT("Failed to select", EXIT_COMMAND);
+ }
+
+ if (FD_ISSET(STDIN_FILENO, &rfds))
+ user_activity();
+
+ if (FD_ISSET(t.fd, &rfds))
+ terminal_activity();
+ }
+
+ /* never get here */
+ return -1;
+}
_______________________________________________
Vserver mailing list
[email protected]
http://list.linux-vserver.org/mailman/listinfo/vserver