~ubuntu-branches/ubuntu/karmic/vzctl/karmic

« back to all changes in this revision

Viewing changes to src/enter.c

  • Committer: Bazaar Package Importer
  • Author(s): Ola Lundqvist
  • Date: 2007-04-10 18:08:16 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20070410180816-0uuzj9fnna7gmzxv
Tags: 3.0.16-4
Etch has been released which means that this version can be uploaded
to unstable.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 *  Copyright (C) 2000-2006 SWsoft. All rights reserved.
 
2
 *  Copyright (C) 2000-2007 SWsoft. All rights reserved.
3
3
 *
4
4
 *  This program is free software; you can redistribute it and/or modify
5
5
 *  it under the terms of the GNU General Public License as published by
21
21
#include <errno.h>
22
22
#include <signal.h>
23
23
#include <fcntl.h>
24
 
#include <sys/syscall.h>
25
24
#include <sys/types.h>
26
25
#include <sys/stat.h>
27
26
#include <string.h>
50
49
        char *name;
51
50
 
52
51
        if (openpty(master, slave, NULL, tios, ws) < 0) {
53
 
                logger(0, errno, "Unable to open pty");
 
52
                logger(-1, errno, "Unable to open pty");
54
53
                return -1;
55
54
        }
56
55
        if ((name = ttyname(*slave)) == NULL) {
57
 
                logger(0, errno, "Unable to get tty name");
 
56
                logger(-1, errno, "Unable to get tty name");
58
57
        } else {
59
58
                logger(2, 0, "Open %s", name);
60
59
        } 
70
69
                close(fd);
71
70
        }
72
71
        if (setsid() < 0)
73
 
                logger(0, errno, "setsid");
 
72
                logger(-1, errno, "setsid");
74
73
        if (ioctl(ttyfd, TIOCSCTTY, NULL) < 0)
75
 
                logger(0, errno, "Failed to connect to controlling tty");
 
74
                logger(-1, errno, "Failed to connect to controlling tty");
76
75
        setpgrp();
77
76
}
78
77
 
79
78
static void raw_off(void)
80
79
{
81
 
        if (tcsetattr(0, TCSADRAIN, &s_tios) == -1)
82
 
                logger(0, errno, "Unable to restore term attr");
 
80
        if (tcsetattr(0, TCSADRAIN, &s_tios) == -1)
 
81
                logger(-1, errno, "Unable to restore term attr");
83
82
}
84
83
 
85
84
static void raw_on(void)
87
86
        struct termios tios;
88
87
 
89
88
        if (tcgetattr(0, &tios) == -1) {
90
 
                logger(0, errno, "Unable to get term attr");
 
89
                logger(-1, errno, "Unable to get term attr");
91
90
                return;
92
91
        }
93
92
        memcpy(&s_tios, &tios, sizeof(struct termios));
94
93
        cfmakeraw(&tios);
95
94
        if (tcsetattr(0, TCSADRAIN, &tios) == -1) 
96
 
                logger(0, errno, "Unable to set raw mode");
 
95
                logger(-1, errno, "Unable to set raw mode");
97
96
}
98
97
 
99
98
static void child_handler(int sig)
175
174
                                }       
176
175
                } else if (n < 0 && errno != EINTR) {
177
176
                        close(r_out);
178
 
                        logger(0, errno, "Error in select()");
 
177
                        logger(-1, errno, "Error in select()");
179
178
                        break;
180
179
                }
181
180
        }
200
199
        struct sigaction act;
201
200
 
202
201
        if (pipe(in) < 0 || pipe(out) < 0 || pipe(st) < 0) {
203
 
                logger(0, errno, "Unable to create pipe");
 
202
                logger(-1, errno, "Unable to create pipe");
204
203
                return VZ_RESOURCE_ERROR;
205
204
        }
206
205
        if ((ret = vz_setluid(veid)))
207
206
                return ret;
208
207
        preload_lib();
209
208
        child_term = 0;
210
 
        sigemptyset(&act.sa_mask);
211
 
        act.sa_flags = SA_NOCLDSTOP;
212
 
        act.sa_handler = child_handler;
213
 
        sigaction(SIGCHLD, &act, NULL);
 
209
        sigemptyset(&act.sa_mask);
 
210
        act.sa_flags = SA_NOCLDSTOP;
 
211
        act.sa_handler = child_handler;
 
212
        sigaction(SIGCHLD, &act, NULL);
214
213
 
215
214
        act.sa_handler = SIG_IGN;
216
215
        act.sa_flags = 0;
217
216
        sigaction(SIGPIPE, &act, NULL);
218
217
 
