- bug-1872 (worker): "Failed to find any disk statistics in /proc/diskstats" ERROR every 15 s on an NVMe-only host. The whole-disk filter guessed from the name and skipped anything ending in a digit or containing 'p' -- every nvmeXnY, mmcblkN, even sdp -- so io was never reported. diskstats.h now counts a device only when /sys/block/<name>/device exists (real disks; not partitions, loop, dm, md, zram), and a host with no disk warns once. - bug-1873 (worker): "Failed to get worker pid" WARN on job start. MainPID reads 0 until systemd has forked the new transient unit; xcecd.c already retries, so the miss is DEBUG and the final failure names the unit. - bug-1874 (scheduler): deprecation WARN for the legacy xce_sched_fcfs on every start, though builtin_fcfs is the picker. Registration still wraps a job_elect_fn plugin but no longer warns; selecting one warns once. - bug-1875 (apiserver): "Not running as root -- PAM authentication will not work" with the default provider config_file; now only for provider pam. - bug-1876 (controller): standbys logged "cluster_init_phase2 ... failed (rc=-22)" WARN every 3 s while waiting for the primary's config push, a state the function itself calls normal. It returns -EAGAIN for that wait; callers log it at INFO, other failures still WARN. - bug-1877 (controller): "WAL/snapshot stored unencrypted" warned without looking. persist_path_encrypted() checks fscrypt (statx) and dm-crypt (sysfs dm/uuid CRYPT-, through LVM slaves); the warning stays when the storage is not shown to be encrypted (e.g. a plain /tmp). Tests: worker diskstats_test (2 of 4 RED on the old filter with pc13v's /proc/diskstats), controller test_phase2_cold_boot and test_persist_encryption, scheduler picker tests, apiserver TestRootWarning. Full ASAN build: all 113 suites pass (controller 319/0, harness 141/0). Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
64 lines
2.1 KiB
C
64 lines
2.1 KiB
C
#pragma once
|
|
/*
|
|
* diskstats.h -- sum the sector counters of the physical disks listed in
|
|
* /proc/diskstats (node_information.c's io metric).
|
|
*/
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <sys/stat.h>
|
|
|
|
/* A whole physical disk has /sys/block/<name>/device (a link to its
|
|
* hardware). Partitions are not in /sys/block, and loop, ram, zram, dm-
|
|
* and md devices have no `device` -- counting dm/md would also count the
|
|
* same I/O twice, once more through their member disks. */
|
|
static inline int diskstats_is_physical(const char* sysblock, const char* name)
|
|
{
|
|
char path[512];
|
|
struct stat st;
|
|
|
|
if (strchr(name, '/') != NULL || name[0] == '.') {
|
|
return 0;
|
|
}
|
|
snprintf(path, sizeof(path), "%s/%s/device", sysblock, name);
|
|
return stat(path, &st) == 0;
|
|
}
|
|
|
|
/* Sum sectors read/written over the physical disks in `fp` (a
|
|
* /proc/diskstats stream). `sysblock` is the /sys/block directory.
|
|
* Returns the number of disks counted.
|
|
*
|
|
* bug-1872: this used to guess from the name (skip names ending in a digit
|
|
* or containing 'p'), which dropped every NVMe disk (nvme0n1), mmc disks
|
|
* (mmcblk0) and even sdp. */
|
|
static inline int diskstats_sum_physical(FILE* fp, const char* sysblock,
|
|
unsigned long long* sectors_read,
|
|
unsigned long long* sectors_written)
|
|
{
|
|
char line[512];
|
|
int ndisks = 0;
|
|
|
|
*sectors_read = 0;
|
|
*sectors_written = 0;
|
|
|
|
while (fgets(line, sizeof(line), fp)) {
|
|
int major, minor;
|
|
char name[64];
|
|
unsigned long long rc, rm, rd, rt, wc, wm, wr, wt, inprog, iot, wiot;
|
|
|
|
if (sscanf(line,
|
|
"%d %d %63s %llu %llu %llu %llu %llu %llu %llu %llu %llu "
|
|
"%llu %llu",
|
|
&major, &minor, name, &rc, &rm, &rd, &rt, &wc, &wm, &wr, &wt,
|
|
&inprog, &iot, &wiot)
|
|
< 14) {
|
|
continue;
|
|
}
|
|
if (!diskstats_is_physical(sysblock, name)) {
|
|
continue;
|
|
}
|
|
*sectors_read += rd;
|
|
*sectors_written += wr;
|
|
ndisks++;
|
|
}
|
|
return ndisks;
|
|
}
|