<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Linux Server and Sysadmin &#8211; Yuanle&#039;s Blog</title>
	<atom:link href="https://blog2.emacsos.com/category/linux-server-and-sysadmin/feed" rel="self" type="application/rss+xml" />
	<link>https://blog2.emacsos.com</link>
	<description></description>
	<lastBuildDate>Sun, 14 Dec 2025 07:18:11 +0000</lastBuildDate>
	<language>en-US</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://blog2.emacsos.com/wp-content/uploads/2025/05/favicon-150x150.png</url>
	<title>Linux Server and Sysadmin &#8211; Yuanle&#039;s Blog</title>
	<link>https://blog2.emacsos.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>How to Build Kernel Module for CP2102 Serial Module</title>
		<link>https://blog2.emacsos.com/how-to-build-kernel-module-for-cp2102-serial-module.html</link>
		
		<dc:creator><![CDATA[sylecn]]></dc:creator>
		<pubDate>Sun, 14 Dec 2025 07:12:04 +0000</pubDate>
				<category><![CDATA[OpenWrt]]></category>
		<guid isPermaLink="false">https://blog2.emacsos.com/?p=120</guid>

					<description><![CDATA[Some CP2102 device is recognized as &#8220;VeriFone Inc Verifone USB to Modem&#8221;, doesn&#8217;t register Serial support. It&#8217;s hardware driver issue. [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Some CP2102 device is recognized as &#8220;VeriFone Inc Verifone USB to Modem&#8221;, doesn&#8217;t register Serial support. It&#8217;s hardware driver issue. You can build a new cp210x module to solve this issue.</p>



<h2 class="wp-block-heading">Get kernel source code</h2>



<p>I use Linux mainline kernel source. My Debian has 6.12.12 kernel.</p>



<pre class="wp-block-code"><code>wget https://mirror.nju.edu.cn/kernel.org/linux/kernel/v6.x/linux-6.12.12.tar.xz</code></pre>



<p>unpack to ~/fromsource/linux-6.12.12/</p>



<p>I think the debian source pkg should also work.</p>



<h2 class="wp-block-heading">Modify the cp210x driver&#8217;s source code</h2>



<p>You need to add support for your device in the source code. First get the USB vendor ID and product ID. You can get it from kernel log (<code>journalctl -k |tail</code>) or <code>lsusb </code>command. Kernel log is usually like &#8220;idVendor=11ca, idProduct=0211, bcdDevice=1.00&#8221;, lsusb output is like &#8220;Bus 007 Device 005: ID 11ca:0211 VeriFone Inc Verifone USB to Modem&#8221;. In my example, vendor ID is 11ca, product ID is 0211. Now you need to modify the source code at <code>~/fromsource/linux-6.12.12/drivers/usb/serial/cp210x.c</code></p>



<p>add<br><code>{ USB_DEVICE(0x11CA, 0x0211) },</code></p>



<p>between all those device vendor ID, product ID lines.</p>



<h2 class="wp-block-heading">Build the cp210x module</h2>



<p>Install some dependencies: pahole and resolve_btfids.</p>



<p>sudo apt install pahole libelf-dev</p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
cd ~/fromsource/linux-6.12.12/
cd ./tools/bpf/resolve_btfids
make
ls -l resolve_btfids
sudo mkdir -p /usr/src/linux-headers-`uname -r`/tools/bpf/resolve_btfids
sudo ln -s $(realpath resolve_btfids) /usr/src/linux-headers-`uname -r`/tools/bpf/resolve_btfids
</pre></div>


<p>To avoid Skipping BTF generation for xxx Error:</p>



<pre class="wp-block-code"><code>sudo cp /sys/kernel/btf/vmlinux /usr/lib/modules/`uname -r`/build/</code></pre>



<p>Now it&#8217;s time to build the cp210x kernel module.</p>



<pre class="wp-block-code"><code>cd ~/fromsource/linux-6.12.12/drivers/usb/serial/
make -C /lib/modules/`uname -r`/build M=$PWD
ls -l cp210x.ko</code></pre>



<h2 class="wp-block-heading">Install and load cp210x module</h2>



<pre class="wp-block-code"><code># install cp210x
sudo cp usbserial.ko /lib/modules/`uname -r`/kernel/drivers/usb/serial/usbserial.ko
sudo cp cp210x.ko /lib/modules/`uname -r`/kernel/drivers/usb/serial/cp210x.ko
# you must update module dependency map after cp new file to kernel
# module dir. otherwise, you will get "unknown symbol in module" error.
sudo depmod -a

# load cp210x
sudo modprobe cp210x</code></pre>



<p>Now plugin your device, you should have /dev/ttyUSB0</p>



<p>In kernel log you should see</p>



<pre class="wp-block-code"><code>Nov 29 00:25:26 agem10.dev.emacsos.com kernel: usbcore: registered new interface driver usbserial_generic
Nov 29 00:25:26 agem10.dev.emacsos.com kernel: usbserial: USB Serial support registered for generic
Nov 29 00:25:28 agem10.dev.emacsos.com kernel: usbcore: registered new interface driver cp210x
Nov 29 00:25:28 agem10.dev.emacsos.com kernel: usbserial: USB Serial support registered for cp210x
Nov 29 00:25:28 agem10.dev.emacsos.com kernel: cp210x 7-1.2:1.0: cp210x converter detected
Nov 29 00:25:28 agem10.dev.emacsos.com kernel: usb 7-1.2: cp210x converter now attached to ttyUSB0</code></pre>



<p>Now the device is fully working.</p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Qihoo 360T7 UART TTL Flash OpenWRT Guide</title>
		<link>https://blog2.emacsos.com/qihoo-360t7-uart-ttl-flash-openwrt-guide.html</link>
		
		<dc:creator><![CDATA[sylecn]]></dc:creator>
		<pubDate>Sun, 14 Dec 2025 06:36:37 +0000</pubDate>
				<category><![CDATA[OpenWrt]]></category>
		<guid isPermaLink="false">https://blog2.emacsos.com/?p=110</guid>

					<description><![CDATA[Qihoo 360T7 is one of the routers that uses MediaTek MT7981B SoC (System-On-Chip). It is a WiFi-6 router with 128M [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Qihoo 360T7 is one of the routers that uses MediaTek MT7981B SoC (System-On-Chip). It is a WiFi-6 router with 128M flash and 256MB RAM. It has good performance and is very affordable. The stock firmware runs an old version of OpenWRT. To get latest security patch and features, this guide shows you how to flash latest OpenWRT on the device.</p>



<h2 class="wp-block-heading">Before You Start</h2>



<p>Before you try to access the UART via TTL, check whether telnet is enabled on the current firmware. If telnet is enabled, you don&#8217;t need to use UART. Also check if a 3rd party u-boot is installed on the device. If it is, you don&#8217;t need to use UART.</p>



<p>Check your USB TTL device is working properly. Plug in your device, you should see /dev/ttyUSB0 shown up in your device tree. In my case, I use a CP2102 USB device, I need to build my own kernel module for it to work.</p>



<p>Get latest OpenWRT files for this device. You can find them at <a href="https://firmware-selector.openwrt.org/">https://firmware-selector.openwrt.org/</a>, type in 360t7, the files will show up. You need the SYSUPGRADE, PRELOADER.BIN, BL31-UBOOT.FIP files.</p>



<h2 class="wp-block-heading">Connect the UART TTL Cables</h2>



<p>It is possible to connect 3 cables to the device without opening the case. Put the device on the table, face down. Put antenna on the left side, put RJ45 sockets on the right side. Put a cellphone flashlight on the back of the device, adjust the flashlight spotlight so you can see 4 holes on the board. The first hole is square; the rest are circles. Ignore the first hole, the remaining 3 circle holes are GND, TX, RX. You need to connect them to your TTL device&#8217;s GND, RX, TX.</p>



<p>Get 3 thin metal wire. Those used to fasten charging cables works fine. Remove the outside of the wire. Fold them to Z shape so they can be insert to the 360t7 device through the louver holes on the case. Use tape to fix each wire once they are in position. Connect all 3 wires to duPont wire on your USB TTL device. GND-GND, TX-RX, RX-TX.</p>



<h2 class="wp-block-heading">Prepare Terminal to Connect to Serial</h2>



<p>On Linux, install minicom package. Run minicom with</p>



<pre class="wp-block-code"><code>sudo minicom -D /dev/ttyUSB0</code></pre>



<p>Configure minicom by pressing <code>Ctrl-A O</code></p>


<div class="wp-block-syntaxhighlighter-code "><pre class="brush: plain; title: ; notranslate">
 Serial port setup
 F - Hardware Flow Control
 G - Software Flow Control
</pre></div>


<p>Make sure both says No. Otherwise, keyboard input won&#8217;t work.</p>



<p>Save this configure as default in <code>Ctrl-A O</code> menu. Otherwise, each time you start minicom, you need to config this again.</p>



<h2 class="wp-block-heading">Go To OpenWRT Failsafe Mode</h2>



<p>With minicom running, all cables connected, now connect power cable to boot your device. You should see u-boot and kernel output in minicom terminal. After kernel boot, wait for 3s, then press F and Enter key repeatedly to enter failsafe mode.</p>



<p>If you never saw failsafe mode text prompt, let the router boot normally, then flash <code>360T7-v4.2.4.7959_upgrade.bin</code> in stock firmware web UI. In newer firmware, failsafe mode is disabled, revert to this older version to allow OpenWRT failsafe mode.</p>



<h2 class="wp-block-heading">Enable Telnet and Set Root Password in Failsafe Mode</h2>



<p>Once you get to failsafe mode root shell, run these commands:</p>



<pre class="wp-block-code"><code>fw_setenv bootmenu_delay 3
mount_root
# Enable telnet service
sed -i 's/.*local debug=.*/\tlocal debug=1/' /etc/init.d/telnet
# Set password for root, type a password of your choice twice.
passwd root
cat /proc/mtd
# you should see stock Qihoo 360t7 layout.</code></pre>



<pre class="wp-block-code"><code>root@(none):/# cat /proc/mtd
dev:    size   erasesize  name
mtd0: 08000000 00020000 "spi0.0"
mtd1: 00100000 00020000 "bl2"
mtd2: 00080000 00020000 "u-boot-env"
mtd3: 00200000 00020000 "Factory"
mtd4: 00200000 00020000 "fip"
mtd5: 02400000 00020000 "ubi"
mtd6: 02400000 00020000 "firmware-1"
mtd7: 02400000 00020000 "plugin"
mtd8: 00100000 00020000 "config"
mtd9: 00080000 00020000 "factory"
mtd10: 00700000 00020000 "log"</code></pre>



<p>Run &#8220;reboot&#8221; to reboot the device. Now you should use stock u-boot menu. You can use u-boot menu to flash u-boot and firmware, or you can do it in telnet session after the device is fully boot. I choose to use u-boot menu.</p>



<p>On u-boot menu, select &#8220;Upgrade ATF BL2&#8221;, serve OpenWRT preloader.bin via TFTP. Run mtkautoboot to show u-boot menu again.</p>



<p>Select &#8220;Upgrade ATF FIP&#8221;, serve OpenWRT bl31-uboot.fip via TFTP. Run &#8220;reset&#8221; to reboot device. Now you should see OpenWRT&#8217;s u-boot menu. It is different than stock u-boot menu.</p>



<pre class="wp-block-code"><code>  ( ( ( OpenWrt ) ) )       U-Boot 2024.10-OpenWrt-r28872-daca7c049b (Sep 19 20

1. Run default boot command.
2. Boot system via TFTP.
3. Boot production system from NAND.
4. Boot recovery system from NAND.
5. Load production system via TFTP then write to NAND.
6. Load recovery system via TFTP then write to NAND.
7. Load BL31+U-Boot FIP via TFTP then write to NAND.
8. Load BL2 preloader via TFTP then write to NAND.
9. Reboot.
a. Reset all settings to factory defaults.
0. Exit

Press UP/DOWN to move, ENTER to select, ESC to quit</code></pre>



<h2 class="wp-block-heading">Flash OpenWRT</h2>



<p>On Linux computer, serve <code>openwrt-mediatek-filogic-qihoo_360t7-initramfs-recovery.itb</code> via 192.168.1.254 TFTP server. In OpenWRT u-boot menu, select &#8220;Boot system via TFTP.&#8221; It will boot to OpenWRT initramfs-recovery. When initramfs-recovery boots, use ssh or luci to flash OpenWRT sysupgrade image.</p>



<p>After that, router will auto reboot, you will have latest OpenWRT running on Qihoo 360T7.</p>



<p></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>How to write to a protected FIP partition in openwrt?</title>
		<link>https://blog2.emacsos.com/how-to-write-to-a-protected-fip-partition-in-openwrt.html</link>
		
		<dc:creator><![CDATA[sylecn]]></dc:creator>
		<pubDate>Sat, 21 Jun 2025 09:58:03 +0000</pubDate>
				<category><![CDATA[OpenWrt]]></category>
		<guid isPermaLink="false">https://blog2.emacsos.com/?p=102</guid>

					<description><![CDATA[When you try to write u-boot image to a partition, sometimes you get this error msg: You may use this [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>When you try to write u-boot image to a partition, sometimes you get this error msg:</p>



<pre class="wp-block-code"><code>Could not open mtd device: fip
Can't open device for writing!</code></pre>



<p>You may use this trick to allow write to the FIP and other MTD partitions.</p>



<pre class="wp-block-code"><code>opkg update
opkg install kmod-mtd-rw

insmod /lib/modules/$(uname -r)/mtd-rw.ko i_want_a_brick=1
# the i_want_a_brick=1 part is required! Otherwise, the command will fail.</code></pre>



<p>Now you can run the mtd write command again.</p>



<p>If write still fail, make sure the partition name is correct. The partition name is case sensitive. You can check the partition name using</p>



<pre class="wp-block-code"><code>cat /proc/mtd</code></pre>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Linux IPv6 debug checklist</title>
		<link>https://blog2.emacsos.com/linux-ipv6-debug-checklist.html</link>
		
		<dc:creator><![CDATA[sylecn]]></dc:creator>
		<pubDate>Tue, 13 May 2025 03:31:08 +0000</pubDate>
				<category><![CDATA[Linux Server and Sysadmin]]></category>
		<category><![CDATA[IPv6]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[network]]></category>
		<category><![CDATA[sysadmin]]></category>
		<guid isPermaLink="false">https://blog2.emacsos.com/?p=82</guid>

					<description><![CDATA[If IPv6 is not working properly in Linux, here are steps you can follow to debug the issue. check kernel [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>If IPv6 is not working properly in Linux, here are steps you can follow to debug the issue.</p>



<h2 class="wp-block-heading">check kernel boot param</h2>



<ol class="wp-block-list"></ol>



<p>Check these two files</p>



<pre class="wp-block-code"><code>cat /proc/cmdline
cat /etc/default/grub</code></pre>



<p>If <code>ipv6.disable=1</code> is set, the kernel IPv6 stack will be disabled. If <code>ipv6.disable_ipv6=1</code> is set, the kernel keeps the IPv6 stack functional but will not assign IPv6 addresses to any of your network devices.</p>



<p>Make sure you do not use any of these kernel options if you want to use IPv6.</p>



<h2 class="wp-block-heading">check interface disable_ipv6 settings</h2>



<pre class="wp-block-code"><code>sysctl net.ipv6.conf.lo.disable_ipv6
sysctl net.ipv6.conf.eno1.disable_ipv6
# -r list all values matching this pattern
sysctl -r 'net.ipv6.conf.*.disable_ipv6' net.ipv6.conf</code></pre>



<p>Make sure all of the interfaces that you want to have ipv6 enabled has <code>disable_ipv6=0</code>. Specifically, you SHOULD also enable ipv6 on <code>lo</code> interface. You should also enable IPv6 on Linux bridge and the physical interface that it is connected to.</p>



<h2 class="wp-block-heading">check interface RA settings if you use SLAAC</h2>



<p>RA stands for router advertisement. It is a broadcast packet that allow configuration of IP address and routing. SLAAC relies on RA to work.</p>



<pre class="wp-block-code"><code>sysctl net.ipv6.conf.all.accept_ra
# replace vmbr0 with your interface
sysctl net.ipv6.conf.vmbr0.accept_ra</code></pre>



<p>It should be 1 or 2 depending on your device.<br>If it&#8217;s 0, you need to set this at boot time. e.g. in <code>/etc/network/interfaces</code></p>



<p><a href="https://www.kernel.org/doc/html/latest/networking/ip-sysctl.html">To learn more about <code>accept_ra</code> param, see Linux kernel document.</a> Search <code>accept_ra</code> in that page.</p>



<p>For example, on one of my promox VE node, I have</p>



<pre class="wp-block-code"><code>auto vmbr0
iface vmbr0 inet static
        address 192.168.2.47/24
        gateway 192.168.2.1
        bridge-ports eno1
        bridge-stp off
        bridge-fd 0
iface vmbr0 inet6 auto
        accept_ra 2</code></pre>



<p>If you doubt whether RA is working properly, run <code>tcpdump</code> to capture the packet and view it in wireshark.</p>



<pre class="wp-block-code"><code># replace INTERFACE with your interface name
sudo tcpdump -i INTERFACE -w /tmp/ra_packets.pcap 'icmp6 and (ip6&#91;40] = 134 or ip6&#91;40] = 133)'</code></pre>



<h2 class="wp-block-heading">check lo ip6-loopback ping</h2>



<pre class="wp-block-code"><code>ping6 ::1<br>ping6 ip6-loopback</code></pre>



<h2 class="wp-block-heading">check local hostname is ipv6 resolvable</h2>



<p>in <code>/etc/hosts</code><br>::1 entry should include your fqdn</p>



<h2 class="wp-block-heading">check whether ipv6 address is assigned on interface</h2>



<pre class="wp-block-code"><code>ip -6 a<br>ip -6 a vmbr0</code></pre>



<p>If your IPv6 network use <a href="https://howdoesinternetwork.com/2013/slaac">SLAAC</a>, IP address should be assigned automatically. One interface usually has one public IPv6 address (starts with <code>2x:xx:xx</code>) and more than one private IPv6 address (starts with <code>fx:xx:xx</code>).</p>



<p>If your IPv6 network use DHCPv6 only, you should config DHCP in <code>/etc/network/interface</code> or corresponding RHEL config file or Network Manager config file. To just test DHCPv6 is working, you can run:</p>



<pre class="wp-block-code"><code>dhclient -6 INTERFACE</code></pre>



<h2 class="wp-block-heading">check ipv6 routes is added</h2>



<pre class="wp-block-code"><code>ip -6 r
ip -6 r | grep default</code></pre>



<p>IPv6 routes are added by clients via RA (router advertisement).</p>



<p>Make sure the default route either has no expire field or has a good expire field. In <a href="https://openwrt.org/">openwrt</a> default config, default route expire should be between 1200s and 1800s. If it&#8217;s less than 1200s, RA is not properly received and processed by host.</p>



<p>In some home server, if you enable IPv6 on IPMI/SBC/iLO/iDrac and use the shared network port, host OS will no longer receive the RA packet. You may see low expire on default route or missing a default route. In that case, you should disable IPv6 on IPMI.</p>



<h2 class="wp-block-heading">check IPv6 neighbors for nodes in the same LAN</h2>



<pre class="wp-block-code"><code>ip -6 n show|grep -v -E '(FAILED|STALE)'</code></pre>



<p>At least one router should be listed when IPv6 is working. You can compare results on different nodes in the same LAN.</p>



<h2 class="wp-block-heading">check you can visit other IPv6 nodes on the Internet</h2>



<pre class="wp-block-code"><code>ping6 aliyun.com
curl -6 https://aliyun.com
curl -I -6 https://mirrors.tuna.tsinghua.edu.cn/
# test whether your OS prefer IPv6 or IPv4 when both are available
curl test.ipw.cn</code></pre>



<p></p>
]]></content:encoded>
					
		
		
			</item>
		<item>
		<title>Why I Choose Debian Over Ubuntu, Arch Linux, Gentoo, FreeBSD</title>
		<link>https://blog2.emacsos.com/why-debian.html</link>
		
		<dc:creator><![CDATA[sylecn]]></dc:creator>
		<pubDate>Sun, 21 Aug 2016 03:30:00 +0000</pubDate>
				<category><![CDATA[Linux Server and Sysadmin]]></category>
		<category><![CDATA[Linux]]></category>
		<guid isPermaLink="false">https://blog2.emacsos.com/?p=89</guid>

					<description><![CDATA[Debian is my favorite Linux distro, as you may already know from my technology radar. In this post, I will [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p><a href="https://www.debian.org/" target="_blank" rel="noreferrer noopener">Debian</a> is my favorite Linux distro, as you may already know from <a href="https://blog.emacsos.com/tech-radar.html" target="_blank" rel="noreferrer noopener">my technology radar</a>. In this post, I will tell you what features I need in a distro and why I choose Debian. Note that all distros in title are good ones, that&#8217;s why I list them for comparison.</p>



<p>Of the choices in title, I have used Ubuntu, Debian and FreeBSD. I had evaluated Arch Linux and Gentoo to a great extend and decide not to use them. I have started to use Linux since around 2005. The first distros that got me interested in Linux was Red Hat Linux 9 and Fedora Core 4. I remember the days when I burned Fedora Core 4 and Ubuntu 6.10 CDs and gave them to others when I was in college. And Ubuntu sent free CDs with free shipping all over the world at that time.</p>



<p>Without further ado, let&#8217;s talk about features I care in Linux distro.</p>



<h2 class="wp-block-heading" id="sec-1">Stable Release Instead of Rolling Release</h2>



<p>Actually rolling release means no release at all. In stable release, the kernel and package are tested, work together well and the feature set is frozen. Security or critical bug fix patches are provided without breaking backward compatibility. Stable release also means there is a documented process of upgrading old release to a new one. All backward incompatible changes are well documented.</p>



<p>Using a stable release doesn&#8217;t mean you have to stick with old versions of software. You can always compile the software you do want. For example, I used to compile <a href="http://www.mplayerhq.hu/" target="_blank" rel="noreferrer noopener">mplayer</a> and <a href="https://www.gnu.org/software/emacs/" target="_blank" rel="noreferrer noopener">Emacs</a> in Debian stable. Some software encourage you to use an official build, such as <a href="https://www.bugzilla.org/" target="_blank" rel="noreferrer noopener">bugzilla</a>. Some software have latest build maintained for Debian stable, such as <a href="https://www.postgresql.org/" target="_blank" rel="noreferrer noopener">postgresql</a>. You are definitely not constrained by the software version that is in Debian stable&#8217;s apt repository. A stable release will make sure the underlying system and library is solid, if you want to get latest applications, go ahead. On the Linux desktop, <a href="https://appimage.org/" target="_blank" rel="noreferrer noopener">AppImage</a> and <a href="https://flatpak.org/" target="_blank" rel="noreferrer noopener">Flatpak</a> is also becoming more popular. If you want to get <a href="https://obsproject.com/download#linux" target="_blank" rel="noreferrer noopener">OBS</a> or <a href="https://www.digikam.org/download/" target="_blank" rel="noreferrer noopener">DigiKam</a>, there is a build for any Linux. Personally I still prefer OS native builds though.</p>



<p>If you want to learn more about how a stable release is made. Read <a href="https://release.debian.org/" target="_blank" rel="noreferrer noopener">Debian Release Management</a> or <a href="https://www.freebsd.org/doc/en/articles/releng/index.html" target="_blank" rel="noreferrer noopener">FreeBSD&#8217;s release engineering</a>. If you are a developer or project manager, you know making a good release is hard.</p>



<p>This rules out Arch Linux, which is a rolling release. Rolling release doesn&#8217;t mean install once and upgrade forever. It&#8217;s more like every package may break at every upgrade. You need to test software you use in a stage environment by yourself if you don&#8217;t want surprises. This also rules out Ubuntu non-LTS releases. I don&#8217;t call it a release anymore.</p>



<h2 class="wp-block-heading" id="sec-2">Binary Packages Instead of Source Packages</h2>



<p>Unless you only use a fixed set of packages and rarely upgrade them, binary packages will greatly simplify and speed up software installation. Even if you have a fairly powerful machine, it still cause great pain if a low level library requires an update, which triggers a chain of recompiles. I was bitten by this once while I was using FreeBSD. For some dedicated web or database server, this may not be a big problem.</p>



<p>A side note for python developers. Since this year (2016), most <a href="https://pypi.python.org/pypi" target="_blank" rel="noreferrer noopener">PyPI packages</a> are in wheel binary format, which makes installing faster and easier. It&#8217;s amazing that <a href="https://m.reddit.com/r/Python/comments/4jaaib/pypi_download_stats_have_stopped_working_again/d355dt6" target="_blank" rel="noreferrer noopener">PyPI is developed and maintained by a single person</a>.</p>



<p>This rules out Gentoo and FreeBSD ports.</p>



<h2 class="wp-block-heading" id="sec-3">Large Selection of Software and Large User Base</h2>



<p>The core team should maintain a large selection of software, so if there are problems, they can be exposed and handled inside the project. Large user base means if you hit a problem, it&#8217;s likely there is already a fix or a workaround.</p>



<p>This rules out FreeBSD. Its binary package system is not as sophisticated as Debian&#8217;s. Binary packages and ports are not part of the official release.</p>



<p>Edit: In 2025, FreeBSD 14 offers significantly more binary packages than it did in 2016. If your hardware runs well on FreeBSD and you don&#8217;t need any Linux-only non-free software, you should give FreeBSD a try.</p>



<h2 class="wp-block-heading" id="sec-4">Worldwide Mirrors for Packages</h2>



<p>This will speed up operating system install and upgrade, and package install greatly.</p>



<h2 class="wp-block-heading" id="sec-5">Honor Mentions About Other Distro</h2>



<p>RedHat Enterprise Linux (RHEL)/Oracle Linux/Amazon Linux, Ubuntu LTS, OpenSUSE.</p>



<p>RHEL is very similar to Debian, if you prefer RedHat&#8217;s way of doing things, they are good choices. Also, RHEL has the best documentation between RHEL, Ubuntu and Debian. The document quality order from high to low is RHEL, Debian, Ubuntu. You do need to register an account to view most of the documents though.</p>



<p>Oracle Linux and Amazon Linux are derived from RHEL (or CentOS-stream, Fedora). If you run on <a href="https://www.oracle.com/cloud/" target="_blank" rel="noreferrer noopener">Oracle Cloud</a> or <a href="https://aws.amazon.com/" target="_blank" rel="noreferrer noopener">AWS</a>, you may use these flavors. They behave similarly to RHEL and do not require a paid license to use. In comparison, the RHEL does require a license to use in mass production. There is a <a href="https://developers.redhat.com/articles/faqs-no-cost-red-hat-enterprise-linux" target="_blank" rel="noreferrer noopener">no-cost RHEL developer license</a> that you can use in development environment and small production environment. There are a few community versions of RHEL re-pack when CentOS is acquired and discontinued by RedHat, such as <a href="https://rockylinux.org/" target="_blank" rel="noreferrer noopener">RockyLinux</a> and <a href="https://almalinux.org/" data-type="link" data-id="https://almalinux.org/" target="_blank" rel="noreferrer noopener">AlmaLinux</a>. The offer binary compatibility with RHEL. But the default dnf repo and management tools are not all the same.</p>



<p>Ubuntu LTS, although the release is not as good as Debian, does have a large user base and a long term support (LTS). That makes it a much better choice than Ubuntu non-LTS release. Ubuntu LTS also got commercial support if you needs that. I found Ubuntu&#8217;s release not as stable as Debian. That&#8217;s why I always choose Debian over Ubuntu LTS. Only choose Ubuntu LTS only if you want to purchase support from <a href="https://canonical.com/" target="_blank" rel="noreferrer noopener">Canonical</a>.</p>



<p>I have not used OpenSUSE for real, so I won&#8217;t remark on them. Based on short experience of OpenSUSE Leap, the installer is very enterprisy. Side note: I think <a href="https://openbuildservice.org/" target="_blank" rel="noreferrer noopener">Open Build Service</a> (e.g. <a href="https://build.opensuse.org/" target="_blank" rel="noreferrer noopener">OpenSUSE OBS</a>) is a cool project, which works for all Linux projects and distros. But I haven&#8217;t tried it yet.</p>



<p>Edit: CentOS is acquired by RedHat and <a href="https://blog.centos.org/2020/12/future-is-centos-stream/" target="_blank" rel="noreferrer noopener">rebrand to CentOS stream</a>. Added notes on Oracle Linux, Amazon Linux and some CentOS remakes.</p>



<p>If you need advice on choosing a Linux distro, you can leave a comment or email me. Do tell me what you want to do with Linux so the advice could be specific to your use case.</p>
]]></content:encoded>
					
		
		
			</item>
	</channel>
</rss>
