Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
L
lxc
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
lxc
Commits
5af85cb1
Commit
5af85cb1
authored
Nov 01, 2016
by
Tycho Andersen
Committed by
Tycho Andersen
Nov 02, 2016
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
c/r: save criu's stdout during dump too
This also allows us to commonize some bits of the dup2 code. Signed-off-by:
Tycho Andersen
<
tycho.andersen@canonical.com
>
parent
52e12945
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
60 additions
and
16 deletions
+60
-16
criu.c
src/lxc/criu.c
+60
-16
No files found.
src/lxc/criu.c
View file @
5af85cb1
...
@@ -62,6 +62,9 @@
...
@@ -62,6 +62,9 @@
lxc_log_define
(
lxc_criu
,
lxc
);
lxc_log_define
(
lxc_criu
,
lxc
);
struct
criu_opts
{
struct
criu_opts
{
/* the thing to hook to stdout and stderr for logging */
int
pipefd
;
/* The type of criu invocation, one of "dump" or "restore" */
/* The type of criu invocation, one of "dump" or "restore" */
char
*
action
;
char
*
action
;
...
@@ -134,6 +137,7 @@ static void exec_criu(struct criu_opts *opts)
...
@@ -134,6 +137,7 @@ static void exec_criu(struct criu_opts *opts)
char
buf
[
4096
],
tty_info
[
32
];
char
buf
[
4096
],
tty_info
[
32
];
size_t
pos
;
size_t
pos
;
/* If we are currently in a cgroup /foo/bar, and the container is in a
/* If we are currently in a cgroup /foo/bar, and the container is in a
* cgroup /lxc/foo, lxcfs will give us an ENOENT if some task in the
* cgroup /lxc/foo, lxcfs will give us an ENOENT if some task in the
* container has an open fd that points to one of the cgroup files
* container has an open fd that points to one of the cgroup files
...
@@ -541,6 +545,21 @@ static void exec_criu(struct criu_opts *opts)
...
@@ -541,6 +545,21 @@ static void exec_criu(struct criu_opts *opts)
INFO
(
"execing: %s"
,
buf
);
INFO
(
"execing: %s"
,
buf
);
/* before criu inits its log, it sometimes prints things to stdout/err;
* let's be sure we capture that.
*/
if
(
dup2
(
opts
->
pipefd
,
STDOUT_FILENO
)
<
0
)
{
SYSERROR
(
"dup2 stdout failed"
);
goto
err
;
}
if
(
dup2
(
opts
->
pipefd
,
STDERR_FILENO
)
<
0
)
{
SYSERROR
(
"dup2 stderr failed"
);
goto
err
;
}
close
(
opts
->
pipefd
);
#undef DECLARE_ARG
#undef DECLARE_ARG
execv
(
argv
[
0
],
argv
);
execv
(
argv
[
0
],
argv
);
err:
err:
...
@@ -781,15 +800,6 @@ static void do_restore(struct lxc_container *c, int status_pipe, struct migrate_
...
@@ -781,15 +800,6 @@ static void do_restore(struct lxc_container *c, int status_pipe, struct migrate_
close
(
pipes
[
0
]);
close
(
pipes
[
0
]);
pipes
[
0
]
=
-
1
;
pipes
[
0
]
=
-
1
;
if
(
dup2
(
pipes
[
1
],
STDERR_FILENO
)
<
0
)
{
SYSERROR
(
"dup2 failed"
);
goto
out_fini_handler
;
}
if
(
dup2
(
pipes
[
1
],
STDOUT_FILENO
)
<
0
)
{
SYSERROR
(
"dup2 failed"
);
goto
out_fini_handler
;
}
if
(
unshare
(
CLONE_NEWNS
))
if
(
unshare
(
CLONE_NEWNS
))
goto
out_fini_handler
;
goto
out_fini_handler
;
...
@@ -816,6 +826,7 @@ static void do_restore(struct lxc_container *c, int status_pipe, struct migrate_
...
@@ -816,6 +826,7 @@ static void do_restore(struct lxc_container *c, int status_pipe, struct migrate_
}
}
}
}
os
.
pipefd
=
pipes
[
1
];
os
.
action
=
"restore"
;
os
.
action
=
"restore"
;
os
.
user
=
opts
;
os
.
user
=
opts
;
os
.
c
=
c
;
os
.
c
=
c
;
...
@@ -1013,29 +1024,38 @@ static bool do_dump(struct lxc_container *c, char *mode, struct migrate_opts *op
...
@@ -1013,29 +1024,38 @@ static bool do_dump(struct lxc_container *c, char *mode, struct migrate_opts *op
{
{
pid_t
pid
;
pid_t
pid
;
char
*
criu_version
=
NULL
;
char
*
criu_version
=
NULL
;
int
criuout
[
2
];
if
(
!
criu_ok
(
c
,
&
criu_version
))
if
(
!
criu_ok
(
c
,
&
criu_version
))
return
false
;
return
false
;
if
(
mkdir_p
(
opts
->
directory
,
0700
)
<
0
)
if
(
pipe
(
criuout
)
<
0
)
{
SYSERROR
(
"pipe() failed"
);
return
false
;
return
false
;
}
if
(
mkdir_p
(
opts
->
directory
,
0700
)
<
0
)
goto
fail
;
pid
=
fork
();
pid
=
fork
();
if
(
pid
<
0
)
{
if
(
pid
<
0
)
{
SYSERROR
(
"fork failed"
);
SYSERROR
(
"fork failed"
);
return
false
;
goto
fail
;
}
}
if
(
pid
==
0
)
{
if
(
pid
==
0
)
{
struct
criu_opts
os
;
struct
criu_opts
os
;
struct
lxc_handler
h
;
struct
lxc_handler
h
;
close
(
criuout
[
0
]);
h
.
name
=
c
->
name
;
h
.
name
=
c
->
name
;
if
(
!
cgroup_init
(
&
h
))
{
if
(
!
cgroup_init
(
&
h
))
{
ERROR
(
"failed to cgroup_init()"
);
ERROR
(
"failed to cgroup_init()"
);
exit
(
1
);
exit
(
1
);
}
}
os
.
pipefd
=
criuout
[
1
];
os
.
action
=
mode
;
os
.
action
=
mode
;
os
.
user
=
opts
;
os
.
user
=
opts
;
os
.
c
=
c
;
os
.
c
=
c
;
...
@@ -1050,27 +1070,51 @@ static bool do_dump(struct lxc_container *c, char *mode, struct migrate_opts *op
...
@@ -1050,27 +1070,51 @@ static bool do_dump(struct lxc_container *c, char *mode, struct migrate_opts *op
exit
(
1
);
exit
(
1
);
}
else
{
}
else
{
int
status
;
int
status
;
ssize_t
n
;
char
buf
[
4096
];
bool
ret
;
close
(
criuout
[
1
]);
pid_t
w
=
waitpid
(
pid
,
&
status
,
0
);
pid_t
w
=
waitpid
(
pid
,
&
status
,
0
);
if
(
w
==
-
1
)
{
if
(
w
==
-
1
)
{
SYSERROR
(
"waitpid"
);
SYSERROR
(
"waitpid"
);
close
(
criuout
[
0
]);
return
false
;
return
false
;
}
}
n
=
read
(
criuout
[
0
],
buf
,
sizeof
(
buf
));
close
(
criuout
[
0
]);
if
(
n
<
0
)
{
SYSERROR
(
"read"
);
n
=
0
;
}
buf
[
n
]
=
0
;
if
(
WIFEXITED
(
status
))
{
if
(
WIFEXITED
(
status
))
{
if
(
WEXITSTATUS
(
status
))
{
if
(
WEXITSTATUS
(
status
))
{
ERROR
(
"dump failed with %d
\n
"
,
WEXITSTATUS
(
status
));
ERROR
(
"dump failed with %d
\n
"
,
WEXITSTATUS
(
status
));
return
false
;
ret
=
false
;
}
else
{
ret
=
true
;
}
}
return
true
;
}
else
if
(
WIFSIGNALED
(
status
))
{
}
else
if
(
WIFSIGNALED
(
status
))
{
ERROR
(
"dump signaled with %d
\n
"
,
WTERMSIG
(
status
));
ERROR
(
"dump signaled with %d
\n
"
,
WTERMSIG
(
status
));
ret
urn
false
;
ret
=
false
;
}
else
{
}
else
{
ERROR
(
"unknown dump exit %d
\n
"
,
status
);
ERROR
(
"unknown dump exit %d
\n
"
,
status
);
ret
urn
false
;
ret
=
false
;
}
}
if
(
!
ret
)
ERROR
(
"criu output: %s"
,
buf
);
return
ret
;
}
}
fail:
close
(
criuout
[
0
]);
close
(
criuout
[
1
]);
rmdir
(
opts
->
directory
);
return
false
;
}
}
bool
__criu_pre_dump
(
struct
lxc_container
*
c
,
struct
migrate_opts
*
opts
)
bool
__criu_pre_dump
(
struct
lxc_container
*
c
,
struct
migrate_opts
*
opts
)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment