Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
iSulad
提交
55fa3cdd
I
iSulad
项目概览
openeuler
/
iSulad
通知
15
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
I
iSulad
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
55fa3cdd
编写于
8月 15, 2020
作者:
O
openeuler-ci-bot
提交者:
Gitee
8月 15, 2020
浏览文件
操作
浏览文件
下载
差异文件
!651 use libarchive to tar container's rootfs
Merge pull request !651 from wangfengtu/export
上级
be60af20
74fbd9bf
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
303 addition
and
139 deletion
+303
-139
cmake/checker.cmake
cmake/checker.cmake
+0
-8
iSulad.spec
iSulad.spec
+2
-2
src/daemon/modules/image/oci/oci_export.c
src/daemon/modules/image/oci/oci_export.c
+2
-2
src/daemon/modules/image/oci/oci_load.c
src/daemon/modules/image/oci/oci_load.c
+25
-0
src/utils/tar/isulad_tar.c
src/utils/tar/isulad_tar.c
+0
-125
src/utils/tar/isulad_tar.h
src/utils/tar/isulad_tar.h
+0
-2
src/utils/tar/util_archive.c
src/utils/tar/util_archive.c
+272
-0
src/utils/tar/util_archive.h
src/utils/tar/util_archive.h
+2
-0
未找到文件。
cmake/checker.cmake
浏览文件 @
55fa3cdd
...
...
@@ -65,14 +65,6 @@ find_library(LIBARCHIVE_LIBRARY archive
HINTS
${
PC_LIBARCHIVE_LIBDIR
}
${
PC_LIBARCHIVE_LIBRARY_DIRS
}
)
_CHECK
(
LIBARCHIVE_LIBRARY
"LIBARCHIVE_LIBRARY-NOTFOUND"
"libarchive.so"
)
# check libtar
find_path
(
LIBTAR_INCLUDE_DIR libtar.h
HINTS
${
PC_LIBTAR_INCLUDEDIR
}
${
PC_LIBTAR_INCLUDE_DIRS
}
)
_CHECK
(
LIBTAR_INCLUDE_DIR
"LIBTAR_INCLUDE_DIR-NOTFOUND"
"libtar.h"
)
find_library
(
LIBTAR_LIBRARY tar
HINTS
${
PC_LIBTAR_LIBDIR
}
${
PC_LIBTAR_LIBRARY_DIRS
}
)
_CHECK
(
LIBTAR_LIBRARY
"LIBTAR_LIBRARY-NOTFOUND"
"libtar.so"
)
# check libcrypto
pkg_check_modules
(
PC_CRYPTO REQUIRED
"libcrypto"
)
find_library
(
CRYPTO_LIBRARY crypto
...
...
iSulad.spec
浏览文件 @
55fa3cdd
...
...
@@ -31,7 +31,7 @@ Requires(preun): initscripts
BuildRequires: cmake gcc-c++ lxc lxc-devel lcr-devel yajl-devel clibcni-devel
BuildRequires: grpc grpc-plugins grpc-devel protobuf-devel
BuildRequires: libcurl libcurl-devel sqlite-devel libarchive-devel
libtar-devel
device-mapper-devel
BuildRequires: libcurl libcurl-devel sqlite-devel libarchive-devel device-mapper-devel
BuildRequires: http-parser-devel
BuildRequires: libseccomp-devel libcap-devel libselinux-devel libwebsockets libwebsockets-devel
BuildRequires: systemd-devel git
...
...
@@ -40,7 +40,7 @@ Requires: lcr lxc clibcni
Requires: grpc protobuf
Requires: libcurl
Requires: sqlite http-parser libseccomp
Requires: libcap libselinux libwebsockets libarchive
libtar
device-mapper
Requires: libcap libselinux libwebsockets libarchive device-mapper
Requires: systemd
%description
...
...
src/daemon/modules/image/oci/oci_export.c
浏览文件 @
55fa3cdd
...
...
@@ -19,7 +19,7 @@
#include "oci_export.h"
#include "isula_libutils/log.h"
#include "err_msg.h"
#include "
isulad_tar
.h"
#include "
util_archive
.h"
int
oci_do_export
(
char
*
id
,
char
*
file
)
{
...
...
@@ -40,7 +40,7 @@ int oci_do_export(char *id, char *file)
return
-
1
;
}
ret
=
chroot_tar
(
mount_point
,
file
,
&
errmsg
);
ret
=
archive_
chroot_tar
(
mount_point
,
file
,
&
errmsg
);
if
(
ret
!=
0
)
{
ERROR
(
"failed to export container %s to file %s: %s"
,
id
,
file
,
errmsg
);
isulad_set_error_message
(
"Failed to export rootfs with error: %s"
,
errmsg
);
...
...
src/daemon/modules/image/oci/oci_load.c
浏览文件 @
55fa3cdd
...
...
@@ -397,6 +397,26 @@ out:
return
ret
;
}
static
int
check_time_valid
(
oci_image_spec
*
conf
)
{
int64_t
nanos
=
0
;
int
i
=
0
;
if
(
to_unix_nanos_from_str
(
conf
->
created
,
&
nanos
)
!=
0
)
{
ERROR
(
"Invalid created time %s"
,
conf
->
created
);
return
-
1
;
}
for
(
i
=
0
;
i
<
conf
->
history_len
;
i
++
)
{
if
(
to_unix_nanos_from_str
(
conf
->
history
[
i
]
->
created
,
&
nanos
)
!=
0
)
{
ERROR
(
"Invalid history created time %s"
,
conf
->
history
[
i
]
->
created
);
return
-
1
;
}
}
return
0
;
}
static
int
oci_load_create_image
(
load_image_t
*
desc
,
const
char
*
dst_tag
)
{
int
ret
=
0
;
...
...
@@ -420,6 +440,11 @@ static int oci_load_create_image(load_image_t *desc, const char *dst_tag)
goto
out
;
}
ret
=
check_time_valid
(
conf
);
if
(
ret
!=
0
)
{
goto
out
;
}
timestamp
=
oci_load_get_timestamp
(
conf
->
created
);
top_layer_index
=
desc
->
layers_len
-
1
;
opts
.
create_time
=
&
timestamp
;
...
...
src/utils/tar/isulad_tar.c
浏览文件 @
55fa3cdd
...
...
@@ -22,7 +22,6 @@
#include <sys/wait.h>
#include <limits.h>
#include <sys/stat.h>
#include <libtar.h>
#include <errno.h>
#include "stdbool.h"
...
...
@@ -43,8 +42,6 @@
#define TAR_EXACT_OPT "-x"
#define TAR_CHDIR_OPT "-C"
#define TAR_GZIP_OPT "-z"
#define TAR_DEFAULT_MODE 0600
#define TAR_DEFAULT_FLAG (O_WRONLY | O_CREAT)
static
void
set_char_to_separator
(
char
*
p
)
{
...
...
@@ -892,125 +889,3 @@ int tar_resource(const struct archive_copy_info *info, struct io_read_wrapper *a
{
return
tar_resource_rebase
(
info
->
path
,
info
->
rebase_name
,
archive_reader
,
err
);
}
static
int
tar_all
(
char
*
path
,
int
fd
)
{
TAR
*
tar
=
NULL
;
int
ret
=
0
;
ret
=
tar_fdopen
(
&
tar
,
fd
,
NULL
,
NULL
,
TAR_DEFAULT_FLAG
,
TAR_DEFAULT_MODE
,
TAR_GNU
);
if
(
ret
!=
0
)
{
ERROR
(
"open file for exporting container rootfs failed: %s"
,
strerror
(
errno
));
fprintf
(
stderr
,
"open file for exporting container rootfs failed: %s"
,
strerror
(
errno
));
return
-
1
;
}
ret
=
tar_append_tree
(
tar
,
path
,
"."
);
if
(
ret
!=
0
)
{
ERROR
(
"append files tree for exporting container rootfs failed: %s"
,
strerror
(
errno
));
fprintf
(
stderr
,
"append files tree for exporting container rootfs failed: %s"
,
strerror
(
errno
));
goto
out
;
}
out:
tar_close
(
tar
);
tar
=
NULL
;
return
ret
;
}
int
chroot_tar
(
char
*
path
,
char
*
file
,
char
**
errmsg
)
{
int
ret
=
0
;
pid_t
pid
;
int
pipe_for_read
[
2
]
=
{
-
1
,
-
1
};
int
keepfds
[]
=
{
-
1
,
-
1
};
char
errbuf
[
BUFSIZ
]
=
{
0
};
int
fd
=
0
;
if
(
pipe2
(
pipe_for_read
,
O_CLOEXEC
)
!=
0
)
{
ERROR
(
"Failed to create pipe"
);
ret
=
-
1
;
goto
cleanup
;
}
pid
=
fork
();
if
(
pid
==
(
pid_t
)
-
1
)
{
ERROR
(
"Failed to fork()"
);
ret
=
-
1
;
close
(
pipe_for_read
[
0
]);
close
(
pipe_for_read
[
1
]);
goto
cleanup
;
}
if
(
pid
==
(
pid_t
)
0
)
{
keepfds
[
0
]
=
isula_libutils_get_log_fd
();
keepfds
[
1
]
=
pipe_for_read
[
1
];
ret
=
util_check_inherited_exclude_fds
(
true
,
keepfds
,
2
);
if
(
ret
!=
0
)
{
ERROR
(
"Failed to close fds."
);
ret
=
-
1
;
goto
child_out
;
}
// child process, dup2 pipe_for_read[1] to stderr,
if
(
dup2
(
pipe_for_read
[
1
],
2
)
<
0
)
{
ERROR
(
"Dup fd error: %s"
,
strerror
(
errno
));
ret
=
-
1
;
goto
child_out
;
}
fd
=
open
(
file
,
TAR_DEFAULT_FLAG
,
TAR_DEFAULT_MODE
);
if
(
fd
<
0
)
{
ERROR
(
"Failed to open file %s for export: %s"
,
file
,
strerror
(
errno
));
fprintf
(
stderr
,
"Failed to open file %s for export: %s"
,
file
,
strerror
(
errno
));
ret
=
-
1
;
goto
child_out
;
}
if
(
chroot
(
path
)
!=
0
)
{
ERROR
(
"Failed to chroot to %s"
,
path
);
fprintf
(
stderr
,
"Failed to chroot to %s"
,
path
);
ret
=
-
1
;
goto
child_out
;
}
if
(
chdir
(
"/"
)
!=
0
)
{
ERROR
(
"Failed to chroot to /"
);
fprintf
(
stderr
,
"Failed to chroot to /"
);
ret
=
-
1
;
goto
child_out
;
}
ret
=
tar_all
(
"/"
,
fd
);
child_out:
if
(
ret
!=
0
)
{
exit
(
EXIT_FAILURE
);
}
else
{
exit
(
EXIT_SUCCESS
);
}
}
ret
=
wait_for_pid
(
pid
);
if
(
ret
!=
0
)
{
ERROR
(
"tar failed"
);
if
(
read
(
pipe_for_read
[
0
],
errbuf
,
BUFSIZ
)
<
0
)
{
ERROR
(
"read error message from child failed"
);
}
close
(
pipe_for_read
[
0
]);
pipe_for_read
[
0
]
=
-
1
;
}
close
(
pipe_for_read
[
1
]);
pipe_for_read
[
1
]
=
-
1
;
cleanup:
if
(
errmsg
!=
NULL
&&
strlen
(
errbuf
)
!=
0
)
{
*
errmsg
=
util_strdup_s
(
errbuf
);
}
return
ret
;
}
src/utils/tar/isulad_tar.h
浏览文件 @
55fa3cdd
...
...
@@ -70,8 +70,6 @@ int archive_copy_to(const struct io_read_wrapper *content, bool compression, con
int
archive_path
(
const
char
*
srcdir
,
const
char
*
srcbase
,
const
char
*
rebase_name
,
bool
compression
,
struct
io_read_wrapper
*
archive_reader
);
int
chroot_tar
(
char
*
path
,
char
*
file
,
char
**
errmsg
);
#ifdef __cplusplus
}
#endif
...
...
src/utils/tar/util_archive.c
浏览文件 @
55fa3cdd
...
...
@@ -32,11 +32,14 @@
#include "isula_libutils/log.h"
#include "io_wrapper.h"
#include "utils_file.h"
#include "map.h"
struct
archive
;
struct
archive_entry
;
#define ARCHIVE_READ_BUFFER_SIZE (10 * 1024)
#define TAR_DEFAULT_MODE 0600
#define TAR_DEFAULT_FLAG (O_WRONLY | O_CREAT | O_TRUNC)
#define WHITEOUT_PREFIX ".wh."
#define WHITEOUT_META_PREFIX ".wh..wh."
...
...
@@ -352,3 +355,272 @@ out:
return
(
ret
==
ARCHIVE_OK
);
}
static
int
copy_data_between_archives
(
struct
archive
*
ar
,
struct
archive
*
aw
)
{
int
ret
=
ARCHIVE_FAILED
;
const
void
*
buff
=
NULL
;
size_t
size
;
int64_t
offset
;
for
(;;)
{
ret
=
archive_read_data_block
(
ar
,
&
buff
,
&
size
,
&
offset
);
if
(
ret
==
ARCHIVE_EOF
)
{
return
ARCHIVE_OK
;
}
if
(
ret
<
ARCHIVE_OK
)
{
ERROR
(
"tar archive read result %d, error: %s"
,
ret
,
archive_error_string
(
ar
));
fprintf
(
stderr
,
"tar archive read result %d, error: %s"
,
ret
,
archive_error_string
(
ar
));
return
ret
;
}
ret
=
archive_write_data
(
aw
,
buff
,
size
);
if
(
ret
<
ARCHIVE_OK
)
{
ERROR
(
"tar archive write result %d, error: %s"
,
ret
,
archive_error_string
(
aw
));
fprintf
(
stderr
,
"tar archive write result %d, error: %s"
,
ret
,
archive_error_string
(
aw
));
return
ret
;
}
}
}
int
update_entry_for_hardlink
(
map_t
*
map_link
,
struct
archive_entry
*
entry
)
{
const
char
*
path
=
archive_entry_pathname
(
entry
);
char
*
linkname
=
NULL
;
unsigned
int
nlink
=
archive_entry_nlink
(
entry
);
int
ino
=
archive_entry_ino
(
entry
);
// hardlink is regular file, not type AE_IFLNK
if
(
archive_entry_filetype
(
entry
)
!=
AE_IFREG
)
{
return
0
;
}
// no hardlink
if
(
nlink
<=
1
)
{
return
0
;
}
linkname
=
map_search
(
map_link
,
(
void
*
)
&
ino
);
if
(
linkname
==
NULL
)
{
linkname
=
(
char
*
)
path
;
if
(
!
map_insert
(
map_link
,
(
void
*
)
&
ino
,
linkname
))
{
ERROR
(
"insert to map failed"
);
fprintf
(
stderr
,
"insert to map failed"
);
return
-
1
;
}
return
0
;
}
archive_entry_set_size
(
entry
,
0
);
archive_entry_set_hardlink
(
entry
,
linkname
);
return
0
;
}
static
void
link_kvfree
(
void
*
key
,
void
*
value
)
{
free
(
key
);
free
(
value
);
return
;
}
int
tar_handler
(
struct
archive
*
r
,
struct
archive
*
w
)
{
int
ret
=
ARCHIVE_OK
;
struct
archive_entry
*
entry
=
NULL
;
map_t
*
map_link
=
NULL
;
map_link
=
map_new
(
MAP_INT_STR
,
MAP_DEFAULT_CMP_FUNC
,
link_kvfree
);
if
(
map_link
==
NULL
)
{
ERROR
(
"out of memory"
);
fprintf
(
stderr
,
"out of memory
\n
"
);
return
-
1
;
}
for
(;;)
{
ret
=
archive_read_next_header
(
r
,
&
entry
);
if
(
ret
==
ARCHIVE_EOF
)
{
ret
=
ARCHIVE_OK
;
break
;
}
if
(
ret
!=
ARCHIVE_OK
)
{
ERROR
(
"read from disk failed: %s"
,
archive_error_string
(
r
));
fprintf
(
stderr
,
"read from disk failed: %s
\n
"
,
archive_error_string
(
r
));
break
;
}
if
(
update_entry_for_hardlink
(
map_link
,
entry
)
!=
0
)
{
ret
=
ARCHIVE_FAILED
;
break
;
}
ret
=
archive_write_header
(
w
,
entry
);
if
(
ret
!=
ARCHIVE_OK
)
{
ERROR
(
"Fail to write tar header: %s"
,
archive_error_string
(
w
));
fprintf
(
stderr
,
"Fail to write tar header: %s
\n
link:%s target:%s"
,
archive_error_string
(
w
),
archive_entry_pathname
(
entry
),
archive_entry_hardlink
(
entry
));
break
;
}
if
(
archive_entry_size
(
entry
)
>
0
)
{
ret
=
copy_data_between_archives
(
r
,
w
);
if
(
ret
!=
ARCHIVE_OK
)
{
ERROR
(
"Failed to do copy data: %s"
,
archive_error_string
(
w
));
fprintf
(
stderr
,
"Failed to do copy data: %s
\n
"
,
archive_error_string
(
w
));
break
;
}
}
ret
=
archive_write_finish_entry
(
w
);
if
(
ret
!=
ARCHIVE_OK
)
{
ERROR
(
"Failed to freeing archive entry: %s
\n
"
,
archive_error_string
(
w
));
fprintf
(
stderr
,
"Failed to freeing archive entry: %s
\n
"
,
archive_error_string
(
w
));
break
;
}
if
(
archive_entry_filetype
(
entry
)
==
AE_IFDIR
)
{
ret
=
archive_read_disk_descend
(
r
);
if
(
ret
!=
ARCHIVE_OK
)
{
ERROR
(
"read disk descend failed: %s
\n
"
,
archive_error_string
(
w
));
fprintf
(
stderr
,
"read disk descend failed: %s
\n
"
,
archive_error_string
(
w
));
break
;
}
}
}
map_free
(
map_link
);
return
ret
;
}
static
int
tar_all
(
int
fd
)
{
struct
archive
*
r
=
NULL
;
struct
archive
*
w
=
NULL
;
int
ret
=
ARCHIVE_OK
;
r
=
archive_read_disk_new
();
archive_read_disk_set_standard_lookup
(
r
);
archive_read_disk_set_symlink_physical
(
r
);
archive_read_disk_set_behavior
(
r
,
ARCHIVE_READDISK_NO_TRAVERSE_MOUNTS
);
ret
=
archive_read_disk_open
(
r
,
"."
);
if
(
ret
!=
ARCHIVE_OK
)
{
ERROR
(
"open archive read failed: %s"
,
archive_error_string
(
r
));
fprintf
(
stderr
,
"open archive read failed: %s
\n
"
,
archive_error_string
(
r
));
goto
out
;
}
w
=
archive_write_new
();
archive_write_set_format_pax
(
w
);
ret
=
archive_write_open_fd
(
w
,
fd
);
if
(
ret
!=
ARCHIVE_OK
)
{
ERROR
(
"open archive write failed: %s"
,
archive_error_string
(
w
));
fprintf
(
stderr
,
"open archive write failed: %s
\n
"
,
archive_error_string
(
w
));
goto
out
;
}
ret
=
tar_handler
(
r
,
w
);
out:
archive_free
(
r
);
archive_free
(
w
);
return
(
ret
==
ARCHIVE_OK
)
?
0
:
-
1
;
}
int
archive_chroot_tar
(
char
*
path
,
char
*
file
,
char
**
errmsg
)
{
int
ret
=
0
;
pid_t
pid
;
int
pipe_for_read
[
2
]
=
{
-
1
,
-
1
};
int
keepfds
[]
=
{
-
1
,
-
1
};
char
errbuf
[
BUFSIZ
]
=
{
0
};
int
fd
=
0
;
if
(
pipe2
(
pipe_for_read
,
O_CLOEXEC
)
!=
0
)
{
ERROR
(
"Failed to create pipe"
);
ret
=
-
1
;
goto
cleanup
;
}
pid
=
fork
();
if
(
pid
==
(
pid_t
)
-
1
)
{
ERROR
(
"Failed to fork()"
);
ret
=
-
1
;
close
(
pipe_for_read
[
0
]);
close
(
pipe_for_read
[
1
]);
goto
cleanup
;
}
if
(
pid
==
(
pid_t
)
0
)
{
keepfds
[
0
]
=
isula_libutils_get_log_fd
();
keepfds
[
1
]
=
pipe_for_read
[
1
];
ret
=
util_check_inherited_exclude_fds
(
true
,
keepfds
,
2
);
if
(
ret
!=
0
)
{
ERROR
(
"Failed to close fds."
);
ret
=
-
1
;
goto
child_out
;
}
// child process, dup2 pipe_for_read[1] to stderr,
if
(
dup2
(
pipe_for_read
[
1
],
2
)
<
0
)
{
ERROR
(
"Dup fd error: %s"
,
strerror
(
errno
));
ret
=
-
1
;
goto
child_out
;
}
fd
=
open
(
file
,
TAR_DEFAULT_FLAG
,
TAR_DEFAULT_MODE
);
if
(
fd
<
0
)
{
ERROR
(
"Failed to open file %s for export: %s"
,
file
,
strerror
(
errno
));
fprintf
(
stderr
,
"Failed to open file %s for export: %s
\n
"
,
file
,
strerror
(
errno
));
ret
=
-
1
;
goto
child_out
;
}
if
(
chroot
(
path
)
!=
0
)
{
ERROR
(
"Failed to chroot to %s"
,
path
);
fprintf
(
stderr
,
"Failed to chroot to %s
\n
"
,
path
);
ret
=
-
1
;
goto
child_out
;
}
if
(
chdir
(
"/"
)
!=
0
)
{
ERROR
(
"Failed to chroot to /"
);
fprintf
(
stderr
,
"Failed to chroot to /
\n
"
);
ret
=
-
1
;
goto
child_out
;
}
ret
=
tar_all
(
fd
);
child_out:
if
(
ret
!=
0
)
{
exit
(
EXIT_FAILURE
);
}
else
{
exit
(
EXIT_SUCCESS
);
}
}
ret
=
wait_for_pid
(
pid
);
if
(
ret
!=
0
)
{
ERROR
(
"tar failed"
);
fcntl
(
pipe_for_read
[
0
],
F_SETFL
,
O_NONBLOCK
);
if
(
read
(
pipe_for_read
[
0
],
errbuf
,
BUFSIZ
)
<
0
)
{
ERROR
(
"read error message from child failed"
);
}
close
(
pipe_for_read
[
0
]);
pipe_for_read
[
0
]
=
-
1
;
}
close
(
pipe_for_read
[
1
]);
pipe_for_read
[
1
]
=
-
1
;
cleanup:
if
(
errmsg
!=
NULL
&&
strlen
(
errbuf
)
!=
0
)
{
*
errmsg
=
util_strdup_s
(
errbuf
);
}
return
ret
;
}
src/utils/tar/util_archive.h
浏览文件 @
55fa3cdd
...
...
@@ -42,6 +42,8 @@ int archive_unpack(const struct io_read_wrapper *content, const char *dstdir, co
bool
valid_archive_format
(
const
char
*
file
);
int
archive_chroot_tar
(
char
*
path
,
char
*
file
,
char
**
errmsg
);
#ifdef __cplusplus
}
#endif
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录