Skip to content

Commit 5001c2f

Browse files
author
docs-bot
committed
docs: update from source@f458ff4
1 parent c623128 commit 5001c2f

6 files changed

Lines changed: 26 additions & 26 deletions

File tree

‎docs/features.html‎

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
<link rel="apple-touch-icon" href="/favicon.ico">
2424
<link rel="stylesheet" href="/assets/css/site.css?v=b310d7c992">
2525
<link rel="stylesheet" href="/assets/css/main.css?v=ccd72260b9">
26-
<script type="application/ld+json">[{"@context": "https://schema.org", "@type": "TechArticle", "headline": "Feature deep dives", "description": "How each Droidspaces feature works: namespace isolation, init system support, OverlayFS volatile mode, GPU acceleration, cgroup isolation, seccomp shields, and Android-specific tuning.", "url": "https://www.droidspaces.org/docs/features.html", "inLanguage": "en", "dateModified": "2026-10-06", "author": {"@type": "Organization", "name": "Droidspaces", "url": "https://www.droidspaces.org/", "sameAs": ["https://github.com/ravindu644/Droidspaces-OSS", "https://t.me/Droidspaces"]}, "publisher": {"@type": "Organization", "name": "Droidspaces", "url": "https://www.droidspaces.org/", "sameAs": ["https://github.com/ravindu644/Droidspaces-OSS", "https://t.me/Droidspaces"]}, "isPartOf": {"@type": "WebSite", "name": "Droidspaces", "url": "https://www.droidspaces.org/"}}, {"@context": "https://schema.org", "@type": "BreadcrumbList", "itemListElement": [{"@type": "ListItem", "position": 1, "name": "Home", "item": "https://www.droidspaces.org/"}, {"@type": "ListItem", "position": 2, "name": "Documentation", "item": "https://www.droidspaces.org/docs/"}, {"@type": "ListItem", "position": 3, "name": "Feature deep dives", "item": "https://www.droidspaces.org/docs/features.html"}]}]</script>
26+
<script type="application/ld+json">[{"@context": "https://schema.org", "@type": "TechArticle", "headline": "Feature deep dives", "description": "How each Droidspaces feature works: namespace isolation, init system support, OverlayFS volatile mode, GPU acceleration, cgroup isolation, seccomp shields, and Android-specific tuning.", "url": "https://www.droidspaces.org/docs/features.html", "inLanguage": "en", "dateModified": "2026-10-08", "author": {"@type": "Organization", "name": "Droidspaces", "url": "https://www.droidspaces.org/", "sameAs": ["https://github.com/ravindu644/Droidspaces-OSS", "https://t.me/Droidspaces"]}, "publisher": {"@type": "Organization", "name": "Droidspaces", "url": "https://www.droidspaces.org/", "sameAs": ["https://github.com/ravindu644/Droidspaces-OSS", "https://t.me/Droidspaces"]}, "isPartOf": {"@type": "WebSite", "name": "Droidspaces", "url": "https://www.droidspaces.org/"}}, {"@context": "https://schema.org", "@type": "BreadcrumbList", "itemListElement": [{"@type": "ListItem", "position": 1, "name": "Home", "item": "https://www.droidspaces.org/"}, {"@type": "ListItem", "position": 2, "name": "Documentation", "item": "https://www.droidspaces.org/docs/"}, {"@type": "ListItem", "position": 3, "name": "Feature deep dives", "item": "https://www.droidspaces.org/docs/features.html"}]}]</script>
2727
<script>(function(){const t=localStorage.getItem('theme');if(t)document.documentElement.setAttribute('data-theme',t);})();</script>
2828
</head>
2929
<body>
@@ -415,7 +415,7 @@ <h3 id="why-use-images">Why use images? <a class="header-anchor" href="#why-use-
415415
<h3 id="how-it-works-1">How it works <a class="header-anchor" href="#how-it-works-1">#</a></h3>
416416
<p>When you use <code>--rootfs-img</code>:</p>
417417
<ol>
418-
<li><strong>Filesystem check:</strong> Droidspaces runs <code>e2fsck -f -y</code> on the image to ensure integrity</li>
418+
<li><strong>Filesystem check:</strong> Droidspaces reads the image's superblock and runs <code>e2fsck -y</code> only when it says the filesystem needs it: not cleanly unmounted, errors flagged, a journal to replay, or the mount-count or check-interval limit reached. A clean image skips the check</li>
419419
<li><strong>SELinux context:</strong> On Android, applies the <code>vold_data_file</code> SELinux context to prevent silent I/O denials</li>
420420
<li><strong>Loop mount:</strong> The image is mounted at <code>/mnt/Droidspaces/&lt;name&gt;</code></li>
421421
<li><strong>Retry logic:</strong> On kernel 4.14, mounts may fail due to stale loop device state. Droidspaces retries up to 3 times with <code>sync()</code> and settle delays.</li>

‎docs/index.html‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
<link rel="apple-touch-icon" href="/favicon.ico">
2424
<link rel="stylesheet" href="/assets/css/site.css?v=b310d7c992">
2525
<link rel="stylesheet" href="/assets/css/main.css?v=ccd72260b9">
26-
<script type="application/ld+json">[{"@context": "https://schema.org", "@type": "CollectionPage", "headline": "Documentation", "description": "Every Droidspaces guide: install on Android or Linux, build the kernel, use the app and the CLI, networking, graphics and audio, recipes, troubleshooting and supported devices.", "url": "https://www.droidspaces.org/docs/", "inLanguage": "en", "dateModified": "2026-10-07", "author": {"@type": "Organization", "name": "Droidspaces", "url": "https://www.droidspaces.org/", "sameAs": ["https://github.com/ravindu644/Droidspaces-OSS", "https://t.me/Droidspaces"]}, "publisher": {"@type": "Organization", "name": "Droidspaces", "url": "https://www.droidspaces.org/", "sameAs": ["https://github.com/ravindu644/Droidspaces-OSS", "https://t.me/Droidspaces"]}, "isPartOf": {"@type": "WebSite", "name": "Droidspaces", "url": "https://www.droidspaces.org/"}}, {"@context": "https://schema.org", "@type": "BreadcrumbList", "itemListElement": [{"@type": "ListItem", "position": 1, "name": "Home", "item": "https://www.droidspaces.org/"}, {"@type": "ListItem", "position": 2, "name": "Documentation", "item": "https://www.droidspaces.org/docs/"}]}]</script>
26+
<script type="application/ld+json">[{"@context": "https://schema.org", "@type": "CollectionPage", "headline": "Documentation", "description": "Every Droidspaces guide: install on Android or Linux, build the kernel, use the app and the CLI, networking, graphics and audio, recipes, troubleshooting and supported devices.", "url": "https://www.droidspaces.org/docs/", "inLanguage": "en", "dateModified": "2026-10-08", "author": {"@type": "Organization", "name": "Droidspaces", "url": "https://www.droidspaces.org/", "sameAs": ["https://github.com/ravindu644/Droidspaces-OSS", "https://t.me/Droidspaces"]}, "publisher": {"@type": "Organization", "name": "Droidspaces", "url": "https://www.droidspaces.org/", "sameAs": ["https://github.com/ravindu644/Droidspaces-OSS", "https://t.me/Droidspaces"]}, "isPartOf": {"@type": "WebSite", "name": "Droidspaces", "url": "https://www.droidspaces.org/"}}, {"@context": "https://schema.org", "@type": "BreadcrumbList", "itemListElement": [{"@type": "ListItem", "position": 1, "name": "Home", "item": "https://www.droidspaces.org/"}, {"@type": "ListItem", "position": 2, "name": "Documentation", "item": "https://www.droidspaces.org/docs/"}]}]</script>
2727
<script>(function(){const t=localStorage.getItem('theme');if(t)document.documentElement.setAttribute('data-theme',t);})();</script>
2828
</head>
2929
<body>

