Memo

共 19 条灌水 · 4

Fedora 44 的 RXE 无法注册 1 GiB MR

环境是 Fedora 44,内核 7.1.10-200.fc44.x86_64,RDMA 设备为 Soft-RoCE rxe0。注册 1 GiB memory region 时,ibv_reg_mr() 返回:

ibv_reg_mr(): Cannot allocate memory [12]

这不是 RLIMIT_MEMLOCK 或 ASan 导致的。测试进程的 memlock 为 unlimited,主机还有约 59 GB 可用内存;1 GiB MR 在 ASan 和非 ASan 下都失败。逐页写入和 MADV_POPULATE_WRITE 也不能解决。实测 512 MiB 位于临界点,640 MiB 以上稳定失败,但 rxe0 仍宣称:

max_mr_size: 0xffffffffffffffff

原因指向 RXE 的页面元数据分配。Linux 7.0 附近的 RDMA/rxe 修改把 xarray 换成预分配的 rxe_mr_page 数组:

mr->page_info = kzalloc_objs(struct rxe_mr_page, num_pages);

4 KiB page 下,1 GiB MR 有 262,144 个页面。struct rxe_mr_page 在 x86-64 上占 16 字节,数组约 4 MiB,并且要求物理连续的内核内存。512 MiB 对应约 2 MiB 元数据,正好落在临界区;640 MiB 对应约 2.5 MiB。这个边界与实测一致。

临时把测试 DMA pool 降到 256 MiB 后,ASan + rxe0 的 39 个启用 RDMA* 用例全部通过。这只能验证 RDMA 功能,不能覆盖生产规模的 1 GiB MR。正式处理应使用硬件 RNIC,或者把 RXE 的 kzalloc_objs() / kfree() 改为可回退到非连续内存的 kvcalloc() / kvfree()。应用层拆分 MR 也能绕开限制,但调用方需要管理多个 MR 和 lkey。

截至 2026-08-29,没有搜到相同的 Fedora kernel 报告。已有的 Bug 2014767 是缺少 RDMA_RXE 模块,Bug 2034556 是 RXE soft lockup,都不是大 MR 注册失败。

修正 ZFS 主机的 Node Exporter 内存告警

Node Exporter 只导出 /proc/meminfo,不计算内存使用率。Grafana 和 Prometheus 通常使用:

100 * (1 - node_memory_MemAvailable_bytes / node_memory_MemTotal_bytes)

Linux 计算 MemAvailable 时不会把 ZFS ARC 计入可回收页缓存。AMD GTT 使用系统内存,但进程 RSS 和 Pod working set 不会完整反映这部分分配。因此,topkubectl top 不能直接核对上述结果。

现场数据:ZFS ARC 43.2 GiB,AMD GTT 27.9 GiB,kubectl top node 42.3 GiB;原公式得到 94.2%。

检查相关数据:

free -h
grep -E '^(size|c_min) ' /proc/spl/kstat/zfs/arcstats
grep -H . /sys/class/drm/card*/device/mem_info_gtt_used
grep -H . /proc/pressure/memory

告警将高于 c_min 的 ARC 计为可回收内存。没有 ZFS 指标时,or ... * 0 回退到原公式:

(
  node_memory_MemAvailable_bytes
  + (
    clamp_min(node_zfs_arc_size - node_zfs_arc_c_min, 0)
    or node_memory_MemTotal_bytes * 0
  )
) / node_memory_MemTotal_bytes < 0.10

面板分别展示 effective used、ZFS ARC、Linux page cache、GPU GTT 和 swap used。amd_gpu_used_gtt 的单位是 MiB,与 Node Exporter 的字节指标合并时需乘 1024 * 1024

该口径用于减少 ARC 引起的误报。实际内存压力仍需检查 swap-out 和 memory PSI。

修复 Zig TSan 找不到 linux/scc.h

新版 Linux headers 上启用 Zig ThreadSanitizer,构建在项目代码编译前就失败:

error: sub-compilation of libtsan failed
lib/libtsan/sanitizer_common/sanitizer_platform_limits_posix.cpp:160:10:
error: 'linux/scc.h' file not found
#include <linux/scc.h>
         ^~~~~~~~~~~~~

不是项目代码的并发问题。Zig 的 -fsanitize-thread 首次构建时会从安装目录里的源码编译一份 ThreadSanitizer runtime,以 Zig 0.16.0 为例在 <zig-lib-dir>/libtsan/sanitizer_common/sanitizer_platform_limits_posix.cpp。这份 vendored libtsan 里有三行死代码:

#include <linux/scc.h>

unsigned struct_scc_modem_sz = sizeof(struct scc_modem);
unsigned struct_scc_stat_sz = sizeof(struct scc_stat);

Linux 内核删掉了废弃的 SCC amateur-radio 接口,linux/scc.h 也从 UAPI headers 里消失,滚动发行版先撞上。LLVM compiler-rt 已通过 #194116 移除这三处引用,但 Zig 用的是自己的快照,要等发布包同步才算修好。

补丁

仓库里建 .mise/tasks/fix/zig-tsan

#!/usr/bin/env bash
#MISE description="Patch Zig libtsan for Linux headers without linux/scc.h"
set -euo pipefail

if [ "$(uname -s)" != Linux ]; then
    echo "Zig libtsan scc.h patch is only needed on Linux"
    exit 0
fi

zig_exe=$(readlink -f "$(command -v zig)")
zig_lib_dir=${ZIG_LIB_DIR:-"$(dirname "$zig_exe")/lib"}
source_file="$zig_lib_dir/libtsan/sanitizer_common/sanitizer_platform_limits_posix.cpp"

if [ ! -f "$source_file" ]; then
    echo "error: Zig libtsan source not found: $source_file" >&2
    exit 1
fi

include='#include <linux/scc.h>'
modem='  unsigned struct_scc_modem_sz = sizeof(struct scc_modem);'
stats='  unsigned struct_scc_stat_sz = sizeof(struct scc_stat);'

remaining=0
for line in "$include" "$modem" "$stats"; do
    count=$(grep -Fxc "$line" "$source_file" || true)
    if [ "$count" -gt 1 ]; then
        echo "error: unexpected duplicate in Zig libtsan: $line" >&2
        exit 1
    fi
    remaining=$((remaining + count))
done

if [ "$remaining" -eq 0 ]; then
    echo "Zig $(zig version) libtsan is already compatible with current Linux headers"
    exit 0
fi

if [ "$remaining" -ne 3 ]; then
    echo "error: Zig libtsan is only partially compatible; refusing to modify it" >&2
    exit 1
fi
if [ ! -w "$source_file" ]; then
    echo "error: Zig libtsan source is not writable: $source_file" >&2
    exit 1
fi

sed -i \
    -e "\\|^$include\$|d" \
    -e "\\|^$modem\$|d" \
    -e "\\|^$stats\$|d" \
    "$source_file"

for line in "$include" "$modem" "$stats"; do
    if grep -Fxq "$line" "$source_file"; then
        echo "error: failed to remove obsolete Zig libtsan reference: $line" >&2
        exit 1
    fi
done

echo "Patched Zig $(zig version) libtsan: $source_file"
chmod +x .mise/tasks/fix/zig-tsan
mise run fix:zig-tsan

任务靠 command -v zigreadlink 定位 mise 当前选中的 Zig,不硬编码版本目录。三行目标代码必须各出现一次才动手:都在就补,都不在就输出 already compatible 直接退出,部分存在或重复则拒绝改。所以可以重复执行,Zig 同步上游修复后也不用删。

验证

清掉独立的 TSan 构建缓存,让 runtime 用修补后的源码重新编译:

rm -rf .zig-cache/tsan
mise run test:tsan

没有封装测试任务就重跑原来的 zig build,保留 -fsanitize-thread 或对应 build option。重新安装或切换 Zig 版本后 mise 会建新的工具链目录,需要再跑一次补丁。

参考

time-warp-test.c: check TSC synchronity on x86 CPUs

time-warp-test.c: check TSC synchronity on x86 CPUs. Also detects gettimeofday()-level time warps.

/*
* Copyright (C) 2005, Ingo Molnar
*
* time-warp-test.c: check TSC synchronity on x86 CPUs. Also detects
*                   gettimeofday()-level time warps.
*
* Compile with: gcc -Wall -O2 -o time-warp-test time-warp-test.c -lrt
*/
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <signal.h>
#include <sys/wait.h>
#include <linux/unistd.h>
#include <unistd.h>
#include <string.h>
#include <pwd.h>
#include <grp.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/time.h>
#include <regex.h>
#include <fcntl.h>
#include <time.h>
#include <sys/mman.h>
#include <dlfcn.h>
//#include <popt.h>
#include <sys/socket.h>
#include <ctype.h>
#include <assert.h>
#include <sched.h>
#include <time.h>

#define TEST_TSC 1
#define TEST_TOD 1
#define TEST_CLOCK 1

#if !TEST_TSC && !TEST_TOD && !TEST_CLOCK
# error this setting makes no sense ...
#endif

#if DEBUG
# define Printf(x...) printf(x)
#else
# define Printf(x...) do { } while (0)
#endif

/*
 * Shared locks and variables between the test tasks:
 */
enum {
    SHARED_LOCK     = 0,
    SHARED_TSC      = 2,
    SHARED_TOD      = 4,
    SHARED_CLOCK        = 6,
    SHARED_WORST_TSC    = 8,
    SHARED_WORST_TOD    = 10,
    SHARED_WORST_CLOCK  = 12,
    SHARED_NR_TSC_LOOPS = 14,
    SHARED_NR_TSC_WARPS = 16,
    SHARED_NR_TOD_LOOPS = 18,
    SHARED_NR_TOD_WARPS = 20,
    SHARED_NR_CLOCK_LOOPS   = 22,
    SHARED_NR_CLOCK_WARPS   = 24,
    SHARED_END      = 26,
};

#define SHARED(x)   (*(shared + SHARED_##x))
#define SHARED_LL(x)    (*(long long *)(shared + SHARED_##x))

#define BUG_ON(c) assert(!(c))

typedef unsigned long long cycles_t;
typedef unsigned long long usecs_t;
typedef unsigned long long u64;

#ifdef __x86_64__
#define DECLARE_ARGS(val, low, high)    unsigned low, high
#define EAX_EDX_VAL(val, low, high)     ((low) | ((u64)(high) << 32))
#define EAX_EDX_ARGS(val, low, high)    "a" (low), "d" (high)
#define EAX_EDX_RET(val, low, high)     "=a" (low), "=d" (high)
#else
#define DECLARE_ARGS(val, low, high)    unsigned long long val
#define EAX_EDX_VAL(val, low, high)     (val)
#define EAX_EDX_ARGS(val, low, high)    "A" (val)
#define EAX_EDX_RET(val, low, high)     "=A" (val)
#endif

static inline unsigned long long __rdtscll(void)
{
    DECLARE_ARGS(val, low, high);

    asm volatile("cpuid; rdtsc" : EAX_EDX_RET(val, low, high));

    return EAX_EDX_VAL(val, low, high);
}

#define rdtscll(val) do { (val) = __rdtscll(); } while (0)

#define rdtod(val)                  \
    do {                            \
        struct timeval tv;              \
        \
        gettimeofday(&tv, NULL);            \
        (val) = tv.tv_sec * 1000000ULL + tv.tv_usec;    \
    } while (0)

#define rdclock(val)                    \
    do {                            \
        struct timespec ts;             \
        \
        clock_gettime(CLOCK_MONOTONIC, &ts);        \
        (val) = ts.tv_sec * 1000000000ULL + ts.tv_nsec; \
    } while (0)

