<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en">
    <title>kimono koans&#x27; blog!</title>
    <subtitle>kimono koans&#x27; blog!</subtitle>
    <link href="/atom.xml" rel="self" type="application/atom+xml"/>
    <link href="/"/>
    <generator uri="https://www.getzola.org/">Zola</generator>
    <updated>2023-12-19T00:00:00+00:00</updated>
    <id>/atom.xml</id>
    <entry xml:lang="en">
        <title>A cross platform, filesystem independent Time Machine (which directly supports your TM backups)</title>
        <published>2023-12-15T00:00:00+00:00</published>
        <updated>2023-12-15T00:00:00+00:00</updated>
        <author>
          <name>Unknown</name>
        </author>
        <link rel="alternate" href="/for-the-people/" type="text/html"/>
        <id>/for-the-people/</id>
        
        <content type="html">&lt;p&gt;You can have it all -- the convenience of Time Machine backups, and the speed and flexibility of &lt;code&gt;httm&lt;&#x2F;code&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Of course, one could always use &lt;code&gt;httm&lt;&#x2F;code&gt; to browse all files in a folder backed up via &lt;code&gt;rsync&lt;&#x2F;code&gt; to a remote ZFS or btrfs share, if that share has a hidden snapshot directory:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;# mount the share
➜ open smb:&amp;#x2F;&amp;#x2F;&amp;lt;your name&amp;gt;@&amp;lt;your remote share&amp;gt;.local&amp;#x2F;Home
# execute httm 
➜ httm -b -R &amp;#x2F;Volumes&amp;#x2F;Home
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Or one could use &lt;code&gt;httm&lt;&#x2F;code&gt; to browse all files in your local MacOS home directory, if you mapped that directory to a remote dataset. Note: The difference from above is, here, you would be browsing files from a &amp;quot;live&amp;quot; directory:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;# mount the share
➜ open smb:&amp;#x2F;&amp;#x2F;&amp;lt;your name&amp;gt;@&amp;lt;your remote share&amp;gt;.local&amp;#x2F;Home
# execute httm
➜ httm -b -R --map-aliases &amp;#x2F;Users&amp;#x2F;&amp;lt;your name&amp;gt;:&amp;#x2F;Volumes&amp;#x2F;Home
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now, &lt;code&gt;httm&lt;&#x2F;code&gt; supports your Time Machine backups directly, when those backups are &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kimono-koans&#x2F;httm&#x2F;blob&#x2F;master&#x2F;scripts&#x2F;equine.bash&quot;&gt;mounted&lt;&#x2F;a&gt;:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;➜ httm .zshrc
─────────────────────────────────────────────────────────────────────────────────────
Tue May 09 22:57:09 2023  6.7 KiB  &amp;quot;&amp;#x2F;Volumes&amp;#x2F;.timemachine&amp;#x2F;842A693F-CB54-4C5A-9AB1-C73681D4DFCD&amp;#x2F;2023-11-08-212757.backup&amp;#x2F;2023-11-08-212757.backup&amp;#x2F;Data&amp;#x2F;Users&amp;#x2F;kimono&amp;#x2F;.zshrc&amp;quot;
Sun Nov 12 20:29:57 2023  6.7 KiB  &amp;quot;&amp;#x2F;Volumes&amp;#x2F;.timemachine&amp;#x2F;842A693F-CB54-4C5A-9AB1-C73681D4DFCD&amp;#x2F;2023-11-18-011056.backup&amp;#x2F;2023-11-18-011056.backup&amp;#x2F;Data&amp;#x2F;Users&amp;#x2F;kimono&amp;#x2F;.zshrc&amp;quot;
Sun Nov 26 02:14:56 2023  6.7 KiB  &amp;quot;&amp;#x2F;Volumes&amp;#x2F;.timemachine&amp;#x2F;842A693F-CB54-4C5A-9AB1-C73681D4DFCD&amp;#x2F;2023-12-13-054342.backup&amp;#x2F;2023-12-13-054342.backup&amp;#x2F;Data&amp;#x2F;Users&amp;#x2F;kimono&amp;#x2F;.zshrc&amp;quot;
─────────────────────────────────────────────────────────────────────────────────────
Sun Nov 26 02:14:56 2023  6.7 KiB  &amp;quot;&amp;#x2F;Users&amp;#x2F;kimono&amp;#x2F;.zshrc&amp;quot;
─────────────────────────────────────────────────────────────────────────────────────
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kimono-koans&#x2F;httm&quot;&gt;httm&lt;&#x2F;a&gt; prints the size, date and corresponding locations of available unique versions (deduplicated by modify time and size) of files residing on snapshots, but can also be used interactively to select and restore files, even snapshot mounts by file! httm might change the way you use snapshots (because ZFS&#x2F;BTRFS&#x2F;NILFS2 aren&#x27;t designed for finding for unique file versions) or the Time Machine concept (because httm is very fast!).&lt;&#x2F;p&gt;
&lt;p&gt;For more info, see the &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kimono-koans&#x2F;httm&#x2F;blob&#x2F;master&#x2F;README.md&quot;&gt;README&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>All your snapshots, at your fingertips, enables NILFS2-inspired ZFS snapshots</title>
        <published>2023-12-04T00:00:00+00:00</published>
        <updated>2023-12-04T00:00:00+00:00</updated>
        <author>
          <name>Unknown</name>
        </author>
        <link rel="alternate" href="/everything/" type="text/html"/>
        <id>/everything/</id>
        
        <content type="html">&lt;p&gt;Of course, ZFS loves that &amp;quot;most things are a file&amp;quot; for certain operations:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;zfs send rpool&amp;#x2F;scratch@autosnap_2022-10-31_17:01:20_hourly | gzip &amp;gt; &amp;#x2F;srv&amp;#x2F;tmp&amp;#x2F;scratch.gz
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;However, I don&#x27;t think the ZFS&#x2F;btrfs&#x2F;NILFS2 communities have wrapped their collective heads around the idea that snapshot datasets can be useful everywhere, especially at the file (read: not dataset) level.&lt;&#x2F;p&gt;
&lt;p&gt;This is the reason why Jim Salter&#x27;s &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jimsalterjrs&#x2F;sanoid&quot;&gt;findoid&lt;&#x2F;a&gt; was such an inspiration for &lt;code&gt;httm&lt;&#x2F;code&gt; (along with &lt;code&gt;fzf&lt;&#x2F;code&gt;, &lt;code&gt;zsh&lt;&#x2F;code&gt; key bindings, and &lt;code&gt;rg&lt;&#x2F;code&gt;).  It was the first CLI tool I saw which made an attempt to deal with snapshots on a file level.  One could always go looking for file versions, but &lt;code&gt;findoid&lt;&#x2F;code&gt; made an effort to consolidate useful snapshot information about a specific file.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kimono-koans&#x2F;httm&quot;&gt;httm&lt;&#x2F;a&gt; attempts to take Jim&#x27;s very broad idea to its logical conclusion.  &lt;code&gt;httm&lt;&#x2F;code&gt; is an interactive, file-level Time Machine-like tool for ZFS&#x2F;btrfs&#x2F;NILFS2.  See:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;asciinema.org&#x2F;a&#x2F;529608&quot;&gt;&lt;img src=&quot;https:&#x2F;&#x2F;asciinema.org&#x2F;a&#x2F;529608.svg&quot; alt=&quot;asciicast&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Put simply -- &lt;code&gt;httm&lt;&#x2F;code&gt; aims to make all your snapshot data more easily accessible to all your UNIX tools, specifically, at the file level, because that&#x27;s where UNIX tools live, so you can create new and interesting things for yourself.&lt;&#x2F;p&gt;
&lt;p&gt;So, what, in practice, does this mean?  It means -- as a ZFS guy, one NILFS2 feature that always impressed me was how it seems to &amp;quot;take&amp;quot; continuous snapshots.  In addition to checkpoints, one can stop a NILFS2 filesystem from garbage collecting, roll back to a point in time, and recover a file that was once there. And, this seems great, if you can take the performance hit of a log-structured file system (which is substantial).  Just as I don&#x27;t understand how people live without snapshots, I didn&#x27;t want to live without &amp;quot;continuous&amp;quot; snapshots.  With &lt;code&gt;httm&lt;&#x2F;code&gt;&#x27;s help, my ZFS alternative to NILFS2 is simple -- instead of continuous snapshots, why don&#x27;t we simply take a snapshot, if we need to, before we do something silly.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kimono-koans&#x2F;httm&#x2F;blob&#x2F;master&#x2F;scripts&#x2F;ounce.bash&quot;&gt;ounce&lt;&#x2F;a&gt; (codename: &amp;quot;dimebag&amp;quot;) is a wrapper script for &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kimono-koans&#x2F;httm&quot;&gt;httm&lt;&#x2F;a&gt; which gives you no mental overhead, non-periodic dynamic snapshots.&lt;&#x2F;p&gt;
&lt;p&gt;When I type &lt;code&gt;ounce nano &#x2F;etc&#x2F;samba&#x2F;smb.conf&lt;&#x2F;code&gt; (I actually &lt;code&gt;alias $EDITOR=&#x27;ounce --trace $EDITOR&#x27;&lt;&#x2F;code&gt;), &lt;code&gt;ounce&lt;&#x2F;code&gt; knows that it&#x27;s smart and I&#x27;m dumb, and it sees that I just edited &lt;code&gt;&#x2F;etc&#x2F;samba&#x2F;smb.conf&lt;&#x2F;code&gt; a few short minutes ago, because it uses seccomp and eBPF to trace all the file open calls my $EDITOR makes, and uses &lt;code&gt;httm&lt;&#x2F;code&gt; to check whether I have any un-snapshot-ed changes.  If I do, it takes a snapshot before I edit the file again.&lt;&#x2F;p&gt;
&lt;p&gt;Instead of an auto-save, you have auto-snapshot. Of course, we can confirm the snapshot was taken with &lt;code&gt;httm&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;➜ httm &amp;#x2F;etc&amp;#x2F;samba&amp;#x2F;smb.conf
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Tue Aug 09 16:46:14 2022  17.6 KiB  &amp;quot;&amp;#x2F;.zfs&amp;#x2F;snapshot&amp;#x2F;autosnap_2022-10-19_20:00:22_hourly&amp;#x2F;etc&amp;#x2F;samba&amp;#x2F;smb.conf&amp;quot;
Fri Oct 21 09:11:17 2022  17.6 KiB  &amp;quot;&amp;#x2F;.zfs&amp;#x2F;snapshot&amp;#x2F;snap_2022-10-21-09:11:18_ounceSnapFileMount&amp;#x2F;etc&amp;#x2F;samba&amp;#x2F;smb.conf&amp;quot;
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Fri Oct 21 09:11:25 2022  17.6 KiB  &amp;quot;&amp;#x2F;etc&amp;#x2F;samba&amp;#x2F;smb.conf&amp;quot;
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;ounce&lt;&#x2F;code&gt; is just one example of a new use enabled by snapshot data at your finger tips.  I hope you&#x27;ll find inspiration to use it to create something new and interesting for yourself too.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Why the Rust Trademark Policy was such a problem...</title>
        <published>2023-04-11T00:00:00+00:00</published>
        <updated>2023-04-11T00:00:00+00:00</updated>
        <author>
          <name>Unknown</name>
        </author>
        <link rel="alternate" href="/trademark/" type="text/html"/>
        <id>/trademark/</id>
        
        <content type="html">&lt;p&gt;The YouTubers had a very good time telling the Foundation&#x2F;project it &lt;a href=&quot;https:&#x2F;&#x2F;www.youtube.com&#x2F;watch?v=2oh7MoEvJ88&quot;&gt;&amp;quot;doesn&#x27;t understand the internet&amp;quot;&lt;&#x2F;a&gt; and other such nonsense.  The Zig VP of Community was able to &lt;a href=&quot;https:&#x2F;&#x2F;twitter.com&#x2F;croloris&#x2F;status&#x2F;1645519013533892608&quot;&gt;gloat&lt;&#x2F;a&gt;.  Notwithstanding, I happen to think the trademark policy itself will be resolved with, relative to the heated rhetoric right now, little controversy.  The Foundation asked for comment.  It got comments.  It will adjust.  We can stop the rending of our garments.&lt;&#x2F;p&gt;