219
218
        if ((pid = fork()) < 0) {
220
 
                logger(0, errno, "Unable to fork");
 
219
                logger(-1, errno, "Unable to fork");
221
220
                ret = VZ_RESOURCE_ERROR;
222
221
                return ret;
223
222
        } else if (pid == 0) {
231
230
                close(in[1]); close(out[0]); close(st[0]);
232
231
                /* list of skipped fds -1 the end mark */
233
232
                close_fds(1, in[0], out[1], st[1], h->vzfd, -1);
 
233
                dup2(out[1], 1);
 
234
                dup2(out[1], 2);
234
235
                if ((ret = vz_chroot(root)))
235
236
                        goto err;
236
237
                ret = vz_env_create_ioctl(h, veid, VE_ENTER);
237
238
                if (ret < 0) {
238
239
                        if (errno == ESRCH) 
239
 
                                ret = VZ_VE_NOT_RUNNING;
 
240
                                ret = VZ_VE_NOT_RUNNING;
240
241
                        else
241
242
                                ret = VZ_ENVCREATE_ERROR;
242
243
                        goto err;
246
247
                        goto err;
247
248
                set_proc_title(ttyname(slave));
248
249
                child_term = 0;
249
 
                sigemptyset(&act.sa_mask);
250
 
                act.sa_flags = SA_NOCLDSTOP;
251
 
                act.sa_handler = child_handler;
252
 
                sigaction(SIGCHLD, &act, NULL);
 
250
                sigemptyset(&act.sa_mask);
 
251
                act.sa_flags = SA_NOCLDSTOP;
 
252
                act.sa_handler = child_handler;
 
253
                sigaction(SIGCHLD, &act, NULL);
253
254
                if ((pid = fork()) == 0) {
254
255
                        char buf[64];
255
256
                        char *term;
256
 
                        char *arg[] = {"-bash", NULL};
257
 
                        char *env[] = {"HOME=/", "HISTFILE=/dev/null",
258
 
                                "PATH=/bin:/sbin:/usr/bin:/usr/sbin:", NULL, NULL};
 
257
                        char *arg[] = {"-bash", NULL};
 
258
                        char *env[] = {"PATH=/bin:/sbin:/usr/bin:/usr/sbin:",
 
259
                                "HISTFILE=/dev/null",
 
260
                                "USER=root", "HOME=/root", "LOGNAME=root",
 
261
                                NULL, /* for TERM */
 
262
                                NULL};
259
263
                        close(master);
260
264
                        set_ctty(slave);
261
265
                        dup2(slave, 0);
265
269
                        close(slave);
266
270
                        if ((term = getenv("TERM")) != NULL) {
267
271
                                snprintf(buf, sizeof(buf), "TERM=%s", term);
268
 
                                env[2] = buf;
 
272
                                env[sizeof(env)/sizeof(env[0]) - 2] = buf;
269
273
                        }
270
274
                        execve("/bin/bash", arg, env);
271
275
                        execve("/bin/sh", arg, env);
272
 
                        logger(0, errno, "enter failed: unable to exec bash");
 
276
                        logger(-1, errno, "enter failed: unable to exec bash");
273
277
                        exit(1);
274
278
                } else if (pid < 0) {
275
 
                        logger(0, errno, "Unable to fork");
 
279
                        logger(-1, errno, "Unable to fork");
276
280
                        ret = VZ_RESOURCE_ERROR;
277
281
                        write(st[1], &ret, sizeof(ret));
278
282
                        exit(ret);
293
297
        /* wait for pts allocation */
294
298
        ret = read(st[0], &status, sizeof(status));
295
299
        if (!ret) {
296
 
                fprintf(stdout, "entered into VPS %d\n", veid);
 
300
                fprintf(stdout, "entered into VE %d\n", veid);
297
301
                raw_on();
298
302
                e_loop(fileno(stdin), in[1], out[0], fileno(stdout));
299
303
        } else {
300
 
                fprintf(stdout, "enter failed\n");
 
304
                fprintf(stdout, "enter into VE %d failed\n", veid);
 
305
                set_not_blk(out[0]);
 
306
                while (stdredir(out[0], fileno(stdout)) == 0)
 
307
                        ;
301
308
        }
302
309
        while ((waitpid(pid, &status, 0)) == -1)
303
310
                if (errno != EINTR)
304
311
                        break;
305
312
        if (WIFSIGNALED(status))
306
 
                logger(0, 0, "got signal %d", WTERMSIG(status));
 
313
                fprintf(stdout, "got signal %d\n", WTERMSIG(status));
307
314
        if (!ret) {
308
315
                raw_off();
309
 
                logger(0, 0, "exited from VPS %d\n", veid);
 
316
                fprintf(stdout, "exited from VE %d\n", veid);
310
317
        }
311
318
        close(in[1]); close(out[0]);
312
 
        return 0;
 
319
        return ret ? status : 0;
313
320
}
314
321