在一个容器中,删除一个目录,失败:

bash-4.2# pwd
/home/zxcdn/ottcache/tomcat
bash-4.2# uname -a
Linux 3516b6c97679 3.10.0-327.22.2.el7.x86_64 #1 SMP Fri Sep 29 15:13:08 CST 2017 x86_64 x86_64 x86_64 GNU/Linux
bash-4.2# whoami
rootbash-4.2# ls -alrt bin
total 8
drwxr-xr-x. 1 root root 4096 Dec  3 02:49 .
drwxr-xr-x. 1 root root 4096 Dec  4 02:28 ..bash-4.2# rm -rf bin
bash-4.2# ls -i
33012 bin
bash-4.2# rm -rf bin
bash-4.2# ls -i
33012 bin

相关docker版本信息:

[root@host-80-80-34-255 caq]# docker info
Containers: 2Running: 1Paused: 0Stopped: 1
Images: 1
Server Version: 1.13.1
Storage Driver: overlay2----------存储引擎Backing Filesystem: extfs--------底层文件系统Supports d_type: trueNative Overlay Diff: false
Logging Driver: journald
Cgroup Driver: systemd
Plugins:Volume: localNetwork: bridge host macvlan null overlay
Swarm: inactive
Runtimes: docker-runc runc
Default Runtime: docker-runc
Init Binary: /usr/libexec/docker/docker-init-current
containerd version:  (expected: aa8187dbd3b7ad67d8e5e3a15115d3eef43a7ed1)
runc version: 5eda6f6fd0c2884c2c8e78a6e7119e8d0ecedb77 (expected: 9df8b306d01f59d3a8029be411de015b7304dd8f)
init version: fec3683b971d9c3ef73f284f176672c44b448662 (expected: 949e6facb77383876aeff8a6944dde66b3089574)
Security Options:seccompWARNING: You're not using the default seccomp profileProfile: /etc/docker/seccomp.json
Kernel Version: 3.10.0-327.22.2.el7.x86_64
Operating System: Carrier Grade Server Linux 5
OSType: linux
Architecture: x86_64
Number of Docker Hooks: 3
CPUs: 2
Total Memory: 3.703 GiB
Name: host-80-80-34-255
ID: 4CV6:Y3Q4:NYGV:PABH:VG42:3CN7:CKET:SEIV:4SYF:63PI:HYAB:AZR2
Docker Root Dir: /var/lib/docker
Debug Mode (client): false
Debug Mode (server): false
Registry: https://index.docker.io/v1/
WARNING: bridge-nf-call-iptables is disabled
WARNING: bridge-nf-call-ip6tables is disabled
Experimental: false
Insecure Registries:0.0.0.0/0127.0.0.0/8
Live Restore Enabled: false
Registries: docker.io (secure)

发现删除不了这个空目录,strace跟踪一下,报错如下:

fcntl(3, F_GETFL)                       = 0x38800 (flags O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_DIRECTORY|O_NOFOLLOW)
fcntl(3, F_SETFD, FD_CLOEXEC)           = 0
getdents(3, /* 2 entries */, 32768)     = 48
getdents(3, /* 0 entries */, 32768)     = 0
close(3)                                = 0
unlinkat(AT_FDCWD, "bin", AT_REMOVEDIR) = -1 EINVAL (Invalid argument)
lseek(0, 0, SEEK_CUR)                   = -1 ESPIPE (Illegal seek)

原来是unlinkat报错,然后内核打点跟踪,堆栈如下:

Returning from:  0xffffffff811ed500 : vfs_rename+0x0/0x790 [kernel]
Returning to  :  0xffffffffa039860b : ovl_do_rename+0x3b/0xa0 [overlay]0xffffffffa0398e4e : ovl_clear_empty+0x27e/0x2e0 [overlay]0xffffffffa0398f28 : ovl_check_empty_and_clear+0x78/0x90 [overlay]0xffffffffa039999c : ovl_do_remove+0x1ec/0x470 [overlay]0xffffffffa0399c36 : ovl_rmdir+0x16/0x20 [overlay]0xffffffff811ec738 : vfs_rmdir+0xa8/0x100 [kernel]0xffffffff811f16d5 : do_rmdir+0x1a5/0x200 [kernel]0xffffffff811f28b5 : SyS_unlinkat+0x25/0x40 [kernel]0xffffffff81649909 : system_call_fastpath+0x16/0x1b [kernel]

看下确定是vfs_name出错了,具体按行号打点:

probe kernel.statement("vfs_rename@namei.c:4122")
{p_my=@cast($old_dir,"struct inode")->i_op;iflags=@cast($old_dir,"struct inode")->i_flags;printf("line 4122 flags=%u,rename2=%x,iflags=%u\r\n",$flags,@cast(p_my,"struct inode_operations_wrapper")->rename2,iflags);print_backtrace();
}

对应的内核源码:

int vfs_rename(struct inode *old_dir, struct dentry *old_dentry,struct inode *new_dir, struct dentry *new_dentry,struct inode **delegated_inode, unsigned int flags)
{
。。。。rename2 = get_rename2_iop(old_dir);---------------4118行if (!old_dir->i_op->rename && !rename2)return -EPERM;if (flags && !rename2)----------------------------4122行return -EINVAL;
。。。。
}

一开始我直接取的rename2,发现不为NULL,按道理进不去4122行,后来经细心的谈虎走查,才发现是进入了如下的判断条件:

