int lxc_init(const char *name, struct lxc_handler *handler)
{
- __do_close_prot_errno int status_fd = -EBADF;
+ __do_close int status_fd = -EBADF;
int ret;
const char *loglevel;
struct lxc_conf *conf = handler->conf;
handler->monitor_pid = lxc_raw_getpid();
status_fd = open("/proc/self/status", O_RDONLY | O_CLOEXEC);
- if (status_fd < 0) {
- SYSERROR("Failed to open monitor status fd");
- goto out_close_maincmd_fd;
- }
+ if (status_fd < 0)
+ return log_error_errno(-1, errno, "Failed to open monitor status fd");
lsm_init();
TRACE("Initialized LSM");
ret = lxc_read_seccomp_config(conf);
- if (ret < 0) {
- ERROR("Failed loading seccomp policy");
- goto out_close_maincmd_fd;
- }
+ if (ret < 0)
+ return log_error(-1, "Failed loading seccomp policy");
TRACE("Read seccomp policy");
/* Begin by setting the state to STARTING. */
ret = lxc_set_state(name, handler, STARTING);
- if (ret < 0) {
- ERROR("Failed to set state to \"%s\"", lxc_state2str(STARTING));
- goto out_close_maincmd_fd;
- }
+ if (ret < 0)
+ return log_error(-1, "Failed to set state to \"%s\"", lxc_state2str(STARTING));
TRACE("Set container state to \"STARTING\"");
/* Start of environment variable setup for hooks. */
TRACE("Set environment variables");
ret = run_lxc_hooks(name, "pre-start", conf, NULL);
- if (ret < 0) {
- ERROR("Failed to run lxc.hook.pre-start for container \"%s\"", name);
- goto out_aborting;
- }
+ if (ret < 0)
+ return log_error(-1, "Failed to run lxc.hook.pre-start for container \"%s\"", name);
TRACE("Ran pre-start hooks");
/* The signal fd has to be created before forking otherwise if the child
* and the command will be stuck.
*/
handler->sigfd = setup_signal_fd(&handler->oldmask);
- if (handler->sigfd < 0) {
- ERROR("Failed to setup SIGCHLD fd handler.");
- goto out_delete_tty;
- }
+ if (handler->sigfd < 0)
+ return log_error(-1, "Failed to setup SIGCHLD fd handler.");
TRACE("Set up signal fd");
/* Do this after setting up signals since it might unblock SIGWINCH. */
out_restore_sigmask:
(void)pthread_sigmask(SIG_SETMASK, &handler->oldmask, NULL);
-out_delete_tty:
- lxc_delete_tty(&conf->ttys);
-
-out_aborting:
- (void)lxc_set_state(name, handler, ABORTING);
-
-out_close_maincmd_fd:
- close_prot_errno_disarm(conf->maincmd_fd);
return -1;
}
handler->pidfd, handler->pid);
}
- if (!ret || errno != ESRCH)
+ if ((!ret || errno != ESRCH) && handler->pid > 0)
if (kill(handler->pid, SIGKILL))
SYSWARN("Failed to send SIGKILL to %d", handler->pid);
static int do_start(void *data)
{
struct lxc_handler *handler = data;
- __lxc_unused __do_close_prot_errno int data_sock0 = handler->data_sock[0],
+ __lxc_unused __do_close int data_sock0 = handler->data_sock[0],
data_sock1 = handler->data_sock[1];
- __do_close_prot_errno int status_fd = -EBADF;
+ __do_close int status_fd = -EBADF;
int ret;
uid_t new_uid;
gid_t new_gid;
*/
static int lxc_spawn(struct lxc_handler *handler)
{
- __do_close_prot_errno int data_sock0 = -EBADF, data_sock1 = -EBADF;
+ __do_close int data_sock0 = -EBADF, data_sock1 = -EBADF;
int i, ret;
char pidstr[20];
bool wants_to_map_ids;
if (error_num)
*error_num = handler->exit_status;
-out_fini:
+/* These are the goto targets you are not allowed to jump to. */
+__out_fini:
lxc_delete_network(handler);
-out_detach_blockdev:
+__out_detach_blockdev:
detach_block_device(handler->conf);
-out_fini_nonet:
+__out_fini_nonet:
lxc_fini(name, handler);
+
return ret;
+/* These are the goto targets you want to jump to. */
+out_fini_nonet:
+ lxc_abort(name, handler);
+ goto __out_fini_nonet;
+
+out_detach_blockdev:
+ lxc_abort(name, handler);
+ goto __out_detach_blockdev;
+
out_abort:
lxc_abort(name, handler);
- goto out_fini;
+ goto __out_fini;
+
}
struct start_args {