Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
openeuler
libvirt
提交
69ab26bd
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,发现更多精彩内容 >>
提交
69ab26bd
编写于
2月 17, 2013
作者:
D
Doug Goldstein
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
interface: add bond support to udev backend
The udev backend now supports bond interfaces.
上级
2f272ad7
变更
1
隐藏空白更改
内联
并排
Showing
1 changed file
with
263 addition
and
1 deletion
+263
-1
src/interface/interface_backend_udev.c
src/interface/interface_backend_udev.c
+263
-1
未找到文件。
src/interface/interface_backend_udev.c
浏览文件 @
69ab26bd
...
...
@@ -493,6 +493,27 @@ err:
return
ret
;
}
/**
* Helper function for finding bond slaves using scandir()
*
* @param entry - directory entry passed by scandir()
*
* @return 1 if we want to add it to scandir's list, 0 if not.
*/
static
int
udevIfaceBondScanDirFilter
(
const
struct
dirent
*
entry
)
{
/* This is ugly so if anyone has a better suggestion, please improve
* this. Unfortunately the kernel stores everything in the top level
* interface sysfs entry and references the slaves as slave_eth0 for
* example.
*/
if
(
STRPREFIX
(
entry
->
d_name
,
"slave_"
))
return
1
;
return
0
;
}
/**
* Helper function for finding bridge members using scandir()
*
...
...
@@ -522,6 +543,14 @@ udevIfaceFreeIfaceDef(virInterfaceDef *ifacedef)
if
(
!
ifacedef
)
return
;
if
(
ifacedef
->
type
==
VIR_INTERFACE_TYPE_BOND
)
{
VIR_FREE
(
ifacedef
->
data
.
bond
.
target
);
for
(
i
=
0
;
i
<
ifacedef
->
data
.
bond
.
nbItf
;
i
++
)
{
udevIfaceFreeIfaceDef
(
ifacedef
->
data
.
bond
.
itf
[
i
]);
}
VIR_FREE
(
ifacedef
->
data
.
bond
.
itf
);
}
if
(
ifacedef
->
type
==
VIR_INTERFACE_TYPE_BRIDGE
)
{
VIR_FREE
(
ifacedef
->
data
.
bridge
.
delay
);
for
(
i
=
0
;
i
<
ifacedef
->
data
.
bridge
.
nbItf
;
i
++
)
{
...
...
@@ -540,6 +569,230 @@ udevIfaceFreeIfaceDef(virInterfaceDef *ifacedef)
VIR_FREE
(
ifacedef
);
}
static
int
ATTRIBUTE_NONNULL
(
1
)
ATTRIBUTE_NONNULL
(
2
)
ATTRIBUTE_NONNULL
(
3
)
ATTRIBUTE_NONNULL
(
4
)
ATTRIBUTE_RETURN_CHECK
udevIfaceGetIfaceDefBond
(
struct
udev
*
udev
,
struct
udev_device
*
dev
,
const
char
*
name
,
virInterfaceDef
*
ifacedef
)
{
struct
dirent
**
slave_list
=
NULL
;
int
slave_count
=
0
;
int
i
;
const
char
*
tmp_str
;
int
tmp_int
;
/* Initial defaults */
ifacedef
->
data
.
bond
.
target
=
NULL
;
ifacedef
->
data
.
bond
.
nbItf
=
0
;
ifacedef
->
data
.
bond
.
itf
=
NULL
;
/* Set the bond specifics */
tmp_str
=
udev_device_get_sysattr_value
(
dev
,
"bonding/downdelay"
);
if
(
!
tmp_str
)
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
_
(
"Could not retrieve 'bonding/downdelay' for '%s'"
),
name
);
goto
cleanup
;
}
if
(
virStrToLong_i
(
tmp_str
,
NULL
,
10
,
&
tmp_int
)
<
0
)
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
_
(
"Could not parse 'bonding/downdelay' '%s' for '%s'"
),
tmp_str
,
name
);
goto
cleanup
;
}
ifacedef
->
data
.
bond
.
downdelay
=
tmp_int
;
tmp_str
=
udev_device_get_sysattr_value
(
dev
,
"bonding/updelay"
);
if
(
!
tmp_str
)
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
_
(
"Could not retrieve 'bonding/updelay' for '%s'"
),
name
);
goto
cleanup
;
}
if
(
virStrToLong_i
(
tmp_str
,
NULL
,
10
,
&
tmp_int
)
<
0
)
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
_
(
"Could not parse 'bonding/updelay' '%s' for '%s'"
),
tmp_str
,
name
);
goto
cleanup
;
}
ifacedef
->
data
.
bond
.
updelay
=
tmp_int
;
tmp_str
=
udev_device_get_sysattr_value
(
dev
,
"bonding/miimon"
);
if
(
!
tmp_str
)
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
_
(
"Could not retrieve 'bonding/miimon' for '%s'"
),
name
);
goto
cleanup
;
}
if
(
virStrToLong_i
(
tmp_str
,
NULL
,
10
,
&
tmp_int
)
<
0
)
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
_
(
"Could not parse 'bonding/miimon' '%s' for '%s'"
),
tmp_str
,
name
);
goto
cleanup
;
}
ifacedef
->
data
.
bond
.
frequency
=
tmp_int
;
tmp_str
=
udev_device_get_sysattr_value
(
dev
,
"bonding/arp_interval"
);
if
(
!
tmp_str
)
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
_
(
"Could not retrieve 'bonding/arp_interval' for '%s'"
),
name
);
goto
cleanup
;
}
if
(
virStrToLong_i
(
tmp_str
,
NULL
,
10
,
&
tmp_int
)
<
0
)
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
_
(
"Could not parse 'bonding/arp_interval' '%s' for '%s'"
),
tmp_str
,
name
);
goto
cleanup
;
}
ifacedef
->
data
.
bond
.
interval
=
tmp_int
;
/* bonding/mode is in the format: "balance-rr 0" so we find the
* space and increment the pointer to get the number and convert
* it to an interger. libvirt uses 1 through 7 while the raw
* number is 0 through 6 so increment it by 1.
*/
tmp_str
=
udev_device_get_sysattr_value
(
dev
,
"bonding/mode"
);
if
(
!
tmp_str
)
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
_
(
"Could not retrieve 'bonding/mode' for '%s'"
),
name
);
goto
cleanup
;
}
tmp_str
=
strchr
(
tmp_str
,
' '
);
if
(
!
tmp_str
)
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
_
(
"Invalid format for 'bonding/mode' for '%s'"
),
name
);
goto
cleanup
;
}
if
(
strlen
(
tmp_str
)
<
2
)
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
_
(
"Unable to find correct value in 'bonding/mode' for '%s'"
),
name
);
goto
cleanup
;
}
if
(
virStrToLong_i
(
tmp_str
+
1
,
NULL
,
10
,
&
tmp_int
)
<
0
)
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
_
(
"Could not parse 'bonding/mode' '%s' for '%s'"
),
tmp_str
,
name
);
goto
cleanup
;
}
ifacedef
->
data
.
bond
.
mode
=
tmp_int
+
1
;
/* bonding/arp_validate is in the format: "none 0" so we find the
* space and increment the pointer to get the number and convert
* it to an interger.
*/
tmp_str
=
udev_device_get_sysattr_value
(
dev
,
"bonding/arp_validate"
);
if
(
!
tmp_str
)
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
_
(
"Could not retrieve 'bonding/arp_validate' for '%s'"
),
name
);
goto
cleanup
;
}
tmp_str
=
strchr
(
tmp_str
,
' '
);
if
(
!
tmp_str
)
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
_
(
"Invalid format for 'bonding/arp_validate' for '%s'"
),
name
);
goto
cleanup
;
}
if
(
strlen
(
tmp_str
)
<
2
)
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
_
(
"Unable to find correct value in 'bonding/arp_validate' "
"for '%s'"
),
name
);
goto
cleanup
;
}
if
(
virStrToLong_i
(
tmp_str
+
1
,
NULL
,
10
,
&
tmp_int
)
<
0
)
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
_
(
"Could not parse 'bonding/arp_validate' '%s' for '%s'"
),
tmp_str
,
name
);
goto
cleanup
;
}
ifacedef
->
data
.
bond
.
validate
=
tmp_int
;
/* bonding/use_carrier is 0 or 1 and libvirt stores it as 1 or 2. */
tmp_str
=
udev_device_get_sysattr_value
(
dev
,
"bonding/use_carrier"
);
if
(
!
tmp_str
)
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
_
(
"Could not retrieve 'bonding/use_carrier' for '%s'"
),
name
);
goto
cleanup
;
}
if
(
virStrToLong_i
(
tmp_str
,
NULL
,
10
,
&
tmp_int
)
<
0
)
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
_
(
"Could not parse 'bonding/use_carrier' '%s' for '%s'"
),
tmp_str
,
name
);
goto
cleanup
;
}
ifacedef
->
data
.
bond
.
carrier
=
tmp_int
+
1
;
/* MII or ARP Monitoring is based on arp_interval and miimon.
* if arp_interval > 0 then ARP monitoring is in play, if
* miimon > 0 then MII monitoring is in play.
*/
if
(
ifacedef
->
data
.
bond
.
interval
>
0
)
ifacedef
->
data
.
bond
.
monit
=
VIR_INTERFACE_BOND_MONIT_ARP
;
else
if
(
ifacedef
->
data
.
bond
.
frequency
>
0
)
ifacedef
->
data
.
bond
.
monit
=
VIR_INTERFACE_BOND_MONIT_MII
;
else
ifacedef
->
data
.
bond
.
monit
=
VIR_INTERFACE_BOND_MONIT_NONE
;
tmp_str
=
udev_device_get_sysattr_value
(
dev
,
"bonding/arp_ip_target"
);
if
(
!
tmp_str
)
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
_
(
"Could not retrieve 'bonding/arp_ip_target' for '%s'"
),
name
);
goto
cleanup
;
}
ifacedef
->
data
.
bond
.
target
=
strdup
(
tmp_str
);
if
(
!
ifacedef
->
data
.
bond
.
target
)
{
virReportOOMError
();
goto
cleanup
;
}
/* Slaves of the bond */
/* Get each slave in the bond */
slave_count
=
scandir
(
udev_device_get_syspath
(
dev
),
&
slave_list
,
udevIfaceBondScanDirFilter
,
alphasort
);
if
(
slave_count
<
0
)
{
virReportSystemError
(
errno
,
_
(
"Could not get slaves of bond '%s'"
),
name
);
goto
cleanup
;
}
/* Allocate our list of slave devices */
if
(
VIR_ALLOC_N
(
ifacedef
->
data
.
bond
.
itf
,
slave_count
)
<
0
)
{
virReportOOMError
();
goto
cleanup
;
}
ifacedef
->
data
.
bond
.
nbItf
=
slave_count
;
for
(
i
=
0
;
i
<
slave_count
;
i
++
)
{
/* Names are slave_interface. e.g. slave_eth0
* so we use the part after the _
*/
tmp_str
=
strchr
(
slave_list
[
i
]
->
d_name
,
'_'
);
tmp_str
++
;
ifacedef
->
data
.
bond
.
itf
[
i
]
=
udevIfaceGetIfaceDef
(
udev
,
tmp_str
);
if
(
!
ifacedef
->
data
.
bond
.
itf
[
i
])
{
virReportError
(
VIR_ERR_INTERNAL_ERROR
,
_
(
"Could not get interface information for '%s', which is "
"a enslaved in bond '%s'"
),
slave_list
[
i
]
->
d_name
,
name
);
goto
cleanup
;
}
VIR_FREE
(
slave_list
[
i
]);
}
VIR_FREE
(
slave_list
);
return
0
;
cleanup:
for
(
i
=
0
;
i
<
slave_count
;
i
++
)
{
VIR_FREE
(
slave_list
[
i
]);
}
VIR_FREE
(
slave_list
);
return
-
1
;
}
static
int
ATTRIBUTE_NONNULL
(
1
)
ATTRIBUTE_NONNULL
(
2
)
ATTRIBUTE_NONNULL
(
3
)
ATTRIBUTE_NONNULL
(
4
)
ATTRIBUTE_RETURN_CHECK
...
...
@@ -774,17 +1027,26 @@ udevIfaceGetIfaceDef(struct udev *udev, const char *name)
if
(
vlan_parent_dev
)
{
ifacedef
->
type
=
VIR_INTERFACE_TYPE_VLAN
;
}
/* Fallback check to see if this is a bond device */
if
(
udev_device_get_sysattr_value
(
dev
,
"bonding/mode"
))
{
ifacedef
->
type
=
VIR_INTERFACE_TYPE_BOND
;
}
}
switch
(
ifacedef
->
type
)
{
case
VIR_INTERFACE_TYPE_VLAN
:
if
(
udevIfaceGetIfaceDefVlan
(
udev
,
dev
,
name
,
ifacedef
))
if
(
udevIfaceGetIfaceDefVlan
(
udev
,
dev
,
name
,
ifacedef
)
<
0
)
goto
cleanup
;
break
;
case
VIR_INTERFACE_TYPE_BRIDGE
:
if
(
udevIfaceGetIfaceDefBridge
(
udev
,
dev
,
name
,
ifacedef
)
<
0
)
goto
cleanup
;
break
;
case
VIR_INTERFACE_TYPE_BOND
:
if
(
udevIfaceGetIfaceDefBond
(
udev
,
dev
,
name
,
ifacedef
)
<
0
)
goto
cleanup
;
break
;
case
VIR_INTERFACE_TYPE_ETHERNET
:
break
;
}
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录