<p dir="auto">From <a class="user-mention notranslate" data-hovercard-type="user" data-hovercard-url="/users/gcs-github/hovercard" data-octo-click="hovercard-link-click" data-octo-dimensions="link_type:self" href="https://github.com/gcs-github">@gcs-github</a> on 2016-11-24T20:14:54Z</p>

<h5 dir="auto">ISSUE TYPE</h5>
<ul dir="auto">
<li>Bug Report</li>
</ul>
<h5 dir="auto">COMPONENT NAME</h5>
<p dir="auto">zfs</p>
<h5 dir="auto">ANSIBLE VERSION</h5>

<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="ansible 2.2.0.0"><pre class="notranslate"><code class="notranslate">ansible 2.2.0.0
</code></pre></div>
<h5 dir="auto">CONFIGURATION</h5>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="hash_behavior = merge
force_handlers = True
pipelining = True
control_path =  %(directory)s/%%p-%%h-%%r"><pre class="notranslate"><code class="notranslate">hash_behavior = merge
force_handlers = True
pipelining = True
control_path =  %(directory)s/%%p-%%h-%%r
</code></pre></div>
<h5 dir="auto">OS / ENVIRONMENT</h5>
<p dir="auto">Managing from macOS 10.12<br>
Managing Gentoo Linux hosts</p>
<h5 dir="auto">SUMMARY</h5>
<p dir="auto">Currently, the ZFS module will only consider <code class="notranslate">local</code> settings while comparing the current state of a ZFS filesystem and its intended target state. This can lead to unwanted <code class="notranslate">set</code> operations to occur even when the target filesystem is in the state described in the play, hurting idempotence.</p>
<p dir="auto">A good example of this is with the "mountpoint" property. If ZFS dataset <code class="notranslate">B</code> exists as a child of dataset <code class="notranslate">A</code>, but dataset <code class="notranslate">A</code> was previously restored from a backup with <code class="notranslate">zfs receive</code>, therefore having most of its properties not flagged as <code class="notranslate">local</code>, but as <code class="notranslate">received</code> instead (including <code class="notranslate">mountpoint</code>), a run of the ZFS module on <code class="notranslate">A</code> will attempt to first unmount <code class="notranslate">B</code> so that it can perform a <code class="notranslate">mountpoint</code> property change on <code class="notranslate">A</code> even though <code class="notranslate">A</code> already has its <code class="notranslate">mountpoint</code> property set to the correct value.</p>
<p dir="auto">In some cases the above will fail (for example if a file is open in dataset <code class="notranslate">B</code> so that <code class="notranslate">B</code> can't be unmounted), but in other cases this will still yield an unwanted side effect where an unmount will be forced to occur even when it shouldn't.</p>
<p dir="auto">I'm not sure why only <code class="notranslate">local</code> properties are being considered at present when comparing current dataset state and target dataset state. Unless I'm missing something, I believe a valid fix could be to simply delete the following line: <a href="https://github.com/ansible/ansible-modules-extras/blob/9760ec2538f8b44cb7f27924617a8e024a694724/system/zfs.py#L198">https://github.com/ansible/ansible-modules-extras/blob/9760ec2538f8b44cb7f27924617a8e024a694724/system/zfs.py#L198</a></p>
<h5 dir="auto">STEPS TO REPRODUCE</h5>
<ol dir="auto">
<li><code class="notranslate">zfs receive</code> any dataset containing children in place of one normally managed by an ansible play</li>
<li>run something on the server making use of a file in the one of the children datasets and keeping it open</li>
<li>run the play containing the zfs module call that tries to ensure zfs dataset properties are set correctly</li>
</ol>
<h5 dir="auto">EXPECTED RESULTS</h5>
<p dir="auto">no <code class="notranslate">zfs set</code> command should be issued for dataset properties which are already set to the correct value</p>
<h5 dir="auto">ACTUAL RESULTS</h5>
<p dir="auto"><code class="notranslate">zfs set</code> commands are issued on the managed host to set properties to a value they are already set at, in some cases causing unwanted side effects on the managed dataset and its children.</p>

<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="Using module file /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/ansible/modules/extras/system/zfs.py
&lt;xxx.yyy.zzz&gt; ESTABLISH SSH CONNECTION FOR USER: root
&lt;xxx.yyy.zzz&gt; SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=root -o ConnectTimeout=10 -o ControlPath=/Users/guillaume/.ansible/cp/%p-%h-%r xxx.yyy.zzz '/bin/sh -c '&quot;'&quot;'/usr/bin/python2 &amp;&amp; sleep 0'&quot;'&quot;''
fatal: [xxx.yyy.zzz]: FAILED! =&gt; {
    &quot;changed&quot;: false, 
    &quot;failed&quot;: true, 
    &quot;invocation&quot;: {
        &quot;module_args&quot;: {
            &quot;atime&quot;: &quot;off&quot;, 
            &quot;canmount&quot;: &quot;on&quot;, 
            &quot;casesensitivity&quot;: &quot;sensitive&quot;, 
            &quot;checksum&quot;: &quot;fletcher4&quot;, 
            &quot;compression&quot;: &quot;lz4&quot;, 
            &quot;copies&quot;: &quot;1&quot;, 
            &quot;createparent&quot;: null, 
            &quot;devices&quot;: &quot;off&quot;, 
            &quot;exec&quot;: &quot;off&quot;, 
            &quot;logbias&quot;: &quot;latency&quot;, 
            &quot;mountpoint&quot;: &quot;/var/lib/mysql&quot;, 
            &quot;nbmand&quot;: &quot;off&quot;, 
            &quot;normalization&quot;: &quot;formD&quot;, 
            &quot;primarycache&quot;: &quot;metadata&quot;, 
            &quot;quota&quot;: &quot;none&quot;, 
            &quot;readonly&quot;: &quot;off&quot;, 
            &quot;recordsize&quot;: &quot;16K&quot;, 
            &quot;refquota&quot;: &quot;none&quot;, 
            &quot;refreservation&quot;: &quot;none&quot;, 
            &quot;reservation&quot;: &quot;none&quot;, 
            &quot;secondarycache&quot;: &quot;none&quot;, 
            &quot;setuid&quot;: &quot;off&quot;, 
            &quot;sharenfs&quot;: &quot;off&quot;, 
            &quot;sharesmb&quot;: &quot;off&quot;, 
            &quot;snapdir&quot;: &quot;hidden&quot;, 
            &quot;utf8only&quot;: &quot;on&quot;, 
            &quot;xattr&quot;: &quot;off&quot;
        }, 
        &quot;module_name&quot;: &quot;zfs&quot;
    }, 
    &quot;msg&quot;: &quot;umount: /var/lib/mysql/relay_log: target is busy\n        (In some cases useful info about processes that\n         use the device is found by lsof(8) or fuser(1).)\ncannot unmount '/var/lib/mysql/relay_log': umount failed\n&quot;
}"><pre class="notranslate"><code class="notranslate">Using module file /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/ansible/modules/extras/system/zfs.py
&lt;xxx.yyy.zzz&gt; ESTABLISH SSH CONNECTION FOR USER: root
&lt;xxx.yyy.zzz&gt; SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=root -o ConnectTimeout=10 -o ControlPath=/Users/guillaume/.ansible/cp/%p-%h-%r xxx.yyy.zzz '/bin/sh -c '"'"'/usr/bin/python2 &amp;&amp; sleep 0'"'"''
fatal: [xxx.yyy.zzz]: FAILED! =&gt; {
    "changed": false, 
    "failed": true, 
    "invocation": {
        "module_args": {
            "atime": "off", 
            "canmount": "on", 
            "casesensitivity": "sensitive", 
            "checksum": "fletcher4", 
            "compression": "lz4", 
            "copies": "1", 
            "createparent": null, 
            "devices": "off", 
            "exec": "off", 
            "logbias": "latency", 
            "mountpoint": "/var/lib/mysql", 
            "nbmand": "off", 
            "normalization": "formD", 
            "primarycache": "metadata", 
            "quota": "none", 
            "readonly": "off", 
            "recordsize": "16K", 
            "refquota": "none", 
            "refreservation": "none", 
            "reservation": "none", 
            "secondarycache": "none", 
            "setuid": "off", 
            "sharenfs": "off", 
            "sharesmb": "off", 
            "snapdir": "hidden", 
            "utf8only": "on", 
            "xattr": "off"
        }, 
        "module_name": "zfs"
    }, 
    "msg": "umount: /var/lib/mysql/relay_log: target is busy\n        (In some cases useful info about processes that\n         use the device is found by lsof(8) or fuser(1).)\ncannot unmount '/var/lib/mysql/relay_log': umount failed\n"
}
</code></pre></div>
<p dir="auto">Copied from original issue: <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="191586395" data-permission-text="Title is private" data-url="https://github.com/ansible/ansible-modules-extras/issues/3543" data-hovercard-type="issue" data-hovercard-url="/ansible/ansible-modules-extras/issues/3543/hovercard" href="https://github.com/ansible/ansible-modules-extras/issues/3543">ansible/ansible-modules-extras#3543</a></p>
<h5 dir="auto">ISSUE TYPE</h5>
<ul dir="auto">
<li>Bug Report</li>
</ul>
<h5 dir="auto">COMPONENT NAME</h5>
<p dir="auto">module system/zfs</p>
<h5 dir="auto">ANSIBLE VERSION</h5>

<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="ansible 2.2.0.0"><pre class="notranslate"><code class="notranslate">ansible 2.2.0.0
</code></pre></div>
<h5 dir="auto">CONFIGURATION</h5>
<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="hash_behavior = merge
force_handlers = True
pipelining = True
control_path =  %(directory)s/%%p-%%h-%%r"><pre class="notranslate"><code class="notranslate">hash_behavior = merge
force_handlers = True
pipelining = True
control_path =  %(directory)s/%%p-%%h-%%r
</code></pre></div>
<h5 dir="auto">OS / ENVIRONMENT</h5>
<p dir="auto">Managing from macOS 10.12<br>
Managing Gentoo Linux hosts</p>
<h5 dir="auto">SUMMARY</h5>
<p dir="auto"><em>(this issue was ported over from <a class="issue-link js-issue-link" data-error-text="Failed to load title" data-id="191586395" data-permission-text="Title is private" data-url="https://github.com/ansible/ansible-modules-extras/issues/3543" data-hovercard-type="issue" data-hovercard-url="/ansible/ansible-modules-extras/issues/3543/hovercard" href="https://github.com/ansible/ansible-modules-extras/issues/3543">ansible/ansible-modules-extras#3543</a> following the repository merge of ansible/ansible-modules-extras into ansible/ansible)</em></p>
<p dir="auto">Currently, the ZFS module will only consider <code class="notranslate">local</code> settings while comparing the current state of a ZFS filesystem and its intended target state. This can lead to unwanted <code class="notranslate">set</code> operations to occur even when the target filesystem is in the state described in the play, hurting idempotence.</p>
<p dir="auto">A good example of this is with the "mountpoint" property. If ZFS dataset <code class="notranslate">B</code> exists as a child of dataset <code class="notranslate">A</code>, but dataset <code class="notranslate">A</code> was previously restored from a backup with <code class="notranslate">zfs receive</code>, therefore having most of its properties not flagged as <code class="notranslate">local</code>, but as <code class="notranslate">received</code> instead (including <code class="notranslate">mountpoint</code>), a run of the ZFS module on <code class="notranslate">A</code> will attempt to first unmount <code class="notranslate">B</code> so that it can perform a <code class="notranslate">mountpoint</code> property change on <code class="notranslate">A</code> even though <code class="notranslate">A</code> already has its <code class="notranslate">mountpoint</code> property set to the correct value.</p>
<p dir="auto">In some cases the above will fail (for example if a file is open in dataset <code class="notranslate">B</code> so that <code class="notranslate">B</code> can't be unmounted), but in other cases this will still yield an unwanted side effect where an unmount will be forced to occur even when it shouldn't.</p>
<p dir="auto">I'm not sure why only <code class="notranslate">local</code> properties are being considered at present when comparing current dataset state and target dataset state. Unless I'm missing something, I believe a valid fix could be to simply delete the following line: <a href="https://github.com/ansible/ansible-modules-extras/blob/9760ec2538f8b44cb7f27924617a8e024a694724/system/zfs.py#L198">https://github.com/ansible/ansible-modules-extras/blob/9760ec2538f8b44cb7f27924617a8e024a694724/system/zfs.py#L198</a></p>
<h5 dir="auto">STEPS TO REPRODUCE</h5>
<ol dir="auto">
<li><code class="notranslate">zfs receive</code> any dataset containing children in place of one normally managed by an ansible play</li>
<li>run something on the server making use of a file in the one of the children datasets and keeping it open</li>
<li>run the play containing the zfs module call that tries to ensure zfs dataset properties are set correctly</li>
</ol>
<h5 dir="auto">EXPECTED RESULTS</h5>
<p dir="auto">no <code class="notranslate">zfs set</code> command should be issued for dataset properties which are already set to the correct value</p>
<h5 dir="auto">ACTUAL RESULTS</h5>
<p dir="auto"><code class="notranslate">zfs set</code> commands are issued on the managed host to set properties to a value they are already set at, in some cases causing unwanted side effects on the managed dataset and its children.</p>

<div class="snippet-clipboard-content notranslate position-relative overflow-auto" data-snippet-clipboard-copy-content="Using module file /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/ansible/modules/extras/system/zfs.py
&lt;xxx.yyy.zzz&gt; ESTABLISH SSH CONNECTION FOR USER: root
&lt;xxx.yyy.zzz&gt; SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=root -o ConnectTimeout=10 -o ControlPath=/Users/guillaume/.ansible/cp/%p-%h-%r xxx.yyy.zzz '/bin/sh -c '&quot;'&quot;'/usr/bin/python2 &amp;&amp; sleep 0'&quot;'&quot;''
fatal: [xxx.yyy.zzz]: FAILED! =&gt; {
    &quot;changed&quot;: false, 
    &quot;failed&quot;: true, 
    &quot;invocation&quot;: {
        &quot;module_args&quot;: {
            &quot;atime&quot;: &quot;off&quot;, 
            &quot;canmount&quot;: &quot;on&quot;, 
            &quot;casesensitivity&quot;: &quot;sensitive&quot;, 
            &quot;checksum&quot;: &quot;fletcher4&quot;, 
            &quot;compression&quot;: &quot;lz4&quot;, 
            &quot;copies&quot;: &quot;1&quot;, 
            &quot;createparent&quot;: null, 
            &quot;devices&quot;: &quot;off&quot;, 
            &quot;exec&quot;: &quot;off&quot;, 
            &quot;logbias&quot;: &quot;latency&quot;, 
            &quot;mountpoint&quot;: &quot;/var/lib/mysql&quot;, 
            &quot;nbmand&quot;: &quot;off&quot;, 
            &quot;normalization&quot;: &quot;formD&quot;, 
            &quot;primarycache&quot;: &quot;metadata&quot;, 
            &quot;quota&quot;: &quot;none&quot;, 
            &quot;readonly&quot;: &quot;off&quot;, 
            &quot;recordsize&quot;: &quot;16K&quot;, 
            &quot;refquota&quot;: &quot;none&quot;, 
            &quot;refreservation&quot;: &quot;none&quot;, 
            &quot;reservation&quot;: &quot;none&quot;, 
            &quot;secondarycache&quot;: &quot;none&quot;, 
            &quot;setuid&quot;: &quot;off&quot;, 
            &quot;sharenfs&quot;: &quot;off&quot;, 
            &quot;sharesmb&quot;: &quot;off&quot;, 
            &quot;snapdir&quot;: &quot;hidden&quot;, 
            &quot;utf8only&quot;: &quot;on&quot;, 
            &quot;xattr&quot;: &quot;off&quot;
        }, 
        &quot;module_name&quot;: &quot;zfs&quot;
    }, 
    &quot;msg&quot;: &quot;umount: /var/lib/mysql/relay_log: target is busy\n        (In some cases useful info about processes that\n         use the device is found by lsof(8) or fuser(1).)\ncannot unmount '/var/lib/mysql/relay_log': umount failed\n&quot;
}"><pre class="notranslate"><code class="notranslate">Using module file /opt/local/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/site-packages/ansible/modules/extras/system/zfs.py
&lt;xxx.yyy.zzz&gt; ESTABLISH SSH CONNECTION FOR USER: root
&lt;xxx.yyy.zzz&gt; SSH: EXEC ssh -C -o ControlMaster=auto -o ControlPersist=60s -o KbdInteractiveAuthentication=no -o PreferredAuthentications=gssapi-with-mic,gssapi-keyex,hostbased,publickey -o PasswordAuthentication=no -o User=root -o ConnectTimeout=10 -o ControlPath=/Users/guillaume/.ansible/cp/%p-%h-%r xxx.yyy.zzz '/bin/sh -c '"'"'/usr/bin/python2 &amp;&amp; sleep 0'"'"''
fatal: [xxx.yyy.zzz]: FAILED! =&gt; {
    "changed": false, 
    "failed": true, 
    "invocation": {
        "module_args": {
            "atime": "off", 
            "canmount": "on", 
            "casesensitivity": "sensitive", 
            "checksum": "fletcher4", 
            "compression": "lz4", 
            "copies": "1", 
            "createparent": null, 
            "devices": "off", 
            "exec": "off", 
            "logbias": "latency", 
            "mountpoint": "/var/lib/mysql", 
            "nbmand": "off", 
            "normalization": "formD", 
            "primarycache": "metadata", 
            "quota": "none", 
            "readonly": "off", 
            "recordsize": "16K", 
            "refquota": "none", 
            "refreservation": "none", 
            "reservation": "none", 
            "secondarycache": "none", 
            "setuid": "off", 
            "sharenfs": "off", 
            "sharesmb": "off", 
            "snapdir": "hidden", 
            "utf8only": "on", 
            "xattr": "off"
        }, 
        "module_name": "zfs"
    }, 
    "msg": "umount: /var/lib/mysql/relay_log: target is busy\n        (In some cases useful info about processes that\n         use the device is found by lsof(8) or fuser(1).)\ncannot unmount '/var/lib/mysql/relay_log': umount failed\n"
}
</code></pre></div>