&lt;p&gt;However, there is an established narrative about the Rust project, which like it or not, fair or not, is: &amp;quot;These people don&#x27;t just want to control how I use memory&amp;quot; (&lt;em&gt;this is a joke&lt;&#x2F;em&gt;).  They have opinions about what are appropriate politics.  And now they think their &lt;em&gt;trademark policy&lt;&#x2F;em&gt; is going to prevent malware.&lt;&#x2F;p&gt;
&lt;p&gt;Of course, this narrative isn&#x27;t the problem.  The problem is &lt;em&gt;actually trying to control anything and everything&lt;&#x2F;em&gt; Rust related.  I know it can be hard to watch your FOSS baby used in a way you didn&#x27;t intend, but very clearly I think the community, when given the choice between being rigidly controlled (which may have some speculative virtues), and being diverse and vibrant and noisy (which may have some speculative vices), will choose diverse and vibrant and noisy.  The Rust project and the Foundation can bristle at that.  And maybe even fight it.  And they may even think a trademark policy is a good way to do it, but Tide and Clorox don&#x27;t have a community, they have customers.  The reason why the Rust mark has any value is that there is a community of people who love using it.&lt;&#x2F;p&gt;
&lt;p&gt;This is self-evidently a fissure between the community, and the Foundation and project.  That&#x27;s not a problem, if our leadership works through it.  Yet the difficulty of not having a BDFL, but having a nameless&#x2F;faceless Executive Director of the Foundation, is, right now, in this moment, there appear to be no leaders within Rust to say the measured and reasonable thing.  Something like: &amp;quot;This missed the mark.  We&#x27;re going to consider changes to the policy itself, but also to our processes for consideration of such a policy.&amp;quot;  For one thing, it appears as if no one sent comments to the attorney asking: &amp;quot;Why is this necessary?  Is there a lighter touch way to achieve X and Y goals?  What are the difficulties with the Python model?&amp;quot;  Staff of nine, and board of twelve, and no one asking these questions, and, significantly, &lt;em&gt;no one available to explain the policy&lt;&#x2F;em&gt;, is a failure of leadership.&lt;&#x2F;p&gt;
&lt;p&gt;I want to be very clear -- I&#x27;m not saying heads should roll.  I&#x27;m saying someone needs to take the wheel.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Use `httm` to convert your ZFS&#x2F;btrfs snapshots to `git` archives</title>
        <published>2023-01-31T00:00:00+00:00</published>
        <updated>2023-01-31T00:00:00+00:00</updated>
        <author>
          <name>Unknown</name>
        </author>
        <link rel="alternate" href="/nicotine/" type="text/html"/>
        <id>/nicotine/</id>
        
        <content type="html">&lt;p&gt;Introducing &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kimono-koans&#x2F;httm&#x2F;blob&#x2F;master&#x2F;scripts&#x2F;nicotine.bash&quot;&gt;nicotine&lt;&#x2F;a&gt;, the perfect complement to &lt;code&gt;tar&lt;&#x2F;code&gt;.  (Yes, I do need a better name for this script.)  &lt;code&gt;nicotine&lt;&#x2F;code&gt; is a wrapper script for &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kimono-koans&#x2F;httm&#x2F;&quot;&gt;httm&lt;&#x2F;a&gt;&lt;sup class=&quot;footnote-reference&quot;&gt;&lt;a href=&quot;#1&quot;&gt;1&lt;&#x2F;a&gt;&lt;&#x2F;sup&gt; which converts unique file versions on snapshots to &lt;code&gt;git&lt;&#x2F;code&gt; archives.&lt;&#x2F;p&gt;
&lt;p&gt;Although a proof of concept script which accomplishes something similar has been included in the &lt;code&gt;httm&lt;&#x2F;code&gt; &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kimono-koans&#x2F;httm&#x2F;README.md&quot;&gt;README.md&lt;&#x2F;a&gt; for awhile, if you need your snapshots on the go, and if you can&#x27;t just send and receive the bits, you shouldn&#x27;t have to copy and paste a script.  Perhaps you also deserve some polish and some basic sanity checks!&lt;&#x2F;p&gt;
&lt;p&gt;First, create a snapshot archive:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;➜ nicotine ~&amp;#x2F;program&amp;#x2F;httm&amp;#x2F;*
nicotine archive created successfully: &amp;#x2F;home&amp;#x2F;kimono&amp;#x2F;Cargo.lock-snapshot-archive.tar.gz
nicotine archive created successfully: &amp;#x2F;home&amp;#x2F;kimono&amp;#x2F;Cargo.toml-snapshot-archive.tar.gz
&amp;#x2F;srv&amp;#x2F;program&amp;#x2F;httm&amp;#x2F;debian is an empty directory. Skipping.
nicotine archive created successfully: &amp;#x2F;home&amp;#x2F;kimono&amp;#x2F;httm.1-snapshot-archive.tar.gz
nicotine archive created successfully: &amp;#x2F;home&amp;#x2F;kimono&amp;#x2F;LICENSE-snapshot-archive.tar.gz
nicotine archive created successfully: &amp;#x2F;home&amp;#x2F;kimono&amp;#x2F;packaging-snapshot-archive.tar.gz
nicotine archive created successfully: &amp;#x2F;home&amp;#x2F;kimono&amp;#x2F;README.md-snapshot-archive.tar.gz
nicotine archive created successfully: &amp;#x2F;home&amp;#x2F;kimono&amp;#x2F;scripts-snapshot-archive.tar.gz
nicotine archive created successfully: &amp;#x2F;home&amp;#x2F;kimono&amp;#x2F;src-snapshot-archive.tar.gz
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Next, expand that archive wherever you need it:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;➜ tar zxvf httm.1-snapshot-archive.tar.gz
.&amp;#x2F;httm.1&amp;#x2F;
.&amp;#x2F;httm.1&amp;#x2F;httm.1
.&amp;#x2F;httm.1&amp;#x2F;.git&amp;#x2F;
...
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then, use it as you would any git repo.  For instance, view changes to files via &lt;code&gt;git log -p&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;➜  cd httm.1; git log -p
commit c2cd0f4c7728b3f3dcd7d87d7c24334b0d5b5d41 (HEAD -&amp;gt; master)
Author: ...
Date:   Mon Jan 30 14:53:30 2023 -0600

    httm commit from ZFS snapshot

diff --git a&amp;#x2F;httm.1 b&amp;#x2F;httm.1
index 3831a10..e895f53 100644
--- a&amp;#x2F;httm.1
+++ b&amp;#x2F;httm.1
@@ -1,9 +1,9 @@
    .\&amp;quot; DO NOT MODIFY THIS FILE!  It was generated by help2man 1.49.3.
-.TH HTTM &amp;quot;1&amp;quot; &amp;quot;January 2023&amp;quot; &amp;quot;httm 0.20.0&amp;quot; &amp;quot;User Commands&amp;quot;
+.TH HTTM &amp;quot;1&amp;quot; &amp;quot;January 2023&amp;quot; &amp;quot;httm 0.20.1&amp;quot; &amp;quot;User Commands&amp;quot;
    .SH NAME
-httm \- manual page for httm 0.20.0
+httm \- manual page for httm 0.20.1
    .SH DESCRIPTION