static unsigned long *setup_shared_var(void)
{
    char zerobuff [4096] = { 0, };
    int ret, fd;
    unsigned long *buf;

    fd = creat(".tmp_mmap", 0700);
    BUG_ON(fd == -1);
    close(fd);

    fd = open(".tmp_mmap", O_RDWR|O_CREAT|O_TRUNC);
    BUG_ON(fd == -1);
    ret = write(fd, zerobuff, 4096);
    BUG_ON(ret != 4096);

    buf = (void *)mmap(0, 4096, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
    BUG_ON(buf == (void *)-1);

    close(fd);
    unlink(".tmp_mmap");

    return buf;
}

static inline void lock(unsigned long *flag)
{
#if 0
    __asm__ __volatile__(
            "1: lock; btsl $0,%0\n"
            "jc 1b\n"
            : "=g"(*flag) : : "memory");
#else
    __asm__ __volatile__(
            "1: lock; btsl $0,%0\n\t"
            "jnc 3f\n"
            "2: testl $1,%0\n\t"
            "je 1b\n\t"
            "rep ; nop\n\t"
            "jmp 2b\n"
            "3:"
            : "+m"(*flag) : : "memory");
#endif
}

static inline void unlock(unsigned long *flag)
{
#if 0
    __asm__ __volatile__(
            "lock; btrl $0,%0\n"
            : "=g"(*flag) :: "memory");
    __asm__ __volatile__("rep; nop");
#else
    __asm__ __volatile__("mov $0,%0; rep; nop" : "=g"(*flag) :: "memory");
#endif
}

static void print_status(unsigned long *shared)
{
    const char progress[] = "\\|/-";

    static unsigned long long sum_tsc_loops, sum_tod_loops, sum_clock_loops,
                         sum_tod;
    static unsigned int count1, count2;
    static usecs_t prev_tod;

    usecs_t tod;

    if (!prev_tod)
        rdtod(prev_tod);

    count1++;
    if (count1 < 1000)
        return;
    count1 = 0;

    rdtod(tod);
    if (abs(tod - prev_tod) < 100000ULL)
        return;

    sum_tod += tod - prev_tod;
    sum_tsc_loops += SHARED_LL(NR_TSC_LOOPS);
    sum_tod_loops += SHARED_LL(NR_TOD_LOOPS);
    sum_clock_loops += SHARED_LL(NR_CLOCK_LOOPS);
    SHARED_LL(NR_TSC_LOOPS) = 0;
    SHARED_LL(NR_TOD_LOOPS) = 0;
    SHARED_LL(NR_CLOCK_LOOPS) = 0;

    if (TEST_TSC)
        printf(" | TSC: %.2fus, fail:%ld",
                (double)sum_tod/(double)sum_tsc_loops,
                SHARED(NR_TSC_WARPS));

    if (TEST_TOD)
        printf(" | TOD: %.2fus, fail:%ld",
                (double)sum_tod/(double)sum_tod_loops,
                SHARED(NR_TOD_WARPS));

    if (TEST_CLOCK)
        printf(" | CLK: %.2fus, fail:%ld",
                (double)sum_tod/(double)sum_clock_loops,
                SHARED(NR_CLOCK_WARPS));

    prev_tod = tod;
    count2++;
    printf(" %c\r", progress[count2 & 3]);
    fflush(stdout);
}

static inline void test_TSC(unsigned long *shared)
{
#if TEST_TSC
    cycles_t t0, t1;
    long long delta;

    lock(&SHARED(LOCK));
    rdtscll(t1);
    t0 = SHARED_LL(TSC);
    SHARED_LL(TSC) = t1;
    SHARED_LL(NR_TSC_LOOPS)++;
    unlock(&SHARED(LOCK));

    delta = t1-t0;
    if (delta < 0) {
        lock(&SHARED(LOCK));
        SHARED(NR_TSC_WARPS)++;
        if (delta < SHARED_LL(WORST_TSC)) {
            SHARED_LL(WORST_TSC) = delta;
            fprintf(stderr, "\rnew TSC-warp maximum: %9Ld cycles, %016Lx -> %016Lx\n",
                    delta, t0, t1);
        }
        unlock(&SHARED(LOCK));
    }
    if (!((unsigned long)t0 & 31))
        asm volatile ("rep; nop");
#endif
}

static inline void test_TOD(unsigned long *shared)
{
#if TEST_TOD
    usecs_t T0, T1;
    long long delta;

    lock(&SHARED(LOCK));
    rdtod(T1);
    T0 = SHARED_LL(TOD);
    SHARED_LL(TOD) = T1;
    SHARED_LL(NR_TOD_LOOPS)++;
    unlock(&SHARED(LOCK));

    delta = T1-T0;
    if (delta < 0) {
        lock(&SHARED(LOCK));
        SHARED(NR_TOD_WARPS)++;
        if (delta < SHARED_LL(WORST_TOD)) {
            SHARED_LL(WORST_TOD) = delta;
            fprintf(stderr, "\rnew TOD-warp maximum: %9Ld usecs,  %016Lx -> %016Lx\n",
                    delta, T0, T1);
        }
        unlock(&SHARED(LOCK));
    }
#endif
}

static inline void test_CLOCK(unsigned long *shared)
{
#if TEST_CLOCK
    usecs_t T0, T1;
    long long delta;

    lock(&SHARED(LOCK));
    rdclock(T1);
    T0 = SHARED_LL(CLOCK);
    SHARED_LL(CLOCK) = T1;
    SHARED_LL(NR_CLOCK_LOOPS)++;
    unlock(&SHARED(LOCK));

    delta = T1-T0;
    if (delta < 0) {
        lock(&SHARED(LOCK));
        SHARED(NR_CLOCK_WARPS)++;
        if (delta < SHARED_LL(WORST_CLOCK)) {
            SHARED_LL(WORST_CLOCK) = delta;
            fprintf(stderr, "\rnew CLOCK-warp maximum: %9Ld nsecs,  %016Lx -> %016Lx\n",
                    delta, T0, T1);
        }
        unlock(&SHARED(LOCK));
    }
#endif
}

int main(int argc, char **argv)
{
    int i, parent, me;
    unsigned long *shared;
    unsigned long cpus, tasks;

    cpus = system("exit `grep ^processor /proc/cpuinfo  | wc -l`");
    cpus = WEXITSTATUS(cpus);

    if (argc > 2) {
usage:
        fprintf(stderr,
                "usage: tsc-sync-test <threads>\n");
        exit(-1);
    }
    if (argc == 2) {
        tasks = atol(argv[1]);
        if (!tasks)
            goto usage;
    } else
        tasks = cpus;

    printf("%ld CPUs, running %ld parallel test-tasks.\n", cpus, tasks);
    printf("checking for time-warps via:\n"
#if TEST_TSC
            "- read time stamp counter (RDTSC) instruction (cycle resolution)\n"
#endif
#if TEST_TOD
            "- gettimeofday (TOD) syscall (usec resolution)\n"
#endif
#if TEST_CLOCK
            "- clock_gettime(CLOCK_MONOTONIC) syscall (nsec resolution)\n"
#endif
            "\n"
          );
    shared = setup_shared_var();

    parent = getpid();

    for (i = 1; i < tasks; i++) {
        if (!fork())
            break;
    }
    me = getpid();

    while (1) {
        int i;

        for (i = 0; i < 10; i++)
            test_TSC(shared);
        for (i = 0; i < 10; i++)
            test_TOD(shared);
        for (i = 0; i < 10; i++)
            test_CLOCK(shared);

        if (me == parent)
            print_status(shared);
    }

    return 0;
}

通过 SSH 迁移 btrfs volumes

配置 SSH 免密:

ssh-copy-id -i ~/.ssh/id_ed25519.pub <user>@<host>

在目标端配置 sudo 免密:

https://serverfault.com/questions/160581/how-to-setup-passwordless-sudo-on-linux

%wheel ALL=(ALL:ALL) NOPASSWD: ALL

The key is to add it after the last line which says

#includedir /etc/sudoers.d

创建快照:

# sudo btrfs subvolume snapshot -r <fs-path> <snapshot-path>
sudo btrfs subvolume snapshot -r / /sysfs_ro

发送:

sudo pacman -S pv
# sudo btrfs send <snapshot-path> | pv | ssh <target-machine> "sudo btrfs receive <target-fs-path>"
sudo btrfs send /sysfs_ro | pv | ssh target-host "sudo btrfs receive /mnt/arc"

# 发送完成后,路径是 /mnt/arc/sysfs_ro

ArchLinux NVIDIA GPU 容器启动失败

ArchLinux (2025-09-06)启动 GPU 容器失败:

-> % docker run --rm --gpus=all nvidia/cuda:12.1.1-base-ubuntu22.04 nvidia-smi
Unable to find image 'nvidia/cuda:12.1.1-base-ubuntu22.04' locally
12.1.1-base-ubuntu22.04: Pulling from nvidia/cuda
aece8493d397: Already exists
dd4939a04761: Pull complete
b0d7cc89b769: Pull complete
1532d9024b9c: Pull complete
04fc8a31fa53: Pull complete
Digest: sha256:457a4076c56025f51217bff647ca631c7880ad3dbf546b03728ba98297ebbc22
Status: Downloaded newer image for nvidia/cuda:12.1.1-base-ubuntu22.04
docker: Error response from daemon: failed to create task for container: failed to create shim task: OCI runtime create failed: runc create failed: unable to start container process: error during container init: error running prestart hook #0: exit status 1, stdout: , stderr: Auto-detected mode as 'legacy'
nvidia-container-cli: ldcache error: process /sbin/ldconfig terminated with signal 9

解决办法:

System Update in Arch Linux, broked NVIDIA container. Open Source drivers

sudo nvidia-ctk cdi generate --output=/etc/cdi/nvidia.yaml
sudo nvidia-ctk config --in-place --set nvidia-container-runtime.mode=cdi
systemctl restart docker
# /etc/docker/daemon.json
  "default-runtime": "nvidia",
  "runtimes": {
    "nvidia": {
      "path": "/usr/bin/nvidia-container-runtime",
      "runtimeArgs": []
    }
  }

关闭侧信道攻击缓解,make Linux great again!

lscpu 会看到一些侧信道攻击缓解措施:

-> % lscpu
  ...
  Spec rstack overflow:      Mitigation; IBPB on VMEXIT only
  Spec store bypass:         Mitigation; Speculative Store Bypass disabled via prctl
  Spectre v1:                Mitigation; usercopy/swapgs barriers and __user pointer sanitization
  Spectre v2:                Mitigation; Enhanced / Automatic IBRS; IBPB conditional; STIBP always-on; PBRSB-eIBRS Not affected; BHI Not affected

Wikipedia - Spectre

但是关我屁事,我是物理机用户,又不是云上的虚拟机用户。

以前有人做了一个 make linux great again 网站,但是下线了。

而且实际上也不需要 那一堆 配置,你只需要 mitigations=off 就行了。

# ArchLinux
-> % cat /boot/loader/entries/2025-06-30_04-02-18_linux.conf
# Created by: archinstall
# Created on: 2025-06-30_04-02-18
title   Arch Linux (linux)
linux   /vmlinuz-linux
initrd  /initramfs-linux.img
options root=PARTUUID=<uuid> zswap.enabled=0 rw rootfstype=btrfs mitigations=off

在 options 最后加上重启就完事。

# Fedora
sudo grubby --update-kernel=ALL --args="mitigations=off selinux=0"

检查好不好使:

-> % cat /proc/cmdline
initrd=\initramfs-linux.img root=PARTUUID=<uuid> zswap.enabled=0 rw rootfstype=btrfs amd_iommu=on amdttm.pages_limit=27648000 amdttm.page_pool_size=27648000 mitigations=off
-> % lscpu
  ...
  Spec rstack overflow:      Vulnerable
  Spec store bypass:         Vulnerable
  Spectre v1:                Vulnerable: __user pointer sanitization and usercopy barriers only; no swapgs barriers
  Spectre v2:                Vulnerable; IBPB: disabled; STIBP: disabled; PBRSB-eIBRS: Not affected; BHI: Not affected

ArchLinux 编译 python-kornia-rs

安装 python-kornia-rs 失败,构建的时候 g 了。

直接一把梭搞定。

user@host [23:50:58] [~/.cache/yay/python-kornia-rs] [master *]
-> % makepkg -s
==> Making package: python-kornia-rs 0.1.9-5 (Thu 24 Jul 2025 11:51:05 PM CST)
==> Checking runtime dependencies...
==> Checking buildtime dependencies...
==> Retrieving sources...
  -> Found kornia-rs-0.1.9.tar.gz
==> Validating source files with sha256sums...
    kornia-rs-0.1.9.tar.gz ... Passed
==> Extracting sources...
  -> Extracting kornia-rs-0.1.9.tar.gz with bsdtar
==> Removing existing $pkgdir/ directory...
==> Starting build()...
* Getting build dependencies for wheel...
* Building wheel...
Running `maturin pep517 build-wheel -i /usr/bin/python --compatibility off`
🔗 Found pyo3 bindings
💥 maturin failed
  Caused by: Python interpreter should be a kind of interpreter (e.g. 'python3.8' or 'pypy3.9') when cross-compiling, got path to interpreter: /usr/bin/python
Error: command ['maturin', 'pep517', 'build-wheel', '-i', '/usr/bin/python', '--compatibility', 'off'] returned non-zero exit status 1

ERROR Backend subprocess exited when trying to invoke build_wheel
==> ERROR: A failure occurred in build().
    Aborting...
export PYO3_CROSS_PYTHON_VERSION=3.13
export PYO3_CROSS_LIB_DIR=/usr/lib
export CARGO_BUILD_TARGET=x86_64-unknown-linux-gnu
makepkg -sf

-> % ls -lah
total 2.8M
drwxr-xr-x 1 user user  310 Jul 24 23:53 .
drwxr-xr-x 1 user user  358 Jul 24 23:17 ..
drwxr-xr-x 1 user user  140 Jul 24 23:49 .git
-rw-r--r-- 1 user user 235K Jul 24 23:17 kornia-rs-0.1.9.tar.gz
-rw-r--r-- 1 user user   96 Jul 24 23:17 .nvchecker.toml
drwxr-xr-x 1 user user   76 Jul 24 23:53 pkg
-rw-r--r-- 1 user user 1.1K Jul 24 23:52 PKGBUILD
-rw-r--r-- 1 user user 2.3M Jul 24 23:53 python-kornia-rs-0.1.9-5-x86_64.pkg.tar.zst
-rw-r--r-- 1 user user 252K Jul 24 23:53 python-kornia-rs-debug-0.1.9-5-x86_64.pkg.tar.zst
drwxr-xr-x 1 user user   74 Jul 24 23:52 src
-rw-r--r-- 1 user user  793 Jul 24 23:17 .SRCINFO

-> % sudo pacman -U python-kornia-rs-0.1.9-5-x86_64.pkg.tar.zst

把 ArchLinux 当成无线路由器用

刚进货一台新服务器,有两个有线网口,只有四个 PCIe,插一个无线网卡太浪费。那么就让他走到另一台有无线网卡的机器上网吧!

sudo pacman -S nftables
-> % cat /etc/nftables.conf
#!/usr/bin/nft -f
# vim:set ts=2 sw=2 et:

# IPv4/IPv6 Simple & Safe firewall ruleset.
# More examples in /usr/share/nftables/ and /usr/share/doc/nftables/examples/.

destroy table inet filter
table inet filter {
  chain input {
    type filter hook input priority 0; policy drop;

    ct state invalid drop comment "early drop of invalid connections"
    ct state {established, related} accept comment "allow tracked connections"
    iif lo accept comment "allow from loopback"
    ip protocol icmp accept comment "allow icmp"
    meta l4proto ipv6-icmp accept comment "allow icmp v6"
    tcp dport ssh accept comment "allow sshd"
    pkttype host limit rate 5/second counter reject with icmpx type admin-prohibited
    counter
  }

  chain forward {
    type filter hook forward priority 0; policy drop;
    iifname "enp2s0" oifname "wlo1" accept
    ct state established,related accept
  }

  chain output {
        type filter hook output priority 0; policy accept;
  }
}

table ip nat {
    chain prerouting {
        type nat hook prerouting priority 0; policy accept;
    }

    chain postrouting {
        type nat hook postrouting priority 100; policy accept;
        oifname "wlo1" masquerade
    }
}
-> % sudo systemctl enable --now nftables.service
-> % cat /etc/sysctl.d/30-ipforward.conf
net.ipv4.ip_forward=1

-> % sudo sysctl --system

解决 PostgreSQL `could not open shared memory segment` 错误

解决 PostgreSQL could not open shared memory segment 错误。

打开 journalctl -u postgresql.service 可以看到:

Jun 15 11:55:52 fanyang-legion postgres[322924]: 2025-06-15 11:55:52.856 CST [322924] ERROR:  could not open shared memory segment "/PostgreSQL.2816709408": No such file or directory
Jun 15 11:56:52 fanyang-legion postgres[322973]: 2025-06-15 11:56:52.914 CST [322973] ERROR:  could not open shared memory segment "/PostgreSQL.2816709408": No such file or directory
Jun 15 11:57:52 fanyang-legion postgres[323026]: 2025-06-15 11:57:52.975 CST [323026] ERROR:  could not open shared memory segment "/PostgreSQL.2816709408": No such file or directory
Jun 15 11:58:53 fanyang-legion postgres[323076]: 2025-06-15 11:58:53.034 CST [323076] ERROR:  could not open shared memory segment "/PostgreSQL.2816709408": No such file or directory
Jun 15 11:59:53 fanyang-legion postgres[323127]: 2025-06-15 11:59:53.042 CST [323127] ERROR:  could not open shared memory segment "/PostgreSQL.2816709408": No such file or directory
Jun 15 12:00:53 fanyang-legion postgres[323181]: 2025-06-15 12:00:53.099 CST [323181] ERROR:  could not open shared memory segment "/PostgreSQL.2816709408": No such file or directory
Jun 15 12:01:53 fanyang-legion postgres[323229]: 2025-06-15 12:01:53.155 CST [323229] ERROR:  could not open shared memory segment "/PostgreSQL.2816709408": No such file or directory
Jun 15 12:02:53 fanyang-legion postgres[323286]: 2025-06-15 12:02:53.193 CST [323286] ERROR:  could not open shared memory segment "/PostgreSQL.2816709408": No such file or directory
Jun 15 12:03:53 fanyang-legion postgres[323334]: 2025-06-15 12:03:53.219 CST [323334] ERROR:  could not open shared memory segment "/PostgreSQL.2816709408": No such file or directory
Jun 15 12:04:53 fanyang-legion postgres[323385]: 2025-06-15 12:04:53.232 CST [323385] ERROR:  could not open shared memory segment "/PostgreSQL.2816709408": No such file or directory
Jun 15 12:05:04 fanyang-legion postgres[323386]: 2025-06-15 12:05:04.501 CST [323386] FATAL:  could not open shared memory segment "/PostgreSQL.2816709408": No such file or directory

解决方法:

PostgreSQL 11 Shared Memory Error: could not open shared memory segment "/PostgreSQL.XXXXXXXX": No such file or directory

# sudo vim /etc/systemd/logind.conf
RemoveIPC=no
systemctl restart systemd-logind.service