Skip to content

Topic archive

Linux

An open-source operating system ecosystem known for its flexibility, developer tooling, and widespread use on servers, cloud platforms, embedded devices, and workstations.

119 articles
Linux 28 Oct 2026 6 min read

Linux 7.3 on Fedora: Why Kernel, Modules, and Initramfs Must Match

Compiling Linux 7.3 produces a kernel image, but that image is only one part of a bootable Fedora installation. On a typical Fedora system, boot also depends on kernel modules, an initramfs assembled for the correct release, and a boot entry pointing to those artifacts. A mismatch can leave a perfectly compiled kernel unable to mount its root filesystem. This matters when using the upstream source from kernel.org rather than Fedora’s kernel RPMs. Fedora’s package installation normally coordinates several boot artifacts. A manual upstream build leaves that coordination to the administrator. The example below assumes an ordinary x86_64 Fedora installation managed with GRUB and grubby, not an rpm-ostree-based desktop.

Linux 26 Oct 2026 5 min read

Why Linux Filesystem Tools Report Different Types

A disk partition can contain an ext4 filesystem while a process sees an overlay filesystem at /. Meanwhile, /proc/filesystems may list tmpfs and nfs, neither of which needs a local partition. These are not conflicting answers. They describe different parts of the Linux storage stack. The distinction matters when identifying a volume, investigating an unexpected mount, or checking which filesystem handles an application’s path. A filesystem signature on a device is not the same thing as a mounted filesystem in a process’s namespace.

Linux 04 Oct 2026 4 min read

SO_REUSEPORT Splits One Listen Address Across Multiple Linux Sockets

A conventional server owns one listening socket for a local address and port. SO_REUSEPORT changes that ownership boundary: multiple eligible sockets can bind the same address, and Linux selects a member of the reuseport group when traffic arrives. The option is useful when several worker threads or processes should receive traffic without sharing one accept or receive queue. It changes kernel-side socket selection, not the transport protocol carried on the network.

Linux 03 Oct 2026 5 min read

SO_BUSY_POLL Trades CPU Time for Earlier Linux Socket Receive Processing

A blocking receive on Linux normally sleeps when no data is ready and resumes after the networking path makes data available. With SO_BUSY_POLL, the receive path may instead spend a bounded interval actively polling the relevant NAPI context for incoming packets. That interval exchanges CPU time for a chance to process an arrival before the ordinary interrupt-driven path wakes the task. The option does not turn a socket into a permanently polling endpoint. It supplies a busy-poll budget in microseconds, and the mechanism depends on receive history and network-device support.

Linux 26 Sep 2026 4 min read

Batch Resize Images with Bash and ImageMagick Without Overwriting Originals

A resize command is straightforward. Keeping a batch recoverable takes more care. Writing results over the source images can leave a collection only partly processed if a conversion fails. Flattening every result into one folder also creates collisions: events/photo.jpg and products/photo.jpg would have the same destination name. A separate output tree avoids both problems. The script below accepts a source directory, a destination directory, and a maximum edge length. It processes JPEG, PNG, and WebP files recursively, retains their relative paths and formats, and leaves the originals alone.

Linux 26 Sep 2026 5 min read

Batch Convert JPEG and PNG to WebP with Bash and cwebp

Two files named photo.jpg and photo.png in the same directory would both become photo.webp. A batch converter that notices the collision only after it starts encoding may leave one image unconverted or replace an earlier result. It is better to check the entire input list first. The Bash script here uses cwebp for encoding and keeps a separate output tree. Its default auto mode encodes JPEG with lossy WebP and PNG with lossless WebP. The source images stay in place; existing destination files are skipped.

Linux 23 Sep 2026 4 min read

TFD_TIMER_CANCEL_ON_SET Turns Realtime Clock Jumps into ECANCELED

An absolute timer tied to CLOCK_REALTIME has a dependency that a monotonic deadline does not: an administrator, synchronization service, or privileged process can move the wall clock discontinuously while the timer is armed. Linux timerfd can expose that event explicitly. With TFD_TIMER_ABSTIME | TFD_TIMER_CANCEL_ON_SET, a qualifying clock jump causes a current or later read() on the timer descriptor to fail with ECANCELED. This behavior separates two events that would otherwise be easy to conflate: reaching a scheduled wall-clock instant and invalidating the clock basis used to schedule it.

Linux 23 Sep 2026 4 min read

signalfd Consumes Blocked Signals Through File Descriptor Reads

signalfd Consumes Blocked Signals Through File Descriptor Reads signalfd() turns selected signal notifications into records that can be consumed with read(). A matching pending signal makes the descriptor readable, which allows signal handling to share the same poll(), select(), or epoll path as sockets, timers, and other descriptors. The descriptor does not redirect signals merely because its mask names them. Normal signal-mask rules still apply. In the usual design, the selected signals are blocked before they can be delivered through their ordinary dispositions, then a signalfd reads the pending instances.

