lxc_start.c revision c36583c3034ca430c98fc0b5afe6e8f0c6511258
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes/*
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes * lxc: linux Container library
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes *
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes * (C) Copyright IBM Corp. 2007, 2008
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes *
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes * Authors:
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes * Daniel Lezcano <dlezcano at fr.ibm.com>
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes *
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes * This library is free software; you can redistribute it and/or
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes * modify it under the terms of the GNU Lesser General Public
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes * License as published by the Free Software Foundation; either
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes * version 2.1 of the License, or (at your option) any later version.
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes *
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes * This library is distributed in the hope that it will be useful,
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes * but WITHOUT ANY WARRANTY; without even the implied warranty of
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes * Lesser General Public License for more details.
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes *
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes * You should have received a copy of the GNU Lesser General Public
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes * License along with this library; if not, write to the Free Software
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes */
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes#include <stdio.h>
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes#include <libgen.h>
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes#include <unistd.h>
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes#include <string.h>
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes#include <termios.h>
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes#include <errno.h>
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes#include <fcntl.h>
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes#include <signal.h>
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes#include <sys/param.h>
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes#include <sys/utsname.h>
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes#include <sys/types.h>
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes#include <sys/socket.h>
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes#include <sys/stat.h>
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes#include <arpa/inet.h>
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes#include <netinet/in.h>
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes#include <net/if.h>
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes#include <lxc/lxc.h>
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes#include <lxc/log.h>
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes#include "arguments.h"
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholeslxc_log_define(lxc_start, lxc);
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholesstatic int my_parser(struct lxc_arguments* args, int c, char* arg)
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes{
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes switch (c) {
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes case 'd': args->daemonize = 1; break;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes }
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes return 0;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes}
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholesstatic const struct option my_longopts[] = {
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes {"daemon", no_argument, 0, 'd'},
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes LXC_COMMON_OPTIONS
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes};
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholesstatic struct lxc_arguments my_args = {
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes .progname = "lxc-start",
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes .help = "\
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes--name=NAME -- COMMAND\n\
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes\n\
bb2b38cd44b032118359afbc743efbea12f48e61bnicholeslxc-start start COMMAND in specified container NAME\n\
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes\n\
bb2b38cd44b032118359afbc743efbea12f48e61bnicholesOptions :\n\
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes -n, --name=NAME NAME for name of the container\n\
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes -d, --daemon daemonize the container",
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes .options = my_longopts,
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes .parser = my_parser,
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes .checker = NULL,
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes .daemonize = 0,
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes};
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholesstatic int save_tty(struct termios *tios)
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes{
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes if (!isatty(0))
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes return 0;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes if (tcgetattr(0, tios))
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes WARN("failed to get current terminal settings : %s",
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes strerror(errno));
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes return 0;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes}
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholesstatic int restore_tty(struct termios *tios)
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes{
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes struct termios current_tios;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes void (*oldhandler)(int);
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes int ret;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes if (!isatty(0))
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes return 0;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes if (tcgetattr(0, &current_tios)) {
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes ERROR("failed to get current terminal settings : %s",
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes strerror(errno));
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes return -1;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes }
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes if (!memcmp(tios, &current_tios, sizeof(*tios)))
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes return 0;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes oldhandler = signal(SIGTTOU, SIG_IGN);
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes ret = tcsetattr(0, TCSADRAIN, tios);
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes if (ret)
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes ERROR("failed to restore terminal attributes");
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes signal(SIGTTOU, oldhandler);
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes return ret;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes}
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholesint main(int argc, char *argv[])
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes{
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes char *const *args;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes int err = -1;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes struct termios tios;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes char *const default_args[] = {
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes "/sbin/init",
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes '\0',
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes };
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes if (lxc_arguments_parse(&my_args, argc, argv))
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes return err;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes if (!my_args.argc)
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes args = default_args;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes else
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes args = my_args.argv;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes if (lxc_log_init(my_args.log_file, my_args.log_priority,
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes my_args.progname, my_args.quiet))
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes return err;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes if (my_args.daemonize && daemon(0 ,0)) {
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes SYSERROR("failed to daemonize '%s'", my_args.name);
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes return err;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes }
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes save_tty(&tios);
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes err = lxc_start(my_args.name, args);
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes restore_tty(&tios);
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes return err;
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes}
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes
bb2b38cd44b032118359afbc743efbea12f48e61bnicholes