static inline const struct inode_operations_wrapper *get_iop_wrapper(struct inode *inode,unsigned version)
{const struct inode_operations_wrapper *wrapper;if (!IS_IOPS_WRAPPER(inode))------------最终是这个条件起作用了return NULL;wrapper = container_of(inode->i_op, const struct inode_operations_wrapper, ops);if (wrapper->version < version)return NULL;return wrapper;
}static inline iop_rename2_t get_rename2_iop(struct inode *inode)
{const struct inode_operations_wrapper *wrapper = get_iop_wrapper(inode, 0);return wrapper ? wrapper->rename2 : NULL;
}

看起来,该内核版本的overlay存储引擎,对ext4的底层文件系统,兼容性存在一些问题。后来使用device-mapper来解决了该问题。

转载于:https://www.cnblogs.com/10087622blog/p/10062918.html

一个docker镜像中的目录删除不了问题相关推荐

  1. 在docker镜像中加入环境变量

    原文链接 前言 reference:https://vsupalov.com/docker-build-time-env-values/ 很多时候,我们需要在docker镜像中加入环境变量,本人了解的 ...

  2. linux docker查找镜像文件,搜索/下载/构建自定义/删除Docker镜像,运行和删除Docker容器的方法...

    本文为你介绍的内容是Docker入门相关的操作方法:搜索Docker镜像.下载Docker镜像.运行Docker容器.构建自定义Docker镜像.删除容器.删除Docker镜像.以下给出的所有步骤均在 ...

  3. 为了实现CI/CD,先来定制一个Docker镜像【实战精华篇】

    背景 计划把手头的项目逐步改造为基于Docker容器的方式发布,同时,项目中已经采用了云厂商提供的CI/CD自动化发布流水线.因此,为配合CI/CD操作,需要先针对项目构建一些发布的脚本,通过脚本来自 ...

  4. 给Ocelot做一个Docker 镜像

    写在前面 在微服务架构中,ApiGateway起到了承前启后,不仅可以根据客户端进行分类,也可以根据功能业务进行分类,而且对于服务调用服务也起到了很好的接口作用.目前在各个云端中,基本上都提供了Api ...

  5. docker中linux用户名密码,linuxea:尽可能不在docker镜像中嵌入配置或者密码

    切勿将配置或机密信息嵌入Docker镜像中.相反,在构建Docker镜像时,期望使用业务流程运行时将配置和机密的信息提供给容器,这些包含:Kubernetes Secrets,Docker Secre ...

  6. 如何push一个docker镜像到DockerHub上

    如何push一个docker镜像到DockerHub上 2018.01.03 11:31:39字数 139阅读 202 有时候想要保存自己的docker镜像,又不想自己搭建docker registr ...

  7. docker镜像容器的创建删除

    目录 1. Docker是什么? 2. CentOS7用阿里云Docker Yum源在线安装Docker 3. 镜像 3.1 配置加速器 3.2 搜索镜像 3.3 下载镜像 3.4 查看宿主机上的镜像 ...

  8. Windows起一个Docker镜像——起起起起起~不~来~

    这次,我们要在Windows上创建一个自己的Docker镜像,并将其打包上传到Docker hub上 首先,当然是面向菜鸟教程的学习,简单了解一下Docker是什么 实际上,使用Linux系统会让整个 ...

  9. 实验:构建第一个Docker镜像

    文章目录 概述 寻找和准备镜像 寻找镜像模板 准备镜像模板 Dockerfile 打包容器并上传到仓库 把容器打包成镜像 把镜像上传到公网 参考文章和链接 概述   docker的关键作用:可靠地重现 ...

最新文章

  1. Kettle系列文章二(安装配置Kettle+SqlServer+简单的输入输出作业)
  2. ubuntu mysql5.6 编译安装_Ubuntu14.04编译安装mysql5.6.26
  3. 最浅显易懂的使用nginx实现端口映射的教程
  4. C#实现 Linq 序列的Distinct—— IEnumerable.Distinct()——IEqualityComparer
  5. [转]进程间通信 - ipcrm
  6. C++ opengl GL_LINE_LOOP的绘制
  7. C语言,期末复习之编写程序返回三个整数中的中间数
  8. Flutter Row和 Column 布局、线性布局概述
  9. python学习知识以及就业方向_Python需要学到什么技术 学完可以从事哪些行业
  10. vSphere 故障排错思路总结
  11. linux有许多sed进程,Linux进程与性能监控
  12. 2021计算机科学调剂,2021北京科技大学计算机科学与技术专业接收调剂研究生的通知...
  13. 体验MSN聚酷(Juku)
  14. Thinkpad E430c安装Ubuntu14.04第三方驱动的选择
  15. Panel面板和三种布局管理器
  16. Modern C++ JSON nlohmann::json 使用详解
  17. oeasy教您玩转linux010203显示logo
  18. 2018年搞笑诺贝尔奖揭晓:坐过山车能甩出肾结石
  19. 实现微信小程序与微信生态的互相跳转H5入口
  20. MAC终端连接服务器问题杂记

热门文章

  1. sql,EXISTS用法
  2. UA OPTI512R 傅立叶光学导论14 Wiener-Khinchine定理,Rayleigh定理与矩定理
  3. UA MATH565C 随机微分方程V Markov Family简介
  4. UA MATH575B 数值分析下II 牛顿算法
  5. 图解在emu8086中学习汇编语言数字比较程序
  6. 创建多线程的4种方式
  7. python 3.x 学习笔记14 (socket_ssh and socket_文件传输)
  8. 在Vista操作系统中通过manifest文件使VC应用程序获得管理员权限
  9. 【BZOJ】 2463 [中山市选2009]谁能赢呢?(博弈论)
  10. 【数据库】MySQL数据库(一)