Linux 23 Sep 2026 4 min read

PR_SET_PDEATHSIG Binds a Child Notification to Parent Thread Exit

PR_SET_PDEATHSIG Binds a Child Notification to Parent Thread Exit PR_SET_PDEATHSIG lets a Linux process request a signal when the thread that created it terminates. The mechanism is narrow: it is a kernel-delivered notification tied to a parental relationship, not a general process-lifetime contract and not a guarantee that two processes terminate together. That distinction matters in supervisors, launchers, and helper processes. A child can react to loss of its creator without polling a PID, but the exact parent identity, setup timing, inheritance rules, and credential transitions define where the mechanism stops.

Linux 23 Sep 2026 4 min read

pidfd_getfd Duplicates a Target Descriptor into the Calling Process

pidfd_getfd Duplicates a Target Descriptor into the Calling Process pidfd_getfd() can place a duplicate of another process’s open file descriptor into the caller’s descriptor table. The returned descriptor is local to the caller, but it refers to the same open file description as the selected descriptor in the target process. That distinction matters. This operation does not reopen a pathname, reconstruct a socket, or create an independent file position. It duplicates an existing kernel reference across a process boundary.

Linux 23 Sep 2026 5 min read

membarrier Private Expedited Orders Userspace Memory Across Threads

Linux membarrier() can move part of a synchronization cost from a frequently executed path to a less frequent coordination path. With MEMBARRIER_CMD_PRIVATE_EXPEDITED, one thread asks the kernel to establish a memory-ordering point across the running threads in the same process. The caller pays for the system call when coordination is needed instead of requiring every fast-path execution to carry an explicit hardware memory barrier. This is narrower than a general thread rendezvous. membarrier() does not run an application callback on sibling threads, does not wait for application-level acknowledgements, and does not turn ordinary data races into valid synchronization. Its contract concerns ordering of userspace memory accesses around the barrier.

Linux 23 Sep 2026 3 min read

MADV_WIPEONFORK Replaces Inherited Private Memory with Zeroes

MADV_WIPEONFORK Replaces Inherited Private Memory with Zeroes A normal fork() gives the child mappings derived from the parent’s address space, with private writable pages commonly handled through copy-on-write. MADV_WIPEONFORK changes that inheritance rule for a selected private anonymous range: the mapping remains present in the child, but its contents are zero-filled there. The parent keeps its existing bytes. The operation therefore changes child-visible memory at the process-creation boundary rather than erasing the parent’s range.

Linux 23 Sep 2026 4 min read

MADV_DONTFORK Excludes Memory Ranges from Child Address Spaces

MADV_DONTFORK changes a specific part of Linux process creation: a mapping marked with this advice is not made available in the child created by fork(). The parent keeps the mapping. The child starts without that address range, so an address that was valid there in the parent is not automatically valid in the child. This is a semantic control over mapping inheritance, not a cache hint. It belongs to the Linux-specific madvise() operations whose effects can change memory behavior.

Linux 23 Sep 2026 5 min read

fcntl OFD Locks Follow Open File Descriptions Instead of Processes

Traditional POSIX record locks have a property that can surprise code with several descriptors for the same file: lock ownership is associated with the process, and closing a descriptor for that file can release the process’s locks on it. Linux open file description locks move ownership to the kernel open file description referenced by a descriptor. The interface still uses fcntl() and struct flock, but the ownership boundary changes. F_OFD_SETLK, F_OFD_SETLKW, and F_OFD_GETLK make byte-range locking track the open file description rather than the process identity.

Linux 23 Sep 2026 5 min read

eventfd Semaphore Mode Turns Counter Values into Single-Unit Reads

Linux eventfd exposes a kernel-maintained 64-bit counter through a file descriptor. Its compact interface hides an important semantic choice: a normal read drains the current counter value, while an EFD_SEMAPHORE read consumes exactly one unit. The write path still adds values to the same counter. That distinction changes the object from an aggregate notification counter into a descriptor-backed source of individually consumable units. The readiness model remains compatible with poll, epoll, and related descriptor multiplexing, so the same object can connect producer accounting with an event loop without adding a separate pipe payload.

Linux 23 Sep 2026 4 min read

EPOLLEXCLUSIVE Limits Wakeups Across epoll Instances

EPOLLEXCLUSIVE Limits Wakeups Across epoll Instances EPOLLEXCLUSIVE changes event distribution when several epoll instances register the same target file description. Without the flag, a readiness event can wake waiters associated with every interested epoll instance. With exclusive registrations, Linux can restrict that fan-out and reduce redundant wakeups. The flag does not make delivery single-consumer, does not assign ownership of the target, and does not replace application-level coordination. Its contract is narrower: among epoll instances that registered a target with EPOLLEXCLUSIVE, one or more receive an event for a wakeup rather than requiring all of them to receive it.

