1. <tr id='m3agy'><strong id='m3agy'></strong><small id='m3agy'></small><button id='m3agy'></button><li id='m3agy'><noscript id='m3agy'><big id='m3agy'></big><dt id='m3agy'></dt></noscript></li></tr><ol id='m3agy'><table id='m3agy'><blockquote id='m3agy'><tbody id='m3agy'></tbody></blockquote></table></ol><u id='m3agy'></u><kbd id='m3agy'><kbd id='m3agy'></kbd></kbd>
    2. <ins id='m3agy'></ins>
      <i id='m3agy'><div id='m3agy'><ins id='m3agy'></ins></div></i><span id='m3agy'></span><fieldset id='m3agy'></fieldset>

        <acronym id='m3agy'><em id='m3agy'></em><td id='m3agy'><div id='m3agy'></div></td></acronym><address id='m3agy'><big id='m3agy'><big id='m3agy'></big><legend id='m3agy'></legend></big></address>

          <dl id='m3agy'></dl>

          <code id='m3agy'><strong id='m3agy'></strong></code>
          <i id='m3agy'></i>

          Linux中文件执行中的锁定怪现象解释

          • 时间:
          • 浏览:9
          • 来源:124软件资讯网

              原来今天禁绝备开电脑了  ,太困了  ,想睡觉  ,然而一哥们儿短信都发过来了 ,要问个问题 ,于是照旧打开了电脑  ,没想到是一个很有代表性的问题  ,顺便也牵涉了前些天我的事情中的一个bug ,值得记载下来  。问题如下:

              linux下  ,一个可执行文件exe1正在执行中  ,rm –f可以将其删除  ,mv可以将其移除  ,mv $other exe1也可以将其替换 ,可是cp $other exe1则显示文件忙  ,求解 。

              这现实上并不是一个真正的问题 ,由于只要你的基础知识扎实  ,这个问题显然很简朴 ,缘故原由只有一个 ,那就是linux文件基于引用计数  。现在问题是这些个下令怎样来操作一个文件的引用计数  。下面的讨论都是基于独占打开的模式 。

              若是一个文件已经被打开 ,那么它的引用计数会增添1 ,若是挪用了rm  ,现实上底层只是unlink了一下 ,也就是说将它的引用计数淘汰1 ,这样虽然你在界面上(下令行或者GUI)看不到它了  ,可是它被打开时的计数还在 ,只有当它被关闭的时间  ,引用计数变为0 ,才彻底删除它  。

              再说mv下令  ,它现实上只是一个源文件的rename而已  ,若是mv的目的原来就存在  ,那么在目的上执行一个类似rm的效果 ,也就是unlink一下  ,联合引用计数的理论  ,目的文件若是已经被打开  ,那么当关闭的时间将不复存在 ,若是原来就没有被打开 ,那么mv的时间  ,目的直接被删除 ,由于unlink之后  ,它的引用计数酿成了0  。

              最后看一下cp下令 ,cp的话并不触动源文件和目的文件元数据自己(时间戳除外)  ,它只是打开源文件和目的文件 ,在源文件上执行read ,然后将效果write到目的文件  ,实质上是一个IO操作  ,对于可执行文件 ,是独占打开的  ,并不允许写入 ,因此会堕落  。

              这里就不再列出内核源码了  ,可以自行参考系统挪用的实现而加深明白 ,不外最好别干巴巴的看  ,照旧联合strace以及objdump比力好  ,要知道是怎么以及什么时间挪用的  ,以及挪用参数是什么 ,否则就和八股文没区别了 。那么这和我事情中的bug有什么关系呢?这个bug源于OpenVPN的日志记载  ,而且设置了日志回滚  ,回滚设置文件要害字段如下:

              size 4M

              missingok

              rotate 9

              compress

              delaycompress

              create 644 xx xx

              …

              效果当日志回滚成了vpn.log.1之后  ,这个vpn.log.1依然继续被写入  。这个缘故原由正是rename造成的  。在logrotate的man页面中  ,有一个copytruncate设置 ,其寄义就是不举行rename  ,而只是copy  ,然后将原来的文件truncate ,加入这个就可以了  。

              万万不要小看这些很简朴的下令  ,真正明白的人并不多  ,纵然真正的明白 ,泛起问题  ,能真正对应到原理也不多  ,很简朴的工具若是能彻底做到透彻的明白而且活用  ,再往深入学习才是有意义的  。