Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
lukaCoding
nvidia-container-runtime
提交
35a9f27c
N
nvidia-container-runtime
项目概览
lukaCoding
/
nvidia-container-runtime
与 Fork 源项目一致
从无法访问的项目Fork
通知
4
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
N
nvidia-container-runtime
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
35a9f27c
编写于
9月 13, 2018
作者:
J
Jonathan Calmels
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Add support for CUDA forward compatibility
上级
ebed710b
变更
11
隐藏空白更改
内联
并排
Showing
11 changed file
with
174 addition
and
26 deletion
+174
-26
src/driver.c
src/driver.c
+0
-3
src/driver.h
src/driver.h
+3
-0
src/nvc.h
src/nvc.h
+1
-0
src/nvc_container.c
src/nvc_container.c
+56
-1
src/nvc_info.c
src/nvc_info.c
+9
-9
src/nvc_internal.h
src/nvc_internal.h
+4
-0
src/nvc_mount.c
src/nvc_mount.c
+46
-3
src/options.h
src/options.h
+10
-8
src/utils.c
src/utils.c
+23
-2
src/utils.h
src/utils.h
+2
-0
src/xfuncs.h
src/xfuncs.h
+20
-0
未找到文件。
src/driver.c
浏览文件 @
35a9f27c
...
...
@@ -29,9 +29,6 @@
#include "utils.h"
#include "xfuncs.h"
#define SONAME_LIBCUDA "libcuda.so.1"
#define SONAME_LIBNVML "libnvidia-ml.so.1"
#define MAX_DEVICES 64
#define REAP_TIMEOUT_MS 10
...
...
src/driver.h
浏览文件 @
35a9f27c
...
...
@@ -18,6 +18,9 @@ SVCXPRT *svcunixfd_create(int, u_int, u_int);
#include "error.h"
#define SONAME_LIBCUDA "libcuda.so.1"
#define SONAME_LIBNVML "libnvidia-ml.so.1"
#define SOCK_CLT 0
#define SOCK_SVC 1
...
...
src/nvc.h
浏览文件 @
35a9f27c
...
...
@@ -77,6 +77,7 @@ struct nvc_container_config {
char
*
bins_dir
;
char
*
libs_dir
;
char
*
libs32_dir
;
char
*
cudart_dir
;
char
*
ldconfig
;
};
...
...
src/nvc_container.c
浏览文件 @
35a9f27c
...
...
@@ -26,6 +26,7 @@ static char *cgroup_root(char *, char *, const char *);
static
char
*
parse_proc_file
(
struct
error
*
,
const
char
*
,
parse_fn
,
char
*
,
const
char
*
);
static
char
*
find_cgroup_path
(
struct
error
*
,
const
struct
nvc_container
*
,
const
char
*
);
static
char
*
find_namespace_path
(
struct
error
*
,
const
struct
nvc_container
*
,
const
char
*
);
static
int
find_library_paths
(
struct
error
*
,
struct
nvc_container
*
);
static
int
lookup_owner
(
struct
error
*
,
struct
nvc_container
*
);
static
int
copy_config
(
struct
error
*
,
struct
nvc_container
*
,
const
struct
nvc_container_config
*
);
...
...
@@ -180,6 +181,48 @@ find_namespace_path(struct error *err, const struct nvc_container *cnt, const ch
return
(
ns
);
}
static
int
find_library_paths
(
struct
error
*
err
,
struct
nvc_container
*
cnt
)
{
char
path
[
PATH_MAX
];
glob_t
gl
;
int
rv
=
-
1
;
char
**
ptr
;
if
(
!
(
cnt
->
flags
&
OPT_COMPUTE_LIBS
))
return
(
0
);
if
(
path_join
(
err
,
path
,
cnt
->
cfg
.
rootfs
,
cnt
->
cfg
.
cudart_dir
)
<
0
)
return
(
-
1
);
if
(
path_append
(
err
,
path
,
"compat/lib*.so.*"
)
<
0
)
return
(
-
1
);
if
(
xglob
(
err
,
path
,
GLOB_ERR
,
NULL
,
&
gl
)
<
0
)
goto
fail
;
if
(
gl
.
gl_pathc
>
0
)
{
cnt
->
nlibs
=
gl
.
gl_pathc
;
cnt
->
libs
=
ptr
=
array_new
(
err
,
gl
.
gl_pathc
);
if
(
cnt
->
libs
==
NULL
)
goto
fail
;
for
(
size_t
i
=
0
;
i
<
gl
.
gl_pathc
;
++
i
)
{
if
(
path_resolve
(
err
,
path
,
cnt
->
cfg
.
rootfs
,
gl
.
gl_pathv
[
i
]
+
strlen
(
cnt
->
cfg
.
rootfs
))
<
0
)
goto
fail
;
if
(
!
str_array_match
(
path
,
(
const
char
*
const
*
)
cnt
->
libs
,
(
size_t
)(
ptr
-
cnt
->
libs
)))
{
log_infof
(
"selecting %s%s"
,
cnt
->
cfg
.
rootfs
,
path
);
if
((
*
ptr
++
=
xstrdup
(
err
,
path
))
==
NULL
)
goto
fail
;
}
}
array_pack
(
cnt
->
libs
,
&
cnt
->
nlibs
);
}
rv
=
0
;
fail:
globfree
(
&
gl
);
return
(
rv
);
}
static
int
lookup_owner
(
struct
error
*
err
,
struct
nvc_container
*
cnt
)
{
...
...
@@ -205,6 +248,7 @@ copy_config(struct error *err, struct nvc_container *cnt, const struct nvc_conta
const
char
*
bins_dir
=
cfg
->
bins_dir
;
const
char
*
libs_dir
=
cfg
->
libs_dir
;
const
char
*
libs32_dir
=
cfg
->
libs32_dir
;
const
char
*
cudart_dir
=
cfg
->
cudart_dir
;
const
char
*
ldconfig
=
cfg
->
ldconfig
;
char
*
rootfs
;
int
multiarch
,
ret
;
...
...
@@ -266,6 +310,8 @@ copy_config(struct error *err, struct nvc_container *cnt, const struct nvc_conta
}
}
}
if
(
cudart_dir
==
NULL
)
cudart_dir
=
CUDA_RUNTIME_DIR
;
if
(
ldconfig
==
NULL
)
{
/*
* Some distributions have a wrapper script around ldconfig to reduce package install time.
...
...
@@ -284,6 +330,8 @@ copy_config(struct error *err, struct nvc_container *cnt, const struct nvc_conta
goto
fail
;
if
((
cnt
->
cfg
.
libs32_dir
=
xstrdup
(
err
,
libs32_dir
))
==
NULL
)
goto
fail
;
if
((
cnt
->
cfg
.
cudart_dir
=
xstrdup
(
err
,
cudart_dir
))
==
NULL
)
goto
fail
;
if
((
cnt
->
cfg
.
ldconfig
=
xstrdup
(
err
,
ldconfig
))
==
NULL
)
goto
fail
;
rv
=
0
;
...
...
@@ -302,7 +350,7 @@ nvc_container_new(struct nvc_context *ctx, const struct nvc_container_config *cf
if
(
validate_context
(
ctx
)
<
0
)
return
(
NULL
);
if
(
validate_args
(
ctx
,
cfg
!=
NULL
&&
cfg
->
pid
>
0
&&
cfg
->
rootfs
!=
NULL
&&
!
str_empty
(
cfg
->
rootfs
)
&&
cfg
->
rootfs
[
0
]
==
'/'
&&
!
str_empty
(
cfg
->
bins_dir
)
&&
!
str_empty
(
cfg
->
libs_dir
)
&&
!
str_empty
(
cfg
->
libs32_dir
)
&&
!
str_empty
(
cfg
->
ldconfig
))
<
0
)
!
str_empty
(
cfg
->
bins_dir
)
&&
!
str_empty
(
cfg
->
libs_dir
)
&&
!
str_empty
(
cfg
->
libs32_dir
)
&&
!
str_empty
(
cfg
->
cudart_dir
)
&&
!
str_empty
(
cfg
->
ldconfig
))
<
0
)
return
(
NULL
);
if
(
opts
==
NULL
)
opts
=
default_container_opts
;
...
...
@@ -322,6 +370,10 @@ nvc_container_new(struct nvc_context *ctx, const struct nvc_container_config *cf
goto
fail
;
if
(
lookup_owner
(
&
ctx
->
err
,
cnt
)
<
0
)
goto
fail
;
if
(
!
(
flags
&
OPT_NO_CNTLIBS
))
{
if
(
find_library_paths
(
&
ctx
->
err
,
cnt
)
<
0
)
goto
fail
;
}
if
((
cnt
->
mnt_ns
=
find_namespace_path
(
&
ctx
->
err
,
cnt
,
"mnt"
))
==
NULL
)
goto
fail
;
if
(
!
(
flags
&
OPT_NO_CGROUPS
))
{
...
...
@@ -335,6 +387,7 @@ nvc_container_new(struct nvc_context *ctx, const struct nvc_container_config *cf
log_infof
(
"setting bins directory to %s"
,
cnt
->
cfg
.
bins_dir
);
log_infof
(
"setting libs directory to %s"
,
cnt
->
cfg
.
libs_dir
);
log_infof
(
"setting libs32 directory to %s"
,
cnt
->
cfg
.
libs32_dir
);
log_infof
(
"setting cudart directory to %s"
,
cnt
->
cfg
.
cudart_dir
);
log_infof
(
"setting ldconfig to %s%s"
,
cnt
->
cfg
.
ldconfig
,
(
cnt
->
cfg
.
ldconfig
[
0
]
==
'@'
)
?
" (host relative)"
:
""
);
log_infof
(
"setting mount namespace to %s"
,
cnt
->
mnt_ns
);
if
(
!
(
flags
&
OPT_NO_CGROUPS
))
...
...
@@ -355,8 +408,10 @@ nvc_container_free(struct nvc_container *cnt)
free
(
cnt
->
cfg
.
bins_dir
);
free
(
cnt
->
cfg
.
libs_dir
);
free
(
cnt
->
cfg
.
libs32_dir
);
free
(
cnt
->
cfg
.
cudart_dir
);
free
(
cnt
->
cfg
.
ldconfig
);
free
(
cnt
->
mnt_ns
);
free
(
cnt
->
dev_cg
);
array_free
(
cnt
->
libs
,
cnt
->
nlibs
);
free
(
cnt
);
}
src/nvc_info.c
浏览文件 @
35a9f27c
...
...
@@ -134,7 +134,7 @@ select_libraries(struct error *err, void *ptr, const char *root, const char *ori
/* Check the driver version. */
if
((
rv
=
str_has_suffix
(
lib
,
info
->
nvrm_version
))
==
false
)
goto
done
;
if
(
str_array_match
(
lib
,
graphics_libs_compat
,
nitems
(
graphics_libs_compat
)))
{
if
(
str_array_match
_prefix
(
lib
,
graphics_libs_compat
,
nitems
(
graphics_libs_compat
)))
{
/* Only choose OpenGL/EGL libraries issued by NVIDIA. */
if
((
rv
=
elftool_has_dependency
(
&
et
,
"libnvidia-glcore.so"
))
!=
false
)
goto
done
;
...
...
@@ -394,9 +394,9 @@ lookup_ipcs(struct error *err, struct nvc_driver_info *info, const char *root, i
bool
match_binary_flags
(
const
char
*
bin
,
int32_t
flags
)
{
if
((
flags
&
OPT_UTILITY_BINS
)
&&
str_array_match
(
bin
,
utility_bins
,
nitems
(
utility_bins
)))
if
((
flags
&
OPT_UTILITY_BINS
)
&&
str_array_match
_prefix
(
bin
,
utility_bins
,
nitems
(
utility_bins
)))
return
(
true
);
if
((
flags
&
OPT_COMPUTE_BINS
)
&&
str_array_match
(
bin
,
compute_bins
,
nitems
(
compute_bins
)))
if
((
flags
&
OPT_COMPUTE_BINS
)
&&
str_array_match
_prefix
(
bin
,
compute_bins
,
nitems
(
compute_bins
)))
return
(
true
);
return
(
false
);
}
...
...
@@ -404,15 +404,15 @@ match_binary_flags(const char *bin, int32_t flags)
bool
match_library_flags
(
const
char
*
lib
,
int32_t
flags
)
{
if
((
flags
&
OPT_UTILITY_LIBS
)
&&
str_array_match
(
lib
,
utility_libs
,
nitems
(
utility_libs
)))
if
((
flags
&
OPT_UTILITY_LIBS
)
&&
str_array_match
_prefix
(
lib
,
utility_libs
,
nitems
(
utility_libs
)))
return
(
true
);
if
((
flags
&
OPT_COMPUTE_LIBS
)
&&
str_array_match
(
lib
,
compute_libs
,
nitems
(
compute_libs
)))
if
((
flags
&
OPT_COMPUTE_LIBS
)
&&
str_array_match
_prefix
(
lib
,
compute_libs
,
nitems
(
compute_libs
)))
return
(
true
);
if
((
flags
&
OPT_VIDEO_LIBS
)
&&
str_array_match
(
lib
,
video_libs
,
nitems
(
video_libs
)))
if
((
flags
&
OPT_VIDEO_LIBS
)
&&
str_array_match
_prefix
(
lib
,
video_libs
,
nitems
(
video_libs
)))
return
(
true
);
if
((
flags
&
OPT_GRAPHICS_LIBS
)
&&
(
str_array_match
(
lib
,
graphics_libs
,
nitems
(
graphics_libs
))
||
str_array_match
(
lib
,
graphics_libs_glvnd
,
nitems
(
graphics_libs_glvnd
))
||
str_array_match
(
lib
,
graphics_libs_compat
,
nitems
(
graphics_libs_compat
))))
if
((
flags
&
OPT_GRAPHICS_LIBS
)
&&
(
str_array_match
_prefix
(
lib
,
graphics_libs
,
nitems
(
graphics_libs
))
||
str_array_match
_prefix
(
lib
,
graphics_libs_glvnd
,
nitems
(
graphics_libs_glvnd
))
||
str_array_match
_prefix
(
lib
,
graphics_libs_compat
,
nitems
(
graphics_libs_compat
))))
return
(
true
);
return
(
false
);
}
...
...
src/nvc_internal.h
浏览文件 @
35a9f27c
...
...
@@ -36,6 +36,8 @@
#define NV_UVM_PROC_DRIVER "/proc/driver/nvidia-uvm"
#define NV_APP_PROFILE_DIR "/etc/nvidia/nvidia-application-profiles-rc.d"
#define CUDA_RUNTIME_DIR "/usr/local/cuda"
struct
nvc_context
{
bool
initialized
;
struct
error
err
;
...
...
@@ -51,6 +53,8 @@ struct nvc_container {
gid_t
gid
;
char
*
mnt_ns
;
char
*
dev_cg
;
char
**
libs
;
size_t
nlibs
;
};
enum
{
...
...
src/nvc_mount.c
浏览文件 @
35a9f27c
...
...
@@ -33,6 +33,7 @@ static void unmount(const char *);
static
int
setup_cgroup
(
struct
error
*
,
const
char
*
,
dev_t
);
static
int
symlink_library
(
struct
error
*
,
const
char
*
,
const
char
*
,
const
char
*
,
uid_t
,
gid_t
);
static
int
symlink_libraries
(
struct
error
*
,
const
struct
nvc_container
*
,
const
char
*
const
[],
size_t
);
static
void
filter_libraries
(
const
struct
nvc_driver_info
*
,
char
*
[],
size_t
*
);
static
char
**
mount_files
(
struct
error
*
err
,
const
char
*
root
,
const
struct
nvc_container
*
cnt
,
const
char
*
dir
,
char
*
paths
[],
size_t
size
)
...
...
@@ -397,7 +398,7 @@ symlink_libraries(struct error *err, const struct nvc_container *cnt, const char
lib
=
basename
(
paths
[
i
]);
if
(
str_has_prefix
(
lib
,
"libcuda.so"
))
{
/* XXX Many applications wrongly assume that libcuda.so exists (e.g. with dlopen). */
if
(
symlink_library
(
err
,
paths
[
i
],
lib
,
"libcuda.so"
,
cnt
->
uid
,
cnt
->
gid
)
<
0
)
if
(
symlink_library
(
err
,
paths
[
i
],
SONAME_LIBCUDA
,
"libcuda.so"
,
cnt
->
uid
,
cnt
->
gid
)
<
0
)
return
(
-
1
);
}
else
if
(
str_has_prefix
(
lib
,
"libGLX_nvidia.so"
))
{
/* XXX GLVND requires this symlink for indirect GLX support. */
...
...
@@ -408,6 +409,27 @@ symlink_libraries(struct error *err, const struct nvc_container *cnt, const char
return
(
0
);
}
static
void
filter_libraries
(
const
struct
nvc_driver_info
*
info
,
char
*
paths
[],
size_t
*
size
)
{
char
*
lib
,
*
maj
;
/*
* XXX Filter out any library that matches the major version of RM to prevent us from
* running into an unsupported configurations (e.g. CUDA compat on Geforce or non-LTS drivers).
*/
for
(
size_t
i
=
0
;
i
<
*
size
;
++
i
)
{
lib
=
basename
(
paths
[
i
]);
if
((
maj
=
strstr
(
lib
,
".so."
))
!=
NULL
)
{
maj
+=
strlen
(
".so."
);
if
(
strncmp
(
info
->
nvrm_version
,
maj
,
strspn
(
maj
,
"0123456789"
)))
continue
;
}
paths
[
i
]
=
NULL
;
}
array_pack
(
paths
,
size
);
}
int
nvc_driver_mount
(
struct
nvc_context
*
ctx
,
const
struct
nvc_container
*
cnt
,
const
struct
nvc_driver_info
*
info
)
{
...
...
@@ -423,7 +445,7 @@ nvc_driver_mount(struct nvc_context *ctx, const struct nvc_container *cnt, const
if
(
ns_enter
(
&
ctx
->
err
,
cnt
->
mnt_ns
,
CLONE_NEWNS
)
<
0
)
return
(
-
1
);
nmnt
=
2
+
info
->
nbins
+
info
->
nlibs
+
info
->
nlibs32
+
info
->
nipcs
+
info
->
ndevs
;
nmnt
=
2
+
info
->
nbins
+
info
->
nlibs
+
cnt
->
nlibs
+
info
->
nlibs32
+
info
->
nipcs
+
info
->
ndevs
;
mnt
=
ptr
=
(
const
char
**
)
array_new
(
&
ctx
->
err
,
nmnt
);
if
(
mnt
==
NULL
)
goto
fail
;
...
...
@@ -431,12 +453,14 @@ nvc_driver_mount(struct nvc_context *ctx, const struct nvc_container *cnt, const
/* Procfs mount */
if
((
*
ptr
++
=
mount_procfs
(
&
ctx
->
err
,
ctx
->
cfg
.
root
,
cnt
))
==
NULL
)
goto
fail
;
/* Application profile mount */
if
(
cnt
->
flags
&
OPT_GRAPHICS_LIBS
)
{
if
((
*
ptr
++
=
mount_app_profile
(
&
ctx
->
err
,
cnt
))
==
NULL
)
goto
fail
;
}
/* Binary and library mounts */
/* Host binary and library mounts */
if
(
info
->
bins
!=
NULL
&&
info
->
nbins
>
0
)
{
if
((
tmp
=
(
const
char
**
)
mount_files
(
&
ctx
->
err
,
ctx
->
cfg
.
root
,
cnt
,
cnt
->
cfg
.
bins_dir
,
info
->
bins
,
info
->
nbins
))
==
NULL
)
goto
fail
;
...
...
@@ -457,6 +481,24 @@ nvc_driver_mount(struct nvc_context *ctx, const struct nvc_container *cnt, const
}
if
(
symlink_libraries
(
&
ctx
->
err
,
cnt
,
mnt
,
(
size_t
)(
ptr
-
mnt
))
<
0
)
goto
fail
;
/* Container library mounts */
if
(
cnt
->
libs
!=
NULL
&&
cnt
->
nlibs
>
0
)
{
size_t
nlibs
=
cnt
->
nlibs
;
char
**
libs
=
array_copy
(
&
ctx
->
err
,
(
const
char
*
const
*
)
cnt
->
libs
,
cnt
->
nlibs
);
if
(
libs
==
NULL
)
goto
fail
;
filter_libraries
(
info
,
libs
,
&
nlibs
);
if
((
tmp
=
(
const
char
**
)
mount_files
(
&
ctx
->
err
,
cnt
->
cfg
.
rootfs
,
cnt
,
cnt
->
cfg
.
libs_dir
,
libs
,
nlibs
))
==
NULL
)
{
free
(
libs
);
goto
fail
;
}
ptr
=
array_append
(
ptr
,
tmp
,
array_size
(
tmp
));
free
(
tmp
);
free
(
libs
);
}
/* IPC mounts */
for
(
size_t
i
=
0
;
i
<
info
->
nipcs
;
++
i
)
{
/* XXX Only utility libraries require persistenced IPC, everything else is compute only. */
...
...
@@ -468,6 +510,7 @@ nvc_driver_mount(struct nvc_context *ctx, const struct nvc_container *cnt, const
if
((
*
ptr
++
=
mount_ipc
(
&
ctx
->
err
,
ctx
->
cfg
.
root
,
cnt
,
info
->
ipcs
[
i
]))
==
NULL
)
goto
fail
;
}
/* Device mounts */
for
(
size_t
i
=
0
;
i
<
info
->
ndevs
;
++
i
)
{
/* XXX Only compute libraries require specific devices (e.g. UVM). */
...
...
src/options.h
浏览文件 @
35a9f27c
...
...
@@ -55,17 +55,18 @@ enum {
OPT_STANDALONE
=
1
<<
1
,
OPT_NO_CGROUPS
=
1
<<
2
,
OPT_NO_DEVBIND
=
1
<<
3
,
OPT_UTILITY_LIBS
=
1
<<
4
,
OPT_COMPUTE_LIBS
=
1
<<
5
,
OPT_VIDEO_LIBS
=
1
<<
6
,
OPT_GRAPHICS_LIBS
=
1
<<
7
,
OPT_DISPLAY
=
1
<<
8
,
OPT_UTILITY_BINS
=
1
<<
9
,
OPT_COMPUTE_BINS
=
1
<<
10
,
OPT_NO_CNTLIBS
=
1
<<
4
,
OPT_UTILITY_LIBS
=
1
<<
5
,
OPT_COMPUTE_LIBS
=
1
<<
6
,
OPT_VIDEO_LIBS
=
1
<<
7
,
OPT_GRAPHICS_LIBS
=
1
<<
8
,
OPT_DISPLAY
=
1
<<
9
,
OPT_UTILITY_BINS
=
1
<<
10
,
OPT_COMPUTE_BINS
=
1
<<
11
,
#if defined(__powerpc64__)
/* ppc64le doesn't support compat32. */
OPT_COMPAT32
=
1
<<
0
,
#else
OPT_COMPAT32
=
1
<<
1
1
,
OPT_COMPAT32
=
1
<<
1
2
,
#endif
/* defined(__powerpc64__) */
};
...
...
@@ -74,6 +75,7 @@ static const struct option container_opts[] = {
{
"standalone"
,
OPT_STANDALONE
},
{
"no-cgroups"
,
OPT_NO_CGROUPS
},
{
"no-devbind"
,
OPT_NO_DEVBIND
},
{
"no-cntlibs"
,
OPT_NO_CNTLIBS
},
{
"utility"
,
OPT_UTILITY_BINS
|
OPT_UTILITY_LIBS
},
{
"compute"
,
OPT_COMPUTE_BINS
|
OPT_COMPUTE_LIBS
},
{
"video"
,
OPT_VIDEO_LIBS
|
OPT_COMPUTE_LIBS
},
...
...
src/utils.c
浏览文件 @
35a9f27c
...
...
@@ -172,7 +172,7 @@ str_empty(const char *str)
}
bool
str_array_match
(
const
char
*
str
,
const
char
*
const
arr
[],
size_t
size
)
str_array_match
_prefix
(
const
char
*
str
,
const
char
*
const
arr
[],
size_t
size
)
{
for
(
size_t
i
=
0
;
i
<
size
;
++
i
)
{
if
(
str_has_prefix
(
str
,
arr
[
i
]))
...
...
@@ -181,6 +181,16 @@ str_array_match(const char *str, const char * const arr[], size_t size)
return
(
false
);
}
bool
str_array_match
(
const
char
*
str
,
const
char
*
const
arr
[],
size_t
size
)
{
for
(
size_t
i
=
0
;
i
<
size
;
++
i
)
{
if
(
str_equal
(
str
,
arr
[
i
]))
return
(
true
);
}
return
(
false
);
}
int
str_join
(
struct
error
*
err
,
char
**
s1
,
const
char
*
s2
,
const
char
*
sep
)
{
...
...
@@ -327,7 +337,7 @@ ns_enter(struct error *err, const char *path, int nstype)
char
**
array_new
(
struct
error
*
err
,
size_t
size
)
{
char
**
arr
=
NULL
;
char
**
arr
;
arr
=
xcalloc
(
err
,
size
,
sizeof
(
*
arr
));
return
(
arr
);
...
...
@@ -350,6 +360,17 @@ array_append(const char **ptr, const char * const arr[], size_t size)
return
(
ptr
+
size
);
}
char
**
array_copy
(
struct
error
*
err
,
const
char
*
const
arr
[],
size_t
size
)
{
char
**
ptr
;
if
((
ptr
=
array_new
(
err
,
size
))
==
NULL
)
return
(
NULL
);
array_append
((
const
char
**
)
ptr
,
arr
,
size
);
return
(
ptr
);
}
void
array_pack
(
char
*
arr
[],
size_t
*
size
)
{
...
...
src/utils.h
浏览文件 @
35a9f27c
...
...
@@ -49,6 +49,7 @@ bool str_case_equal(const char *, const char *);
bool
str_has_prefix
(
const
char
*
,
const
char
*
);
bool
str_has_suffix
(
const
char
*
,
const
char
*
);
bool
str_empty
(
const
char
*
);
bool
str_array_match_prefix
(
const
char
*
,
const
char
*
const
[],
size_t
);
bool
str_array_match
(
const
char
*
,
const
char
*
const
[],
size_t
);
int
str_to_pid
(
struct
error
*
,
const
char
*
,
pid_t
*
);
int
str_to_ugid
(
struct
error
*
,
char
*
,
uid_t
*
,
gid_t
*
);
...
...
@@ -60,6 +61,7 @@ int ns_enter(struct error *, const char *, int);
char
**
array_new
(
struct
error
*
,
size_t
);
void
array_free
(
char
*
[],
size_t
);
void
array_pack
(
char
*
[],
size_t
*
);
char
**
array_copy
(
struct
error
*
,
const
char
*
const
[],
size_t
);
size_t
array_size
(
const
char
*
const
[]);
const
char
**
array_append
(
const
char
**
,
const
char
*
const
[],
size_t
);
...
...
src/xfuncs.h
浏览文件 @
35a9f27c
...
...
@@ -10,7 +10,9 @@
#include <sys/types.h>
#include <dlfcn.h>
#include <errno.h>
#include <fcntl.h>
#include <glob.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
...
...
@@ -30,6 +32,7 @@ static inline void *xdlopen(struct error *, const char *, int);
static
inline
int
xdlclose
(
struct
error
*
,
void
*
);
static
inline
int
xmount
(
struct
error
*
,
const
char
*
,
const
char
*
,
const
char
*
,
unsigned
long
,
const
void
*
);
static
inline
int
xglob
(
struct
error
*
,
const
char
*
,
int
,
int
(
*
)(
const
char
*
,
int
),
glob_t
*
);
#include "error.h"
...
...
@@ -154,4 +157,21 @@ xmount(struct error *err, const char *source, const char *target,
return
(
rv
);
}
static
inline
int
xglob
(
struct
error
*
err
,
const
char
*
pattern
,
int
flags
,
int
(
*
errfn
)(
const
char
*
,
int
),
glob_t
*
pglob
)
{
int
rv
;
rv
=
glob
(
pattern
,
flags
,
errfn
,
pglob
);
if
(
rv
!=
0
&&
rv
!=
GLOB_NOMATCH
&&
errno
!=
ENOENT
)
{
error_set
(
err
,
"glob search failed: %s"
,
pattern
);
return
(
-
1
);
}
if
(
rv
!=
0
)
{
pglob
->
gl_pathc
=
0
;
pglob
->
gl_pathv
=
NULL
;
}
return
(
0
);
}
#endif
/* HEADER_XFUNCS_H */
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录