-httm 0.20.0
+httm 0.20.1
...
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;div class=&quot;footnote-definition&quot; id=&quot;1&quot;&gt;&lt;sup class=&quot;footnote-definition-label&quot;&gt;1&lt;&#x2F;sup&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kimono-koans&#x2F;httm&#x2F;&quot;&gt;httm&lt;&#x2F;a&gt; prints the size, date and corresponding locations of available unique versions (deduplicated by modify time and size) of files residing on snapshots, and can also be used &lt;em&gt;interactively&lt;&#x2F;em&gt; to select, restore, and snapshot files.&lt;&#x2F;p&gt;
&lt;&#x2F;div&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>A Somewhat Opinionated Guide to Effective ZFS Snapshots</title>
        <published>2022-12-14T00:00:00+00:00</published>
        <updated>2023-12-19T00:00:00+00:00</updated>
        <author>
          <name>Unknown</name>
        </author>
        <link rel="alternate" href="/opinionated-guide/" type="text/html"/>
        <id>/opinionated-guide/</id>
        
        <content type="html">&lt;p&gt;Much too long ago, I was &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kimono-koans&#x2F;httm&#x2F;issues&#x2F;11&quot;&gt;asked by a user&lt;&#x2F;a&gt; of &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kimono-koans&#x2F;httm&quot;&gt;httm&lt;&#x2F;a&gt; to describe the way I (over)use snapshots, and, though I said I would explain, I never thought I had anything important enough to say about best practices.&lt;&#x2F;p&gt;
&lt;p&gt;However, I&#x27;m increasingly seeing posts on r&#x2F;ZFS requesting instruction of how best to use the snapshot mechanisms of ZFS, and though I can only share my &lt;em&gt;opinions&lt;&#x2F;em&gt; regarding my perhaps &lt;em&gt;very idiosyncratic&lt;&#x2F;em&gt; snapshot setup, maybe these opinions could be helpful for those just starting out.&lt;&#x2F;p&gt;
&lt;p&gt;Of course, this Getting Started guide will make some assumptions that may not apply to your setup.  This guide assumes you&#x27;re using:&lt;&#x2F;p&gt;
&lt;ul&gt;
&lt;li&gt;ZFS for a data and a root pool&lt;&#x2F;li&gt;
&lt;li&gt;Running Ubuntu&lt;&#x2F;li&gt;
&lt;&#x2F;ul&gt;
&lt;p&gt;But I&#x27;m certain at least some of this advice will be useful even if you&#x27;re on a different setup.&lt;&#x2F;p&gt;
&lt;p&gt;I believe an effective snapshot scheme is composed of possibly three types of snapshots:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;kimono-koans.github.io&#x2F;opinionated-guide&#x2F;#periodic-snapshots&quot;&gt;Periodic Snapshots&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;kimono-koans.github.io&#x2F;opinionated-guide&#x2F;#triggered-snapshots&quot;&gt;Triggered Snapshots&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;li&gt;&lt;a href=&quot;https:&#x2F;&#x2F;kimono-koans.github.io&#x2F;opinionated-guide&#x2F;#dynamic-snapshots&quot;&gt;Dynamic Snapshots&lt;&#x2F;a&gt;&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Let&#x27;s discuss each.&lt;&#x2F;p&gt;
&lt;h2 id=&quot;periodic-snapshots&quot;&gt;Periodic Snapshots&lt;a class=&quot;zola-anchor&quot; href=&quot;#periodic-snapshots&quot; aria-label=&quot;Anchor link for: periodic-snapshots&quot;&gt;§&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Periodic snapshots, or snapshots taken at a regular intervals, should be considered the base of any good snapshot scheme, and I wholeheartedly recommend &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jimsalterjrs&#x2F;sanoid&quot;&gt;sanoid&lt;&#x2F;a&gt; as a periodic snapshot tool.  For those that don&#x27;t already know, &lt;code&gt;sanoid&lt;&#x2F;code&gt; describes itself as &amp;quot;a policy-driven snapshot management tool for ZFS filesystems&amp;quot;.  Although other tools exist and perhaps deserve mention, &lt;code&gt;sanoid&lt;&#x2F;code&gt; and &lt;code&gt;syncoid&lt;&#x2F;code&gt;, its replication tools, have made periodic snapshots and replication simple for me.&lt;&#x2F;p&gt;
&lt;p&gt;But note -- like any good tool -- &lt;code&gt;sanoid&lt;&#x2F;code&gt; isn&#x27;t a perfect fit for every use case (and shouldn&#x27;t be, see later &lt;code&gt;zsys&lt;&#x2F;code&gt; and the &amp;quot;Curse of Trying to Do Too Much&amp;quot;).  But what &lt;code&gt;sanoid&lt;&#x2F;code&gt; &lt;em&gt;is&lt;&#x2F;em&gt; is simple and composable.&lt;&#x2F;p&gt;
&lt;p&gt;To my mind, what makes &lt;code&gt;sanoid&lt;&#x2F;code&gt; great is that it doesn&#x27;t force you into using all its features, all the time.  It doesn&#x27;t force you into a complicated policy&#x2F;scheme (even I can do it!), and since it includes such good &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;jimsalterjrs&#x2F;sanoid&#x2F;blob&#x2F;master&#x2F;sanoid.conf&quot;&gt;documentation&lt;&#x2F;a&gt;, I won&#x27;t waste time discussing how to initially configure your pools here.&lt;&#x2F;p&gt;
&lt;p&gt;Instead, I&#x27;d like to highlight, how, in contrast to some other tools, it allows you to compose it with your other Linux utilities, and doesn&#x27;t break when you do something a little different.  For instance, suppose you want to sleep your NAS drives occasionally and not invoke &lt;code&gt;sanoid&lt;&#x2F;code&gt; when your drives are sleeping.  Here&#x27;s how this user solved this particular problem.&lt;&#x2F;p&gt;
&lt;p&gt;First, you&#x27;ll need to check if any of the spinning rust drives are sleeping:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;find &amp;#x2F;dev&amp;#x2F;disk&amp;#x2F;by-id&amp;#x2F; -type l | \
grep -v -e part -e wwn | \
while read disk; do
 if [[ $(lsblk -o rota &amp;quot;$disk&amp;quot; | grep -c &amp;quot;1&amp;quot;) -gt 0 ]]; then
  smartctl -d sat --nocheck=standby &amp;quot;$disk&amp;quot;
 fi
