<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>What every SRE should know on Viacheslav Biriukov</title>
    <link>https://biriukov.dev/</link>
    <description>Recent content in What every SRE should know on Viacheslav Biriukov</description>
    <generator>Hugo</generator>
    <language>en-us</language>
    <atom:link href="https://biriukov.dev/index.xml" rel="self" type="application/rss+xml" />
    <item>
      <title>Async Rust gotcha: evolving tokio::select! code has sharp edges</title>
      <link>https://biriukov.dev/posts/async-rust-gocha-tokio-cancelation-select-future-then/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://biriukov.dev/posts/async-rust-gocha-tokio-cancelation-select-future-then/</guid>
      <description>&lt;p style=&#34;margin-top:-12px;&#34;&gt;&#xA;&lt;p style=&#34;font-size:120%;&#34;&gt; … or a story about Cancellation safety, &lt;code&gt;FutureExt::then()&lt;/code&gt;, insufficient tests, and I/O actors.&lt;/p&gt;&#xA;&lt;/p&gt;&#xA;&lt;p class=&#34;updated-right&#34;&gt;&#xA;    &lt;i&gt;&#xA;        &lt;time datetime=&#34;2025-10&#34;&gt;Posted: Feb 2026&lt;/time&gt;&#xA;    &lt;/i&gt;&#xA;&lt;/p&gt;&#xA;&lt;h4 id=&#34;tldr&#34;&gt;&#xA;  TL;DR&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#tldr&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h4&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;Be careful evolving and refactoring your application with &lt;a href=&#34;https://docs.rs/tokio/latest/tokio/macro.select.html&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;code&gt;tokio::select!&lt;/code&gt;&lt;/a&gt;, because the missing or too simple tests could lead to data losses due to cancellation safety issues. Assume &lt;strong&gt;any branch can be dropped at any &lt;code&gt;.await&lt;/code&gt;&lt;/strong&gt; unless you’ve designed it to be restart/cancel-safe.&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://docs.rs/futures/latest/futures/future/trait.FutureExt.html#method.then&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;code&gt;stream.next().then()&lt;/code&gt;&lt;/a&gt; is not cancellation safe if you have an &lt;code&gt;await&lt;/code&gt; point inside the async closure – &lt;strong&gt;data can be lost&lt;/strong&gt;.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Make your tests exercise &lt;a href=&#34;https://doc.rust-lang.org/beta/std/task/enum.Poll.html&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;code&gt;Poll::Pending&lt;/code&gt;&lt;/a&gt; paths.&lt;/strong&gt; If you test with &lt;a href=&#34;https://docs.rs/tokio/latest/tokio/io/fn.duplex.html&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;code&gt;tokio::io::duplex()&lt;/code&gt;&lt;/a&gt;, check that it goes pending, otherwise cancellation bugs might not show up.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Follow the single I/O actor model&lt;/strong&gt; – no mutexes, no sharing I/O objects.&lt;/li&gt;&#xA;&lt;li&gt;Use &lt;a href=&#34;https://docs.rs/tokio/latest/tokio/sync/mpsc/fn.channel.html&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;code&gt;tokio::mpsc&lt;/code&gt;&lt;/a&gt; channels with allocated permits by calling &lt;a href=&#34;https://docs.rs/tokio/latest/tokio/sync/mpsc/struct.Sender.html#method.reserve&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;code&gt;reserve()&lt;/code&gt;&lt;/a&gt; to consume data from streams &lt;strong&gt;only when you have capacity&lt;/strong&gt; on the next step (producer side). This propagates backpressure and preserves data.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;hr/&gt;&#xA;&lt;h2 id=&#34;intro&#34;&gt;&#xA;  Intro&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#intro&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;Rust adoption keeps accelerating, and many new teams are writing Async Rust for production systems for the first time. Developers arrive from both low-level systems backgrounds and enterprise ecosystems – but Async Rust, and Tokio especially, comes with a few crucial concepts that can make or break your ability to build high-performance, zero-cost abstraction networking code.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Trixter: A Chaos Proxy for Simulating Network Faults</title>
      <link>https://biriukov.dev/posts/trixter-chaos-proxy/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://biriukov.dev/posts/trixter-chaos-proxy/</guid>
      <description>&lt;p class=&#34;updated-right&#34;&gt;&#xA;    &lt;i&gt;&#xA;        &lt;time datetime=&#34;2025-10&#34;&gt;Posted: Oct 2025&lt;/time&gt;&#xA;    &lt;/i&gt;&#xA;&lt;/p&gt;&#xA;&lt;p style=&#34;float1:right&#34; class=&#34;text&#34;&gt;&#xA;    &lt;i class=&#34;bi bi-github&#34;&gt;&lt;/i&gt; Github: &lt;a href=&#34;https://github.com/brk0v/trixter&#34;&gt;https://github.com/brk0v/trixter&lt;/a&gt;&#xA;&lt;/p&gt;&#xA;&lt;hr/&gt;&#xA;&lt;p&gt;&lt;strong&gt;Contents&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;posts/trixter-chaos-proxy/#chaos-engineering-and-network-fault-injection&#34;&gt;Chaos Engineering and Network Fault Injection&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/posts/trixter-chaos-proxy/#introducing-trixter--a-chaos-monkey-for-tcp&#34;&gt;Introducing Trixter – A Chaos Monkey for TCP&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/posts/trixter-chaos-proxy/#why-trixter-vs-gnulinux-tc-netem-kernel-network-emulator&#34;&gt;Why Trixter vs GNU/Linux &lt;code&gt;tc&lt;/code&gt; &lt;code&gt;netem&lt;/code&gt; (Kernel Network Emulator)&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/posts/trixter-chaos-proxy/#using-trixter-examples-of-injecting-chaos&#34;&gt;Using Trixter: Examples of Injecting Chaos&lt;/a&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/posts/trixter-chaos-proxy/#example-1-adding-latency-and-packet-loss&#34;&gt;Example 1: Adding latency and packet loss&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/posts/trixter-chaos-proxy/#example-2-throttling-bandwidth&#34;&gt;Example 2: Throttling bandwidth&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/posts/trixter-chaos-proxy/#example-3-running-in-cicd-with-chaos&#34;&gt;Example 3: Running in CI/CD with chaos&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/posts/trixter-chaos-proxy/#example-4-control-failures-on-per-connection-in-runtime&#34;&gt;Example 4: Control failures on per connection in runtime&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/posts/trixter-chaos-proxy/#documentation-recipes-reference&#34;&gt;Documentation, recipes, reference&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;hr/&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;em&gt;Break your network before production does&lt;/em&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>Async Rust with Tokio I/O Streams: Backpressure, Concurrency, and Ergonomics</title>
      <link>https://biriukov.dev/docs/async-rust-tokio-io/1-async-rust-with-tokio-io-streams-backpressure-concurrency-and-ergonomics/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://biriukov.dev/docs/async-rust-tokio-io/1-async-rust-with-tokio-io-streams-backpressure-concurrency-and-ergonomics/</guid>
      <description>&lt;h1 id=&#34;async-rust-with-tokio-io-streams-backpressure-concurrency-and-ergonomics&#34;&gt;&#xA;  Async Rust with Tokio I/O Streams: Backpressure, Concurrency, and Ergonomics&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#async-rust-with-tokio-io-streams-backpressure-concurrency-and-ergonomics&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h1&gt;&#xA;&lt;p class=&#34;updated-right&#34;&gt;&#xA;    &lt;i&gt;&#xA;        &lt;time datetime=&#34;2025-10&#34;&gt;Last updated: Oct 2025&lt;/time&gt;&#xA;    &lt;/i&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Contents&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/rust-tokio-io/&#34;&gt;1 Async Rust with Tokio IO Streams: Backpressure, Concurrency, and Ergonomics&lt;/a&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/async-rust-tokio-io/1-async-rust-with-tokio-io-streams-backpressure-concurrency-and-ergonomics/#backpressure&#34;&gt;Backpressure&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/async-rust-tokio-io/1-async-rust-with-tokio-io-streams-backpressure-concurrency-and-ergonomics/#cancellation&#34;&gt;Cancellation&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/async-rust-tokio-io/2-io-loop/&#34;&gt;2. I/O loop&lt;/a&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/async-rust-tokio-io/2-io-loop/#backpressure-propagation&#34;&gt;Backpressure propagation&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/async-rust-tokio-io/2-io-loop/#concurrency&#34;&gt;Concurrency&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/async-rust-tokio-io/3-tokio-io-patterns/&#34;&gt;3. Tokio I/O Patterns&lt;/a&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/async-rust-tokio-io/3-tokio-io-patterns/#tcp-split-stream&#34;&gt;TCP split stream&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/async-rust-tokio-io/3-tokio-io-patterns/#split-generic-asyncreadasyncwrite-stream&#34;&gt;Split generic &lt;code&gt;AsyncRead+AsyncWrite&lt;/code&gt; stream&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/async-rust-tokio-io/3-tokio-io-patterns/#bidirectional-driver-for-io-without-split&#34;&gt;Bidirectional driver for I/O without split&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/async-rust-tokio-io/3-tokio-io-patterns/#framed-io&#34;&gt;Framed I/O&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/async-rust-tokio-io/3-tokio-io-patterns/#35-bidirectional-driver-for-framed-io&#34;&gt;Bidirectional driver for framed I/O&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;hr/&gt;&#xA;&lt;p&gt;There are many excellent, straightforward guides for getting started with Async Rust and Tokio. Most focus on the core building blocks: Tokio primitives, Rust futures, and concepts such as &lt;code&gt;Pin&lt;/code&gt;/&lt;code&gt;Unpin&lt;/code&gt;, and often finish with a simple TCP client-server sample. In fact, the typical tutorial example can usually be reduced to something as simple as:&lt;/p&gt;</description>
    </item>
    <item>
      <title>GNU/Linux shell related internals</title>
      <link>https://biriukov.dev/docs/fd-pipe-session-terminal/0-sre-should-know-about-gnu-linux-shell-related-internals-file-descriptors-pipes-terminals-user-sessions-process-groups-and-daemons/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://biriukov.dev/docs/fd-pipe-session-terminal/0-sre-should-know-about-gnu-linux-shell-related-internals-file-descriptors-pipes-terminals-user-sessions-process-groups-and-daemons/</guid>
      <description>&lt;h1 id=&#34;what-every-sre-should-know-about-gnulinux-shell-related-internals-file-descriptors-pipes-terminals-user-sessions-process-groups-and-daemons&#34;&gt;&#xA;  What every SRE should know about GNU/Linux shell related internals: file descriptors, pipes, terminals, user sessions, process groups and daemons&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#what-every-sre-should-know-about-gnulinux-shell-related-internals-file-descriptors-pipes-terminals-user-sessions-process-groups-and-daemons&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h1&gt;&#xA;&lt;p class=&#34;updated-right&#34;&gt;&#xA;    &lt;i&gt;&#xA;        &lt;time datetime=&#34;2025-10&#34;&gt;Last updated: Oct 2025&lt;/time&gt;&#xA;    &lt;/i&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Contents&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/fd-pipe-session-terminal/1-file-descriptor-and-open-file-description/&#34;&gt;File descriptor and open file description&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/fd-pipe-session-terminal/2-pipes/&#34;&gt;Pipes&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/fd-pipe-session-terminal/3-process-groups-jobs-and-sessions/&#34;&gt;Process groups, jobs and sessions&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/fd-pipe-session-terminal/4-terminals-and-pseudoterminals/&#34;&gt;Terminals and pseudoterminals&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;hr/&gt;&#xA;&lt;p&gt;Despite the era of containers, virtualization, and the rising number of UI of all kinds, SREs often spend a significant part of their time in GNU/Linux shells. It could be debugging, testing, developing, or preparing the new infrastructure.  It may be the good old &lt;code&gt;bash&lt;/code&gt;, the more recent and fancy &lt;code&gt;zsh&lt;/code&gt;, or even &lt;code&gt;fish&lt;/code&gt; or &lt;code&gt;tcsh&lt;/code&gt; with their interesting and unique features.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Linux Page Cache for SRE</title>
      <link>https://biriukov.dev/docs/page-cache/0-linux-page-cache-for-sre/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://biriukov.dev/docs/page-cache/0-linux-page-cache-for-sre/</guid>
      <description>&lt;h1 id=&#34;sre-deep-dive-into-linux-page-cache&#34;&gt;&#xA;  SRE deep dive into Linux Page Cache&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#sre-deep-dive-into-linux-page-cache&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h1&gt;&#xA;&lt;p class=&#34;updated-right&#34;&gt;&#xA;    &lt;i&gt;&#xA;        &lt;time datetime=&#34;2025-10&#34;&gt;Last updated: Oct 2025&lt;/time&gt;&#xA;    &lt;/i&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Contents&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/page-cache/1-prepare-environment-for-experiments/&#34;&gt;Prepare environment for experiments&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/page-cache/2-essential-page-cache-theory/&#34;&gt;Essential Page Cache theory&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/page-cache/3-page-cache-and-basic-file-operations/&#34;&gt;Page Cache and basic file operations&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/page-cache/4-page-cache-eviction-and-page-reclaim/&#34;&gt;Page Cache eviction and page reclaim&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/page-cache/5-more-about-mmap-file-access/&#34;&gt;More about &lt;code&gt;mmap()&lt;/code&gt; file access&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/page-cache/6-cgroup-v2-and-page-cache/&#34;&gt;cgroup v2 and Page Cache&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/page-cache/7-how-much-memory-my-program-uses-or-the-tale-of-working-set-size/&#34;&gt;How much memory my program uses or the tale of working set size&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/page-cache/8-direct-io-dio/&#34;&gt;Direct IO (DIO)&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/page-cache/9-advanced-page-cache-observability-and-troubleshooting-tools/&#34;&gt;Advanced Page Cache observability and troubleshooting tools&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;hr/&gt;&#xA;&lt;p&gt;In this series of articles, I would like to talk about &lt;strong&gt;Linux Page Cache&lt;/strong&gt;. I believe that the following knowledge of the theory and tools is &lt;strong&gt;essential and crucial for every SRE&lt;/strong&gt;. This understanding can help both in usual and routine everyday DevOps-like tasks and in emergency debugging and firefighting. Page Cache is often left unattended, and its better understanding leads to the following:&lt;/p&gt;</description>
    </item>
    <item>
      <title>What every SRE should know about GNU/Linux resolvers and Dual-Stack applications</title>
      <link>https://biriukov.dev/docs/resolver-dual-stack-application/0-sre-should-know-about-gnu-linux-resolvers-and-dual-stack-applications/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://biriukov.dev/docs/resolver-dual-stack-application/0-sre-should-know-about-gnu-linux-resolvers-and-dual-stack-applications/</guid>
      <description>&lt;h1 id=&#34;what-every-sre-should-know-about-gnulinux-resolvers-and-dual-stack-applications&#34;&gt;&#xA;  What every SRE should know about GNU/Linux resolvers and Dual-Stack applications&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#what-every-sre-should-know-about-gnulinux-resolvers-and-dual-stack-applications&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h1&gt;&#xA;&lt;p class=&#34;updated-right&#34;&gt;&#xA;    &lt;i&gt;&#xA;        &lt;time datetime=&#34;2025-10&#34;&gt;Last updated: Oct 2025&lt;/time&gt;&#xA;    &lt;/i&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Contents&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/1-what-is-a-stub-resolver/&#34;&gt;What is a stub resolver?&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/2-history-gethostbyname/&#34;&gt;History: &lt;code&gt;gethostbyname()&lt;/code&gt; and old good friends&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/3-getaddrinfo-and-posix-spec/&#34;&gt;&lt;code&gt;getaddrinfo()&lt;/code&gt; and POSIX spec&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/4-getaddrinfo-from-glibc/&#34;&gt;&lt;code&gt;getaddrinfo() &lt;/code&gt;from glibc&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/5-getaddrinfo-from-musl-libc/&#34;&gt;&lt;code&gt;getaddrinfo()&lt;/code&gt; from musl libc&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/6-dual-stack-applications/&#34;&gt;Dual-Stack applications&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/7-async-non-blocking-resolvers-in-c/&#34;&gt;Async non-blocking resolvers in &lt;code&gt;C&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/8-stub-resolvers-in-languages/&#34;&gt;Stub resolvers in languages&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/9-dual-stack-software-examples/&#34;&gt;Dual-stack software examples&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/10-systemd-resolved/&#34;&gt;&lt;code&gt;systemd-resolved&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/11-querying-nameservers-on-dual-stack-hosts/&#34;&gt;Querying Nameservers on dual-stack hosts&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/12-present-and-future-of-resolvers-and-dns-related-features/&#34;&gt;The Present and the future of resolvers and DNS related features&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/troubleshooting-tools-for-resolvers-and-dns/&#34;&gt;Tools for troubleshooting in one place&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;hr/&gt;&#xA;&lt;p&gt;In this series of posts, I’d like to  make a deep dive into the GNU/Linux local facilities used to convert a domain name or hostname into IP addresses, specifically in the context of dual-stack applications. This process of resolution is one of the oldest forms of networking abstraction, designed to replace hard-to-remember network addresses with human-readable strings. Although it may seem simple at first glance, the entire process involving stub resolvers is filled with complexities and subtle nuances. One contributing factor to this complexity is the growing number of IPv6 addresses, which, although not increasing at the pace everyone might want, is gradually changing servers and clients to support dual-stack hosts. Thus a seamless transition to IPv6 become an important feature and should occur without degrading user experience or increasing response latency.&lt;/p&gt;</description>
    </item>
    <item>
      <title>File descriptor and open file description</title>
      <link>https://biriukov.dev/docs/fd-pipe-session-terminal/1-file-descriptor-and-open-file-description/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://biriukov.dev/docs/fd-pipe-session-terminal/1-file-descriptor-and-open-file-description/</guid>
      <description>&lt;h1 id=&#34;file-descriptor-and-open-file-description&#34;&gt;&#xA;  File descriptor and open file description&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#file-descriptor-and-open-file-description&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h1&gt;&#xA;&lt;p class=&#34;updated-right&#34;&gt;&#xA;    &lt;i&gt;&#xA;        &lt;time datetime=&#34;2025-10&#34;&gt;Last updated: Oct 2025&lt;/time&gt;&#xA;    &lt;/i&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Contents&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/fd-pipe-session-terminal/1-file-descriptor-and-open-file-description/#stdin-stdout-and-stderr&#34;&gt;&lt;code&gt;stdin&lt;/code&gt;, &lt;code&gt;stdout&lt;/code&gt; and &lt;code&gt;stderr&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/fd-pipe-session-terminal/1-file-descriptor-and-open-file-description/#procfs-and-file-descriptors&#34;&gt;&lt;code&gt;Procfs&lt;/code&gt; and file descriptors&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/fd-pipe-session-terminal/1-file-descriptor-and-open-file-description/#sharing-file-descriptors-between-parent-and-child-after-fork&#34;&gt;Sharing file descriptors between parent and child after &lt;code&gt;fork()&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/fd-pipe-session-terminal/1-file-descriptor-and-open-file-description/#duplication-of-file-descriptors&#34;&gt;Duplication of file descriptors&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/fd-pipe-session-terminal/1-file-descriptor-and-open-file-description/#execve-and-file-descriptors&#34;&gt;&lt;code&gt;execve()&lt;/code&gt; and file descriptors&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/fd-pipe-session-terminal/1-file-descriptor-and-open-file-description/#check-if-2-file-descriptors-share-the-same-open-file-description-with-kcmp&#34;&gt;Check if 2 file descriptors share the same open file description with &lt;code&gt;kcmp()&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/fd-pipe-session-terminal/1-file-descriptor-and-open-file-description/#more-ways-to-transfer-file-descriptors-between-processes-pidfd_getfd-and-unix-datagrams&#34;&gt;More ways to transfer file descriptors between processes: &lt;code&gt;pidfd_getfd()&lt;/code&gt; and Unix datagrams.&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/fd-pipe-session-terminal/1-file-descriptor-and-open-file-description/#shell-redirections-and-file-descriptors&#34;&gt;Shell redirections and file descriptors&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;hr/&gt;&#xA;&lt;p&gt;First of all, I want to touch on the two fundamental concepts of working with files:&lt;/p&gt;</description>
    </item>
    <item>
      <title>I/O loop</title>
      <link>https://biriukov.dev/docs/async-rust-tokio-io/2-io-loop/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://biriukov.dev/docs/async-rust-tokio-io/2-io-loop/</guid>
      <description>&lt;h1 id=&#34;io-loop&#34;&gt;&#xA;  I/O loop&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#io-loop&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h1&gt;&#xA;&lt;p class=&#34;updated-right&#34;&gt;&#xA;    &lt;i&gt;&#xA;        &lt;time datetime=&#34;2025-10&#34;&gt;Last updated: Oct 2025&lt;/time&gt;&#xA;    &lt;/i&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Contents&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/async-rust-tokio-io/2-io-loop/#backpressure-propagation&#34;&gt;Backpressure propagation&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/async-rust-tokio-io/2-io-loop/#concurrency&#34;&gt;Concurrency&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;hr/&gt;&#xA;&lt;p&gt;Before changing the code, let&amp;rsquo;s outline our goals for I/O loops:&lt;/p&gt;&#xA;&lt;ol&gt;&#xA;&lt;li&gt;&lt;strong&gt;Preserve backpressure propagation&lt;/strong&gt;: blocked writes should slow down the local producer over the &lt;code&gt;rx&lt;/code&gt; channel.&lt;/li&gt;&#xA;&lt;li&gt;&lt;strong&gt;Retain concurrency&lt;/strong&gt;: other work (e.g., cancellation, timeouts) should make progress while reads/writes are pending. Reads and writes should not block each other.&lt;/li&gt;&#xA;&lt;/ol&gt;&#xA;&lt;h2 id=&#34;backpressure-propagation&#34;&gt;&#xA;  Backpressure propagation&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#backpressure-propagation&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;To address the first issue we could flip the perspective: instead of eagerly pulling from the &lt;code&gt;rx&lt;/code&gt; channel, &lt;strong&gt;wait until the writer proves it has capacity&lt;/strong&gt;. Some async primitives support this. For example, &lt;code&gt;&lt;a href=&#34;https://docs.rs/tokio/latest/tokio/sync/mpsc/struct.Sender.html&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;tokio::sync::mpsc::Sender&lt;/a&gt;&lt;/code&gt; offers &lt;code&gt;&lt;a href=&#34;https://docs.rs/tokio/latest/tokio/sync/mpsc/struct.Sender.html#method.reserve&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;reserve()&lt;/a&gt;&lt;/code&gt;, which &lt;code&gt;await&lt;/code&gt;s for a slot to become available to write. When the permission is granted, we can dequeue the message from our &lt;code&gt;rx&lt;/code&gt; channel. But one important note here is that &lt;code&gt;mpsc&lt;/code&gt; is slot-based, and not byte-sized, which is not what we usually need when working with I/O streams.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Prepare environment for experiments</title>
      <link>https://biriukov.dev/docs/page-cache/1-prepare-environment-for-experiments/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://biriukov.dev/docs/page-cache/1-prepare-environment-for-experiments/</guid>
      <description>&lt;h1 id=&#34;prepare-environment-for-experiments&#34;&gt;&#xA;  Prepare environment for experiments&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#prepare-environment-for-experiments&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h1&gt;&#xA;&lt;p class=&#34;updated-right&#34;&gt;&#xA;    &lt;i&gt;&#xA;        &lt;time datetime=&#34;2025-10&#34;&gt;Last updated: Oct 2025&lt;/time&gt;&#xA;    &lt;/i&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;Before starting, I want to be on the same page with the reader so that any example or code snippet can be executed, compiled, and checked. Therefore we need a modern GNU/Linux installation to play with code and kernel.&lt;/p&gt;&#xA;&lt;p&gt;If you are using Windows or Mac OS, I would suggest installing &lt;a href=&#34;https://www.vagrantup.com&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Vagrant&lt;/a&gt; with &lt;a href=&#34;https://www.virtualbox.org/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Virtual Box&lt;/a&gt;. For the GNU/Linux distributive, I&amp;rsquo;d like to use &lt;a href=&#34;https://archlinux.org/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Arch Linux&lt;/a&gt;. Arch is a good example of an actual modern version of the GNU/Linux system (&lt;a href=&#34;https://i.redd.it/qxsttm8sg5k11.png&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;BTW, I use Arch Linux&lt;/a&gt;). It supports the latest kernels, systemd and cgroup v2.&lt;/p&gt;</description>
    </item>
    <item>
      <title>What is a stub resolver?</title>
      <link>https://biriukov.dev/docs/resolver-dual-stack-application/1-what-is-a-stub-resolver/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://biriukov.dev/docs/resolver-dual-stack-application/1-what-is-a-stub-resolver/</guid>
      <description>&lt;h1 id=&#34;1-what-is-a-stub-resolver&#34;&gt;&#xA;  1. What is a stub resolver?&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#1-what-is-a-stub-resolver&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h1&gt;&#xA;&lt;p class=&#34;updated-right&#34;&gt;&#xA;    &lt;i&gt;&#xA;        &lt;time datetime=&#34;2025-10&#34;&gt;Last updated: Oct 2025&lt;/time&gt;&#xA;    &lt;/i&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;First of all, let’s shed some light on what a stub resolver is.&lt;/p&gt;&#xA;&lt;p&gt;Whenever someone begins talking about hostname resolution issues or nameserver changes, the first thing most people think of is the &lt;code&gt;/etc/resolv.conf&lt;/code&gt; configuration file. Indeed, &lt;code&gt;/etc/resolv.conf&lt;/code&gt; is a core and fundamental part of the local resolver system, and we will discuss it in detail later in this series,  including how it’s managed on modern GNU/Linux distributions with &lt;code&gt;systemd&lt;/code&gt;. However, it’s far from being the only component involved in converting a hostname string into a list of IP addresses. Often, other lesser-known parts of the system may cause unpredictable behaviors and have their own unique features and limitations.&lt;/p&gt;</description>
    </item>
    <item>
      <title>History: gethostbyname() and old good friends</title>
      <link>https://biriukov.dev/docs/resolver-dual-stack-application/2-history-gethostbyname/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://biriukov.dev/docs/resolver-dual-stack-application/2-history-gethostbyname/</guid>
      <description>&lt;h1 id=&#34;2-history-gethostbyname-and-old-good-friends&#34;&gt;&#xA;  2. History: &lt;code&gt;gethostbyname()&lt;/code&gt; and old good friends&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#2-history-gethostbyname-and-old-good-friends&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h1&gt;&#xA;&lt;p class=&#34;updated-right&#34;&gt;&#xA;    &lt;i&gt;&#xA;        &lt;time datetime=&#34;2025-10&#34;&gt;Last updated: Oct 2025&lt;/time&gt;&#xA;    &lt;/i&gt;&#xA;&lt;/p&gt;&#xA;&lt;blockquote class=&#34;book-hint warning&#34;&gt;&#xA;  Please do not use any of the code snippets from this chapter in your projects. They are provided solely for historical and educational purposes. Instead, you should use &lt;code&gt;getaddrinfo()&lt;/code&gt;.&#xA;&lt;/blockquote&gt;&#xA;&#xA;&lt;p&gt;The &lt;code&gt;gethostbyname&lt;/code&gt; (&lt;code&gt;&lt;a href=&#34;https://man7.org/linux/man-pages/man3/gethostbyname.3.html&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;man 3 gethostbyname&lt;/a&gt;&lt;/code&gt;) function first appeared in the 1980s and has been a part of the networking landscape ever since. Despite its obsoletion, some programs still use it. It was deprecated in POSIX.1-2001, over two decades ago, due to its internal design limitations and limited functionality. However, for a long time, it was the preferred and standardized helper function for resolving a domain name into a list of IP addresses.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Pipes</title>
      <link>https://biriukov.dev/docs/fd-pipe-session-terminal/2-pipes/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://biriukov.dev/docs/fd-pipe-session-terminal/2-pipes/</guid>
      <description>&lt;h1 id=&#34;pipes&#34;&gt;&#xA;  Pipes&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#pipes&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h1&gt;&#xA;&lt;p class=&#34;updated-right&#34;&gt;&#xA;    &lt;i&gt;&#xA;        &lt;time datetime=&#34;2025-10&#34;&gt;Last updated: Oct 2025&lt;/time&gt;&#xA;    &lt;/i&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Contents&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/fd-pipe-session-terminal/2-pipes/#how-shells-internally-create-pipes&#34;&gt;How shells internally create pipes&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/fd-pipe-session-terminal/2-pipes/#pipe-and-write-buffer&#34;&gt;Pipe and write buffer&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/fd-pipe-session-terminal/2-pipes/#sigpipe-signal&#34;&gt;&lt;code&gt;SIGPIPE&lt;/code&gt; signal&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/fd-pipe-session-terminal/2-pipes/#pipestatus--and-pipefail&#34;&gt;&lt;code&gt;$pipestatus&lt;/code&gt;, &lt;code&gt;$?&lt;/code&gt; and &lt;code&gt;pipefail&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/fd-pipe-session-terminal/2-pipes/#fifo-or-named-pipes&#34;&gt;FIFO or Named pipes&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/fd-pipe-session-terminal/2-pipes/#pv-tool&#34;&gt;&lt;code&gt;pv&lt;/code&gt; tool&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/fd-pipe-session-terminal/2-pipes/#pipe-usage&#34;&gt;&lt;code&gt;Pipe usage&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/fd-pipe-session-terminal/2-pipes/#packets-pipe-mode-o_direct&#34;&gt;Packets pipe mode (&lt;code&gt;O_DIRECT&lt;/code&gt;)&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/fd-pipe-session-terminal/2-pipes/#pipe-nonblocking-io&#34;&gt;Pipe Nonblocking I/O&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/fd-pipe-session-terminal/2-pipes/#partial-writes-and-syscall-restarts&#34;&gt;Partial writes and syscall restarts&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/fd-pipe-session-terminal/2-pipes/#pipe-performance-splice-vmsplice-and-tee&#34;&gt;Pipe performance: &lt;code&gt;splice()&lt;/code&gt;, &lt;code&gt;vmsplice()&lt;/code&gt; and &lt;code&gt;tee()&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;hr/&gt;&#xA;&lt;p&gt;The pipe is a neat feature of the Linux kernel that allows us to build &lt;strong&gt;one-directional communication channels&lt;/strong&gt; between related processes (often a parent and a  child).&lt;/p&gt;</description>
    </item>
    <item>
      <title>Tokio I/O patterns</title>
      <link>https://biriukov.dev/docs/async-rust-tokio-io/3-tokio-io-patterns/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://biriukov.dev/docs/async-rust-tokio-io/3-tokio-io-patterns/</guid>
      <description>&lt;h1 id=&#34;tokio-io-patterns&#34;&gt;&#xA;  Tokio I/O Patterns&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#tokio-io-patterns&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h1&gt;&#xA;&lt;p class=&#34;updated-right&#34;&gt;&#xA;    &lt;i&gt;&#xA;        &lt;time datetime=&#34;2025-10&#34;&gt;Last updated: Oct 2025&lt;/time&gt;&#xA;    &lt;/i&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Contents&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/async-rust-tokio-io/3-tokio-io-patterns/#tcp-split-stream&#34;&gt;TCP split stream&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/async-rust-tokio-io/3-tokio-io-patterns/#split-generic-asyncreadasyncwrite-stream&#34;&gt;Split generic &lt;code&gt;AsyncRead+AsyncWrite&lt;/code&gt; stream&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/async-rust-tokio-io/3-tokio-io-patterns/#bidirectional-driver-for-io-without-split&#34;&gt;Bidirectional driver for I/O without split&lt;/a&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/async-rust-tokio-io/3-tokio-io-patterns/#backpressure&#34;&gt;Backpressure&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/async-rust-tokio-io/3-tokio-io-patterns/#cancellation&#34;&gt;Cancellation&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/async-rust-tokio-io/3-tokio-io-patterns/#framed-io&#34;&gt;Framed I/O&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/async-rust-tokio-io/3-tokio-io-patterns/#35-bidirectional-driver-for-framed-io&#34;&gt;Bidirectional driver for framed I/O&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;hr/&gt;&#xA;&lt;p&gt;Now let&amp;rsquo;s look at the possible solutions and weigh their pros and cons.&lt;/p&gt;&#xA;&lt;h2 id=&#34;tcp-split-stream&#34;&gt;&#xA;  TCP split stream&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#tcp-split-stream&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;The first obvious solution, suggested by the documentation, is to split the TCP stream into two parts: a reader and a writer.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Essential Linux Page Cache theory</title>
      <link>https://biriukov.dev/docs/page-cache/2-essential-page-cache-theory/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://biriukov.dev/docs/page-cache/2-essential-page-cache-theory/</guid>
      <description>&lt;h1 id=&#34;essential-page-cache-theory&#34;&gt;&#xA;  Essential Page Cache theory&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#essential-page-cache-theory&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h1&gt;&#xA;&lt;p class=&#34;updated-right&#34;&gt;&#xA;    &lt;i&gt;&#xA;        &lt;time datetime=&#34;2025-10&#34;&gt;Last updated: Oct 2025&lt;/time&gt;&#xA;    &lt;/i&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Contents&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/page-cache/2-essential-page-cache-theory/#read-requests&#34;&gt;Read requests&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/page-cache/2-essential-page-cache-theory/#write-requests&#34;&gt;Write requests&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;hr/&gt;&#xA;&lt;p&gt;First of all, let’s start with a bunch of reasonable questions about Page Cache:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;What is the &lt;strong&gt;Linux Page Cache&lt;/strong&gt;?&lt;/li&gt;&#xA;&lt;li&gt;What problems does it solve?&lt;/li&gt;&#xA;&lt;li&gt;Why do we call it &lt;strong&gt;«Page»&lt;/strong&gt; Cache ?&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;In essence, the Page Cache is a part of the Virtual File System (&lt;a href=&#34;https://en.wikipedia.org/wiki/Virtual_file_system&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;VFS&lt;/a&gt;) whose primary purpose, as you can guess, is improving the IO latency of read and write operations. A write-back cache algorithm is a core building block of the Page Cache.&lt;/p&gt;</description>
    </item>
    <item>
      <title>getaddrinfo() and POSIX spec</title>
      <link>https://biriukov.dev/docs/resolver-dual-stack-application/3-getaddrinfo-and-posix-spec/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://biriukov.dev/docs/resolver-dual-stack-application/3-getaddrinfo-and-posix-spec/</guid>
      <description>&lt;h1 id=&#34;3-getaddrinfo-and-posix-spec&#34;&gt;&#xA;  3. &lt;code&gt;getaddrinfo()&lt;/code&gt; and POSIX spec&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#3-getaddrinfo-and-posix-spec&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h1&gt;&#xA;&lt;p class=&#34;updated-right&#34;&gt;&#xA;    &lt;i&gt;&#xA;        &lt;time datetime=&#34;2025-10&#34;&gt;Last updated: Oct 2025&lt;/time&gt;&#xA;    &lt;/i&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Contents&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/3-getaddrinfo-and-posix-spec/#31-resolving-hostname-node&#34;&gt;3.1 Resolving hostname (node)&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/3-getaddrinfo-and-posix-spec/#32-resolving-ports-services&#34;&gt;3.2 Resolving ports (services)&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;hr/&gt;&#xA;&lt;p&gt;Thus, instead of the deprecated &lt;code&gt;gethostbyname()&lt;/code&gt;, &lt;code&gt;getaddrinfo()&lt;/code&gt; should be used within &lt;code&gt;libc&lt;/code&gt;. The &lt;code&gt;getaddrinfo()&lt;/code&gt; function is a POSIX-&lt;a href=&#34;https://pubs.opengroup.org/onlinepubs/9799919799.2024edition/functions/getaddrinfo.html&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;standardized&lt;/a&gt; function and is defined in &lt;a href=&#34;http://www.ietf.org/rfc/rfc3493.txt&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;RFC 3943&lt;/a&gt;. It is IP version agnostic and returns data structures that can be easily reused in subsequent socket API calls (such as &lt;code&gt;socket()&lt;/code&gt;, &lt;code&gt;connect()&lt;/code&gt;, &lt;code&gt;sendto()&lt;/code&gt;).&lt;/p&gt;&#xA;&lt;p&gt;First of all, if you have a codebase that uses &lt;code&gt;gethostbyname()&lt;/code&gt; and you are looking to migrate to the modern &lt;code&gt;getaddrinfo()&lt;/code&gt;, I have bad news: it’s not a drop-in replacement. You need to understand the new data structures, logic and flags.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Process groups, jobs and sessions</title>
      <link>https://biriukov.dev/docs/fd-pipe-session-terminal/3-process-groups-jobs-and-sessions/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://biriukov.dev/docs/fd-pipe-session-terminal/3-process-groups-jobs-and-sessions/</guid>
      <description>&lt;h1 id=&#34;process-groups-jobs-and-sessions&#34;&gt;&#xA;  Process groups, jobs and sessions&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#process-groups-jobs-and-sessions&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h1&gt;&#xA;&lt;p class=&#34;updated-right&#34;&gt;&#xA;    &lt;i&gt;&#xA;        &lt;time datetime=&#34;2025-10&#34;&gt;Last updated: Oct 2025&lt;/time&gt;&#xA;    &lt;/i&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Contents&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/fd-pipe-session-terminal/3-process-groups-jobs-and-sessions/#process-groups&#34;&gt;Process groups&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/fd-pipe-session-terminal/3-process-groups-jobs-and-sessions/#sessions&#34;&gt;Sessions&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/fd-pipe-session-terminal/3-process-groups-jobs-and-sessions/#controlling-terminal-controlling-process-foreground-and-background-process-groups&#34;&gt;Controlling terminal, controlling process, foreground and background process groups&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/fd-pipe-session-terminal/3-process-groups-jobs-and-sessions/#shell-job-control&#34;&gt;Shell job control&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/fd-pipe-session-terminal/3-process-groups-jobs-and-sessions/#kill-command&#34;&gt;&lt;code&gt;kill&lt;/code&gt; command&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/fd-pipe-session-terminal/3-process-groups-jobs-and-sessions/#terminating-shell&#34;&gt;Terminating shell&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/fd-pipe-session-terminal/3-process-groups-jobs-and-sessions/#nohup-and-disown&#34;&gt;&lt;code&gt;nohup&lt;/code&gt; and &lt;code&gt;disown&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/fd-pipe-session-terminal/3-process-groups-jobs-and-sessions/#daemons&#34;&gt;Daemons&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;hr/&gt;&#xA;&lt;p&gt;A new process group is created every time we execute a command or a pipeline of commands in a shell. Inside a shell, a &lt;strong&gt;process group&lt;/strong&gt; is usually called a &lt;strong&gt;job&lt;/strong&gt;. In its turn, each process group belongs to a session. Linux kernel provides a &lt;strong&gt;two-level hierarchy&lt;/strong&gt; for all running processes (look at figure 3 below). As such, a process group is a set of processes, and a session is a set of related process groups. Another important limitation is that a process group and its members can be members of a single session.&lt;/p&gt;</description>
    </item>
    <item>
      <title>getaddrinfo() from glibc</title>
      <link>https://biriukov.dev/docs/resolver-dual-stack-application/4-getaddrinfo-from-glibc/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://biriukov.dev/docs/resolver-dual-stack-application/4-getaddrinfo-from-glibc/</guid>
      <description>&lt;h1 id=&#34;4-getaddrinfo-from-glibc&#34;&gt;&#xA;  4. &lt;code&gt;getaddrinfo()&lt;/code&gt; from &lt;code&gt;glibc&lt;/code&gt;&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#4-getaddrinfo-from-glibc&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h1&gt;&#xA;&lt;p class=&#34;updated-right&#34;&gt;&#xA;    &lt;i&gt;&#xA;        &lt;time datetime=&#34;2025-10&#34;&gt;Last updated: Oct 2025&lt;/time&gt;&#xA;    &lt;/i&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Contents&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/4-getaddrinfo-from-glibc/#41-internals-and-design&#34;&gt;4.1 Internals and design&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/4-getaddrinfo-from-glibc/#42-name-service-switch-nss&#34;&gt;4.2 Name Service Switch (&lt;code&gt;nss&lt;/code&gt;)&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/4-getaddrinfo-from-glibc/#43-name-service-cache-daemon-nscd&#34;&gt;4.3 Name service cache daemon &lt;code&gt;NSCD&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/4-getaddrinfo-from-glibc/#44-thread-safety-issues-with-getaddrinfo&#34;&gt;4.4 Thread safety issues with &lt;code&gt;getaddrinfo()&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/4-getaddrinfo-from-glibc/#45-etcresolvconf&#34;&gt;4.5. &lt;code&gt;/etc/resolv.conf&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/4-getaddrinfo-from-glibc/#46-etchosts&#34;&gt;4.6. &lt;code&gt;/etc/hosts&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;hr/&gt;&#xA;&lt;p&gt;The standard in POSIX describes only the behavior and interface of the &lt;code&gt;getaddrinfo()&lt;/code&gt; function. However, the actual implementation can vary between different frameworks. In this chapter, we will examine the internals of the &lt;code&gt;getaddrinfo()&lt;/code&gt; implementation from &lt;code&gt;glibc&lt;/code&gt; version 2.39. In the GNU/Linux world the &lt;code&gt;glibc&lt;/code&gt; remains the default C library for the overwhelming majority of systems.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Terminals and pseudoterminals</title>
      <link>https://biriukov.dev/docs/fd-pipe-session-terminal/4-terminals-and-pseudoterminals/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://biriukov.dev/docs/fd-pipe-session-terminal/4-terminals-and-pseudoterminals/</guid>
      <description>&lt;h1 id=&#34;terminals-and-pseudoterminals&#34;&gt;&#xA;  Terminals and pseudoterminals&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#terminals-and-pseudoterminals&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h1&gt;&#xA;&lt;p class=&#34;updated-right&#34;&gt;&#xA;    &lt;i&gt;&#xA;        &lt;time datetime=&#34;2025-10&#34;&gt;Last updated: Oct 2025&lt;/time&gt;&#xA;    &lt;/i&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Contents&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/fd-pipe-session-terminal/4-terminals-and-pseudoterminals/#pseudoterminal-devpts&#34;&gt;Pseudoterminal (&lt;code&gt;devpts&lt;/code&gt;)&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/fd-pipe-session-terminal/4-terminals-and-pseudoterminals/#terminal-settings&#34;&gt;Terminal settings&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/fd-pipe-session-terminal/4-terminals-and-pseudoterminals/#handling-terminal-signals&#34;&gt;Handling Terminal Signals&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/fd-pipe-session-terminal/4-terminals-and-pseudoterminals/#screen-and-tmux&#34;&gt;&lt;code&gt;screen&lt;/code&gt; and &lt;code&gt;tmux&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/fd-pipe-session-terminal/4-terminals-and-pseudoterminals/#pseudoterminal-proxy&#34;&gt;Pseudoterminal proxy&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/fd-pipe-session-terminal/4-terminals-and-pseudoterminals/#changing-a-processs-controlling-terminal&#34;&gt;Changing a process’s controlling terminal&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;hr/&gt;&#xA;&lt;p&gt;Terminals come to us from the history of &lt;code&gt;UNIX&lt;/code&gt; systems. Basically, terminals provided an API for the console utils (physical ones!) to generalize interaction with users. It includes ways of reading input and writing to it in &lt;strong&gt;two&lt;/strong&gt; modes:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;the &lt;strong&gt;canonical&lt;/strong&gt; mode (default) – input is buffered line by line and read into after a new line char &lt;code&gt;\n&lt;/code&gt; occurs;&lt;/li&gt;&#xA;&lt;li&gt;the &lt;strong&gt;noncanonical&lt;/strong&gt; mode –  an application can read terminal input a character at a time. For example &lt;code&gt;vi&lt;/code&gt;, &lt;code&gt;emacs&lt;/code&gt; and &lt;code&gt;less&lt;/code&gt; use this mode.&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;Nowadays, with the widespread use of rich graphical UIs, the significance of the terminals are lesser than it was, but still, we use this protocol implicitly every time we start an ssh connection.&lt;/p&gt;</description>
    </item>
    <item>
      <title>getaddrinfo() from musl libc</title>
      <link>https://biriukov.dev/docs/resolver-dual-stack-application/5-getaddrinfo-from-musl-libc/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://biriukov.dev/docs/resolver-dual-stack-application/5-getaddrinfo-from-musl-libc/</guid>
      <description>&lt;h1 id=&#34;5-getaddrinfo-from-musl-libc&#34;&gt;&#xA;  5. &lt;code&gt;getaddrinfo()&lt;/code&gt; from &lt;code&gt;musl&lt;/code&gt; &lt;code&gt;libc&lt;/code&gt;&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#5-getaddrinfo-from-musl-libc&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h1&gt;&#xA;&lt;p class=&#34;updated-right&#34;&gt;&#xA;    &lt;i&gt;&#xA;        &lt;time datetime=&#34;2025-10&#34;&gt;Last updated: Oct 2025&lt;/time&gt;&#xA;    &lt;/i&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;&lt;code&gt;musl libc&lt;/code&gt; is a lightweight, fast, and simple implementation of the standard C library (&lt;code&gt;libc&lt;/code&gt;) that aims for efficiency, standards compliance, and security.&lt;/p&gt;&#xA;&lt;p&gt;It gained popularity following its extensive use in &lt;a href=&#34;https://alpinelinux.org/&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;Alpine Linux&lt;/a&gt;, a security-oriented, lightweight Linux distribution often used as a base image for Docker containers.&lt;/p&gt;&#xA;&lt;p&gt;However, it is crucial for us to understand that &lt;code&gt;musl libc&lt;/code&gt; incorporates a completely new resolver code that behaves differently in certain &lt;a href=&#34;https://wiki.musl-libc.org/functional-differences-from-glibc.html#Name_Resolver_.2F_DNS&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;situations&lt;/a&gt;. The most significant differences include:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Page Cache and basic file operations</title>
      <link>https://biriukov.dev/docs/page-cache/3-page-cache-and-basic-file-operations/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://biriukov.dev/docs/page-cache/3-page-cache-and-basic-file-operations/</guid>
      <description>&lt;h1 id=&#34;page-cache-and-basic-file-operations&#34;&gt;&#xA;  Page Cache and basic file operations&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#page-cache-and-basic-file-operations&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h1&gt;&#xA;&lt;p class=&#34;updated-right&#34;&gt;&#xA;    &lt;i&gt;&#xA;        &lt;time datetime=&#34;2025-10&#34;&gt;Last updated: Oct 2025&lt;/time&gt;&#xA;    &lt;/i&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Contents&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/page-cache/3-page-cache-and-basic-file-operations/#file-reads&#34;&gt;File reads&lt;/a&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/page-cache/3-page-cache-and-basic-file-operations/#reading-files-with-read-syscall&#34;&gt;Reading files with &lt;code&gt;read()&lt;/code&gt; syscall&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/page-cache/3-page-cache-and-basic-file-operations/#reading-files-with-mmap-syscall&#34;&gt;Reading files with &lt;code&gt;mmap()&lt;/code&gt; syscall&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/page-cache/3-page-cache-and-basic-file-operations/#file-writes&#34;&gt;File writes&lt;/a&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/page-cache/3-page-cache-and-basic-file-operations/#writing-to-files-with-write-syscall&#34;&gt;Writing to files with &lt;code&gt;write()&lt;/code&gt; syscall&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/page-cache/3-page-cache-and-basic-file-operations/#file-writes-with-mmap--syscall&#34;&gt;File writes with &lt;code&gt;mmap()&lt;/code&gt; syscall&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/page-cache/3-page-cache-and-basic-file-operations/#dirty-pages&#34;&gt;Dirty pages&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/page-cache/3-page-cache-and-basic-file-operations/#synchronize-file-changes-with-fsync-fdatasync-and-msync&#34;&gt;Synchronize file changes with &lt;code&gt;fsync()&lt;/code&gt;, &lt;code&gt;fdatasync()&lt;/code&gt; and &lt;code&gt;msync()&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/page-cache/3-page-cache-and-basic-file-operations/#checking-file-presence-in-page-cache-with-mincore&#34;&gt;Checking file presence in Page Cache with &lt;code&gt;mincore()&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;hr/&gt;&#xA;&lt;p&gt;Now it&amp;rsquo;s time to roll up our sleeves and get started with some practical examples. By the end of this chapter, you will know how to interact with Page Cache and which tools you can use.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Dual-Stack applications</title>
      <link>https://biriukov.dev/docs/resolver-dual-stack-application/6-dual-stack-applications/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://biriukov.dev/docs/resolver-dual-stack-application/6-dual-stack-applications/</guid>
      <description>&lt;h1 id=&#34;6-dual-stack-applications&#34;&gt;&#xA;  6. Dual-Stack applications&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#6-dual-stack-applications&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h1&gt;&#xA;&lt;p class=&#34;updated-right&#34;&gt;&#xA;    &lt;i&gt;&#xA;        &lt;time datetime=&#34;2025-10&#34;&gt;Last updated: Oct 2025&lt;/time&gt;&#xA;    &lt;/i&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Contents&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/6-dual-stack-applications/#61-dual-stack-server&#34;&gt;6.1 Dual stack server&lt;/a&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/6-dual-stack-applications/#611--ipv6_v6only-socket-option&#34;&gt;6.1.1 &lt;code&gt;IPV6_V6ONLY&lt;/code&gt; socket option&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/6-dual-stack-applications/#612-multiple-listening-sockets-with-systemd&#34;&gt;6.1.2 Multiple listening sockets with &lt;code&gt;systemd&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/6-dual-stack-applications/#62-dual-stack-client&#34;&gt;6.2 Dual stack client&lt;/a&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/6-dual-stack-applications/#621-sorting-destination-addresses-rfc-6724&#34;&gt;6.2.1 Sorting destination addresses (RFC 6724)&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/6-dual-stack-applications/#622-happy-eyeballs-success-with-dual-stack-hosts&#34;&gt;6.2.2 Happy Eyeballs: Success with Dual-Stack Hosts&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;hr/&gt;&#xA;&lt;img alt=&#34;IPv4 or IPv6&#34; src=&#34;../images/dns_two_buttons.png&#34; width=&#34;40%&#34; class=&#34;img-center&#34;&gt;&#xA;&lt;p&gt;Let’s now focus on dual-stack programs, which support both IPv4 and IPv6. Here are some critical questions to consider:&lt;/p&gt;&#xA;&lt;p&gt;For server code:&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;How can we easily listen on all IPv4 and all IPv6 addresses? Do we need separate listeners for each?&lt;/li&gt;&#xA;&lt;li&gt;Are there any tools or helpers available to manage multiple listeners?&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;p&gt;For client code:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Async non-blocking resolvers in C</title>
      <link>https://biriukov.dev/docs/resolver-dual-stack-application/7-async-non-blocking-resolvers-in-c/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://biriukov.dev/docs/resolver-dual-stack-application/7-async-non-blocking-resolvers-in-c/</guid>
      <description>&lt;h1 id=&#34;7-async-non-blocking-resolvers-in-c&#34;&gt;&#xA;  7. Async non-blocking resolvers in &lt;code&gt;C&lt;/code&gt;&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#7-async-non-blocking-resolvers-in-c&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h1&gt;&#xA;&lt;p class=&#34;updated-right&#34;&gt;&#xA;    &lt;i&gt;&#xA;        &lt;time datetime=&#34;2025-10&#34;&gt;Last updated: Oct 2025&lt;/time&gt;&#xA;    &lt;/i&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Contents&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/7-async-non-blocking-resolvers-in-c/#71-getaddrinfo_a&#34;&gt;7.1 &lt;code&gt;getaddrinfo_a()&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/7-async-non-blocking-resolvers-in-c/#72--c-ares-library&#34;&gt;7.2 &lt;code&gt;c-ares&lt;/code&gt; library&lt;/a&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/7-async-non-blocking-resolvers-in-c/#721-essentials&#34;&gt;7.2.1 Essentials&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/7-async-non-blocking-resolvers-in-c/#721-dual-stack-application&#34;&gt;7.2.1 Dual stack application&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;hr/&gt;&#xA;&lt;p&gt;Now that we’ve covered the essential theory, let’s explore alternative stub resolver libraries and frameworks for the &lt;code&gt;C&lt;/code&gt; language. Other languages will be discussed next, but don’t skip this chapter, as it contains foundational information that will be referenced later.&lt;/p&gt;&#xA;&lt;h2 id=&#34;71-getaddrinfo_a&#34;&gt;&#xA;  7.1 &lt;code&gt;getaddrinfo_a()&lt;/code&gt;&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#71-getaddrinfo_a&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;&lt;code&gt;getaddrinfo_a&lt;/code&gt; (&lt;code&gt;&lt;a href=&#34;https://www.man7.org/linux/man-pages/man3/getaddrinfo_a.3.html&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;man 7 getaddrinfo_a&lt;/a&gt;&lt;/code&gt;) is an asynchronous version of &lt;code&gt;getaddrinfo()&lt;/code&gt; but with some limitations: results can be collected by polling or notified by a signal.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Page Cache eviction and page reclaim</title>
      <link>https://biriukov.dev/docs/page-cache/4-page-cache-eviction-and-page-reclaim/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://biriukov.dev/docs/page-cache/4-page-cache-eviction-and-page-reclaim/</guid>
      <description>&lt;h1 id=&#34;page-cache-eviction-and-page-reclaim&#34;&gt;&#xA;  Page Cache eviction and page reclaim&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#page-cache-eviction-and-page-reclaim&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h1&gt;&#xA;&lt;p class=&#34;updated-right&#34;&gt;&#xA;    &lt;i&gt;&#xA;        &lt;time datetime=&#34;2025-10&#34;&gt;Last updated: Oct 2025&lt;/time&gt;&#xA;    &lt;/i&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Contents&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/page-cache/4-page-cache-eviction-and-page-reclaim/#theory&#34;&gt;Essesntial theory&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/page-cache/4-page-cache-eviction-and-page-reclaim/#manual-pages-eviction-with-posix_fadv_dontneed&#34;&gt;Manual pages eviction with &lt;code&gt;POSIX_FADV_DONTNEED&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/page-cache/4-page-cache-eviction-and-page-reclaim/#make-your-memory-unevictable&#34;&gt;Make your memory unevictable&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/page-cache/4-page-cache-eviction-and-page-reclaim/#page-cache-vmswappiness-and-modern-kernels&#34;&gt;Page Cache, &lt;code&gt;vm.swappiness&lt;/code&gt; and modern kernels&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/page-cache/4-page-cache-eviction-and-page-reclaim/#understanding-memory-reclaim-process-with-procpidpagemap&#34;&gt;Understanding memory reclaim process with &lt;code&gt;/proc/pid/pagemap&lt;/code&gt;&lt;/a&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/page-cache/4-page-cache-eviction-and-page-reclaim/#page-types-kernel-page-tool&#34;&gt;&lt;code&gt;page-types&lt;/code&gt; kernel page tool&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/page-cache/4-page-cache-eviction-and-page-reclaim/#writing-page-cache-lru-monitor-tool&#34;&gt;Writing Page Cache LRU monitor tool&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;hr/&gt;&#xA;&lt;p&gt;So far, we have talked about adding data to Page Cache by reading and writing files, checking the existence of files in the cache, and flushing the cache content manually. But the most crucial part of any cache system is its &lt;strong&gt;eviction policy&lt;/strong&gt;, or regarding Linux Page Cache, it&amp;rsquo;s also the memory &lt;strong&gt;page reclaim&lt;/strong&gt; policy. Like any other cache, Linux Page Cache continuously monitors the last used pages and makes decisions about which pages should be deleted and which should be kept in the cache.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Stub resolvers in languages</title>
      <link>https://biriukov.dev/docs/resolver-dual-stack-application/8-stub-resolvers-in-languages/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://biriukov.dev/docs/resolver-dual-stack-application/8-stub-resolvers-in-languages/</guid>
      <description>&lt;h1 id=&#34;8-stub-resolvers-in-languages&#34;&gt;&#xA;  8. Stub resolvers in languages&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#8-stub-resolvers-in-languages&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h1&gt;&#xA;&lt;p class=&#34;updated-right&#34;&gt;&#xA;    &lt;i&gt;&#xA;        &lt;time datetime=&#34;2025-10&#34;&gt;Last updated: Oct 2025&lt;/time&gt;&#xA;    &lt;/i&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Contents&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/8-stub-resolvers-in-languages/#81-python&#34;&gt;8.1 &lt;code&gt;Python&lt;/code&gt;&lt;/a&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/8-stub-resolvers-in-languages/#811--stub-resolvers&#34;&gt;8.1.1 Stub resolvers&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/8-stub-resolvers-in-languages/#812-happy-eyeballs&#34;&gt;8.1.2 Happy Eyeballs&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/8-stub-resolvers-in-languages/#82-go-golang&#34;&gt;8.2 &lt;code&gt;Go&lt;/code&gt; (&lt;code&gt;golang&lt;/code&gt;)&lt;/a&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/8-stub-resolvers-in-languages/#821-resolver&#34;&gt;8.2.1 Resolver&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/8-stub-resolvers-in-languages/#822-happy-eyeballs&#34;&gt;8.2.2 Happy Eyeballs&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/8-stub-resolvers-in-languages/#83-rust&#34;&gt;8.3 &lt;code&gt;Rust&lt;/code&gt;&lt;/a&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/8-stub-resolvers-in-languages/#831-resolver&#34;&gt;8.3.1 Resolver&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/8-stub-resolvers-in-languages/#832-happy-eyeballs&#34;&gt;8.3.2 Happy Eyeballs&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/8-stub-resolvers-in-languages/#84-java-and-netty&#34;&gt;8.4 &lt;code&gt;Java&lt;/code&gt; and &lt;code&gt;Netty&lt;/code&gt;&lt;/a&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/8-stub-resolvers-in-languages/#841-resolver&#34;&gt;8.4.1 Resolver&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/8-stub-resolvers-in-languages/#842-java-securitymanager&#34;&gt;8.4.2 &lt;code&gt;Java&lt;/code&gt; &lt;code&gt;SecurityManager&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/8-stub-resolvers-in-languages/#843-happy-eyeballs&#34;&gt;8.4.3 Happy eyeballs&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/8-stub-resolvers-in-languages/#85-nodejs&#34;&gt;8.5 &lt;code&gt;Node.js&lt;/code&gt;&lt;/a&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/8-stub-resolvers-in-languages/#851-resoler&#34;&gt;8.5.1 Resoler&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/8-stub-resolvers-in-languages/#852-happy-eyeballs&#34;&gt;8.5.2 Happy Eyeballs&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;hr/&gt;&#xA;&lt;p&gt;Let’s now take a look at other popular languages and understand the capabilities, features and options they provide in the context of resolvers.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Dual-stack software examples</title>
      <link>https://biriukov.dev/docs/resolver-dual-stack-application/9-dual-stack-software-examples/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://biriukov.dev/docs/resolver-dual-stack-application/9-dual-stack-software-examples/</guid>
      <description>&lt;h1 id=&#34;9-dual-stack-software-examples&#34;&gt;&#xA;  9. Dual-stack software examples&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#9-dual-stack-software-examples&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h1&gt;&#xA;&lt;p class=&#34;updated-right&#34;&gt;&#xA;    &lt;i&gt;&#xA;        &lt;time datetime=&#34;2025-10&#34;&gt;Last updated: Oct 2025&lt;/time&gt;&#xA;    &lt;/i&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Contents&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/9-dual-stack-software-examples/#91-nginx&#34;&gt;9.1 &lt;code&gt;Nginx&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/9-dual-stack-software-examples/#92-envoy-proxy&#34;&gt;9.2 &lt;code&gt;Envoy&lt;/code&gt; proxy&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/9-dual-stack-software-examples/#93-haproxy&#34;&gt;9.3 &lt;code&gt;HAProxy&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;hr/&gt;&#xA;&lt;h2 id=&#34;91-nginx&#34;&gt;&#xA;  9.1 Nginx&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#91-nginx&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;&lt;code&gt;Nginx&lt;/code&gt; treats the hostname as a set of distinct entries rather than multiple paths to the same host. From the upstream module &lt;a href=&#34;https://nginx.org/en/docs/http/ngx_http_upstream_module.html#server&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;doc&lt;/a&gt;:&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;A domain name that resolves to several IP addresses defines multiple servers at once.&lt;/p&gt;&#xA;&lt;/blockquote&gt;&#xA;&lt;p&gt;On start &lt;code&gt;Nginx&lt;/code&gt; resolves all hostnames using its &lt;a href=&#34;https://github.com/nginx/nginx/blob/145b228530c364452c14d3184f1eee5e09b324aa/src/core/ngx_inet.c#L1117&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;static resolver&lt;/a&gt; with &lt;code&gt;getaddrinfo()&lt;/code&gt; and the &lt;code&gt;AF_UNSPEC&lt;/code&gt; and the &lt;code&gt;AI_ADDRCONFIG&lt;/code&gt; flags.&lt;/p&gt;</description>
    </item>
    <item>
      <title>More about mmap() file access</title>
      <link>https://biriukov.dev/docs/page-cache/5-more-about-mmap-file-access/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://biriukov.dev/docs/page-cache/5-more-about-mmap-file-access/</guid>
      <description>&lt;h1 id=&#34;more-about-mmap-file-access&#34;&gt;&#xA;  More about &lt;code&gt;mmap()&lt;/code&gt; file access&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#more-about-mmap-file-access&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h1&gt;&#xA;&lt;p class=&#34;updated-right&#34;&gt;&#xA;    &lt;i&gt;&#xA;        &lt;time datetime=&#34;2025-10&#34;&gt;Last updated: Oct 2025&lt;/time&gt;&#xA;    &lt;/i&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Contents&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/page-cache/5-more-about-mmap-file-access/#mmap-overview&#34;&gt;&lt;code&gt;mmap()&lt;/code&gt; overview&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/page-cache/5-more-about-mmap-file-access/#what-is-a-page-fault&#34;&gt;What is a page fault?&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/page-cache/5-more-about-mmap-file-access/#subtle-madv_dont_need-mmap-feature&#34;&gt;Subtle &lt;code&gt;MADV_DONT_NEED&lt;/code&gt; &lt;code&gt;mmap()&lt;/code&gt; feature&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;hr/&gt;&#xA;&lt;p&gt;Before we start the cgroup chapter, where I&amp;rsquo;m showing how to leverage memory and IO limits in order to control Page Cache eviction and improve  the reliability of services, I want to delve a bit deeper into &lt;code&gt;mmap()&lt;/code&gt;  syscall. We need to understand what is happening under the hood and shed more light on the reading and writing process with &lt;code&gt;mmap()&lt;/code&gt;.&lt;/p&gt;</description>
    </item>
    <item>
      <title>systemd-resolved</title>
      <link>https://biriukov.dev/docs/resolver-dual-stack-application/10-systemd-resolved/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://biriukov.dev/docs/resolver-dual-stack-application/10-systemd-resolved/</guid>
      <description>&lt;h1 id=&#34;10-systemd-resolved&#34;&gt;&#xA;  10. systemd-resolved&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#10-systemd-resolved&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h1&gt;&#xA;&lt;p class=&#34;updated-right&#34;&gt;&#xA;    &lt;i&gt;&#xA;        &lt;time datetime=&#34;2025-10&#34;&gt;Last updated: Oct 2025&lt;/time&gt;&#xA;    &lt;/i&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Contents&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/10-systemd-resolved/#101-managing-etcresolvconf-content&#34;&gt;10.1 Managing &lt;code&gt;/etc/resolv.conf&lt;/code&gt; content&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/10-systemd-resolved/#102-integrating-systemd-resolved-into-system&#34;&gt;10.2 Integrating &lt;code&gt;systemd-resolved &lt;/code&gt;into system&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/10-systemd-resolved/#103-per-link-name-servers-and-search-domains&#34;&gt;10.3 Per link name servers and search domains&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/10-systemd-resolved/#104-useful-commands&#34;&gt;10.4 Useful commands&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/10-systemd-resolved/#105-querying-systemd-resolved&#34;&gt;10.5 Querying &lt;code&gt;systemd-resolved&lt;/code&gt;&lt;/a&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/10-systemd-resolved/#1051-varlink&#34;&gt;10.5.1 &lt;code&gt;Varlink&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/10-systemd-resolved/#1052-d-bus&#34;&gt;10.5.2 &lt;code&gt;D-Bus&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;hr/&gt;&#xA;&lt;h2 id=&#34;101-managing-etcresolvconf-content&#34;&gt;&#xA;  10.1 Managing &lt;code&gt;/etc/resolv.conf&lt;/code&gt; content&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#101-managing-etcresolvconf-content&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;The main issue with &lt;code&gt;/etc/resolv.conf&lt;/code&gt; is managing it in modern distributions, which can have multiple sources of nameserver and search domain information due to multiple interfaces (both real and virtual, such as VPN tunnels) with concurrent DHCP clients.&lt;/p&gt;</description>
    </item>
    <item>
      <title>cgroup v2 and Page Cache</title>
      <link>https://biriukov.dev/docs/page-cache/6-cgroup-v2-and-page-cache/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://biriukov.dev/docs/page-cache/6-cgroup-v2-and-page-cache/</guid>
      <description>&lt;h1 id=&#34;cgroup-v2-and-page-cache&#34;&gt;&#xA;  cgroup v2 and Page Cache&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#cgroup-v2-and-page-cache&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h1&gt;&#xA;&lt;p class=&#34;updated-right&#34;&gt;&#xA;    &lt;i&gt;&#xA;        &lt;time datetime=&#34;2025-10&#34;&gt;Last updated: Oct 2025&lt;/time&gt;&#xA;    &lt;/i&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Contents&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/page-cache/6-cgroup-v2-and-page-cache/#overview&#34;&gt;Overview&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/page-cache/6-cgroup-v2-and-page-cache/#memory-cgroup-files&#34;&gt;Memory cgroup files&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/page-cache/6-cgroup-v2-and-page-cache/#pressure-stall-information-psi&#34;&gt;Pressure Stall Information (PSI)&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/page-cache/6-cgroup-v2-and-page-cache/#writeback-and-io&#34;&gt;Writeback and I/O&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/page-cache/6-cgroup-v2-and-page-cache/#memory-and-io-cgroup-ownership&#34;&gt;Memory and I/O cgroup ownership&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/page-cache/6-cgroup-v2-and-page-cache/#safe-ad-hoc-tasks&#34;&gt;Safe ad-hoc tasks&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;hr/&gt;&#xA;&lt;p&gt;The cgroup subsystem is the way to distribute and limit system resources fairly. It organizes all data in a hierarchy where the leaf nodes depend on their parents and inherit their settings. In addition, the cgroup provides a lot of helpful resource counters and statistics.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Querying Nameservers on dual-stack hosts</title>
      <link>https://biriukov.dev/docs/resolver-dual-stack-application/11-querying-nameservers-on-dual-stack-hosts/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://biriukov.dev/docs/resolver-dual-stack-application/11-querying-nameservers-on-dual-stack-hosts/</guid>
      <description>&lt;h1 id=&#34;11-querying-nameservers-on-dual-stack-hosts&#34;&gt;&#xA;  11. Querying Nameservers on dual-stack hosts&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#11-querying-nameservers-on-dual-stack-hosts&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h1&gt;&#xA;&lt;p class=&#34;updated-right&#34;&gt;&#xA;    &lt;i&gt;&#xA;        &lt;time datetime=&#34;2025-10&#34;&gt;Last updated: Oct 2025&lt;/time&gt;&#xA;    &lt;/i&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;The already seen &lt;a href=&#34;https://datatracker.ietf.org/doc/html/rfc8305&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;RFC 8305  Happy Eyeballs Version 2: Better Connectivity Using Concurrency&lt;/a&gt; force the same preference for IPv6 name servers as it does for establishing new connections:&lt;/p&gt;&#xA;&lt;blockquote&gt;&#xA;&lt;p&gt;&lt;i&gt;If multiple DNS server addresses are configured for the current network, the client may have the option of sending its DNS queries over IPv4 or IPv6.  In keeping with the Happy Eyeballs approach, queries SHOULD be sent over IPv6 first (note that this is not referring to the sending of &lt;code&gt;AAAA&lt;/code&gt; or &lt;code&gt;A&lt;/code&gt; queries, but rather the address of the DNS server itself and IP version used to transport DNS messages).  If DNS queries sent to the IPv6 address do not receive responses, that address may be marked as penalized and queries can be sent to other DNS server addresses.&lt;/i&gt;&lt;/p&gt;</description>
    </item>
    <item>
      <title>The Present and the future of resolvers and DNS related features</title>
      <link>https://biriukov.dev/docs/resolver-dual-stack-application/12-present-and-future-of-resolvers-and-dns-related-features/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://biriukov.dev/docs/resolver-dual-stack-application/12-present-and-future-of-resolvers-and-dns-related-features/</guid>
      <description>&lt;h1 id=&#34;12-the-present-and-the-future-of-resolvers-and-dns-related-features&#34;&gt;&#xA;  12. The Present and the future of resolvers and DNS related features&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#12-the-present-and-the-future-of-resolvers-and-dns-related-features&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h1&gt;&#xA;&lt;p class=&#34;updated-right&#34;&gt;&#xA;    &lt;i&gt;&#xA;        &lt;time datetime=&#34;2025-10&#34;&gt;Last updated: Oct 2025&lt;/time&gt;&#xA;    &lt;/i&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Contents&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/12-present-and-future-of-resolvers-and-dns-related-features/#121-new-dns-record-https&#34;&gt;12.1 New DNS record: HTTPS&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/12-present-and-future-of-resolvers-and-dns-related-features/#122-dnssec&#34;&gt;12.2. DNSSEC&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/12-present-and-future-of-resolvers-and-dns-related-features/#123-dns-over-tls-dot--dsn-over-https-doh-and-dns-over-quick-doq&#34;&gt;12.3 DNS over TLS (DoT), DSN over HTTPS (DoH) and DNS over QUICK (DoQ)&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/12-present-and-future-of-resolvers-and-dns-related-features/#124-oblivious-dns&#34;&gt;12.4 Oblivious DNS&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/resolver-dual-stack-application/12-present-and-future-of-resolvers-and-dns-related-features/#125-dns-push-notifications&#34;&gt;12.5. DNS Push Notifications&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;hr/&gt;&#xA;&lt;p&gt;Let me briefly review some important features and topics related to DNS, stub resolvers, and dual-stack applications. While these are beyond the scope of this series, they are worth mentioning.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Troubleshooting tools for resolvers and DNS</title>
      <link>https://biriukov.dev/docs/resolver-dual-stack-application/troubleshooting-tools-for-resolvers-and-dns/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://biriukov.dev/docs/resolver-dual-stack-application/troubleshooting-tools-for-resolvers-and-dns/</guid>
      <description>&lt;h1 id=&#34;tools-for-troubleshooting-in-one-place&#34;&gt;&#xA;  Tools for troubleshooting in one place&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#tools-for-troubleshooting-in-one-place&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h1&gt;&#xA;&lt;p class=&#34;updated-right&#34;&gt;&#xA;    &lt;i&gt;&#xA;        &lt;time datetime=&#34;2025-10&#34;&gt;Last updated: Oct 2025&lt;/time&gt;&#xA;    &lt;/i&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;Let me reiterate and consolidate all the tools that can be used to troubleshoot applications and systems when the stub resolver is under suspicion.&lt;/p&gt;&#xA;&lt;h2 id=&#34;-getent&#34;&gt;&#xA;  • &lt;code&gt;getent&lt;/code&gt;&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#-getent&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;&lt;code&gt;&lt;a href=&#34;https://man7.org/linux/man-pages/man1/getent.1.html&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;man 1 getent&lt;/a&gt;&lt;/code&gt;&lt;/p&gt;&#xA;&lt;p&gt;When you need to query hostname via all NSS modules:&lt;/p&gt;&#xA;&lt;div class=&#34;highlight&#34;&gt;&lt;pre tabindex=&#34;0&#34; style=&#34;color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;&#34;&gt;&lt;code class=&#34;language-bash&#34; data-lang=&#34;bash&#34;&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ getent host microsoft.com&#xA;&lt;/span&gt;&lt;/span&gt;&lt;span style=&#34;display:flex;&#34;&gt;&lt;span&gt;$ getent ahost microsoft.com&#xA;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id=&#34;-tcpdump&#34;&gt;&#xA;  • &lt;code&gt;tcpdump&lt;/code&gt;&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#-tcpdump&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;To dump in a user friendly format all requests to 53 port:&lt;/p&gt;</description>
    </item>
    <item>
      <title>Unique set size and working set size</title>
      <link>https://biriukov.dev/docs/page-cache/7-how-much-memory-my-program-uses-or-the-tale-of-working-set-size/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://biriukov.dev/docs/page-cache/7-how-much-memory-my-program-uses-or-the-tale-of-working-set-size/</guid>
      <description>&lt;h1 id=&#34;how-much-memory-my-program-uses-or-the-tale-of-working-set-size&#34;&gt;&#xA;  How much memory my program uses or the tale of working set size&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#how-much-memory-my-program-uses-or-the-tale-of-working-set-size&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h1&gt;&#xA;&lt;p class=&#34;updated-right&#34;&gt;&#xA;    &lt;i&gt;&#xA;        &lt;time datetime=&#34;2025-10&#34;&gt;Last updated: Oct 2025&lt;/time&gt;&#xA;    &lt;/i&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Contents&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/page-cache/7-how-much-memory-my-program-uses-or-the-tale-of-working-set-size/#its-all-about-who-counts-or-the-story-of-unique-set-size&#34;&gt;It’s all about who counts or the story of unique set size&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/page-cache/7-how-much-memory-my-program-uses-or-the-tale-of-working-set-size/#idle-pages-and-working-set-size&#34;&gt;Idle pages and working set size&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/page-cache/7-how-much-memory-my-program-uses-or-the-tale-of-working-set-size/#calculating-memory-limits-with-pressure-stall-information-psi&#34;&gt;Calculating memory limits with Pressure Stall Information (PSI)&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/page-cache/7-how-much-memory-my-program-uses-or-the-tale-of-working-set-size/#-and-what-about-writeback&#34;&gt;… and what about writeback?&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;hr/&gt;&#xA;&lt;p&gt;Currently, in the world of containers, auto-scaling, and on-demand clouds, it&amp;rsquo;s vital to understand the resource needs of services both in norman regular situations and under pressure near the software limits. But every time someone touches on the topic of memory usage, it becomes almost immediately unclear what and how to measure. RAM is a valuable and often expensive type of hardware. In some cases, its latency is even more important than disk latency. Therefore, the Linux kernel tries as hard as it can to optimize memory utilization, for instance by sharing the same pages among processes. In addition, the Linux Kernel has its Page Cache in order to improve storage IO speed by storing a subset of the disk data in memory. Page Cache not only, by its nature, performs implicit memory sharing, which usually confuses users, but also actively asynchronously works with the storage in the background. Thus, Page Cache brings even more complexity to the table of memory usage estimation.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Direct IO</title>
      <link>https://biriukov.dev/docs/page-cache/8-direct-io-dio/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://biriukov.dev/docs/page-cache/8-direct-io-dio/</guid>
      <description>&lt;h1 id=&#34;direct-io-dio-not-ready&#34;&gt;&#xA;  Direct IO (DIO) (NOT READY)&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#direct-io-dio-not-ready&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h1&gt;&#xA;&lt;p class=&#34;updated-right&#34;&gt;&#xA;    &lt;i&gt;&#xA;        &lt;time datetime=&#34;2025-10&#34;&gt;Last updated: Oct 2025&lt;/time&gt;&#xA;    &lt;/i&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Contents&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/page-cache/8-direct-io-dio/#why-its-good&#34;&gt;Why it’s good&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/page-cache/8-direct-io-dio/#why-its-bad-and-io_uring-alternative&#34;&gt;Why it’s bad and &lt;code&gt;io_uring&lt;/code&gt; alternative&#xA;&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;hr/&gt;&#xA;&lt;p&gt;As usual, there is always an exception to any rule. And Page Cache is no different. So let&amp;rsquo;s talk about file reads and writes, which can ignore Page Cache content.&lt;/p&gt;&#xA;&lt;h2 id=&#34;why-its-good&#34;&gt;&#xA;  Why it’s good&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#why-its-good&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;Some applications require low-level access to the storage subsystem and the linux kernel gives such a feature by providing &lt;code&gt;O_DIRECT&lt;/code&gt; file open flag. This IO is called the Direct IO or DIO. A program, which opens a file with this flag, bypasses the kernel Page Cache completely and directly communicates with the VFS and the underlying filesystem.&lt;/p&gt;</description>
    </item>
    <item>
      <title>Advanced Page Cache observability and troubleshooting tools</title>
      <link>https://biriukov.dev/docs/page-cache/9-advanced-page-cache-observability-and-troubleshooting-tools/</link>
      <pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate>
      <guid>https://biriukov.dev/docs/page-cache/9-advanced-page-cache-observability-and-troubleshooting-tools/</guid>
      <description>&lt;h1 id=&#34;advanced-page-cache-observability-and-troubleshooting-tools&#34;&gt;&#xA;  Advanced Page Cache observability and troubleshooting tools&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#advanced-page-cache-observability-and-troubleshooting-tools&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h1&gt;&#xA;&lt;p class=&#34;updated-right&#34;&gt;&#xA;    &lt;i&gt;&#xA;        &lt;time datetime=&#34;2025-10&#34;&gt;Last updated: Oct 2025&lt;/time&gt;&#xA;    &lt;/i&gt;&#xA;&lt;/p&gt;&#xA;&lt;p&gt;&lt;strong&gt;Contents&lt;/strong&gt;&lt;/p&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/page-cache/9-advanced-page-cache-observability-and-troubleshooting-tools/#ebpf-tools&#34;&gt;&lt;code&gt;eBPF&lt;/code&gt; tools&lt;/a&gt;&#xA;&lt;ul&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/page-cache/9-advanced-page-cache-observability-and-troubleshooting-tools/#writeback-monitor&#34;&gt;Writeback monitor&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/page-cache/9-advanced-page-cache-observability-and-troubleshooting-tools/#page-cache-top&#34;&gt;Page Cache Top&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/page-cache/9-advanced-page-cache-observability-and-troubleshooting-tools/#cache-stat&#34;&gt;Cache stat&lt;/a&gt;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/page-cache/9-advanced-page-cache-observability-and-troubleshooting-tools/#bpftrace-and-kfunc-trace&#34;&gt;&lt;code&gt;bpftrace&lt;/code&gt; and &lt;code&gt;kfunc&lt;/code&gt; trace&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;/li&gt;&#xA;&lt;li&gt;&lt;a href=&#34;https://biriukov.dev/docs/page-cache/9-advanced-page-cache-observability-and-troubleshooting-tools/#perf-tool&#34;&gt;&lt;code&gt;perf&lt;/code&gt; tool&lt;/a&gt;&lt;/li&gt;&#xA;&lt;/ul&gt;&#xA;&lt;hr/&gt;&#xA;&lt;p&gt;Let&amp;rsquo;s touch on some advanced tools we can use to perform low-level kernel tracing and debugging.&lt;/p&gt;&#xA;&lt;h2 id=&#34;ebpf-tools&#34;&gt;&#xA;  eBPF tools&#xA;  &lt;a class=&#34;anchor&#34; href=&#34;#ebpf-tools&#34;&gt;#&lt;/a&gt;&#xA;&lt;/h2&gt;&#xA;&lt;p&gt;First of all, we can use &lt;code&gt;eBPF&lt;/code&gt; tools. The [&lt;code&gt;bcc&lt;/code&gt;]https://github.com/iovisor/bcc and &lt;a href=&#34;https://github.com/iovisor/bpftrace&#34; target=&#34;_blank&#34; rel=&#34;noopener&#34;&gt;&lt;code&gt;bpftrace&lt;/code&gt;&lt;/a&gt; are your friends when you want to get some internal kernel information.&lt;/p&gt;</description>
    </item>
  </channel>
</rss>
