首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法在MacOS -套接字下工作的原始套接字:协议不支持的地址系列

无法在MacOS -套接字下工作的原始套接字:协议不支持的地址系列
EN

Stack Overflow用户
提问于 2019-03-27 12:18:39
回答 1查看 1.8K关注 0票数 2

我正在尝试开发一个码头映像来测试SocketCAN (用vcan),它可以在MacOS和MacOS上工作,一切都很好,直到我运行了坎特普特vcan0,返回:“套接字:地址家族不受协议支持”

过了一段时间后,我成功地让它在Linux上工作,方法是用“--network=主机-特权”启动容器。不过,这在Mac上启动的容器上不起作用,因为Mac返回:

代码语言:javascript
复制
socket: Address family not supported by protocol

一段“烛光vcan0”显示它在这个电话上停了下来:

代码语言:javascript
复制
socket(AF_CAN, SOCK_RAW, 1)             = -1 EAFNOSUPPORT (Address family not supported by protocol)

奇怪的是,即使Mac (https://docs.docker.com/network/host/)不支持"--network=host“,容器的主机名显示的是LinuxKit映像(运行容器的VM ):

代码语言:javascript
复制
root@linuxkit-025000000001:~#

当然,vcan模块已经加载:

代码语言:javascript
复制
root@linuxkit-025000000001:~# lsmod
Module                  Size  Used by
vcan                   16384  0
xfrm_user              32768  1
xfrm_algo              16384  1 xfrm_user

我不知道还能尝试什么;)

EN

回答 1

Stack Overflow用户

发布于 2019-09-19 23:59:10

我最近也经历了同样的痛苦,终于成功了。

以下是我所做的:

1)克隆https://github.com/linuxkit/linuxkit.git

2)按照这里的说明修改内核:https://github.com/linuxkit/linuxkit/blob/master/docs/kernels.md#modifying-the-kernel-config

具体而言,您希望将CAN网络添加为模块,将CAN驱动程序添加为模块。

3)将修改后的配置(例如config-4.9.x-x86_64)复制到linuxkit/kernel,以覆盖已经存在的配置。

4)来自linuxkit/kernel run make build_4.9.x HASH=mods HASH_COMMIT=HEAD

5)使用下面这个简单的Dockerfile (称为'Dockerfile.kernel')运行docker build . -f Dockerfile.kernel -t kernel_extract (可能有一种更优雅的方法来做到这一点,但我有点像一个码头管理员n00b)。

6)使用docker run -it --entrypoint=/bin/sh kernel_extract运行映像

7)在图像中,通过做以下操作来提取模块:

代码语言:javascript
复制
cd /ksrc
tar -xvf kernel.tar
find lib/modules/ -name "*.ko" | grep can > /tmp/files
tar cpzf can.tar.gz -T /tmp/files

8)当容器仍在运行时,用以下方法复制tarball:

代码语言:javascript
复制
id=$(docker container ls | grep kernel_extract | awk '{print $1}')
docker cp $id:/ksrc/can.tar.gz .

9)在码头映像中安装can.tar.gz文件。

10)使用--net=host--cap-add=ALL运行您的坞映像,以确保您可以加载内核模块并设置接口。

11)启动坞映像时,需要运行如下代码(在容器中,我在入口点上使用了一个shell脚本来完成这个任务,然后执行我真正想做的事情):

代码语言:javascript
复制
for module in "can" "can-raw" "can-gw" "can-bcm" "can-dev" "vcan"; do
  module_name=$(echo $module | tr "-" "_")
  lsmod | grep $module_name >/dev/null
  if [ $? -ne 0 ]; then
    insmod $(find /lib/modules -name "${module}.ko")
  fi
done

for iface in "can0" "can1"; do
  ip link show $iface >/dev/null 2>&1
  if [ $? -ne 0 ]; then
    ip link add $iface type vcan
    ip link set $iface up
  fi
done

由于您正在处理主机内核(在本例中是运行在mac上的hyperkit vm ),它将在每个单独的容器运行之后持续存在,这就是为什么要小心地检查它不会尝试两次。

不幸的是,这是一种令人费解的方式,也许一个有着更多码头细微差别的人可以描述一种更优雅的方式,但这确实有效!

Dockerfile.kernel:

代码语言:javascript
复制
FROM linuxkit/kernel:4.9.184-mods-amd64 AS ksrc
FROM linuxkit/alpine:3fdc49366257e53276c6f363956a4353f95d9a81 AS build
RUN apk add build-base

COPY --from=ksrc / /ksrc

ENTRYPOINT ["/bin/sh"]
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55377025

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档