done
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Then, it becomes simple to check that condition whenever you invoke &lt;code&gt;sanoid&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;...
[[ $( &amp;#x2F;usr&amp;#x2F;local&amp;#x2F;sbin&amp;#x2F;checkHDstatus | grep -i &amp;#x27;Device&amp;#x27; | &amp;#x2F;usr&amp;#x2F;bin&amp;#x2F;grep -i -c &amp;#x27;STANDBY&amp;#x27; ) -gt 0 ]] || \
&amp;#x2F;usr&amp;#x2F;sbin&amp;#x2F;sanoid --prune-snapshots --verbose --configdir=&amp;#x2F;etc&amp;#x2F;sanoid&amp;#x2F;
...
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now imagine you want to use an alternate configuration file when that spinning rust is asleep.  Just change the configuration file path:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;...
if [[ $( &amp;#x2F;usr&amp;#x2F;local&amp;#x2F;sbin&amp;#x2F;checkHDstatus | grep -i &amp;#x27;Device&amp;#x27; | &amp;#x2F;usr&amp;#x2F;bin&amp;#x2F;grep -i -c &amp;#x27;STANDBY&amp;#x27; ) -gt 0 ]]; then
 &amp;#x2F;usr&amp;#x2F;sbin&amp;#x2F;sanoid --take-snapshots --verbose --configdir=&amp;#x2F;etc&amp;#x2F;sanoid&amp;#x2F;awake&amp;#x2F;
else
 &amp;#x2F;usr&amp;#x2F;sbin&amp;#x2F;sanoid --take-snapshots --verbose --configdir=&amp;#x2F;etc&amp;#x2F;sanoid&amp;#x2F;sleep&amp;#x2F;
fi
...
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;sanoid&lt;&#x2F;code&gt; handles all this in stride.  It doesn&#x27;t panic when you skip a few hours worth of snapshots on a certain pool.  It doesn&#x27;t need to control heaven and earth.  It just keeps trucking.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;replicating&quot;&gt;Replicating&lt;a class=&quot;zola-anchor&quot; href=&quot;#replicating&quot; aria-label=&quot;Anchor link for: replicating&quot;&gt;§&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;Pop Quiz Hotshot: now that you&#x27;ve made a few snapshots, how would you replicate your &lt;code&gt;rpool&lt;&#x2F;code&gt; to your local &lt;code&gt;datapool&lt;&#x2F;code&gt; using your own custom &lt;code&gt;zfs send&#x2F;recv&lt;&#x2F;code&gt; options?&lt;&#x2F;p&gt;
&lt;p&gt;Easy peasy, you say. Just like &lt;code&gt;sanoid&lt;&#x2F;code&gt;, &lt;code&gt;syncoid&lt;&#x2F;code&gt; has simple options, sane defaults, and an ability to cut a rug when you need to.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&amp;#x2F;usr&amp;#x2F;sbin&amp;#x2F;syncoid -r --sendoptions=&amp;quot;L ec&amp;quot; --recvoptions=&amp;quot;o recordsize=1M o compression=zstd&amp;quot; \
--force-delete --exclude=scratch --exclude=test --exclude=tmp rpool datapool&amp;#x2F;rpool 2&amp;gt;&amp;amp;1 | logger -t syncoid
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;triggered-snapshots&quot;&gt;Triggered Snapshots&lt;a class=&quot;zola-anchor&quot; href=&quot;#triggered-snapshots&quot; aria-label=&quot;Anchor link for: triggered-snapshots&quot;&gt;§&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Canonical&#x27;s &lt;code&gt;zsys&lt;&#x2F;code&gt; promised snapshots of every system update and seamless rollback on boot &lt;em&gt;as well as&lt;&#x2F;em&gt; periodic snapshots of significant datasets&#x2F;directories.  It&#x27;s unfortunate &lt;code&gt;zsys&lt;&#x2F;code&gt; wasn&#x27;t ready for the Ubuntu 22.04 release, and may never be ready.  I won&#x27;t rehash &amp;quot;Why?&amp;quot; here, but one basic &lt;code&gt;zsys&lt;&#x2F;code&gt; premise is sound: &lt;em&gt;Periodic Snapshots are not enough&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;You may ask -- why?  Because, for me, it&#x27;s sometimes important to know that a snapshot was triggered on a date and time certain.  Let&#x27;s discuss a few examples of triggers you might like to use for a snapshot and how you might take those snapshots.&lt;&#x2F;p&gt;
&lt;h3 id=&quot;before-a-system-upgrade&quot;&gt;Before a System Upgrade&lt;a class=&quot;zola-anchor&quot; href=&quot;#before-a-system-upgrade&quot; aria-label=&quot;Anchor link for: before-a-system-upgrade&quot;&gt;§&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;The first triggers we might consider are snapshots upon &lt;code&gt;apt upgrade&lt;&#x2F;code&gt; and kernel updates.&lt;&#x2F;p&gt;
&lt;p&gt;First, you&#x27;ll need a snapshot script to execute (perhaps called &lt;code&gt;&#x2F;usr&#x2F;local&#x2F;sbin&#x2F;snapPrepApt&lt;&#x2F;code&gt;):&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;DATE=&amp;quot;$( &amp;#x2F;bin&amp;#x2F;date +%F-%T )&amp;quot;
# FYI a user helpfully notes there may be some issue with snapshot-ing a bpool and GRUB
# See: https:&amp;#x2F;&amp;#x2F;github.com&amp;#x2F;kimono-koans&amp;#x2F;httm&amp;#x2F;issues&amp;#x2F;11#issuecomment-1860329869
#zfs snapshot -r bpool@snap_&amp;quot;$DATE&amp;quot;_prepApt
zfs snapshot -r bpool&amp;#x2F;BOOT@snap_&amp;quot;$DATE&amp;quot;_prepApt
zfs snapshot rpool@snap_&amp;quot;$DATE&amp;quot;_prepApt
zfs snapshot -r rpool&amp;#x2F;ROOT@snap_&amp;quot;$DATE&amp;quot;_prepApt
zfs snapshot -r rpool&amp;#x2F;USERDATA@snap_&amp;quot;$DATE&amp;quot;_prepApt
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Next, you&#x27;ll need to execute such a script automatically upon &lt;code&gt;apt upgrade&lt;&#x2F;code&gt;.  A simple script in &lt;code&gt;&#x2F;etc&#x2F;apt&#x2F;apt.conf.d&lt;&#x2F;code&gt; will suffice:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&amp;#x2F;&amp;#x2F; Takes a snapshot of the system before package changes.
DPkg::Pre-Invoke {&amp;quot;[ -x &amp;#x2F;usr&amp;#x2F;local&amp;#x2F;sbin&amp;#x2F;snapPrepApt ] &amp;amp;&amp;amp; &amp;#x2F;usr&amp;#x2F;local&amp;#x2F;sbin&amp;#x2F;snapPrepApt || true&amp;quot;;};
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And you will also probably want to execute a script each time you update your kernel.  A script invoked from &lt;code&gt;&#x2F;etc&#x2F;kernel&#x2F;preinst.d&lt;&#x2F;code&gt; might look something like:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;[ -x &amp;#x2F;usr&amp;#x2F;local&amp;#x2F;sbin&amp;#x2F;snapPrepApt ] &amp;amp;&amp;amp; &amp;#x2F;usr&amp;#x2F;local&amp;#x2F;sbin&amp;#x2F;snapPrepApt || true
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;before-service-launch&quot;&gt;Before Service Launch&lt;a class=&quot;zola-anchor&quot; href=&quot;#before-service-launch&quot; aria-label=&quot;Anchor link for: before-service-launch&quot;&gt;§&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;Sometimes you will want to take a snapshot when a service starts up or shuts down.  For instance perhaps you have a service, with a database, that needs to be cleanly shutdown so that its state can also be cleanly snapshot-ed.&lt;&#x2F;p&gt;
&lt;p&gt;Just add a little script to execute before or after start up via &lt;code&gt;systemctl edit&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;...
[Service]
ExecStartPre=&amp;#x2F;bin&amp;#x2F;bash -c &amp;quot;&amp;#x2F;usr&amp;#x2F;local&amp;#x2F;sbin&amp;#x2F;snapDataService&amp;quot;
...
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;on-network-mount&quot;&gt;On Network Mount&lt;a class=&quot;zola-anchor&quot; href=&quot;#on-network-mount&quot; aria-label=&quot;Anchor link for: on-network-mount&quot;&gt;§&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;Perhaps you want to take a snapshot every time a network drive is mounted or unmounted.  So, when you or a program deletes something over the network, you have snapshot of the state just prior to mount or just after unmount.&lt;&#x2F;p&gt;
&lt;p&gt;Your &lt;code&gt;smb.conf&lt;&#x2F;code&gt; allows you to execute scripts just like this:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;...
[TM Volume]
path = &amp;quot;&amp;#x2F;srv&amp;#x2F;timemachine&amp;quot;
valid users = timemachine
read only = no
wide links = no
create mask = 0740
directory mask = 0750
root preexec = &amp;quot;&amp;#x2F;usr&amp;#x2F;local&amp;#x2F;sbin&amp;#x2F;TMpre&amp;quot;
root postexec = &amp;quot;&amp;#x2F;usr&amp;#x2F;local&amp;#x2F;sbin&amp;#x2F;TMpost&amp;quot;
...
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;watch-a-directory&quot;&gt;Watch a Directory&lt;a class=&quot;zola-anchor&quot; href=&quot;#watch-a-directory&quot; aria-label=&quot;Anchor link for: watch-a-directory&quot;&gt;§&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;Maybe you only want to take a snapshot of a folder when new files are added to it.  &lt;code&gt;inotifywait&lt;&#x2F;code&gt; is a wonderful tool for just that use case (and many others!):&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;inotifywait -m -e moved_to &amp;quot;&amp;#x2F;srv&amp;#x2F;downloads&amp;#x2F;&amp;quot; | while read -r line; do
 snapDownloads
done
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h3 id=&quot;cleanup&quot;&gt;Cleanup&lt;a class=&quot;zola-anchor&quot; href=&quot;#cleanup&quot; aria-label=&quot;Anchor link for: cleanup&quot;&gt;§&lt;&#x2F;a&gt;
&lt;&#x2F;h3&gt;
&lt;p&gt;Now that you&#x27;ve made these snapshots, if you&#x27;re anything like me, you &lt;em&gt;must&lt;&#x2F;em&gt; clean them up once they aren&#x27;t needed anymore.  I suggest &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;bahamas10&#x2F;zfs-prune-snapshots&quot;&gt;zfs-prune-snapshots&lt;&#x2F;a&gt; for this task.&lt;&#x2F;p&gt;
&lt;p&gt;Just run as a cron script daily to cleanup any triggered or dynamic snapshots that have outlived their usefulness:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;&amp;#x2F;usr&amp;#x2F;local&amp;#x2F;sbin&amp;#x2F;zfs-prune-snapshots -s &amp;#x27;_prepApt&amp;#x27; 2w 2&amp;gt;&amp;amp;1 | logger -t sanoid
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;dynamic-snapshots&quot;&gt;Dynamic Snapshots&lt;a class=&quot;zola-anchor&quot; href=&quot;#dynamic-snapshots&quot; aria-label=&quot;Anchor link for: dynamic-snapshots&quot;&gt;§&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;&amp;quot;Dynamic Snapshots&amp;quot; is a term I&#x27;ll credit myself for, at least, popularizing.  Dynamic Snapshots are very similar to Triggered Snapshots.  In fact, I think it is appropriate to think of Dynamic Snapshots as simply a breed of Triggered Snapshots.  The key difference is how ad-hoc a Dynamic Snapshot &lt;em&gt;feels&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;I&#x27;ll try to give a few examples.&lt;&#x2F;p&gt;
&lt;p&gt;Imagine -- you&#x27;re in a folder and you realize you&#x27;re about to change a bunch of files, and you want a snapshot of the state of the folder before you make any edits.  You don&#x27;t know precisely which dataset your working directory resides.  And you&#x27;re not really in the mood to think about it.  Of course, you could just copy that folder, rename it, and make edits in the new folder. Or you could do the same with each file as you go.  Or you could determine the dataset upon which this folder is located and manually do a snapshot yourself.&lt;&#x2F;p&gt;
&lt;p&gt;All of these things you could do, &lt;em&gt;feel&lt;&#x2F;em&gt; like leg work.  A Dynamic Snapshot shouldn&#x27;t feel like leg work.  A Dynamic Snapshot should just work by determining the ZFS mount of the &lt;code&gt;$PWD&lt;&#x2F;code&gt; and taking a snapshot immediately.&lt;&#x2F;p&gt;
&lt;p&gt;For instance, with &lt;code&gt;httm&lt;&#x2F;code&gt;, you might invoke a Dynamic Snapshot like so:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;➜ httm -S .
httm took a snapshot named: rpool&amp;#x2F;ROOT&amp;#x2F;ubuntu_tiebek@snap_2022-12-14-12:31:41_httmSnapFileMount
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;In order for the above to work you will need permissions.  The most elegant way to give a user ZFS permissions is now through the new &lt;code&gt;zfs allow&lt;&#x2F;code&gt; function.  If you have &lt;code&gt;httm&lt;&#x2F;code&gt; installed on Ubuntu, running &lt;code&gt;ounce --give-priv&lt;&#x2F;code&gt;, as an ordinary user, will execute something like the block below to give an ordinary user (you!) permissions to snapshot on all pools.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;for pool in &amp;quot;$( sudo zpool list -o name | grep -v -e NAME )&amp;quot;; do
 sudo zfs allow &amp;quot;$( whoami )&amp;quot; mount,snapshot &amp;quot;$pool&amp;quot;
done
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Speaking of &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kimono-koans&#x2F;httm&#x2F;blob&#x2F;master&#x2F;scripts&#x2F;ounce.bash&quot;&gt;ounce&lt;&#x2F;a&gt;, &lt;code&gt;ounce&lt;&#x2F;code&gt; is a script I wrote which wraps a target executable, can trace its system calls, and will execute snapshots &lt;em&gt;before&lt;&#x2F;em&gt; you do something silly.  &lt;code&gt;ounce&lt;&#x2F;code&gt; is my canonical example of a dynamic snapshot script.  When I type &lt;code&gt;ounce nano &#x2F;etc&#x2F;samba&#x2F;smb.conf&lt;&#x2F;code&gt; (I actually &lt;code&gt;alias &#x27;nano&#x27;=&#x27;ounce --trace nano&#x27;&lt;&#x2F;code&gt;), &lt;code&gt;ounce&lt;&#x2F;code&gt; knows that it&#x27;s smart and I&#x27;m dumb, so -- it traces each file open call, sees that I just edited &lt;code&gt;&#x2F;etc&#x2F;samba&#x2F;smb.conf&lt;&#x2F;code&gt; a few short minutes ago.  Once &lt;code&gt;ounce&lt;&#x2F;code&gt; sees I have no snapshot of those file changes, it takes a snapshot of the dataset upon which &lt;code&gt;&#x2F;etc&#x2F;samba&#x2F;smb.conf&lt;&#x2F;code&gt; is located, before I edit and save the file again.&lt;&#x2F;p&gt;
&lt;p&gt;We can check that &lt;code&gt;ounce&lt;&#x2F;code&gt; worked as advertised via &lt;code&gt;httm&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;➜ httm &amp;#x2F;etc&amp;#x2F;samba&amp;#x2F;smb.conf
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Fri Dec 09 07:45:41 2022  17.6 KiB  &amp;quot;&amp;#x2F;.zfs&amp;#x2F;snapshot&amp;#x2F;autosnap_2022-12-13_18:00:27_hourly&amp;#x2F;etc&amp;#x2F;samba&amp;#x2F;smb.conf&amp;quot;
Wed Dec 14 12:58:10 2022  17.6 KiB  &amp;quot;&amp;#x2F;.zfs&amp;#x2F;snapshot&amp;#x2F;snap_2022-12-14-12:58:18_ounceSnapFileMount&amp;#x2F;etc&amp;#x2F;samba&amp;#x2F;smb.conf&amp;quot;&amp;quot;
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Wed Dec 14 12:58:10 2022  17.6 KiB  &amp;quot;&amp;#x2F;etc&amp;#x2F;samba&amp;#x2F;smb.conf&amp;quot;
───────────────────────────────────────────────────────────────────────────────────────────────────────────────────
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;a class=&quot;zola-anchor&quot; href=&quot;#conclusion&quot; aria-label=&quot;Anchor link for: conclusion&quot;&gt;§&lt;&#x2F;a&gt;
&lt;&#x2F;h2&gt;
&lt;p&gt;Good luck with your future snapshot adventures!  I&#x27;d love to know your thoughts on how you do it better&#x2F;more cleverly!&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>New ways to make ZFS&#x2F;btrfs snapshots UNIX-y (again?)</title>
        <published>2022-10-31T00:00:00+00:00</published>
        <updated>2022-10-31T00:00:00+00:00</updated>
        <author>
          <name>Unknown</name>
        </author>
        <link rel="alternate" href="/unix/" type="text/html"/>
        <id>/unix/</id>
        
        <content type="html">&lt;p&gt;One thing I didn&#x27;t understand when I started using ZFS is why there wasn&#x27;t a standard periodic snapshot tool packaged with the filesystem.  Given the triumph of engineering that ZFS is, and the good taste shown in the design of the &lt;code&gt;zfs&lt;&#x2F;code&gt; and &lt;code&gt;zpool&lt;&#x2F;code&gt; utilities, it was hard for me to understand why a standard set of snapshot scripts wasn&#x27;t included everywhere ZFS was used.&lt;&#x2F;p&gt;
&lt;p&gt;One can only guess at a few reasons why.  Maybe the ZFS developers simply wanted a thousand flowers to bloom.  They didn&#x27;t want to impose their strict idea of what a periodic snapshot tool should look like.  Maybe they were simply too busy shipping an OS, and they didn&#x27;t really know, at the time, how snapshots would be used by their consumers.  Perhaps significantly, ZFS was not a &amp;quot;desktop&amp;quot; filesystem until only recently.  Apple missed their opportunity (at eternal glory!).  Ubuntu is now the first mainstream OS most will encounter with ZFS on root.&lt;&#x2F;p&gt;
&lt;p&gt;Of course, not including standard scripts has probably had some positive results.  Through trial and error, I&#x2F;we have created or found snapshot, pruning, replication tools, etc., with which I am&#x2F;we are comfortable.  An ecosystem was allowed to develop in the absence of strict direction.  An ecosystem that developed good tools for one, or a set of jobs, rather than all or too many.&lt;&#x2F;p&gt;
&lt;p&gt;But I think it has had some negative results, as well.  Some very beautiful UNIX-y abstractions have been allowed to languish -- many of us have loads of snapshots, and many of us seem to never use them, except perhaps when we do the occasional rollback, or go hunting for an older version of a file.&lt;&#x2F;p&gt;
&lt;p&gt;Of course, ZFS loves that &amp;quot;most things are a file&amp;quot; for certain operations:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;zfs send rpool&amp;#x2F;scratch@autosnap_2022-10-31_17:01:20_hourly | gzip &amp;gt; &amp;#x2F;srv&amp;#x2F;tmp&amp;#x2F;scratch.gz
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;But it seems the ZFS&#x2F;btrfs communities still haven&#x27;t wrapped their collective heads around the idea that snapshot datasets can be useful everywhere, especially at the file (read: not dataset) level.  This is the reason why Jim Salter&#x27;s &lt;code&gt;findoid&lt;&#x2F;code&gt; was such a revelation for me, and such a huge inspiration for &lt;code&gt;httm&lt;&#x2F;code&gt;.  It was the first CLI tool I saw which made an attempt to deal with snapshots on a file level.&lt;&#x2F;p&gt;
&lt;p&gt;And &lt;code&gt;httm&lt;&#x2F;code&gt; attempts to take that very broad idea to its logical conclusion.  See:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;asciinema.org&#x2F;a&#x2F;529608&quot;&gt;&lt;img src=&quot;https:&#x2F;&#x2F;asciinema.org&#x2F;a&#x2F;529608.svg&quot; alt=&quot;asciicast&quot; &#x2F;&gt;&lt;&#x2F;a&gt;&lt;&#x2F;p&gt;
&lt;p&gt;Of course, &lt;code&gt;httm&lt;&#x2F;code&gt; does lots of neat stuff on its own, but I won&#x27;t describe all that stuff here.  If you&#x27;re interested in the specifics of &lt;code&gt;httm&lt;&#x2F;code&gt;, please take a look at the &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kimono-koans&#x2F;httm&#x2F;blob&#x2F;master&#x2F;README.md&quot;&gt;README&lt;&#x2F;a&gt;.  I could spend all day (okay, maybe an hour) talking about the things &lt;code&gt;httm&lt;&#x2F;code&gt; does simply by itself.  But what is of most interest is to me is the ways it &lt;em&gt;could be used&lt;&#x2F;em&gt;.  I&#x27;ve tried to spark some curiosity by showing the very UNIX-y ways I use &lt;code&gt;httm&lt;&#x2F;code&gt;, see, for instance, &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kimono-koans&#x2F;httm&#x2F;blob&#x2F;master&#x2F;README.md#example-usage&quot;&gt;to create &lt;code&gt;tar&lt;&#x2F;code&gt; and &lt;code&gt;git&lt;&#x2F;code&gt; archives&lt;&#x2F;a&gt;.  However, shell snippets are just proofs of concept.  I think what people (like me) need are fully working scripts&#x2F;models of how &lt;code&gt;httm&lt;&#x2F;code&gt; could be used to do new and interesting and UNIX-y things.&lt;&#x2F;p&gt;
&lt;p&gt;So -- the following are two fully formed (that is, at the limits of my &lt;code&gt;bash&lt;&#x2F;code&gt; scripting abilities!) examples of how you might use &lt;code&gt;httm&lt;&#x2F;code&gt; to create other new and interesting tools:&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kimono-koans&#x2F;httm&#x2F;blob&#x2F;master&#x2F;scripts&#x2F;ounce.bash&quot;&gt;ounce&lt;&#x2F;a&gt; (codename: &amp;quot;dimebag&amp;quot;) is a wrapper script for &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kimono-koans&#x2F;httm&quot;&gt;httm&lt;&#x2F;a&gt; which gives you no mental overhead, non-periodic dynamic snapshots.&lt;&#x2F;p&gt;
&lt;p&gt;When I type &lt;code&gt;ounce nano &#x2F;etc&#x2F;samba&#x2F;smb.conf&lt;&#x2F;code&gt; (I actually &lt;code&gt;alias &#x27;nano&#x27;=&#x27;ounce nano&#x27;&lt;&#x2F;code&gt;), &lt;code&gt;ounce&lt;&#x2F;code&gt; knows that it&#x27;s smart and I&#x27;m dumb, and it sees that I just edited &lt;code&gt;&#x2F;etc&#x2F;samba&#x2F;smb.conf&lt;&#x2F;code&gt; a few short minutes ago and it takes a snapshot before I edit the file again because it wants me to have snapshots of all my file changes.&lt;&#x2F;p&gt;
&lt;p&gt;Of course, we can check with &lt;code&gt;httm&lt;&#x2F;code&gt;:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;➜ httm &amp;#x2F;etc&amp;#x2F;samba&amp;#x2F;smb.conf
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Tue Aug 09 16:46:14 2022  17.6 KiB  &amp;quot;&amp;#x2F;.zfs&amp;#x2F;snapshot&amp;#x2F;autosnap_2022-10-19_20:00:22_hourly&amp;#x2F;etc&amp;#x2F;samba&amp;#x2F;smb.conf&amp;quot;
Fri Oct 21 09:11:17 2022  17.6 KiB  &amp;quot;&amp;#x2F;.zfs&amp;#x2F;snapshot&amp;#x2F;snap_2022-10-21-09:11:18_ounceSnapFileMount&amp;#x2F;etc&amp;#x2F;samba&amp;#x2F;smb.conf&amp;quot;
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────
Fri Oct 21 09:11:25 2022  17.6 KiB  &amp;quot;&amp;#x2F;etc&amp;#x2F;samba&amp;#x2F;smb.conf&amp;quot;
──────────────────────────────────────────────────────────────────────────────────────────────────────────────────
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kimono-koans&#x2F;httm&#x2F;tree&#x2F;master&#x2F;scripts&#x2F;bowie.bash&quot;&gt;bowie&lt;&#x2F;a&gt; is a wrapper script for &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kimono-koans&#x2F;httm&quot;&gt;httm&lt;&#x2F;a&gt; which quickly displays the difference (with colors) between unique snapshot versions and the live file.&lt;&#x2F;p&gt;
&lt;p&gt;A search, in the default, last change mode:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;➜ bowie `which bowie`
&amp;#x2F;usr&amp;#x2F;bin&amp;#x2F;bowie
__
Files &amp;#x2F;.zfs&amp;#x2F;snapshot&amp;#x2F;snap_2022-10-31-08:34:09_ounceSnapFileMount&amp;#x2F;usr&amp;#x2F;bin&amp;#x2F;bowie and &amp;#x2F;usr&amp;#x2F;bin&amp;#x2F;bowie differ
69c69
&amp;lt;		while read line; do
---
&amp;gt;		while read -r line; do
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Each script contains more options and features than can be described here.  I&#x27;m interested in your thoughts on what new options to add, or other potential scripts ideas.  But I&#x27;m even &lt;em&gt;more interested&lt;&#x2F;em&gt; in &lt;em&gt;your scripts&lt;&#x2F;em&gt;, and what new features you&#x27;d like me to add to &lt;code&gt;httm&lt;&#x2F;code&gt; to make new scripts possible&#x2F;better.&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;ounce&lt;&#x2F;code&gt; and &lt;code&gt;bowie&lt;&#x2F;code&gt; are available in &lt;code&gt;httm&lt;&#x2F;code&gt; version &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kimono-koans&#x2F;httm&#x2F;releases&#x2F;tag&#x2F;0.16.7&quot;&gt;0.16.7&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>ounce (codename: &#x27;dimebag&#x27;): Dynamic File-Level ZFS Snapshots</title>
        <published>2022-10-21T00:00:00+00:00</published>
        <updated>2022-10-23T00:00:00+00:00</updated>
        <author>
          <name>Unknown</name>
        </author>
        <link rel="alternate" href="/ounce/" type="text/html"/>
        <id>/ounce/</id>
        
        <content type="html">&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kimono-koans&#x2F;httm&#x2F;blob&#x2F;master&#x2F;scripts&#x2F;ounce.zsh&quot;&gt;ounce&lt;&#x2F;a&gt; (codename: &amp;quot;dimebag&amp;quot;) is a wrapper script for &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kimono-koans&#x2F;httm&quot;&gt;httm&lt;&#x2F;a&gt; which give you no mental overhead, non-periodic dynamic snapshots.&lt;&#x2F;p&gt;
&lt;p&gt;On &lt;a href=&quot;https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=33162259&quot;&gt;Hacker News&lt;&#x2F;a&gt;, there was an article about how NILFS seems to &amp;quot;take&amp;quot; continuous snapshots.  In addition to checkpoints, one can stop a NILFS filesystem from garbage collecting, roll back to a point in time, and recover a file that was once there.  And, this seems great, if you can take the performance hit of a log-structured file system (which is substantial).&lt;&#x2F;p&gt;
&lt;p&gt;But perhaps like my boy Ben Franklin (or was it my mother, or Ben Franklin&#x27;s mother?) said &amp;quot;an ounce of prevention is worth a pound of cure&amp;quot;?  Why not just take a snapshot before you do something silly?&lt;&#x2F;p&gt;
&lt;p&gt;For awhile, one has been able to just feed &lt;code&gt;httm&lt;&#x2F;code&gt; file names and have it figure out which dataset those files resided on.  Like so:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;➜  printf &amp;quot;&amp;#x2F;var&amp;#x2F;log&amp;#x2F;syslog\n&amp;#x2F;etc&amp;#x2F;passwd\n&amp;quot; | sudo httm --snap
httm took a snapshot named: rpool&amp;#x2F;var&amp;#x2F;log@snap_2022-10-21-08:57:04_httmSnapFileMount
httm took a snapshot named: rpool@snap_2022-10-21-08:57:04_httmSnapFileMount
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;But I don&#x27;t know about you, I don&#x27;t usually feed file names into a pipe before I type &lt;code&gt;Name of $EDITOR redacted to prevent flame war&lt;&#x2F;code&gt; or &lt;code&gt;rm&lt;&#x2F;code&gt;?&lt;&#x2F;p&gt;
&lt;p&gt;When I type:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;# nano used here to frustrate just you
➜  nano &amp;#x2F;etc&amp;#x2F;samba&amp;#x2F;smb.conf
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If there is not a snapshot that matches the live version, I would like my computer to snapshot &lt;code&gt;&#x2F;etc&#x2F;samba&#x2F;smb.conf&lt;&#x2F;code&gt; before I do something stupid.  &lt;code&gt;ounce&lt;&#x2F;code&gt; does this for me and now for you.&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;# why do you hate nano so much?
➜  ounce nano &amp;#x2F;etc&amp;#x2F;samba&amp;#x2F;smb.conf
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;&lt;code&gt;ounce&lt;&#x2F;code&gt; knows that it&#x27;s smart and I&#x27;m dumb, and sees that I just edited &lt;code&gt;&#x2F;etc&#x2F;samba&#x2F;smb.conf&lt;&#x2F;code&gt; a few short minutes ago and takes a snapshot before I edit the file again because it wants me to have snapshots of all my file changes.  You can check:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;➜  httm &amp;#x2F;etc&amp;#x2F;samba&amp;#x2F;smb.conf
─────────────────────────────────────────────────────────────────────────────────────────────────────────────
Tue Aug 09 16:46:14 2022  17.6 KiB  &amp;quot;&amp;#x2F;.zfs&amp;#x2F;snapshot&amp;#x2F;autosnap_2022-10-19_20:00:22_hourly&amp;#x2F;etc&amp;#x2F;samba&amp;#x2F;smb.conf&amp;quot;
Fri Oct 21 09:11:17 2022  17.6 KiB  &amp;quot;&amp;#x2F;.zfs&amp;#x2F;snapshot&amp;#x2F;snap_2022-10-21-09:11:18_httmSnapFileMount&amp;#x2F;etc&amp;#x2F;samba&amp;#x2F;smb.conf&amp;quot;
─────────────────────────────────────────────────────────────────────────────────────────────────────────────
Fri Oct 21 09:11:25 2022  17.6 KiB  &amp;quot;&amp;#x2F;etc&amp;#x2F;samba&amp;#x2F;smb.conf&amp;quot;
─────────────────────────────────────────────────────────────────────────────────────────────────────────────
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;For more fun, simply alias to the commands you make modifications with:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;# don&amp;#x27;t get triggered but...
alias nano=&amp;quot;ounce nano&amp;quot;
alias rm=&amp;quot;ounce rm&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Now available in &lt;code&gt;httm&lt;&#x2F;code&gt; version &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kimono-koans&#x2F;httm&#x2F;releases&#x2F;tag&#x2F;0.16.1&quot;&gt;0.16.1&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Imagine You&#x27;re a Goofball: Dynamic Preventative ZFS Snapshots</title>
        <published>2022-10-19T00:00:00+00:00</published>
        <updated>2022-10-20T00:00:00+00:00</updated>
        <author>
          <name>Unknown</name>
        </author>
        <link rel="alternate" href="/dynamic/" type="text/html"/>
        <id>/dynamic/</id>
        
        <content type="html">&lt;p&gt;On &lt;a href=&quot;https:&#x2F;&#x2F;news.ycombinator.com&#x2F;item?id=33162259&quot;&gt;Hacker News&lt;&#x2F;a&gt;, there is an article about how NILFS seems to &amp;quot;take&amp;quot; continuous snapshots.  In addition to checkpoints, one can stop a NILFS filesystem from garbage collecting, roll back to a point in time, and recover a file that was once there.  And, this seems great, if you can take the performance hit of a log-structured file system (which is substantial).&lt;&#x2F;p&gt;
&lt;p&gt;But perhaps like our mother&#x27;s said &amp;quot;an ounce of prevention is worth a pound of cure&amp;quot;?  Why not just take a snapshot before you do something silly?  With &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kimono-koans&#x2F;httm&quot;&gt;httm&lt;&#x2F;a&gt;, one can now take these sorts of no mental overhead, non-periodic dynamic snapshots, which can &lt;em&gt;complement&lt;&#x2F;em&gt; your current periodic snapshot scheme.&lt;&#x2F;p&gt;
&lt;p&gt;Let me reiterate -- one can and &lt;em&gt;should be able to&lt;&#x2F;em&gt; take a snapshot without needing to specify a dataset or snapshot name. Just feed &lt;code&gt;httm&lt;&#x2F;code&gt; a filename and &lt;code&gt;httm&lt;&#x2F;code&gt; will figure out the rest.&lt;&#x2F;p&gt;
&lt;p&gt;See, for example:&lt;&#x2F;p&gt;
&lt;pre&gt;&lt;code&gt;#!&amp;#x2F;bin&amp;#x2F;bash
function ounce_of_prevention {
    for a; do
        # is the argument a file?
        if [[ -f &amp;quot;$a&amp;quot; ]]; then
            local LIVE_FILE=&amp;quot;$a&amp;quot;
        else
            continue
        fi

        # get last snap version of the live file?
        local LAST_SNAP=&amp;quot;$(httm -l &amp;quot;$LIVE_FILE&amp;quot;)&amp;quot;

        # check whether to take snap - do we have a snap of the live file already?
        # 1) if empty, live file does not have a snapshot, then take snap, or
        # 2) if live file is not the same as the last snap, then take snap
        if [[ -z &amp;quot;$LAST_SNAP&amp;quot; ]] || \
           [[ ! -z &amp;quot;$LAST_SNAP&amp;quot; &amp;amp;&amp;amp; &amp;quot;$(stat -c %Y &amp;quot;$LIVE_FILE&amp;quot;)&amp;quot; -ne &amp;quot;$(stat -c %Y &amp;quot;$LAST_SNAP&amp;quot;)&amp;quot; ]]
        then
            # httm will dynamically determine the location of
            # the file&amp;#x27;s ZFS dataset and snapshot that mount
            sudo httm --snap &amp;quot;$LIVE_FILE&amp;quot; &amp;gt; &amp;#x2F;dev&amp;#x2F;null &amp;amp;
        fi
    done
}

ounce_of_prevention &amp;quot;$@&amp;quot;
# expressly used `nano` instead of `vim` or `emacs` to avoid a unholy war
&amp;#x2F;usr&amp;#x2F;bin&amp;#x2F;nano &amp;quot;$@&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;First, we check whether we even need to take a snapshot:&lt;&#x2F;p&gt;
&lt;ol&gt;
&lt;li&gt;The 0th condition checks whether an argument is a file.&lt;&#x2F;li&gt;
&lt;li&gt;The command &lt;code&gt;httm -l $LIVE_FILE&lt;&#x2F;code&gt; requests the last snapshot for the file, allowing you to test the 1st condition, which checks whether that file has a snapshot, and,&lt;&#x2F;li&gt;
&lt;li&gt;The 2nd condition checks whether the live file is not the same as the last snapshot version.&lt;&#x2F;li&gt;
&lt;&#x2F;ol&gt;
&lt;p&gt;Next, &lt;code&gt;httm&lt;&#x2F;code&gt; makes certain that it doesn&#x27;t matter whether you are editing &lt;code&gt;~&#x2F;.zshrc&lt;&#x2F;code&gt; or &lt;code&gt;&#x2F;etc&#x2F;samba&#x2F;smb.conf&lt;&#x2F;code&gt;.  &lt;code&gt;httm&lt;&#x2F;code&gt; dynamically determines and snapshots the appropriate mount (before you modify&#x2F;screw up the file!).&lt;&#x2F;p&gt;
&lt;p&gt;Now, one will have to also set up a bash alias (&lt;code&gt;alias nano=nano-with-prevention&lt;&#x2F;code&gt;), and a sudoers policy (&lt;code&gt;kimono ALL=(ALL) NOPASSWD: &#x2F;usr&#x2F;bin&#x2F;httm --snap&lt;&#x2F;code&gt;), which allows these types of dynamic snapshots, but this pattern does seem to work pretty well.&lt;&#x2F;p&gt;
&lt;p&gt;Does anyone else have any other fancy dynamic snapshot tricks I could add to my arsenal?&lt;&#x2F;p&gt;
&lt;p&gt;The latest release of &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kimono-koans&#x2F;httm&quot;&gt;httm&lt;&#x2F;a&gt; is &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kimono-koans&#x2F;httm&#x2F;releases&#x2F;tag&#x2F;0.16.0&quot;&gt;0.16.0&lt;&#x2F;a&gt;. &lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Using `httm` and ZFS to detect file modifications for `dano` (or getting a little sleazy to do a little good)</title>
        <published>2022-10-10T00:00:00+00:00</published>
        <updated>2022-10-10T00:00:00+00:00</updated>
        <author>
          <name>Unknown</name>
        </author>
        <link rel="alternate" href="/dano/" type="text/html"/>
        <id>/dano/</id>
        
        <content type="html">&lt;p&gt;One thing ZFS doesn&#x27;t do (and thank goodness it doesn&#x27;t?), it doesn&#x27;t detect out-of-band changes to files.  If a program has the permissions to modify a file, ZFS happily modifies that file.  But, for some files (and for the truly paranoid), we may want to keep additional metadata about file integrity.  For instance, FLAC files keep checksums of its music streams. A program I wrote, &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kimono-koans&#x2F;dano&quot;&gt;dano&lt;&#x2F;a&gt;, provides a way to do the same for all FFMPEG compatible media streams.&lt;&#x2F;p&gt;
&lt;p&gt;And perhaps you want to read back and verify such media bitstreams occasionally as one might in a &lt;code&gt;zpool scrub&lt;&#x2F;code&gt;, of course &lt;code&gt;dano&lt;&#x2F;code&gt; lets you do that too:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;% find &amp;#x2F;tank&amp;#x2F;Media -type f | dano --test
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;But doesn&#x27;t verifying &lt;em&gt;all those checksums&lt;&#x2F;em&gt; take a long time?  And don&#x27;t you already do this when you do a &lt;code&gt;zpool scrub&lt;&#x2F;code&gt;?  Good point!  Wouldn&#x27;t it be nice to only test those files which ZFS tells us have changed (if you trust ZFS)?  Is it wrong&#x2F;sleazy to not verify these checksums if we know the underlying bits haven&#x27;t changed?  Maybe &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kimono-koans&#x2F;httm&quot;&gt;httm&lt;&#x2F;a&gt; can help us be a little sleazy:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;% httm --num-versions ~&amp;#x2F;program&amp;#x2F;httm&amp;#x2F;*
&amp;quot;&amp;#x2F;srv&amp;#x2F;program&amp;#x2F;httm&amp;#x2F;Cargo.lock&amp;quot; : 3 Versions available.
&amp;quot;&amp;#x2F;srv&amp;#x2F;program&amp;#x2F;httm&amp;#x2F;Cargo.toml&amp;quot; : 4 Versions available.
&amp;quot;&amp;#x2F;srv&amp;#x2F;program&amp;#x2F;httm&amp;#x2F;LICENSE&amp;quot; : 1 Version available.
&amp;quot;&amp;#x2F;srv&amp;#x2F;program&amp;#x2F;httm&amp;#x2F;README.md&amp;quot; : 2 Versions available.
&amp;quot;&amp;#x2F;srv&amp;#x2F;program&amp;#x2F;httm&amp;#x2F;httm.1&amp;quot; : 3 Versions available.
&amp;quot;&amp;#x2F;srv&amp;#x2F;program&amp;#x2F;httm&amp;#x2F;packaging&amp;quot; : 1 Version available.
&amp;quot;&amp;#x2F;srv&amp;#x2F;program&amp;#x2F;httm&amp;#x2F;scripts&amp;quot; : 1 Version available.
&amp;quot;&amp;#x2F;srv&amp;#x2F;program&amp;#x2F;httm&amp;#x2F;src&amp;quot; : 6 Versions available.
&amp;quot;&amp;#x2F;srv&amp;#x2F;program&amp;#x2F;httm&amp;#x2F;target&amp;quot; : 1 Version available
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Of course, this is really great for determining, at a glace, &amp;quot;Wow, some of these files in &lt;code&gt;&#x2F;etc&lt;&#x2F;code&gt; are seeing lot&#x27;s of churn.  I have more questions...&amp;quot;.  But maybe what I really want, right now, is files with a single version available but which have been around long enough to have at least one snapshot available, &lt;code&gt;httm&lt;&#x2F;code&gt; has you covered:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;% httm --num-versions=single-with-snap ~&amp;#x2F;program&amp;#x2F;httm&amp;#x2F;*
&amp;quot;&amp;#x2F;srv&amp;#x2F;program&amp;#x2F;httm&amp;#x2F;LICENSE&amp;quot;
&amp;quot;&amp;#x2F;srv&amp;#x2F;program&amp;#x2F;httm&amp;#x2F;packaging&amp;quot;
&amp;quot;&amp;#x2F;srv&amp;#x2F;program&amp;#x2F;httm&amp;#x2F;scripts&amp;quot;
&amp;quot;&amp;#x2F;srv&amp;#x2F;program&amp;#x2F;httm&amp;#x2F;target&amp;quot;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And we might now also rewrite our little &lt;code&gt;dano&lt;&#x2F;code&gt; script to verify only those files with multiple versions that ZFS detected:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;% find &amp;#x2F;tank&amp;#x2F;Media -type f | httm --num-versions=multiple | dano --test
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Available in &lt;code&gt;httm&lt;&#x2F;code&gt; version &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kimono-koans&#x2F;httm&#x2F;releases&#x2F;tag&#x2F;0.15.2&quot;&gt;0.15.2&lt;&#x2F;a&gt;.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Fun with ZFS, httm, and inotifywait</title>
        <published>2022-06-25T00:00:00+00:00</published>
        <updated>2022-06-25T00:00:00+00:00</updated>
        <author>
          <name>Unknown</name>
        </author>
        <link rel="alternate" href="/inotifywait/" type="text/html"/>
        <id>/inotifywait/</id>
        
        <content type="html">&lt;p&gt;If you&#x27;ve never used &lt;code&gt;inotifywait&lt;&#x2F;code&gt;, it&#x27;s pretty handy for when you want to snapshot a directory after a file is accessed, or written to, or moved to a watched directory, etc., like so:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;inotifywait -r -m --exclude &amp;quot;&amp;#x2F;srv&amp;#x2F;downloads&amp;#x2F;incomplete&amp;#x2F;&amp;quot; -e moved_to &amp;quot;&amp;#x2F;srv&amp;#x2F;downloads&amp;#x2F;&amp;quot; | while read -r line; do
	sudo &amp;#x2F;usr&amp;#x2F;sbin&amp;#x2F;zfs snapshot rpool&amp;#x2F;downloads@snap_&amp;quot;$( &amp;#x2F;bin&amp;#x2F;date +%F-%T )&amp;quot;_completionSnap
done
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;However, imagine you&#x27;re watching a large directory tree where there may be many ZFS datasets, how would you know which dataset to snapshot?&lt;&#x2F;p&gt;
&lt;p&gt;&lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kimono-koans&#x2F;httm&quot;&gt;httm&lt;&#x2F;a&gt; has your back!&lt;&#x2F;p&gt;
&lt;p&gt;&lt;code&gt;httm -m &amp;lt;INPUT_FILE&amp;gt;&lt;&#x2F;code&gt; will detect and report back the mount of the ZFS dataset upon which that watched file resides, so you can use that mount&#x2F;dataset in your snapshot scripts:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;inotifywait -r -m --format %w%f --exclude &amp;quot;&amp;#x2F;srv&amp;#x2F;downloads&amp;#x2F;incomplete&amp;#x2F;&amp;quot; -e moved_to &amp;quot;&amp;#x2F;srv&amp;#x2F;downloads&amp;#x2F;&amp;quot; | while read -r line; do
	filemount=&amp;quot;$(httm -m $line)&amp;quot; 
	filedataset=&amp;quot;$(mount | grep $filemount | cut -f1 -d&amp;#x27; &amp;#x27;)&amp;quot; 
	sudo &amp;#x2F;usr&amp;#x2F;sbin&amp;#x2F;zfs snapshot $filedataset@snap_&amp;quot;$( &amp;#x2F;bin&amp;#x2F;date +%F-%T )&amp;quot;_completionSnap 
done
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;If you&#x27;re comfortable with &lt;code&gt;httm&lt;&#x2F;code&gt; making a few choices for you, &lt;code&gt;httm&lt;&#x2F;code&gt; can also take a snapshot from using just the filename as input:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;% sudo httm --snap &amp;#x2F;var&amp;#x2F;log&amp;#x2F;syslog
httm took a snapshot named: rpool&amp;#x2F;ROOT&amp;#x2F;ubuntu_wi01vc&amp;#x2F;var&amp;#x2F;log@snap_Jun-25-2022-23:11:50_httmSnapFileMount
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;This last feature is ZFS only for right now.&lt;&#x2F;p&gt;
&lt;p&gt;Available now for &lt;a href=&quot;https:&#x2F;&#x2F;github.com&#x2F;kimono-koans&#x2F;httm&#x2F;releases&#x2F;tag&#x2F;0.12.6&quot;&gt;0.12.6&lt;&#x2F;a&gt; and later editions.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Re: packaging, FOSS user expectations are out of alignment</title>
        <published>2022-06-07T00:00:00+00:00</published>
        <updated>2022-06-07T00:00:00+00:00</updated>
        <author>
          <name>Unknown</name>
        </author>
        <link rel="alternate" href="/user-expectations/" type="text/html"/>
        <id>/user-expectations/</id>
        
        <content type="html">&lt;p&gt;Usually when asked to build a package for your particular distribution, I say, &amp;quot;I&#x27;m afraid I just don&#x27;t have the time, but PRs for your distribution are welcome.&amp;quot;  But my real talk, B-side opinion on FOSS packaging, is -- when you ask a dev to package software in a specific way for you, in the FOSS world, that&#x27;s entitlement, because you can do it yourself.&lt;&#x2F;p&gt;
&lt;p&gt;Of course, you may &lt;em&gt;refuse to use&lt;&#x2F;em&gt; packages that aren&#x27;t natively packaged just the way you like. But -- for me -- it crosses a line when one whines about the packages that are available. &amp;quot;Ugh, only Flatpak (or deb, or rpm), how dare you, the dev, not pay attention to my tastes after I&#x27;ve done &lt;em&gt;nothing&lt;&#x2F;em&gt;, contributed &lt;em&gt;nothing&lt;&#x2F;em&gt;.&amp;quot;&lt;&#x2F;p&gt;
&lt;p&gt;Because one should &lt;em&gt;build a package&lt;&#x2F;em&gt; or two before they are entitled to an opinion about the packaging a dev uses for their personal project.  Why?  Because packaging sucks. It&#x27;s the last thing anyone wants to do. And when you do make a package, and no one is happy, it sucks even more.&lt;&#x2F;p&gt;
&lt;p&gt;A few common refrains and my feelings --&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;What no pkgsrc?&amp;quot; &amp;quot;Where&#x27;s my PKGBUILD?&amp;quot;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;I use&#x2F;like pkgsrc and have used PKGBUILD and think it&#x27;s pretty neat, but I think we all know these are fairly niche systems.  People&#x2F;users who use fairly niche systems should be the first to take responsibility for them, and not expect someone else to do it for them.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;Just figure out my preferred packaging and distribution system (I have no idea but I imagine it&#x27;s easy).&amp;quot;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Why?  The software builds on my system just fine, and there are instructions for you to build it yourself.  &amp;quot;But you want me as a user...&amp;quot;  Explain this to me -- do I want anyone as a user who is not willing to build their own package for their distribution&#x2F;OS?  Because that user &lt;em&gt;tends to be&lt;&#x2F;em&gt; more of a consumer (who doesn&#x27;t pay) than a valued community member.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;The package you distribute doesn&#x27;t work on my slightly different system.&amp;quot;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;I totally sympathize, but this is the problem with packaging.  You ship one binary with one dependency, say libc, and guess what?  Debian 10 or whatever decides to use a version that is way older than what Ubuntu uses.  I guess we need 3 more Debian packages then...  Yeesh.&lt;&#x2F;p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;quot;Snap&#x2F;Flatpak&#x2F;AppImage sucks.&amp;quot;&lt;&#x2F;p&gt;
&lt;&#x2F;blockquote&gt;
&lt;p&gt;Maybe.  At least they allow you to easily ship your dependencies.  The concept seems quite nice when: 1) there are multiple packaging models to be covered, 2) distribution maintainers are overworked and aren&#x27;t packaging your software for you, and 3) their distribution&#x27;s users aren&#x27;t helping you or them out either.&lt;&#x2F;p&gt;
</content>
        
    </entry>
    <entry xml:lang="en">
        <title>Workflow: ZFS snapshot-ed file versions to tar and git archives with httm</title>
        <published>2022-05-07T00:00:00+00:00</published>
        <updated>2022-05-07T00:00:00+00:00</updated>
        <author>
          <name>Unknown</name>
        </author>
        <link rel="alternate" href="/git/" type="text/html"/>
        <id>/git/</id>
        
        <content type="html">&lt;p&gt;For most non-programming tasks, no one actually wants to work within a git repo.  While git repos offer many benefits, including interoperating with the git ecosystem, most of the time, they&#x27;re just &lt;em&gt;too heavy weight&lt;&#x2F;em&gt; for most system administration tasks.&lt;&#x2F;p&gt;
&lt;p&gt;Imagine you could have many of those same benefits, but only &lt;em&gt;when you need them&lt;&#x2F;em&gt;.&lt;&#x2F;p&gt;
&lt;p&gt;Maybe you already know what to do when you want to send all snapshot-ed versions of your &lt;code&gt;syslog&lt;&#x2F;code&gt; via email:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;httm -n &amp;#x2F;var&amp;#x2F;log&amp;#x2F;syslog | tar -zcvf all-versions-syslog.tar.gz -T -
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;But imagine something a little more difficult.  Imagine you&#x27;ve misconfigured your &lt;code&gt;sysctl.conf&lt;&#x2F;code&gt; and you have just the pal you know knows how to fix it, but she&#x27;s a half-a-world away.  You think -- &lt;em&gt;who wants to dig through 10+ file versions&lt;&#x2F;em&gt; to identify the source of the error?  Wouldn&#x27;t it be nice if she could see your changes as you made them incrementally?&lt;&#x2F;p&gt;
&lt;p&gt;Use &lt;code&gt;httm&lt;&#x2F;code&gt; and this just works:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;# create variable for file name
file=&amp;quot;&amp;#x2F;etc&amp;#x2F;sysctl.conf&amp;quot;
# create git repo
mkdir .&amp;#x2F;archive-git; cd .&amp;#x2F;archive-git; git init
# copy each file version to repo and commit after each copy
for version in $(httm -n $file); do 
	cp &amp;quot;$version&amp;quot; .&amp;#x2F; 
	git add &amp;quot;.&amp;#x2F;$(basename $version)&amp;quot; 
	git commit -m &amp;quot;$(stat -c %y $version)&amp;quot;
done
# create git tar.gz archive in the parent directory
git archive --format=tar.gz -o &amp;quot;..&amp;#x2F;archive-git-$(basename $file).tar.gz&amp;quot; master; cd ..&amp;#x2F;
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;And to view the your changes incrementally:&lt;&#x2F;p&gt;
&lt;pre data-lang=&quot;bash&quot; class=&quot;language-bash &quot;&gt;&lt;code class=&quot;language-bash&quot; data-lang=&quot;bash&quot;&gt;tar zxvf archive-git-sysctl.conf.tar.gz 
cd .&amp;#x2F;archive-git
git log -p
&lt;&#x2F;code&gt;&lt;&#x2F;pre&gt;
&lt;p&gt;Is there a Unix-y workflow you&#x27;d like to see covered by &lt;code&gt;httm&lt;&#x2F;code&gt;?  Let me know!&lt;&#x2F;p&gt;
</content>
        
    </entry>
</feed>
