Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
libvirt
提交
4a4e272f
L
libvirt
项目概览
openeuler
/
libvirt
通知
3
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
L
libvirt
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
提交
4a4e272f
编写于
2月 20, 2008
作者:
D
Daniel P. Berrange
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Added storage backend helper APIs
上级
20878720
变更
7
隐藏空白更改
内联
并排
Showing
7 changed file
with
560 addition
and
1 deletion
+560
-1
ChangeLog
ChangeLog
+8
-0
configure.in
configure.in
+39
-0
libvirt.spec.in
libvirt.spec.in
+1
-0
src/Makefile.am
src/Makefile.am
+2
-1
src/storage_backend.c
src/storage_backend.c
+470
-0
src/storage_backend.h
src/storage_backend.h
+38
-0
tests/Makefile.am
tests/Makefile.am
+2
-0
未找到文件。
ChangeLog
浏览文件 @
4a4e272f
Wed Feb 20 10:32:27 EST 2008 Daniel P. Berrange <berrange@redhat.com>
* configure.in: Add check for selinux library
* libvirt.spec.in: Add BuildRequires on libselinux-devel
* src/Makefile.am, tests/Makefile.am: Add selinux build flags
* src/storage_backend.c, src/storage_backend.h: Add some
helper routines for storage backend impls
Wed Feb 20 10:26:27 EST 2008 Daniel P. Berrange <berrange@redhat.com>
* Makefile.maint: Add virStorageReportError to locale check rule
...
...
configure.in
浏览文件 @
4a4e272f
...
...
@@ -473,6 +473,40 @@ AM_CONDITIONAL(HAVE_AVAHI, [test "x$with_avahi" = "xyes"])
AC_SUBST(AVAHI_CFLAGS)
AC_SUBST(AVAHI_LIBS)
dnl SELinux
AC_ARG_WITH(selinux,
[ --with-selinux use SELinux to manage security],
[],
[with_selinux=check])
SELINUX_CFLAGS=
SELINUX_LIBS=
if test "$with_selinux" != "no"; then
old_cflags="$CFLAGS"
old_libs="$LIBS"
if test "$with_selinux" = "check"; then
AC_CHECK_HEADER([selinux/selinux.h],[],[with_selinux=no])
AC_CHECK_LIB(selinux, fgetfilecon,[],[with_selinux=no])
if test "$with_selinux" != "no"; then
with_selinux="yes"
fi
else
AC_CHECK_HEADER([selinux/selinux.h],[],
[AC_MSG_ERROR([You must install the SELinux development package in order to compile libvirt])])
AC_CHECK_LIB(selinux, fgetfilecon,[],
[AC_MSG_ERROR([You must install the SELinux development package in order to compile and run libvirt])])
fi
CFLAGS="$old_cflags"
LIBS="$old_libs"
fi
if test "$with_selinux" = "yes"; then
SELINUX_LIBS="-lselinux"
AC_DEFINE_UNQUOTED(HAVE_SELINUX, 1, [whether SELinux is available for security])
fi
AM_CONDITIONAL(HAVE_SELINUX, [test "$with_selinux" != "no"])
AC_SUBST(SELINUX_CFLAGS)
AC_SUBST(SELINUX_LIBS)
dnl virsh libraries
AC_CHECK_HEADERS([readline/readline.h])
...
...
@@ -745,6 +779,11 @@ AC_MSG_NOTICE([ polkit: $POLKIT_CFLAGS $POLKIT_LIBS])
else
AC_MSG_NOTICE([ polkit: no])
fi
if test "$with_selinux" = "yes" ; then
AC_MSG_NOTICE([ selinux: $SELINUX_CFLAGS $SELINUX_LIBS])
else
AC_MSG_NOTICE([ selinux: no])
fi
AC_MSG_NOTICE([])
AC_MSG_NOTICE([Miscellaneous])
AC_MSG_NOTICE([])
...
...
libvirt.spec.in
浏览文件 @
4a4e272f
...
...
@@ -41,6 +41,7 @@ BuildRequires: ncurses-devel
BuildRequires: gettext
BuildRequires: gnutls-devel
BuildRequires: avahi-devel
BuildRequires: libselinux-devel
BuildRequires: dnsmasq
BuildRequires: bridge-utils
BuildRequires: qemu
...
...
src/Makefile.am
浏览文件 @
4a4e272f
...
...
@@ -8,6 +8,7 @@ INCLUDES = \
$(LIBXML_CFLAGS)
\
$(GNUTLS_CFLAGS)
\
$(SASL_CFLAGS)
\
$(SELINUX_CFLAGS)
\
-DBINDIR
=
\"
"
$(libexecdir)
"
\"
\
-DSBINDIR
=
\"
"
$(sbindir)
"
\"
\
-DSYSCONF_DIR
=
"
\"
$(sysconfdir)
\"
"
\
...
...
@@ -67,7 +68,7 @@ SERVER_SOURCES = \
../qemud/remote_protocol.c ../qemud/remote_protocol.h
libvirt_la_SOURCES
=
$(CLIENT_SOURCES)
$(SERVER_SOURCES)
libvirt_la_LIBADD
=
$(LIBXML_LIBS)
$(GNUTLS_LIBS)
$(SASL_LIBS)
\
libvirt_la_LIBADD
=
$(LIBXML_LIBS)
$(GNUTLS_LIBS)
$(SASL_LIBS)
$(SELINUX_LIBS)
\
@CYGWIN_EXTRA_LIBADD@ ../gnulib/lib/libgnu.la
libvirt_la_LDFLAGS
=
-Wl
,--version-script
=
$(srcdir)
/libvirt_sym.version
\
-version-info
@LIBVIRT_VERSION_INFO@
\
...
...
src/storage_backend.c
浏览文件 @
4a4e272f
...
...
@@ -28,6 +28,14 @@
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdint.h>
#include <sys/stat.h>
#include <dirent.h>
#if HAVE_SELINUX
#include <selinux/selinux.h>
#endif
#include "util.h"
...
...
@@ -73,6 +81,468 @@ virStorageBackendToString(int type) {
}
int
virStorageBackendUpdateVolInfo
(
virConnectPtr
conn
,
virStorageVolDefPtr
vol
,
int
withCapacity
)
{
int
ret
,
fd
;
if
((
fd
=
open
(
vol
->
target
.
path
,
O_RDONLY
))
<
0
)
{
virStorageReportError
(
conn
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"cannot open volume '%s': %s"
),
vol
->
target
.
path
,
strerror
(
errno
));
return
-
1
;
}
ret
=
virStorageBackendUpdateVolInfoFD
(
conn
,
vol
,
fd
,
withCapacity
);
close
(
fd
);
return
ret
;
}
int
virStorageBackendUpdateVolInfoFD
(
virConnectPtr
conn
,
virStorageVolDefPtr
vol
,
int
fd
,
int
withCapacity
)
{
struct
stat
sb
;
#if HAVE_SELINUX
security_context_t
filecon
=
NULL
;
#endif
if
(
fstat
(
fd
,
&
sb
)
<
0
)
{
virStorageReportError
(
conn
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"cannot stat file '%s': %s"
),
vol
->
target
.
path
,
strerror
(
errno
));
return
-
1
;
}
if
(
!
S_ISREG
(
sb
.
st_mode
)
&&
!
S_ISCHR
(
sb
.
st_mode
)
&&
!
S_ISBLK
(
sb
.
st_mode
))
return
-
2
;
if
(
S_ISREG
(
sb
.
st_mode
))
{
vol
->
allocation
=
(
unsigned
long
long
)
sb
.
st_blocks
*
(
unsigned
long
long
)
sb
.
st_blksize
;
/* Regular files may be sparse, so logical size (capacity) is not same
* as actual allocation above
*/
if
(
withCapacity
)
vol
->
capacity
=
sb
.
st_size
;
}
else
{
off_t
end
;
/* XXX this is POSIX compliant, but doesn't work for for CHAR files,
* only BLOCK. There is a Linux specific ioctl() for getting
* size of both CHAR / BLOCK devices we should check for in
* configure
*/
end
=
lseek
(
fd
,
0
,
SEEK_END
);
if
(
end
==
(
off_t
)
-
1
)
{
virStorageReportError
(
conn
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"cannot seek to end of file '%s':%s"
),
vol
->
target
.
path
,
strerror
(
errno
));
return
-
1
;
}
vol
->
allocation
=
end
;
if
(
withCapacity
)
vol
->
capacity
=
end
;
}
vol
->
target
.
perms
.
mode
=
sb
.
st_mode
;
vol
->
target
.
perms
.
uid
=
sb
.
st_uid
;
vol
->
target
.
perms
.
gid
=
sb
.
st_gid
;
free
(
vol
->
target
.
perms
.
label
);
vol
->
target
.
perms
.
label
=
NULL
;
#if HAVE_SELINUX
if
(
fgetfilecon
(
fd
,
&
filecon
)
==
-
1
)
{
virStorageReportError
(
conn
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"cannot get file context of %s: %s"
),
vol
->
target
.
path
,
strerror
(
errno
));
return
-
1
;
}
vol
->
target
.
perms
.
label
=
strdup
(
filecon
);
if
(
vol
->
target
.
perms
.
label
==
NULL
)
{
virStorageReportError
(
conn
,
VIR_ERR_NO_MEMORY
,
_
(
"context"
));
return
-
1
;
}
freecon
(
filecon
);
#else
vol
->
target
.
perms
.
label
=
NULL
;
#endif
return
0
;
}
/*
* Given a volume path directly in /dev/XXX, iterate over the
* entries in the directory pool->def->target.path and find the
* first symlink pointing to the volume path.
*
* If, the target.path is /dev/, then return the original volume
* path.
*
* If no symlink is found, then return the original volume path
*
* Typically target.path is one of the /dev/disk/by-XXX dirs
* with stable paths.
*/
char
*
virStorageBackendStablePath
(
virConnectPtr
conn
,
virStoragePoolObjPtr
pool
,
char
*
devpath
)
{
DIR
*
dh
;
struct
dirent
*
dent
;
/* Short circuit if pool has no target, or if its /dev */
if
(
pool
->
def
->
target
.
path
==
NULL
||
STREQ
(
pool
->
def
->
target
.
path
,
"/dev"
)
||
STREQ
(
pool
->
def
->
target
.
path
,
"/dev/"
))
return
devpath
;
/* The pool is pointing somewhere like /dev/disk/by-path
* or /dev/disk/by-id, so we need to check all symlinks in
* the target directory and figure out which one points
* to this device node
*/
if
((
dh
=
opendir
(
pool
->
def
->
target
.
path
))
==
NULL
)
{
virStorageReportError
(
conn
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"cannot read dir %s: %s"
),
pool
->
def
->
target
.
path
,
strerror
(
errno
));
return
NULL
;
}
while
((
dent
=
readdir
(
dh
))
!=
NULL
)
{
char
*
stablepath
;
if
(
dent
->
d_name
[
0
]
==
'.'
)
continue
;
stablepath
=
malloc
(
strlen
(
pool
->
def
->
target
.
path
)
+
1
+
strlen
(
dent
->
d_name
)
+
1
);
if
(
stablepath
==
NULL
)
{
virStorageReportError
(
conn
,
VIR_ERR_NO_MEMORY
,
_
(
"path"
));
closedir
(
dh
);
return
NULL
;
}
strcpy
(
stablepath
,
pool
->
def
->
target
.
path
);
strcat
(
stablepath
,
"/"
);
strcat
(
stablepath
,
dent
->
d_name
);
if
(
virFileLinkPointsTo
(
stablepath
,
devpath
))
{
closedir
(
dh
);
return
stablepath
;
}
free
(
stablepath
);
}
closedir
(
dh
);
/* Couldn't find any matching stable link so give back
* the original non-stable dev path
*/
return
devpath
;
}
/*
* Run an external program.
*
* Read its output and apply a series of regexes to each line
* When the entire set of regexes has matched consequetively
* then run a callback passing in all the matches
*/
int
virStorageBackendRunProgRegex
(
virConnectPtr
conn
,
virStoragePoolObjPtr
pool
,
const
char
**
prog
,
int
nregex
,
const
char
**
regex
,
int
*
nvars
,
virStorageBackendListVolRegexFunc
func
,
void
*
data
)
{
int
child
=
0
,
fd
=
-
1
,
exitstatus
,
err
,
failed
=
1
;
FILE
*
list
=
NULL
;
regex_t
*
reg
;
regmatch_t
*
vars
=
NULL
;
char
line
[
1024
];
int
maxReg
=
0
,
i
,
j
;
int
totgroups
=
0
,
ngroup
=
0
,
maxvars
=
0
;
char
**
groups
;
/* Compile all regular expressions */
if
((
reg
=
calloc
(
nregex
,
sizeof
(
*
reg
)))
==
NULL
)
{
virStorageReportError
(
conn
,
VIR_ERR_NO_MEMORY
,
_
(
"regex"
));
return
-
1
;
}
for
(
i
=
0
;
i
<
nregex
;
i
++
)
{
err
=
regcomp
(
&
reg
[
i
],
regex
[
i
],
REG_EXTENDED
);
if
(
err
!=
0
)
{
char
error
[
100
];
regerror
(
err
,
&
reg
[
i
],
error
,
sizeof
(
error
));
virStorageReportError
(
conn
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"Failed to compile regex %s"
),
error
);
for
(
j
=
0
;
j
<=
i
;
j
++
)
regfree
(
&
reg
[
j
]);
free
(
reg
);
return
-
1
;
}
totgroups
+=
nvars
[
i
];
if
(
nvars
[
i
]
>
maxvars
)
maxvars
=
nvars
[
i
];
}
/* Storage for matched variables */
if
((
groups
=
calloc
(
totgroups
,
sizeof
(
*
groups
)))
==
NULL
)
{
virStorageReportError
(
conn
,
VIR_ERR_NO_MEMORY
,
_
(
"regex groups"
));
goto
cleanup
;
}
if
((
vars
=
calloc
(
maxvars
+
1
,
sizeof
(
*
vars
)))
==
NULL
)
{
virStorageReportError
(
conn
,
VIR_ERR_NO_MEMORY
,
_
(
"regex groups"
));
goto
cleanup
;
}
/* Run the program and capture its output */
if
(
virExec
(
conn
,
(
char
**
)
prog
,
&
child
,
-
1
,
&
fd
,
NULL
)
<
0
)
{
goto
cleanup
;
}
if
((
list
=
fdopen
(
fd
,
"r"
))
==
NULL
)
{
virStorageReportError
(
conn
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"cannot read fd"
));
goto
cleanup
;
}
while
(
fgets
(
line
,
sizeof
(
line
),
list
)
!=
NULL
)
{
/* Strip trailing newline */
int
len
=
strlen
(
line
);
if
(
len
&&
line
[
len
-
1
]
==
'\n'
)
line
[
len
-
1
]
=
'\0'
;
for
(
i
=
0
;
i
<=
maxReg
&&
i
<
nregex
;
i
++
)
{
if
(
regexec
(
&
reg
[
i
],
line
,
nvars
[
i
]
+
1
,
vars
,
0
)
==
0
)
{
maxReg
++
;
if
(
i
==
0
)
ngroup
=
0
;
/* NULL terminate each captured group in the line */
for
(
j
=
0
;
j
<
nvars
[
i
]
;
j
++
)
{
/* NB vars[0] is the full pattern, so we offset j by 1 */
line
[
vars
[
j
+
1
].
rm_eo
]
=
'\0'
;
if
((
groups
[
ngroup
++
]
=
strdup
(
line
+
vars
[
j
+
1
].
rm_so
))
==
NULL
)
{
virStorageReportError
(
conn
,
VIR_ERR_NO_MEMORY
,
_
(
"regex groups"
));
goto
cleanup
;
}
}
/* We're matching on the last regex, so callback time */
if
(
i
==
(
nregex
-
1
))
{
if
(((
*
func
)(
conn
,
pool
,
groups
,
data
))
<
0
)
goto
cleanup
;
/* Release matches & restart to matching the first regex */
for
(
j
=
0
;
j
<
totgroups
;
j
++
)
{
free
(
groups
[
j
]);
groups
[
j
]
=
NULL
;
}
maxReg
=
0
;
ngroup
=
0
;
}
}
}
}
failed
=
0
;
cleanup:
if
(
groups
)
{
for
(
j
=
0
;
j
<
totgroups
;
j
++
)
free
(
groups
[
j
]);
free
(
groups
);
}
free
(
vars
);
for
(
i
=
0
;
i
<
nregex
;
i
++
)
regfree
(
&
reg
[
i
]);
free
(
reg
);
if
(
list
)
fclose
(
list
);
else
close
(
fd
);
while
((
err
=
waitpid
(
child
,
&
exitstatus
,
0
)
==
-
1
)
&&
errno
==
EINTR
);
/* Don't bother checking exit status if we already failed */
if
(
failed
)
return
-
1
;
if
(
err
==
-
1
)
{
virStorageReportError
(
conn
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"failed to wait for command: %s"
),
strerror
(
errno
));
return
-
1
;
}
else
{
if
(
WIFEXITED
(
exitstatus
))
{
if
(
WEXITSTATUS
(
exitstatus
)
!=
0
)
{
virStorageReportError
(
conn
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"non-zero exit status from command %d"
),
WEXITSTATUS
(
exitstatus
));
return
-
1
;
}
}
else
{
virStorageReportError
(
conn
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"command did not exit cleanly"
));
return
-
1
;
}
}
return
0
;
}
/*
* Run an external program and read from its standard output
* a stream of tokens from IN_STREAM, applying FUNC to
* each successive sequence of N_COLUMNS tokens.
* If FUNC returns < 0, stop processing input and return -1.
* Return -1 if N_COLUMNS == 0.
* Return -1 upon memory allocation error.
* If the number of input tokens is not a multiple of N_COLUMNS,
* then the final FUNC call will specify a number smaller than N_COLUMNS.
* If there are no input tokens (empty input), call FUNC with N_COLUMNS == 0.
*/
int
virStorageBackendRunProgNul
(
virConnectPtr
conn
,
virStoragePoolObjPtr
pool
,
const
char
**
prog
,
size_t
n_columns
,
virStorageBackendListVolNulFunc
func
,
void
*
data
)
{
size_t
n_tok
=
0
;
int
child
=
0
,
fd
=
-
1
,
exitstatus
;
FILE
*
fp
=
NULL
;
char
**
v
;
int
err
=
-
1
;
int
w_err
;
int
i
;
if
(
n_columns
==
0
)
return
-
1
;
if
(
n_columns
>
SIZE_MAX
/
sizeof
*
v
||
(
v
=
malloc
(
n_columns
*
sizeof
*
v
))
==
NULL
)
{
virStorageReportError
(
conn
,
VIR_ERR_NO_MEMORY
,
_
(
"n_columns too large"
));
return
-
1
;
}
for
(
i
=
0
;
i
<
n_columns
;
i
++
)
v
[
i
]
=
NULL
;
/* Run the program and capture its output */
if
(
virExec
(
conn
,
(
char
**
)
prog
,
&
child
,
-
1
,
&
fd
,
NULL
)
<
0
)
{
goto
cleanup
;
}
if
((
fp
=
fdopen
(
fd
,
"r"
))
==
NULL
)
{
virStorageReportError
(
conn
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"cannot read fd"
));
goto
cleanup
;
}
while
(
1
)
{
char
*
buf
=
NULL
;
size_t
buf_len
=
0
;
/* Be careful: even when it returns -1,
this use of getdelim allocates memory. */
ssize_t
tok_len
=
getdelim
(
&
buf
,
&
buf_len
,
0
,
fp
);
v
[
n_tok
]
=
buf
;
if
(
tok_len
<
0
)
{
/* Maybe EOF, maybe an error.
If n_tok > 0, then we know it's an error. */
if
(
n_tok
&&
func
(
conn
,
pool
,
n_tok
,
v
,
data
)
<
0
)
goto
cleanup
;
break
;
}
++
n_tok
;
if
(
n_tok
==
n_columns
)
{
if
(
func
(
conn
,
pool
,
n_tok
,
v
,
data
)
<
0
)
goto
cleanup
;
n_tok
=
0
;
for
(
i
=
0
;
i
<
n_columns
;
i
++
)
{
free
(
v
[
i
]);
v
[
i
]
=
NULL
;
}
}
}
if
(
feof
(
fp
))
err
=
0
;
else
virStorageReportError
(
conn
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"read error: %s"
),
strerror
(
errno
));
cleanup:
for
(
i
=
0
;
i
<
n_columns
;
i
++
)
free
(
v
[
i
]);
free
(
v
);
if
(
fp
)
fclose
(
fp
);
else
close
(
fd
);
while
((
w_err
=
waitpid
(
child
,
&
exitstatus
,
0
)
==
-
1
)
&&
errno
==
EINTR
)
/* empty */
;
/* Don't bother checking exit status if we already failed */
if
(
err
<
0
)
return
-
1
;
if
(
w_err
==
-
1
)
{
virStorageReportError
(
conn
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"failed to wait for command: %s"
),
strerror
(
errno
));
return
-
1
;
}
else
{
if
(
WIFEXITED
(
exitstatus
))
{
if
(
WEXITSTATUS
(
exitstatus
)
!=
0
)
{
virStorageReportError
(
conn
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"non-zero exit status from command %d"
),
WEXITSTATUS
(
exitstatus
));
return
-
1
;
}
}
else
{
virStorageReportError
(
conn
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"command did not exit cleanly"
));
return
-
1
;
}
}
return
0
;
}
/*
* vim: set tabstop=4:
* vim: set shiftwidth=4:
...
...
src/storage_backend.h
浏览文件 @
4a4e272f
...
...
@@ -103,6 +103,44 @@ virStorageBackendVolOptionsPtr virStorageBackendVolOptionsForType(int type);
int
virStorageBackendFromString
(
const
char
*
type
);
const
char
*
virStorageBackendToString
(
int
type
);
int
virStorageBackendUpdateVolInfo
(
virConnectPtr
conn
,
virStorageVolDefPtr
vol
,
int
withCapacity
);
int
virStorageBackendUpdateVolInfoFD
(
virConnectPtr
conn
,
virStorageVolDefPtr
vol
,
int
fd
,
int
withCapacity
);
char
*
virStorageBackendStablePath
(
virConnectPtr
conn
,
virStoragePoolObjPtr
pool
,
char
*
devpath
);
typedef
int
(
*
virStorageBackendListVolRegexFunc
)(
virConnectPtr
conn
,
virStoragePoolObjPtr
pool
,
char
**
const
groups
,
void
*
data
);
typedef
int
(
*
virStorageBackendListVolNulFunc
)(
virConnectPtr
conn
,
virStoragePoolObjPtr
pool
,
size_t
n_tokens
,
char
**
const
groups
,
void
*
data
);
int
virStorageBackendRunProgRegex
(
virConnectPtr
conn
,
virStoragePoolObjPtr
pool
,
const
char
**
prog
,
int
nregex
,
const
char
**
regex
,
int
*
nvars
,
virStorageBackendListVolRegexFunc
func
,
void
*
data
);
int
virStorageBackendRunProgNul
(
virConnectPtr
conn
,
virStoragePoolObjPtr
pool
,
const
char
**
prog
,
size_t
n_columns
,
virStorageBackendListVolNulFunc
func
,
void
*
data
);
#endif
/* __VIR_STORAGE_BACKEND_H__ */
...
...
tests/Makefile.am
浏览文件 @
4a4e272f
...
...
@@ -20,6 +20,7 @@ INCLUDES = \
$(LIBXML_CFLAGS)
\
$(GNUTLS_CFLAGS)
\
$(SASL_CFLAGS)
\
$(SELINUX_CFLAGS)
\
-D_XOPEN_SOURCE
=
600
-D_POSIX_C_SOURCE
=
199506L
\
-DGETTEXT_PACKAGE
=
\"
$(PACKAGE)
\"
\
$(COVERAGE_CFLAGS)
\
...
...
@@ -31,6 +32,7 @@ LDADDS = \
$(LIBXML_LIBS)
\
$(GNUTLS_LIBS)
\
$(SASL_LIBS)
\
$(SELINUX_LIBS)
\
$(WARN_CFLAGS)
\
$(LIBVIRT)
\
../gnulib/lib/libgnu.la
\
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录