龍芯Fedora21平臺上解決docker 1.12.2退出問題
阿新 • • 發佈:2019-01-02
http://ask.loongnix.org/?/article/80
作業系統版本
loongnix(Fedora21) 20170726及以前版本,安裝docker 1.12.2後,建立容器正常,但是docker stop容器會阻塞住,容器無法正常退出。
解決方法
此問題是Docker官方版本缺少對MIPS平臺的epoll支援。
現在龍芯已經修正這個問題,loongnix.org上已經提交了功能正常的docker包。
執行以下命令即可自動安裝新版本的包。
# yum update docker
# service docker restart
注意
具體步驟如下:
# ps aux | grep docker
loongson 7477 0.0 0.0 107488 1728 pts/5 S+ 16:44 0:00 grep --color=auto docker root 17693 0.0 0.2 492960 8560 ? Ssl 9月21 0:54 /usr/libexec/docker/docker-containerd-current --listen unix:///run/containerd.sock --shim /usr/libexec/docker/docker-containerd-shim-current root 17719 0.3 0.8 826192 35920 ? Ssl 9月21 5:16 /usr/bin/dockerd-current --add-runtime oci=/usr/libexec/docker/docker-runc-current --default-runtime=oci --containerd /run/containerd.sock --exec-opt native.cgroupdriver=systemd --userland-proxy-path=/usr/libexec/docker/docker-proxy-current --selinux-enabled --log-driver=journald root 17902 0.0 0.0 196512 2544 ? Sl 9月21 0:00 /usr/libexec/docker/docker-containerd-shim-current fac1ee0c5de07257e5d65215abae4728bd08ec245026693d2b0444fe3f9d0745 /var/run/docker/libcontainerd/fac1ee0c5de07257e5d65215abae4728bd08ec245026693d2b0444fe3f9d0745 /usr/libexec/docker/docker-runc-current root 17986 0.0 0.2 351472 11776 pts/2 Sl+ 9月21 0:00 /usr/bin/docker-current attach fac1
ps 命令輸出的每一行是一個docker程序,第2列是程序號,對所有這些程序號執行kill命令,例如:
# kill -9 17693 17719 17902 17986
執行kill命令後,務必再次執行ps命令,保證所有docker程序都已經被kill掉。
最後,再重新啟動docker服務:
# service docker restart
這樣才能確保執行的docker是新版本。
如果覺得上面的步驟實在太費事,有一個簡單的方法,重新啟動整個機器。
附:原始碼包連結
http://ftp.loongnix.org/os/loongnix/1.0/SRPMS/d/docker-1.12.2-5.git8f1975c.2.fc21.loongson.src.rpm
原始patch
From 57de5faf811e68fea1828faba6cc5ac2bb60474d Mon Sep 17 00:00:00 2001 Date: Thu, 21 Sep 2017 20:46:26 +0800 Subject: [PATCH] docker 1.12.2 fix stop failed on mips64le --- .../archutils/epoll.go | 2 +- .../archutils/epoll_mips64le.go | 73 ++++++++++++++++++++++ 2 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 containerd-0366d7e9693c930cf18c0f50cc16acec064e96c5/archutils/epoll_mips64le.go diff --git a/containerd-0366d7e9693c930cf18c0f50cc16acec064e96c5/archutils/epoll.go b/containerd-0366d7e9693c930cf18c0f50cc16acec064e96c5/archutils/epoll.go index 3f08d8f..bca5015 100644 --- a/containerd-0366d7e9693c930cf18c0f50cc16acec064e96c5/archutils/epoll.go +++ b/containerd-0366d7e9693c930cf18c0f50cc16acec064e96c5/archutils/epoll.go @@ -1,4 +1,4 @@ -// +build linux,!arm64 +// +build linux,!arm64,!mips64le package archutils diff --git a/containerd-0366d7e9693c930cf18c0f50cc16acec064e96c5/archutils/epoll_mips64le.go b/containerd-0366d7e9693c930cf18c0f50cc16acec064e96c5/archutils/epoll_mips64le.go new file mode 100644 index 0000000..524f0cc --- /dev/null +++ b/containerd-0366d7e9693c930cf18c0f50cc16acec064e96c5/archutils/epoll_mips64le.go @@ -0,0 +1,73 @@ +// +build linux,mips64le + +package archutils + +// #include <sys/epoll.h> +/* +int EpollCreate1(int flag) { + return epoll_create1(flag); +} + +int EpollCtl(int efd, int op,int sfd, int events, int fd) { + struct epoll_event event; + event.events = events; + event.data.fd = fd; + + return epoll_ctl(efd, op, sfd, &event); +} + +struct event_t { + uint32_t events; + int fd; +}; + +struct epoll_event events[128]; +int run_epoll_wait(int fd, struct event_t *event) { + int n, i; + n = epoll_wait(fd, events, 128, -1); + for (i = 0; i < n; i++) { + event[i].events = events[/i].events; + event.fd = events.data.fd; + } + return n; +} +*/ +import "C" + +import ( + "fmt" + "syscall" + "unsafe" +) + +// EpollCreate1 calls a C implementation +func EpollCreate1(flag int) (int, error) { + fd := int(C.EpollCreate1(C.int(flag))) + if fd < 0 { + return fd, fmt.Errorf("failed to create epoll, errno is %d", fd) + } + return fd, nil +} + +// EpollCtl calls a C implementation +func EpollCtl(epfd int, op int, fd int, event *syscall.EpollEvent) error { + errno := C.EpollCtl(C.int(epfd), C.int(syscall.EPOLL_CTL_ADD), C.int(fd), C.int(event.Events), C.int(event.Fd)) + if errno < 0 { + return fmt.Errorf("Failed to ctl epoll") + } + return nil +} + +// EpollWait calls a C implementation +func EpollWait(epfd int, events syscall.EpollEvent, msec int) (int, error) { + var c_events [128]C.struct_event_t + n := int(C.run_epoll_wait(C.int(epfd), (*C.struct_event_t)(unsafe.Pointer(&c_events)))) + if n < 0 { + return int(n), fmt.Errorf("Failed to wait epoll") + } + for i := 0; i < n; i++ { + events.Fd = int32(c_events.fd) + events.Events = uint32(c_events[i].events) + } + return int(n), nil +} -- 2.1.0[/i]