Linux 23 Sep 2026 5 min read

close_range with UNSHARE Separates File Descriptor Cleanup from Peer Threads

A multithreaded Linux process can share one file descriptor table across its threads. That arrangement is convenient during normal execution: a descriptor opened by one thread becomes available to its peers. It becomes less convenient when one thread is preparing a restricted execution context and wants to discard a broad descriptor range without racing with peers that can still allocate descriptors. close_range() provides a range operation for this boundary. With CLOSE_RANGE_UNSHARE, the kernel first separates the caller from the shared descriptor table and then applies the requested closure to the caller’s resulting table. The operation is close to combining unshare(CLONE_FILES) with a range close, but the kernel can perform less work in common cases.

Linux 22 Sep 2026 5 min read

TFD_TIMER_CANCEL_ON_SET Reports Realtime Clock Discontinuities

A timerfd armed against wall-clock time can cross a discontinuous clock adjustment before its deadline. With TFD_TIMER_CANCEL_ON_SET, Linux exposes that event through the descriptor: a subsequent read() fails with ECANCELED rather than presenting the clock jump as an ordinary timer expiration. The flag is deliberately narrow. It applies only when timerfd_settime() arms an absolute timer on CLOCK_REALTIME or CLOCK_REALTIME_ALARM, and it changes the handling of discontinuous changes to those clocks.

Linux 22 Sep 2026 5 min read

SO_PEEK_OFF Gives UNIX Sockets a Stateful Peek Cursor

SO_PEEK_OFF Gives UNIX Sockets a Stateful Peek Cursor A normal recv(..., MSG_PEEK) examines data at the front of a socket receive queue without removing it. On Linux UNIX-domain sockets, SO_PEEK_OFF can replace that repeated front-of-queue view with a cursor that advances after each peek. The cursor is socket state. Peeking moves it forward, while consuming bytes from the front of the queue moves it backward by the amount removed. That interaction lets a process inspect successive queued regions without consuming them, while keeping the peek position tied to the remaining queue.

Linux 22 Sep 2026 6 min read

signalfd Turns Blocked Signals into Readable Events

Linux signals normally interrupt a thread through asynchronous delivery. signalfd() offers a different boundary for selected signals: keep them blocked in the relevant threads, then consume pending instances by reading a file descriptor. The signal mechanism itself does not become a byte stream. The kernel still maintains signal state and normal process- or thread-directed delivery rules. signalfd adds a file-descriptor interface for accepting signals from a configured set. Blocking and the descriptor mask are separate state A signalfd has a signal-set mask that selects which signals it can accept. That mask does not block those signals for a thread. Normal use therefore pairs descriptor creation with a signal mask operation.

Linux 22 Sep 2026 5 min read

EFD_SEMAPHORE Makes eventfd Reads Consume One Counter Unit

An eventfd normally turns its entire nonzero counter into one read result and resets the counter to zero. Creating it with EFD_SEMAPHORE changes only the read side: each successful read returns the 64-bit value 1 and subtracts one from the kernel-maintained counter. That difference lets several units accumulated by writers remain separately consumable. The object is still an eventfd, with the same counter, write rules, descriptor lifetime, and readiness integration.

Linux 21 Sep 2026 5 min read

openat2 Resolve Flags Constrain Path Traversal During Lookup

A pathname passed to openat() is resolved by the kernel, but the caller has limited control over traversal through intermediate components. Linux openat2() adds a resolve field that applies constraints to the complete lookup operation. The restriction is evaluated while components are traversed, rather than by validating a pathname in userspace and opening it later. That distinction matters when path components can change concurrently. A userspace sequence that checks a path and then opens it creates separate observations of mutable filesystem state. openat2() places the selected lookup policy in the same system call that returns the file descriptor.

Linux 21 Sep 2026 6 min read

memfd File Seals Freeze Shared Memory State

A memfd_create() file starts as a mutable anonymous file. It can be resized, written, and mapped much like a regular file, while its storage remains volatile and disappears after the last reference is released. File sealing adds a different phase to that lifecycle: after data has been populated, the kernel can permanently reject selected classes of later modification. That transition is useful when one process prepares bytes and then hands the same file description to another process. The receiver can inspect the seals attached to the inode instead of relying only on a convention that the sender will stop changing the object.

Linux 21 Sep 2026 6 min read

io_uring Multishot Accept Keeps One Accept Request Active

A normal accept request has a one-to-one shape: one submitted operation eventually yields one completion. io_uring multishot accept changes that relationship. A single accept SQE can remain active across multiple incoming connections and emit a separate completion queue entry for each accepted socket. The request is persistent, but not permanent. Each CQE carries enough state for the application to tell whether the original request can produce another completion. That boundary matters because a server that treats every successful CQE as proof that accept is still armed can silently stop accepting after the multishot request terminates.