‎docs/networking-from-zero.html‎

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
<link rel="apple-touch-icon" href="/favicon.ico">
2424
<link rel="stylesheet" href="/assets/css/site.css?v=b310d7c992">
2525
<link rel="stylesheet" href="/assets/css/main.css?v=ccd72260b9">
26-
<script type="application/ld+json">[{"@context": "https://schema.org", "@type": "TechArticle", "headline": "Networking from zero", "description": "Every networking concept behind Droidspaces gateway mode, from the start: IP addresses, LAN, WAN, DHCP, DNS, NAT, bridges, veth pairs, network namespaces and OpenWRT.", "url": "https://www.droidspaces.org/docs/networking-from-zero.html", "inLanguage": "en", "dateModified": "2026-10-03", "author": {"@type": "Organization", "name": "Droidspaces", "url": "https://www.droidspaces.org/", "sameAs": ["https://github.com/ravindu644/Droidspaces-OSS", "https://t.me/Droidspaces"]}, "publisher": {"@type": "Organization", "name": "Droidspaces", "url": "https://www.droidspaces.org/", "sameAs": ["https://github.com/ravindu644/Droidspaces-OSS", "https://t.me/Droidspaces"]}, "isPartOf": {"@type": "WebSite", "name": "Droidspaces", "url": "https://www.droidspaces.org/"}}, {"@context": "https://schema.org", "@type": "BreadcrumbList", "itemListElement": [{"@type": "ListItem", "position": 1, "name": "Home", "item": "https://www.droidspaces.org/"}, {"@type": "ListItem", "position": 2, "name": "Documentation", "item": "https://www.droidspaces.org/docs/"}, {"@type": "ListItem", "position": 3, "name": "Networking from zero", "item": "https://www.droidspaces.org/docs/networking-from-zero.html"}]}]</script>
26+
<script type="application/ld+json">[{"@context": "https://schema.org", "@type": "TechArticle", "headline": "Networking from zero", "description": "Every networking concept behind Droidspaces gateway mode, from the start: IP addresses, LAN, WAN, DHCP, DNS, NAT, bridges, veth pairs, network namespaces and OpenWRT.", "url": "https://www.droidspaces.org/docs/networking-from-zero.html", "inLanguage": "en", "dateModified": "2026-10-08", "author": {"@type": "Organization", "name": "Droidspaces", "url": "https://www.droidspaces.org/", "sameAs": ["https://github.com/ravindu644/Droidspaces-OSS", "https://t.me/Droidspaces"]}, "publisher": {"@type": "Organization", "name": "Droidspaces", "url": "https://www.droidspaces.org/", "sameAs": ["https://github.com/ravindu644/Droidspaces-OSS", "https://t.me/Droidspaces"]}, "isPartOf": {"@type": "WebSite", "name": "Droidspaces", "url": "https://www.droidspaces.org/"}}, {"@context": "https://schema.org", "@type": "BreadcrumbList", "itemListElement": [{"@type": "ListItem", "position": 1, "name": "Home", "item": "https://www.droidspaces.org/"}, {"@type": "ListItem", "position": 2, "name": "Documentation", "item": "https://www.droidspaces.org/docs/"}, {"@type": "ListItem", "position": 3, "name": "Networking from zero", "item": "https://www.droidspaces.org/docs/networking-from-zero.html"}]}]</script>
2727
<script>(function(){const t=localStorage.getItem('theme');if(t)document.documentElement.setAttribute('data-theme',t);})();</script>
2828
</head>
2929
<body>
@@ -359,7 +359,7 @@ <h3 id="how-nat-mode-uses-bridges-and-veths">How NAT mode uses bridges and veths
359359
wlan0 / rmnet0
360360
(Android&#x27;s real network)
361361
</code></pre></div>
362-
<p>The bridge <code>ds-br0</code> holds the gateway IP <code>172.28.0.1</code>, which every NAT container uses as its default gateway. The veth pair is named after the container's init process ID: the host side is <code>ds-v&lt;PID&gt;</code>, and the container side starts as <code>ds-p&lt;PID&gt;</code> and is renamed to <code>eth0</code> inside the container.</p>
362+
<p>The bridge <code>ds-br0</code> holds the gateway IP <code>172.28.0.1</code>, which every NAT container uses as its default gateway. Its MAC is pinned from its name on every start, because an unpinned bridge borrows the lowest MAC among its ports and would change it whenever that container stops, leaving every other container with a stale ARP entry for the gateway. The veth pair is named after the container's init process ID: the host side is <code>ds-v&lt;PID&gt;</code>, and the container side starts as <code>ds-p&lt;PID&gt;</code> and is renamed to <code>eth0</code> inside the container.</p>
363363
<p>Droidspaces runs a small per-container DHCP server on the container's host-side veth. The whole <code>172.28.0.0/16</code> subnet belongs to Droidspaces. The <code>172.28.0.x</code> row is reserved for the gateway itself, so containers always get an address from <code>172.28.1.x</code> to <code>172.28.254.x</code>, and all of it is NATed out through Android's real interface.</p>
364364
<hr />
365365
<h2 id="part-7-network-namespaces-how-containers-are-isolated">Part 7: Network namespaces (how containers are isolated) <a class="header-anchor" href="#part-7-network-namespaces-how-containers-are-isolated">#</a></h2>
@@ -483,15 +483,15 @@ <h3 id="why-bridge-nf-call-iptables-is-set-to-0">Why bridge-nf-call-iptables is
483483
<p>The bridge <code>ds-lan</code> carries traffic between OpenWRT and Kali. By default, Linux can pass bridged traffic through the host's iptables. Android's iptables rules, which may drop or NAT packets unexpectedly, would then interfere with traffic OpenWRT is supposed to manage.</p>
484484
<p>Setting it to <code>0</code> tells Linux not to run iptables on bridged traffic. OpenWRT's firewall is then the <em>only</em> firewall that sees this traffic, which is what we want.</p>
485485
<h3 id="start-order-and-automatic-self-healing">Start order and automatic self-healing <a class="header-anchor" href="#start-order-and-automatic-self-healing">#</a></h3>
486-
<p>All wiring for a gateway-mode client is done <strong>from the host side</strong> by one function, <code>gateway_wire_client()</code>. It makes sure the bridge and the gateway-side cable exist, creates the client's app veth, and moves and renames the peer into the client's namespace as <code>eth0</code> (with a pinned MAC, brought up). The client's own boot code only brings up <code>lo</code>. Because the host owns every step, the same function wires a client whether it is starting or already running.</p>
486+
<p>All wiring for a gateway-mode client is done <strong>from the host side</strong> by one function, <code>gateway_wire_client()</code>. It makes sure the bridge and the gateway-side cable exist, then creates the client's app veth with its peer born inside the client's namespace as <code>eth0</code> (with a pinned MAC, brought up). The client's own boot code only brings up <code>lo</code>. Because the host owns every step, the same function wires a client whether it is starting or already running.</p>
487487
<p>That leads to one simple rule, keyed on <strong>whether the gateway is running</strong>:</p>
488488
<ul>
489489
<li><strong>Gateway already running when a client starts</strong> → the client is wired immediately (its own monitor calls <code>gateway_wire_client</code>).</li>
490490
<li><strong>Gateway not running when a client starts</strong> → the client wires <strong>nothing at all</strong> (no bridge, no veth, no <code>eth0</code>) and boots. The work is left entirely to the gateway.</li>
491491
</ul>
492492
<p>So healing is driven by <strong>the gateway</strong>, not the clients. On every boot cycle, the gateway container's monitor calls <code>ds_net_rewire_gateway_clients()</code>. It scans the running containers, finds those that delegate to this gateway, and runs <code>gateway_wire_client</code> for each, setting up the gateway-side <code>eth1</code> cable and every client's <code>eth0</code> in the gateway's <em>current</em> namespace. When the gateway <strong>starts or reboots</strong>, every running client is (re)wired <strong>without restarting the client</strong>.</p>
493493
<p>Wiring nothing while the gateway is down, instead of half-wiring a bridge and a dangling veth, also closes a race. A client started before its gateway can have its gateway and LAN settings (<code>--gateway-net</code>, <code>--host-bridge</code>, …) edited before the gateway comes up, and the gateway then wires each client from that client's <em>current</em> config, never a stale one.</p>
494-
<p>There is exactly <strong>one actor</strong> (the gateway) doing the wiring, so there is nothing to poll and no thundering herd. Wiring is serialised per segment with an advisory file lock, so concurrent client starts and the gateway's re-wire cannot race. Both <code>eth1</code> (gateway side) and each <code>eth0</code> (client side) keep a <strong>stable MAC</strong> and are moved and renamed into their namespace in one atomic step, so the container's own <code>netifd</code>/DHCP sees one persistent device instead of one that keeps being re-created.</p>
494+
<p>There is exactly <strong>one actor</strong> (the gateway) doing the wiring, so there is nothing to poll and no thundering herd. Wiring is serialised per segment with an advisory file lock, so concurrent client starts and the gateway's re-wire cannot race. Both <code>eth1</code> (gateway side) and each <code>eth0</code> (client side) keep a <strong>stable MAC</strong> and are created inside their namespace under their final name, in the one request that creates the pair. Nothing is moved or renamed afterwards: a rename is announced by the kernel before the device can be looked up by its new name, and a <code>netifd</code> inside the gateway that hears the announcement first fails to claim the device for good (seen on a 4.14 kernel, where that gap is tens of milliseconds).</p>
495495
<h3 id="what-happens-when-containers-stop">What happens when containers stop <a class="header-anchor" href="#what-happens-when-containers-stop">#</a></h3>
496496
<p>Cleanup in gateway mode is deliberately minimal, in line with &quot;plumbing only&quot;:</p>
497497
<ul>
@@ -568,7 +568,7 @@ <h3 id="what---gateway-net-does">What --gateway-net does <a class="header-anchor
568568
<p>Inside OpenWRT, the <code>lan</code> clients arrive on <code>eth1</code> and the <code>vpn</code> clients on <code>eth2</code>. Each segment gets its own veth, because <code>openwrt:lan</code> and <code>openwrt:vpn</code> hash differently.</p>
569569
<h3 id="what---gateway-iface-does">What --gateway-iface does <a class="header-anchor" href="#what---gateway-iface-does">#</a></h3>
570570
<p>This sets <strong>the name of the LAN interface inside the gateway container's network namespace</strong>.</p>
571-
<p>When Droidspaces creates the gateway veth for a segment, it moves one end into OpenWRT's netns and renames it from its raw hash name (<code>ds-hXXXXXXXX</code>) to the name you pass here (default <code>eth1</code>).</p>
571+
<p>When Droidspaces creates the gateway veth for a segment, the gateway's end is born directly inside OpenWRT's netns under the name you pass here (default <code>eth1</code>); only the host end carries a hash name (<code>ds-gXXXXXXXX</code>).</p>
572572
<p><strong>Why it matters:</strong> OpenWRT's configuration is keyed on interface names. If your OpenWRT <code>/etc/config/network</code> says:</p>
573573
<div class="code-block"><button class="icon-button copy-btn" onclick="copyCode(this)" aria-label="Copy"><span class="icon" aria-hidden="true">content_copy</span></button><pre><code>config interface &#x27;lan&#x27;
574574
option device &#x27;eth1&#x27;

‎docs/search.json‎

Lines changed: 1 addition & 1 deletion
Large diffs are not rendered by default.

‎index.html‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ <h1>A homelab that keeps running when the power cuts.</h1>
127127
<a href="/downloads.html" class="button button-filled"><span class="icon" aria-hidden="true">download</span>Download</a>
128128
<a href="/docs/" class="button button-outlined"><span class="icon" aria-hidden="true">menu_book</span>Documentation</a>
129129
</div>
130-
<p class="body-md">Release <span data-version>v6.6.0</span>, GPLv3. <span data-stars>2,278</span> stars and <span data-contributors>89</span> contributors <a href="https://github.com/ravindu644/Droidspaces-OSS" rel="noopener noreferrer">on GitHub</a>.</p>
130+
<p class="body-md">Release <span data-version>v6.6.0</span>, GPLv3. <span data-stars>2,288</span> stars and <span data-contributors>89</span> contributors <a href="https://github.com/ravindu644/Droidspaces-OSS" rel="noopener noreferrer">on GitHub</a>.</p>
131131
</div>
132132
<div class="stage">
133133
<div class="shape arrive" style="--shape: url(/assets/shapes/cookie-12.svg)"></div>

0 commit comments

Comments
 (0)