AS_AC_EXPAND(SYSCONFDIR, $sysconfdir)
AS_AC_EXPAND(LOCALSTATEDIR, $localstatedir)
AS_AC_EXPAND(LXCPATH, "${localstatedir}/lib/lxc")
+AS_AC_EXPAND(LXC_GENERATE_DATE, "$(date)")
AC_CHECK_HEADERS([linux/netlink.h linux/genetlink.h], [], AC_MSG_ERROR([netlink headers not found]),
[#include <linux/types.h>
<refsynopsisdiv>
<cmdsynopsis>
<command>lxc-console <replaceable>-n name</replaceable>
- <replaceable>-t ttynum</replaceable>
+ <optional>-t ttynum</optional>
</command>
</cmdsynopsis>
</refsynopsisdiv>
<para>
If the tty service has been configured and is available for the
container specified as parameter, this command will launch a
- console allowing to log to the container.
+ console allowing to log on the container.
</para>
<para>
<varlistentry>
<term>
- <option>-t <replaceable>ttynum</replaceable></option>
+ <option>-t <optional>ttynum</optional></option>
</term>
<listitem>
<para>
- Specify the tty number to connect.
+ Specify the tty number to connect, if not specified a tty
+ number will be automatically choosen by the container.
</para>
</listitem>
</varlistentry>
sock = lxc_af_unix_connect(addr.sun_path);
if (sock < 0) {
ERROR("failed to connect to the tty service");
- goto out_err;
+ goto out;
}
ret = lxc_af_unix_send_credential(sock, &ttynum, sizeof(ttynum));
if (ret < 0) {
SYSERROR("failed to send credentials");
- goto out_err;
+ goto out_close;
}
- ret = lxc_af_unix_recv_fd(sock, fd, NULL, 0);
+ ret = lxc_af_unix_recv_fd(sock, fd, &ttynum, sizeof(ttynum));
if (ret < 0) {
ERROR("failed to connect to the tty");
- goto out_err;
+ goto out_close;
}
+ INFO("tty %d allocated", ttynum);
+
if (!ret) {
- ERROR("tty%d denied by '%s'", ttynum, name);
+ ERROR("console denied by '%s'", name);
ret = -LXC_ERROR_TTY_DENIED;
- goto out_err;
+ goto out_close;
}
ret = 0;
-out_err:
- close(sock);
+out:
return ret;
+out_close:
+ close(sock);
+ goto out;
}
/*
* Show the console of the container.
* @name : the name of container
+ * @tty : the tty number
+ * @fd : a pointer to a tty file descriptor
* Returns 0 on sucess, < 0 otherwise
*/
extern int lxc_console(const char *name, int ttynum, int *fd);
{
fprintf(stderr, "%s <command>\n", basename(cmd));
fprintf(stderr, "\t -n <name> : name of the container\n");
- fprintf(stderr, "\t -t <tty#> : tty number\n");
+ fprintf(stderr, "\t [-t <tty#>] : tty number\n");
_exit(1);
}
{
char *name = NULL;
int opt;
- int ttynum = 0;
int nbargs = 0;
int master = -1;
+ int ttynum = -1;
int wait4q = 0;
int err = LXC_ERROR_INTERNAL;
struct termios tios, oldtios;
case 'n':
name = optarg;
break;
+
case 't':
ttynum = atoi(optarg);
break;
nbargs++;
}
- if (!name || !ttynum)
+ if (!name)
usage(argv[0]);
/* Get current termios */
if (lxc_af_unix_rcv_credential(conn, &ttynum, sizeof(ttynum)))
goto out_close;
- if (ttynum <= 0 || ttynum > tty_info->nbtty)
- goto out_close;
+ if (ttynum > 0) {
+ if (ttynum > tty_info->nbtty)
+ goto out_close;
+
+ if (tty_info->pty_info[ttynum - 1].busy)
+ goto out_close;
- /* fixup index array (eg. tty1 is index 0) */
- ttynum--;
+ goto out_send;
+ }
- if (tty_info->pty_info[ttynum].busy)
+ /* fixup index tty1 => [0] */
+ for (ttynum = 1;
+ ttynum <= tty_info->nbtty && tty_info->pty_info[ttynum - 1].busy;
+ ttynum++);
+
+ /* we didn't find any available slot for tty */
+ if (ttynum > tty_info->nbtty)
goto out_close;
- if (lxc_af_unix_send_fd(conn, tty_info->pty_info[ttynum].master,
- NULL, 0) < 0) {
+out_send:
+ if (lxc_af_unix_send_fd(conn, tty_info->pty_info[ttynum - 1].master,
+ &ttynum, sizeof(ttynum)) < 0) {
ERROR("failed to send tty to client");
goto out_close;
}
- if (lxc_mainloop_add_handler(descr, conn,
+ if (lxc_mainloop_add_handler(descr, conn,
ttyclient_handler, tty_info)) {
ERROR("failed to add tty client handler");
goto out_close;
}
- tty_info->pty_info[ttynum].busy = conn;
+ tty_info->pty_info[ttynum - 1].busy = conn;
ret = 0;
-
out:
return ret;
out_close: