<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Linux on Besterry — Linux &amp; DevOps Notes</title><link>https://besterry.com/tags/linux/</link><description>Recent content in Linux on Besterry — Linux &amp; DevOps Notes</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Mon, 02 Sep 2024 00:00:00 +0000</lastBuildDate><atom:link href="https://besterry.com/tags/linux/index.xml" rel="self" type="application/rss+xml"/><item><title>ZFS on Linux: Six Months of Production Use</title><link>https://besterry.com/posts/zfs-on-linux/</link><pubDate>Mon, 02 Sep 2024 00:00:00 +0000</pubDate><guid>https://besterry.com/posts/zfs-on-linux/</guid><description>&lt;p&gt;Migrated our build server array from ext4+mdadm to ZFS on Linux six months ago. Here&amp;rsquo;s what I learned.&lt;/p&gt;
&lt;h2 id="why-zfs"&gt;Why ZFS&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Checksumming catches silent data corruption (we found 14 affected files on the old array)&lt;/li&gt;
&lt;li&gt;Snapshots are cheap and instant (100ms for a 10TB dataset)&lt;/li&gt;
&lt;li&gt;Compression often makes things faster — less I/O, more CPU&lt;/li&gt;
&lt;li&gt;Send/receive for efficient replication&lt;/li&gt;
&lt;li&gt;No separate mdadm/LVM layer to debug&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="pool-design"&gt;Pool design&lt;/h2&gt;
&lt;p&gt;For the build server, 6 x 4TB NVMe in RAIDZ2:&lt;/p&gt;</description></item><item><title>Useful bpftrace One-Liners for System Debugging</title><link>https://besterry.com/posts/bpftrace-oneliners/</link><pubDate>Thu, 02 May 2024 00:00:00 +0000</pubDate><guid>https://besterry.com/posts/bpftrace-oneliners/</guid><description>&lt;p&gt;bpftrace makes the kernel event space accessible from a bash one-liner. Here are the scripts I keep reaching for.&lt;/p&gt;
&lt;h2 id="count-syscalls-by-process"&gt;Count syscalls by process&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;bpftrace -e 'tracepoint:raw_syscalls:sys_enter { @[comm] = count(); }'
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="distribution-of-file-read-sizes"&gt;Distribution of file read sizes&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;bpftrace -e 'tracepoint:syscalls:sys_enter_read { @ = hist(args-&amp;gt;count); }'
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="tcp-retransmissions-by-remote-address"&gt;TCP retransmissions by remote address&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;bpftrace -e '
kprobe:tcp_retransmit_skb {
$sk = (struct sock *)arg0;
$daddr = $sk-&amp;gt;__sk_common.skc_daddr;
@[ntop($daddr)] = count();
}'
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="process-creation-stream"&gt;Process creation stream&lt;/h2&gt;
&lt;pre&gt;&lt;code&gt;bpftrace -e 'tracepoint:sched:sched_process_exec { printf(&amp;quot;%s\n&amp;quot;, str(args-&amp;gt;filename)); }'
&lt;/code&gt;&lt;/pre&gt;
&lt;h2 id="when-to-use-bpftrace-vs-perf-vs-strace"&gt;When to use bpftrace vs perf vs strace&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;strace: simple, but adds significant overhead. Fine for debugging a single misbehaving process.&lt;/li&gt;
&lt;li&gt;perf: best for sampling-based profiling (CPU time, cache misses). Low overhead.&lt;/li&gt;
&lt;li&gt;bpftrace: best for event-driven tracing across the whole system. Tiny overhead if used sparingly.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;All three should be in your toolbox.&lt;/p&gt;</description></item><item><title>systemd Timers vs Cron: When to Use Which</title><link>https://besterry.com/posts/systemd-timer-vs-cron/</link><pubDate>Sat, 17 Feb 2024 00:00:00 +0000</pubDate><guid>https://besterry.com/posts/systemd-timer-vs-cron/</guid><description>&lt;p&gt;Cron has been the standard scheduler on Unix for decades. systemd timers are newer, more powerful, but also more verbose.&lt;/p&gt;
&lt;h2 id="cron-wins-when"&gt;Cron wins when&lt;/h2&gt;
&lt;p&gt;Cron is perfect for one-line scripts that need to run on a simple schedule. Writing:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;0 3 * * * /usr/local/bin/backup.sh
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;is fast, requires no other files, and works on every Unix-like system since the 1970s.&lt;/p&gt;
&lt;h2 id="systemd-timers-win-when"&gt;systemd timers win when&lt;/h2&gt;
&lt;p&gt;You want any of these:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Logging integrated with journalctl&lt;/li&gt;
&lt;li&gt;Dependencies on other units (&lt;code&gt;After=network-online.target&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Resource limits (&lt;code&gt;MemoryMax=&lt;/code&gt;, &lt;code&gt;CPUQuota=&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;Randomized delays to avoid thundering herd (&lt;code&gt;RandomizedDelaySec=&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;The ability to manually trigger with &lt;code&gt;systemctl start&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Catch-up behavior after system was off (&lt;code&gt;Persistent=true&lt;/code&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="minimal-systemd-timer-example"&gt;Minimal systemd timer example&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;/etc/systemd/system/backup.service&lt;/code&gt;:&lt;/p&gt;</description></item><item><title>Linux Networking Deep Dive: From Socket to Wire</title><link>https://besterry.com/posts/linux-networking-deep-dive/</link><pubDate>Sat, 10 Feb 2024 00:00:00 +0000</pubDate><guid>https://besterry.com/posts/linux-networking-deep-dive/</guid><description>&lt;p&gt;Every time a packet leaves your Linux machine, it travels through a surprisingly long sequence of stages. Understanding this path helps enormously when debugging network issues.&lt;/p&gt;
&lt;h2 id="the-socket-layer"&gt;The socket layer&lt;/h2&gt;
&lt;p&gt;When your application calls &lt;code&gt;send()&lt;/code&gt; or &lt;code&gt;write()&lt;/code&gt; on a socket, the kernel&amp;rsquo;s socket layer takes over. For a TCP socket this means handing the data to &lt;code&gt;tcp_sendmsg()&lt;/code&gt;, which in turn enqueues it into the socket&amp;rsquo;s send buffer.&lt;/p&gt;
&lt;p&gt;You can observe the send queue depth with &lt;code&gt;ss -tipm&lt;/code&gt;:&lt;/p&gt;</description></item></channel></rss>