Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
libvirt
提交
c0d74ed4
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看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
c0d74ed4
编写于
6月 03, 2009
作者:
D
Daniel P. Berrange
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Support networking in UML driver
上级
7cce4768
变更
8
隐藏空白更改
内联
并排
Showing
8 changed file
with
285 addition
and
31 deletion
+285
-31
ChangeLog
ChangeLog
+10
-0
src/bridge.c
src/bridge.c
+48
-4
src/bridge.h
src/bridge.h
+9
-1
src/domain_conf.c
src/domain_conf.c
+1
-0
src/libvirt_bridge.syms
src/libvirt_bridge.syms
+1
-0
src/uml_conf.c
src/uml_conf.c
+177
-10
src/uml_conf.h
src/uml_conf.h
+1
-3
src/uml_driver.c
src/uml_driver.c
+38
-13
未找到文件。
ChangeLog
浏览文件 @
c0d74ed4
Wed Jun 3 12:03:52 BST 2009 Daniel P. Berrange <berrange@redhat.com>
Support networking in UML driver
* src/bridge.c: Add new brDeleteTap function. Allow brAddTap
to create a persistent tap devices.
* src/bridge.h, src/libvirt_bridge.syms: Add brDeleteTap
* src/domain_conf.c: Fix missing 'break' in network XML formatter
* src/uml_conf.c, src/uml_conf.h, src/uml_driver.c: Add support
for bridge, network, mcast and user mode network interfaces
Wed Jun 3 11:53:52 BST 2009 Daniel P. Berrange <berrange@redhat.com>
Misc User Mode Linux startup/shutdown bugs
...
...
src/bridge.c
浏览文件 @
c0d74ed4
...
...
@@ -451,8 +451,11 @@ brProbeVnetHdr(int tapfd)
*
* This function creates a new tap device on a bridge. @ifname can be either
* a fixed name or a name template with '%d' for dynamic name allocation.
* in either case the final name for the bridge will be stored in @ifname
* and the associated file descriptor in @tapfd.
* in either case the final name for the bridge will be stored in @ifname.
* If the @tapfd parameter is supplied, the open tap device file
* descriptor will be returned, otherwise the TAP device will be made
* persistent and closed. The caller must use brDeleteTap to remove
* a persistent TAP devices when it is no longer needed.
*
* Returns 0 in case of success or an errno code in case of failure.
*/
...
...
@@ -465,7 +468,7 @@ brAddTap(brControl *ctl,
{
int
id
,
subst
,
fd
;
if
(
!
ctl
||
!
ctl
->
fd
||
!
bridge
||
!
ifname
||
!
tapfd
)
if
(
!
ctl
||
!
ctl
->
fd
||
!
bridge
||
!
ifname
)
return
EINVAL
;
subst
=
id
=
0
;
...
...
@@ -520,10 +523,14 @@ brAddTap(brControl *ctl,
goto
error
;
if
((
errno
=
brSetInterfaceUp
(
ctl
,
try
.
ifr_name
,
1
)))
goto
error
;
if
(
!
tapfd
&&
(
errno
=
ioctl
(
fd
,
TUNSETPERSIST
,
1
)))
goto
error
;
VIR_FREE
(
*
ifname
);
if
(
!
(
*
ifname
=
strdup
(
try
.
ifr_name
)))
goto
error
;
*
tapfd
=
fd
;
if
(
tapfd
)
*
tapfd
=
fd
;
return
0
;
}
...
...
@@ -536,6 +543,43 @@ brAddTap(brControl *ctl,
return
errno
;
}
int
brDeleteTap
(
brControl
*
ctl
,
const
char
*
ifname
)
{
struct
ifreq
try
;
int
len
;
int
fd
;
if
(
!
ctl
||
!
ctl
->
fd
||
!
ifname
)
return
EINVAL
;
if
((
fd
=
open
(
"/dev/net/tun"
,
O_RDWR
))
<
0
)
return
errno
;
memset
(
&
try
,
0
,
sizeof
(
struct
ifreq
));
try
.
ifr_flags
=
IFF_TAP
|
IFF_NO_PI
;
len
=
strlen
(
ifname
);
if
(
len
>=
BR_IFNAME_MAXLEN
-
1
)
{
errno
=
EINVAL
;
goto
error
;
}
strncpy
(
try
.
ifr_name
,
ifname
,
len
);
try
.
ifr_name
[
len
]
=
'\0'
;
if
(
ioctl
(
fd
,
TUNSETIFF
,
&
try
)
==
0
)
{
if
((
errno
=
ioctl
(
fd
,
TUNSETPERSIST
,
0
)))
goto
error
;
}
error:
close
(
fd
);
return
errno
;
}
/**
* brSetInterfaceUp:
* @ctl: bridge control pointer
...
...
src/bridge.h
浏览文件 @
c0d74ed4
...
...
@@ -60,12 +60,20 @@ int brDeleteInterface (brControl *ctl,
const
char
*
bridge
,
const
char
*
iface
);
enum
{
BR_TAP_VNET_HDR
=
(
1
<<
0
),
BR_TAP_PERSIST
=
(
1
<<
1
),
};
int
brAddTap
(
brControl
*
ctl
,
const
char
*
bridge
,
char
**
ifname
,
int
vnet_hdr
,
int
features
,
int
*
tapfd
);
int
brDeleteTap
(
brControl
*
ctl
,
const
char
*
ifname
);
int
brSetInterfaceUp
(
brControl
*
ctl
,
const
char
*
ifname
,
int
up
);
...
...
src/domain_conf.c
浏览文件 @
c0d74ed4
...
...
@@ -3146,6 +3146,7 @@ virDomainNetDefFormat(virConnectPtr conn,
else
virBufferVSprintf
(
buf
,
" <source port='%d'/>
\n
"
,
def
->
data
.
socket
.
port
);
break
;
case
VIR_DOMAIN_NET_TYPE_INTERNAL
:
virBufferEscapeString
(
buf
,
" <source name='%s'/>
\n
"
,
...
...
src/libvirt_bridge.syms
浏览文件 @
c0d74ed4
...
...
@@ -8,6 +8,7 @@
brAddBridge;
brAddInterface;
brAddTap;
brDeleteTap;
brDeleteBridge;
brHasBridge;
brInit;
...
...
src/uml_conf.c
浏览文件 @
c0d74ed4
...
...
@@ -44,6 +44,7 @@
#include "memory.h"
#include "nodeinfo.h"
#include "verify.h"
#include "bridge.h"
#define VIR_FROM_THIS VIR_FROM_UML
...
...
@@ -91,6 +92,172 @@ virCapsPtr umlCapsInit(void) {
}
static
int
umlConnectTapDevice
(
virConnectPtr
conn
,
virDomainNetDefPtr
net
,
const
char
*
bridge
)
{
int
tapfd
=
-
1
;
int
err
;
brControl
*
brctl
=
NULL
;
if
(
!
net
->
ifname
||
STRPREFIX
(
net
->
ifname
,
"vnet"
)
||
strchr
(
net
->
ifname
,
'%'
))
{
VIR_FREE
(
net
->
ifname
);
if
(
!
(
net
->
ifname
=
strdup
(
"vnet%d"
)))
goto
no_memory
;
}
if
((
err
=
brInit
(
&
brctl
)))
{
char
ebuf
[
1024
];
umlReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"cannot initialize bridge support: %s"
),
virStrerror
(
err
,
ebuf
,
sizeof
ebuf
));
goto
error
;
}
if
((
err
=
brAddTap
(
brctl
,
bridge
,
&
net
->
ifname
,
BR_TAP_PERSIST
,
&
tapfd
)))
{
if
(
errno
==
ENOTSUP
)
{
/* In this particular case, give a better diagnostic. */
umlReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"Failed to add tap interface to bridge. "
"%s is not a bridge device"
),
bridge
);
}
else
{
char
ebuf
[
1024
];
umlReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"Failed to add tap interface '%s' "
"to bridge '%s' : %s"
),
net
->
ifname
,
bridge
,
virStrerror
(
err
,
ebuf
,
sizeof
ebuf
));
}
goto
error
;
}
close
(
tapfd
);
brShutdown
(
brctl
);
return
0
;
no_memory:
virReportOOMError
(
conn
);
error:
brShutdown
(
brctl
);
return
-
1
;
}
static
char
*
umlBuildCommandLineNet
(
virConnectPtr
conn
,
virDomainNetDefPtr
def
,
int
idx
)
{
char
*
ret
;
virBuffer
buf
=
VIR_BUFFER_INITIALIZER
;
/* General format: ethNN=type,options */
virBufferVSprintf
(
&
buf
,
"eth%d="
,
idx
);
switch
(
def
->
type
)
{
case
VIR_DOMAIN_NET_TYPE_USER
:
/* ethNNN=slirp,macaddr */
virBufferAddLit
(
&
buf
,
"slirp"
);
break
;
case
VIR_DOMAIN_NET_TYPE_ETHERNET
:
/* ethNNN=tuntap,tapname,macaddr,gateway */
virBufferAddLit
(
&
buf
,
"tuntap"
);
if
(
def
->
data
.
ethernet
.
ipaddr
)
{
umlReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"IP address not supported for ethernet inteface"
));
goto
error
;
}
if
(
def
->
data
.
ethernet
.
script
)
{
umlReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"script execution not supported for ethernet inteface"
));
goto
error
;
}
break
;
case
VIR_DOMAIN_NET_TYPE_SERVER
:
umlReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"TCP server networking type not supported"
));
goto
error
;
case
VIR_DOMAIN_NET_TYPE_CLIENT
:
umlReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"TCP client networking type not supported"
));
goto
error
;
case
VIR_DOMAIN_NET_TYPE_MCAST
:
/* ethNNN=tuntap,macaddr,ipaddr,port */
virBufferAddLit
(
&
buf
,
"mcast"
);
break
;
case
VIR_DOMAIN_NET_TYPE_NETWORK
:
{
char
*
bridge
;
virNetworkPtr
network
=
virNetworkLookupByName
(
conn
,
def
->
data
.
network
.
name
);
if
(
!
network
)
{
umlReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
_
(
"Network '%s' not found"
),
def
->
data
.
network
.
name
);
goto
error
;
}
bridge
=
virNetworkGetBridgeName
(
network
);
virNetworkFree
(
network
);
if
(
bridge
==
NULL
)
{
goto
error
;
}
if
(
umlConnectTapDevice
(
conn
,
def
,
bridge
)
<
0
)
{
VIR_FREE
(
bridge
);
goto
error
;
}
/* ethNNN=tuntap,tapname,macaddr,gateway */
virBufferVSprintf
(
&
buf
,
"tuntap,%s"
,
def
->
ifname
);
break
;
}
case
VIR_DOMAIN_NET_TYPE_BRIDGE
:
if
(
umlConnectTapDevice
(
conn
,
def
,
def
->
data
.
bridge
.
brname
)
<
0
)
goto
error
;
/* ethNNN=tuntap,tapname,macaddr,gateway */
virBufferVSprintf
(
&
buf
,
"tuntap,%s"
,
def
->
ifname
);
break
;
case
VIR_DOMAIN_NET_TYPE_INTERNAL
:
umlReportError
(
conn
,
NULL
,
NULL
,
VIR_ERR_INTERNAL_ERROR
,
"%s"
,
_
(
"internal networking type not supported"
));
goto
error
;
}
virBufferVSprintf
(
&
buf
,
",%02x:%02x:%02x:%02x:%02x:%02x"
,
def
->
mac
[
0
],
def
->
mac
[
1
],
def
->
mac
[
2
],
def
->
mac
[
3
],
def
->
mac
[
4
],
def
->
mac
[
5
]);
if
(
def
->
type
==
VIR_DOMAIN_NET_TYPE_MCAST
)
{
virBufferVSprintf
(
&
buf
,
",%s,%d"
,
def
->
data
.
socket
.
address
,
def
->
data
.
socket
.
port
);
}
if
(
virBufferError
(
&
buf
))
{
virReportOOMError
(
conn
);
return
NULL
;
}
return
virBufferContentAndReset
(
&
buf
);
error:
ret
=
virBufferContentAndReset
(
&
buf
);
VIR_FREE
(
ret
);
return
NULL
;
}
static
char
*
umlBuildCommandLineChr
(
virConnectPtr
conn
,
virDomainChrDefPtr
def
,
...
...
@@ -166,9 +333,8 @@ int umlBuildCommandLine(virConnectPtr conn,
struct
uml_driver
*
driver
ATTRIBUTE_UNUSED
,
virDomainObjPtr
vm
,
const
char
***
retargv
,
const
char
***
retenv
,
int
**
tapfds
,
int
*
ntapfds
)
{
const
char
***
retenv
)
{
int
i
,
j
;
char
memory
[
50
];
struct
utsname
ut
;
...
...
@@ -277,6 +443,13 @@ int umlBuildCommandLine(virConnectPtr conn,
ADD_ARG_PAIR
(
disk
->
dst
,
disk
->
src
);
}
for
(
i
=
0
;
i
<
vm
->
def
->
nnets
;
i
++
)
{
char
*
ret
=
umlBuildCommandLineNet
(
conn
,
vm
->
def
->
nets
[
i
],
i
);
if
(
!
ret
)
goto
error
;
ADD_ARG
(
ret
);
}
for
(
i
=
0
;
i
<
UML_MAX_CHAR_DEVICE
;
i
++
)
{
char
*
ret
;
if
(
i
==
0
&&
vm
->
def
->
console
)
...
...
@@ -311,13 +484,7 @@ int umlBuildCommandLine(virConnectPtr conn,
no_memory:
virReportOOMError
(
conn
);
error:
if
(
tapfds
&&
*
tapfds
)
{
for
(
i
=
0
;
i
<
*
ntapfds
;
i
++
)
close
((
*
tapfds
)[
i
]);
VIR_FREE
(
*
tapfds
);
*
ntapfds
=
0
;
}
if
(
qargv
)
{
for
(
i
=
0
;
i
<
qargc
;
i
++
)
VIR_FREE
((
qargv
)[
i
]);
...
...
src/uml_conf.h
浏览文件 @
c0d74ed4
...
...
@@ -70,8 +70,6 @@ int umlBuildCommandLine (virConnectPtr conn,
struct
uml_driver
*
driver
,
virDomainObjPtr
dom
,
const
char
***
retargv
,
const
char
***
retenv
,
int
**
tapfds
,
int
*
ntapfds
);
const
char
***
retenv
);
#endif
/* __UML_CONF_H */
src/uml_driver.c
浏览文件 @
c0d74ed4
...
...
@@ -722,6 +722,35 @@ error:
}
static
int
umlCleanupTapDevices
(
virConnectPtr
conn
ATTRIBUTE_UNUSED
,
virDomainObjPtr
vm
)
{
int
i
;
int
err
;
int
ret
=
0
;
brControl
*
brctl
=
NULL
;
VIR_ERROR0
(
"Cleanup tap"
);
if
(
brInit
(
&
brctl
)
<
0
)
return
-
1
;
for
(
i
=
0
;
i
<
vm
->
def
->
nnets
;
i
++
)
{
virDomainNetDefPtr
def
=
vm
->
def
->
nets
[
i
];
if
(
def
->
type
!=
VIR_DOMAIN_NET_TYPE_BRIDGE
&&
def
->
type
!=
VIR_DOMAIN_NET_TYPE_NETWORK
)
continue
;
VIR_ERROR
(
"Cleanup '%s'"
,
def
->
ifname
);
err
=
brDeleteTap
(
brctl
,
def
->
ifname
);
if
(
err
)
{
VIR_ERROR
(
"Cleanup failed %d"
,
err
);
ret
=
-
1
;
}
}
VIR_ERROR0
(
"Cleanup tap done"
);
brShutdown
(
brctl
);
return
ret
;
}
static
int
umlStartVMDaemon
(
virConnectPtr
conn
,
struct
uml_driver
*
driver
,
virDomainObjPtr
vm
)
{
...
...
@@ -732,8 +761,6 @@ static int umlStartVMDaemon(virConnectPtr conn,
char
*
logfile
;
int
logfd
=
-
1
;
struct
stat
sb
;
int
*
tapfds
=
NULL
;
int
ntapfds
=
0
;
fd_set
keepfd
;
char
ebuf
[
1024
];
...
...
@@ -792,9 +819,9 @@ static int umlStartVMDaemon(virConnectPtr conn,
}
if
(
umlBuildCommandLine
(
conn
,
driver
,
vm
,
&
argv
,
&
progenv
,
&
tapfds
,
&
ntapfds
)
<
0
)
{
&
argv
,
&
progenv
)
<
0
)
{
close
(
logfd
);
umlCleanupTapDevices
(
conn
,
vm
);
return
-
1
;
}
...
...
@@ -824,9 +851,6 @@ static int umlStartVMDaemon(virConnectPtr conn,
vm
->
monitor
=
-
1
;
for
(
i
=
0
;
i
<
ntapfds
;
i
++
)
FD_SET
(
tapfds
[
i
],
&
keepfd
);
ret
=
virExecDaemonize
(
conn
,
argv
,
progenv
,
&
keepfd
,
&
pid
,
-
1
,
&
logfd
,
&
logfd
,
0
,
NULL
,
NULL
,
NULL
);
...
...
@@ -840,15 +864,14 @@ static int umlStartVMDaemon(virConnectPtr conn,
VIR_FREE
(
progenv
[
i
]);
VIR_FREE
(
progenv
);
if
(
tapfds
)
{
for
(
i
=
0
;
i
<
ntapfds
;
i
++
)
{
close
(
tapfds
[
i
]);
}
VIR_FREE
(
tapfds
);
}
if
(
ret
<
0
)
umlCleanupTapDevices
(
conn
,
vm
);
/* NB we don't mark it running here - we do that async
with inotify */
/* XXX what if someone else tries to start it again
before we get the inotification ? Sounds like
trouble.... */
return
ret
;
}
...
...
@@ -879,6 +902,8 @@ static void umlShutdownVMDaemon(virConnectPtr conn ATTRIBUTE_UNUSED,
VIR_FREE
(
vm
->
vcpupids
);
vm
->
nvcpupids
=
0
;
umlCleanupTapDevices
(
conn
,
vm
);
if
(
vm
->
newDef
)
{
virDomainDefFree
(
vm
->
def
);
vm
->
def
=
vm
->
newDef
;
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录