PhysicalDisk: adds option hideVirtual (defaults to false) and hideUnknown (defaults to true)

This commit is contained in:
李通洲
2026-04-08 15:42:03 +08:00
parent c09a788ce3
commit 17eb22dfdb
11 changed files with 205 additions and 80 deletions
+10
View File
@@ -3638,6 +3638,16 @@
"description": "Show disks with given name prefix only",
"type": "string"
},
"hideVirtual": {
"description": "Hide virtual disks (e.g. loop, RAM or file baked disks)",
"type": "boolean",
"default": false
},
"hideUnknown": {
"description": "Hide disks with `size == 0`",
"type": "boolean",
"default": true
},
"temp": {
"$ref": "#/$defs/temperature"
},
+23 -12
View File
@@ -63,14 +63,6 @@ const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options)
continue;
}
uint64_t size = 0;
{
FF_CFTYPE_AUTO_RELEASE CFNumberRef mediaSize = IORegistryEntryCreateCFProperty(entryMedia, CFSTR(kIOMediaSizeKey), kCFAllocatorDefault, kNilOptions);
if (mediaSize) {
ffCfNumGetInt64(mediaSize, (int64_t*) &size);
}
}
FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t entryPhysical = 0;
if (IORegistryEntryGetParentEntry(entryDriver, kIOServicePlane, &entryPhysical) != KERN_SUCCESS) {
continue;
@@ -85,13 +77,18 @@ const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options)
continue;
}
FFPhysicalDiskType type = FF_PHYSICALDISK_TYPE_NONE;
FF_STRBUF_AUTO_DESTROY interconnect = ffStrbufCreate();
bool isVirtual = false;
FF_CFTYPE_AUTO_RELEASE CFDictionaryRef protocolCharacteristics = IORegistryEntryCreateCFProperty(entryPhysical, CFSTR(kIOPropertyProtocolCharacteristicsKey), kCFAllocatorDefault, kNilOptions);
if (protocolCharacteristics) {
if (ffCfDictGetString(protocolCharacteristics, CFSTR(kIOPropertyPhysicalInterconnectTypeKey), &interconnect) == NULL) {
if (ffStrbufEqualS(&interconnect, kIOPropertyPhysicalInterconnectTypeVirtual)) {
isVirtual = true;
if (options->hideType & FF_PHYSICALDISK_TYPE_VIRTUAL) {
continue;
}
type |= FF_PHYSICALDISK_TYPE_VIRTUAL;
FF_STRBUF_AUTO_DESTROY location = ffStrbufCreate();
if (ffCfDictGetString(protocolCharacteristics, CFSTR(kIOPropertyPhysicalInterconnectLocationKey), &location) == NULL) {
ffStrbufAppendS(&interconnect, " - ");
@@ -101,14 +98,28 @@ const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options)
}
}
uint64_t size = 0;
{
FF_CFTYPE_AUTO_RELEASE CFNumberRef mediaSize = IORegistryEntryCreateCFProperty(entryMedia, CFSTR(kIOMediaSizeKey), kCFAllocatorDefault, kNilOptions);
if (mediaSize) {
ffCfNumGetInt64(mediaSize, (int64_t*) &size);
if (size == 0) {
if (options->hideType & FF_PHYSICALDISK_TYPE_UNKNOWN) {
continue;
}
type |= FF_PHYSICALDISK_TYPE_UNKNOWN;
}
}
}
FFPhysicalDiskResult* device = (FFPhysicalDiskResult*) ffListAdd(result);
ffStrbufInit(&device->serial);
ffStrbufInit(&device->revision);
ffStrbufInitS(&device->name, deviceName);
ffStrbufInit(&device->devPath);
ffStrbufInitMove(&device->interconnect, &interconnect);
device->type = (isVirtual ? FF_PHYSICALDISK_TYPE_VIRTUAL : FF_PHYSICALDISK_TYPE_NONE) |
(size > 0 ? FF_PHYSICALDISK_TYPE_NONE : FF_PHYSICALDISK_TYPE_UNKNOWN);
device->type = type;
device->size = size;
device->temperature = FF_PHYSICALDISK_TEMP_UNSET;
@@ -41,10 +41,18 @@ const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options)
FFPhysicalDiskType type = FF_PHYSICALDISK_TYPE_NONE;
if (!ffStrEquals(provider->lg_geom->lg_class->lg_name, "DISK")) {
if (options->hideType & FF_PHYSICALDISK_TYPE_VIRTUAL) {
continue;
}
type |= FF_PHYSICALDISK_TYPE_VIRTUAL;
}
uint64_t size = (uint64_t) provider->lg_mediasize;
if (size == 0) {
if (options->hideType & FF_PHYSICALDISK_TYPE_UNKNOWN) {
continue;
}
type |= FF_PHYSICALDISK_TYPE_UNKNOWN;
}
+45 -37
View File
@@ -8,39 +8,7 @@
#include <Drivers.h>
#include <sys/ioctl.h>
static const char* detectDisk(FFstrbuf* path, const char* diskType, FFlist* result) {
FF_AUTO_CLOSE_FD int rawfd = open(path->chars, O_RDONLY | O_CLOEXEC);
if (rawfd < 0) {
return "detectDisk: open(rawfd) failed";
}
device_geometry geometry;
if (ioctl(rawfd, B_GET_GEOMETRY, &geometry, sizeof(geometry)) < 0) {
return "ioctl(B_GET_GEOMETRY) failed";
}
char name[B_OS_NAME_LENGTH];
if (ioctl(rawfd, B_GET_DEVICE_NAME, name, sizeof(name)) != 0) {
// ioctl reports `not a tty` for NVME drives for some reason
snprintf(name, sizeof(name), "Unknown %s drive", diskType);
}
FFPhysicalDiskResult* device = (FFPhysicalDiskResult*) ffListAdd(result);
ffStrbufInitS(&device->name, name);
ffStrbufInitCopy(&device->devPath, path);
ffStrbufInit(&device->serial);
ffStrbufInit(&device->revision);
ffStrbufInitS(&device->interconnect, diskType);
device->temperature = FF_PHYSICALDISK_TEMP_UNSET;
device->type = FF_PHYSICALDISK_TYPE_NONE;
device->type |= (geometry.read_only ? FF_PHYSICALDISK_TYPE_READONLY : FF_PHYSICALDISK_TYPE_READWRITE) |
(geometry.removable ? FF_PHYSICALDISK_TYPE_REMOVABLE : FF_PHYSICALDISK_TYPE_FIXED);
device->size = (uint64_t) geometry.cylinder_count * geometry.head_count * geometry.sectors_per_track * geometry.bytes_per_sector;
return NULL;
}
static const char* searchRawDeviceFile(FFstrbuf* path, const char* diskType, FFlist* result) {
static const char* searchRawDeviceFile(FFstrbuf* path, const char* diskType, FFlist* result, FFPhysicalDiskOptions* options) {
FF_AUTO_CLOSE_DIR DIR* dir = opendir(path->chars);
if (!dir) {
return "detectDiskType: opendir() failed";
@@ -62,9 +30,49 @@ static const char* searchRawDeviceFile(FFstrbuf* path, const char* diskType, FFl
}
if (S_ISDIR(st.st_mode)) {
searchRawDeviceFile(path, diskType, result);
searchRawDeviceFile(path, diskType, result, options);
} else if (ffStrEquals(entry->d_name, "raw")) {
detectDisk(path, diskType, result);
FF_AUTO_CLOSE_FD int rawfd = open(path->chars, O_RDONLY | O_CLOEXEC);
if (rawfd < 0) {
continue;
}
device_geometry geometry;
if (ioctl(rawfd, B_GET_GEOMETRY, &geometry, sizeof(geometry)) < 0) {
continue;
}
char name[B_OS_NAME_LENGTH];
if (ioctl(rawfd, B_GET_DEVICE_NAME, name, sizeof(name)) != 0) {
// ioctl reports `not a tty` for NVME drives for some reason
snprintf(name, sizeof(name), "Unknown %s drive", diskType);
}
if (options->namePrefix.length && strncmp(name, options->namePrefix.chars, options->namePrefix.length) != 0) {
continue;
}
FFPhysicalDiskType type = FF_PHYSICALDISK_TYPE_NONE;
uint64_t size = (uint64_t) geometry.cylinder_count * geometry.head_count * geometry.sectors_per_track * geometry.bytes_per_sector;
if (size == 0) {
if (options->hideType & FF_PHYSICALDISK_TYPE_UNKNOWN) {
continue;
}
type |= FF_PHYSICALDISK_TYPE_UNKNOWN;
}
FFPhysicalDiskResult* device = (FFPhysicalDiskResult*) ffListAdd(result);
ffStrbufInitS(&device->name, name);
ffStrbufInitCopy(&device->devPath, path);
ffStrbufInit(&device->serial);
ffStrbufInit(&device->revision);
ffStrbufInitS(&device->interconnect, diskType);
device->temperature = FF_PHYSICALDISK_TEMP_UNSET;
device->type = type |
(geometry.read_only ? FF_PHYSICALDISK_TYPE_READONLY : FF_PHYSICALDISK_TYPE_READWRITE) |
(geometry.removable ? FF_PHYSICALDISK_TYPE_REMOVABLE : FF_PHYSICALDISK_TYPE_FIXED);
device->size = size;
}
ffStrbufSubstrBefore(path, baseLen);
@@ -72,7 +80,7 @@ static const char* searchRawDeviceFile(FFstrbuf* path, const char* diskType, FFl
return NULL;
}
const char* ffDetectPhysicalDisk(FFlist* result, FF_MAYBE_UNUSED FFPhysicalDiskOptions* options) {
const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options) {
FF_AUTO_CLOSE_DIR DIR* dir = opendir("/dev/disk");
if (!dir) {
return "opendir(/dev/disk) failed";
@@ -88,7 +96,7 @@ const char* ffDetectPhysicalDisk(FFlist* result, FF_MAYBE_UNUSED FFPhysicalDiskO
continue;
}
ffStrbufAppendS(&path, entry->d_name);
searchRawDeviceFile(&path, entry->d_name, result);
searchRawDeviceFile(&path, entry->d_name, result, options);
ffStrbufSubstrBefore(&path, baseLen);
}
@@ -38,8 +38,25 @@ static void parsePhysicalDisk(int dfd, const char* devName, FFPhysicalDiskOption
}
}
FFPhysicalDiskType type = FF_PHYSICALDISK_TYPE_NONE;
if (size == 0) {
if (options->hideType & FF_PHYSICALDISK_TYPE_UNKNOWN) {
return;
}
type |= FF_PHYSICALDISK_TYPE_UNKNOWN;
}
int devfd = openat(dfd, "device", O_RDONLY | O_CLOEXEC | O_PATH | O_DIRECTORY);
if (devfd < 0) {
if (options->hideType & FF_PHYSICALDISK_TYPE_VIRTUAL) {
return;
}
type |= FF_PHYSICALDISK_TYPE_VIRTUAL;
}
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate();
if (devfd > 0) {
@@ -86,8 +103,7 @@ static void parsePhysicalDisk(int dfd, const char* devName, FFPhysicalDiskOption
ffStrbufInit(&device->serial);
ffStrbufInit(&device->revision);
ffStrbufInit(&device->interconnect);
device->type = (devfd > 0 ? FF_PHYSICALDISK_TYPE_NONE : FF_PHYSICALDISK_TYPE_VIRTUAL) |
(size > 0 ? FF_PHYSICALDISK_TYPE_NONE : FF_PHYSICALDISK_TYPE_UNKNOWN);
device->type = type;
device->size = size;
device->temperature = FF_PHYSICALDISK_TEMP_UNSET;
+21 -8
View File
@@ -68,7 +68,8 @@ const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options)
sectorSize = dl.d_secsize;
}
bool isVirtual = false;
FFPhysicalDiskType type = dl.d_flags & D_REMOVABLE ? FF_PHYSICALDISK_TYPE_REMOVABLE : FF_PHYSICALDISK_TYPE_FIXED;
switch (dl.d_type) {
case DKTYPE_VND:
case DKTYPE_LD:
@@ -77,21 +78,33 @@ const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options)
case DKTYPE_VINUM:
case DKTYPE_DM:
case DKTYPE_RUMPD:
case DKTYPE_MD:
isVirtual = true;
case DKTYPE_MD: {
if (options->hideType & FF_PHYSICALDISK_TYPE_VIRTUAL) {
continue;
}
type |= FF_PHYSICALDISK_TYPE_VIRTUAL;
break;
}
}
uint64_t size = sectorsPerUnit * sectorSize;
if (size == 0) {
if (options->hideType & FF_PHYSICALDISK_TYPE_UNKNOWN) {
continue;
}
type |= FF_PHYSICALDISK_TYPE_UNKNOWN;
}
bool isUnknown = sectorsPerUnit == 0;
FFPhysicalDiskResult* device = (FFPhysicalDiskResult*) ffListAdd(result);
ffStrbufInitS(&device->name, devType ?: dl.d_packname);
ffStrbufInitS(&device->devPath, devPath);
ffStrbufInit(&device->serial);
ffStrbufInit(&device->revision);
ffStrbufInitS(&device->interconnect, dktypenames[dl.d_type]);
device->type = (!isVirtual ? FF_PHYSICALDISK_TYPE_NONE : FF_PHYSICALDISK_TYPE_VIRTUAL) |
(!isUnknown ? FF_PHYSICALDISK_TYPE_NONE : FF_PHYSICALDISK_TYPE_UNKNOWN) |
(dl.d_flags & D_REMOVABLE ? FF_PHYSICALDISK_TYPE_REMOVABLE : FF_PHYSICALDISK_TYPE_FIXED);
device->size = sectorsPerUnit * sectorSize;
device->type = type;
device->size = size;
device->temperature = FF_PHYSICALDISK_TEMP_UNSET;
if (dict) {
+20 -5
View File
@@ -49,17 +49,32 @@ const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options)
continue;
}
bool isVirtual = dl.d_type == DTYPE_VND || dl.d_type == DTYPE_RDROOT;
bool isUnknown = dl.d_ncylinders == 0;
FFPhysicalDiskType type = FF_PHYSICALDISK_TYPE_NONE;
if (dl.d_type == DTYPE_VND || dl.d_type == DTYPE_RDROOT) {
if (options->hideType & FF_PHYSICALDISK_TYPE_VIRTUAL) {
continue;
}
type |= FF_PHYSICALDISK_TYPE_VIRTUAL;
}
uint64_t size = DL_GETDSIZE(&dl) * dl.d_secsize;
if (size == 0) {
if (options->hideType & FF_PHYSICALDISK_TYPE_UNKNOWN) {
continue;
}
type |= FF_PHYSICALDISK_TYPE_UNKNOWN;
}
FFPhysicalDiskResult* device = (FFPhysicalDiskResult*) ffListAdd(result);
ffStrbufInitS(&device->name, dl.d_packname);
ffStrbufInitS(&device->devPath, devPath);
ffStrbufInit(&device->serial);
ffStrbufInit(&device->revision);
ffStrbufInitS(&device->interconnect, dl.d_typename);
device->type = (!isVirtual ? FF_PHYSICALDISK_TYPE_NONE : FF_PHYSICALDISK_TYPE_VIRTUAL) |
(!isUnknown ? FF_PHYSICALDISK_TYPE_NONE : FF_PHYSICALDISK_TYPE_UNKNOWN);
device->size = DL_GETDSIZE(&dl) * dl.d_secsize;
device->type = type;
device->size = size;
device->temperature = FF_PHYSICALDISK_TEMP_UNSET;
struct scsi_inquiry_data inquiry = {};
+24 -15
View File
@@ -11,6 +11,9 @@ struct FFWalkTreeBundle {
};
static int walkDevTree(di_node_t node, di_minor_t minor, struct FFWalkTreeBundle* bundle) {
FFPhysicalDiskOptions* options = bundle->options;
FFlist* result = bundle->disks;
if (di_minor_spectype(minor) != S_IFCHR || !ffStrEquals(di_minor_name(minor), "a,raw")) {
return DI_WALK_CONTINUE;
}
@@ -19,19 +22,36 @@ static int walkDevTree(di_node_t node, di_minor_t minor, struct FFWalkTreeBundle
char* vendorId;
if (di_prop_lookup_strings(DDI_DEV_T_ANY, node, "inquiry-product-id", &productId) > 0 && di_prop_lookup_strings(DDI_DEV_T_ANY, node, "inquiry-vendor-id", &vendorId) > 0) {
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreateF("%s %s", vendorId, productId);
if (bundle->options->namePrefix.length && !ffStrbufStartsWithIgnCase(&name, &bundle->options->namePrefix)) {
if (options->namePrefix.length && !ffStrbufStartsWithIgnCase(&name, &options->namePrefix)) {
return DI_WALK_CONTINUE;
}
FFPhysicalDiskResult* device = (FFPhysicalDiskResult*) ffListAdd(bundle->disks);
int* value;
FFPhysicalDiskType type = FF_PHYSICALDISK_TYPE_NONE;
uint64_t size = 0;
int64_t* nblocks;
if (di_prop_lookup_int64(DDI_DEV_T_ANY, node, "device-nblocks", &nblocks) > 0) {
if (*nblocks == 0) {
if (options->hideType & FF_PHYSICALDISK_TYPE_UNKNOWN) {
return DI_WALK_CONTINUE;
}
type |= FF_PHYSICALDISK_TYPE_UNKNOWN;
} else if (di_prop_lookup_ints(DDI_DEV_T_ANY, node, "device-blksize", &value) > 0) {
size = (uint64_t) ((uint64_t) *nblocks * (uint64_t) *value);
}
}
FFPhysicalDiskResult* device = (FFPhysicalDiskResult*) ffListAdd(result);
ffStrbufInitMove(&device->name, &name);
ffStrbufInitF(&device->devPath, "/devices%s", di_devfs_path(node));
ffStrbufInit(&device->serial);
ffStrbufInit(&device->revision);
ffStrbufInit(&device->interconnect);
device->temperature = FF_PHYSICALDISK_TEMP_UNSET;
device->type = FF_PHYSICALDISK_TYPE_NONE;
device->size = 0;
device->type = type;
device->size = size;
char* buf;
bool usb = false;
@@ -63,7 +83,6 @@ static int walkDevTree(di_node_t node, di_minor_t minor, struct FFWalkTreeBundle
device->type |= di_prop_find(DDI_DEV_T_ANY, node, "removable-media") ? FF_PHYSICALDISK_TYPE_REMOVABLE : FF_PHYSICALDISK_TYPE_FIXED;
int* value;
if (di_prop_lookup_ints(DDI_DEV_T_ANY, node, "device-solid-state", &value) > 0) {
device->type |= *value ? FF_PHYSICALDISK_TYPE_SSD : FF_PHYSICALDISK_TYPE_HDD;
}
@@ -71,16 +90,6 @@ static int walkDevTree(di_node_t node, di_minor_t minor, struct FFWalkTreeBundle
device->type |= *value == DTYPE_DIRECT ? FF_PHYSICALDISK_TYPE_READWRITE : *value == DTYPE_RODIRECT ? FF_PHYSICALDISK_TYPE_READONLY
: 0;
}
int64_t* nblocks;
if (di_prop_lookup_int64(DDI_DEV_T_ANY, node, "device-nblocks", &nblocks) > 0) {
if (*nblocks == 0) {
device->size = 0;
device->type |= FF_PHYSICALDISK_TYPE_UNKNOWN;
} else if (di_prop_lookup_ints(DDI_DEV_T_ANY, node, "device-blksize", &value) > 0) {
device->size = (uint64_t) ((uint64_t) *nblocks * (uint64_t) *value);
}
}
}
return DI_WALK_CONTINUE;
@@ -84,6 +84,10 @@ static const char* detectPhysicalDisk(const char* physicalType, const wchar_t* s
}
}
if (size == 0) {
if (options->hideType & FF_PHYSICALDISK_TYPE_UNKNOWN) {
return "Skipping unknown disk with size 0";
}
type |= FF_PHYSICALDISK_TYPE_UNKNOWN;
}
@@ -174,6 +178,10 @@ static const char* detectPhysicalDisk(const char* physicalType, const wchar_t* s
break;
}
if (type & FF_PHYSICALDISK_TYPE_VIRTUAL && options->hideType & FF_PHYSICALDISK_TYPE_VIRTUAL) {
return "Skipping virtual disk";
}
if (sdd->VendorIdOffset != 0) {
ffStrbufSetS(&name, (const char*) sdd + sdd->VendorIdOffset);
ffStrbufTrim(&name, ' ');
+1
View File
@@ -26,6 +26,7 @@ typedef struct FFPhysicalDiskOptions {
FFModuleArgs moduleArgs;
FFstrbuf namePrefix;
FFPhysicalDiskType hideType;
bool temp;
FFColorRangeConfig tempConfig;
} FFPhysicalDiskOptions;
+27 -1
View File
@@ -2,7 +2,6 @@
#include "common/jsonconfig.h"
#include "common/temps.h"
#include "common/size.h"
#include "common/stringUtils.h"
#include "detection/physicaldisk/physicaldisk.h"
#include "modules/physicaldisk/physicaldisk.h"
@@ -139,6 +138,32 @@ void ffParsePhysicalDiskJsonObject(FFPhysicalDiskOptions* options, yyjson_val* m
continue;
}
if (unsafe_yyjson_equals_str(key, "hideVirtual")) {
if (!yyjson_is_bool(val)) {
ffPrintError(FF_PHYSICALDISK_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "hideVirtual must be a boolean");
} else {
if (unsafe_yyjson_is_true(val)) {
options->hideType |= FF_PHYSICALDISK_TYPE_VIRTUAL;
} else {
options->hideType &= ~FF_PHYSICALDISK_TYPE_VIRTUAL;
}
}
continue;
}
if (unsafe_yyjson_equals_str(key, "hideUnknown")) {
if (!yyjson_is_bool(val)) {
ffPrintError(FF_PHYSICALDISK_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "hideUnknown must be a boolean");
} else {
if (unsafe_yyjson_is_true(val)) {
options->hideType |= FF_PHYSICALDISK_TYPE_UNKNOWN;
} else {
options->hideType &= ~FF_PHYSICALDISK_TYPE_UNKNOWN;
}
}
continue;
}
if (ffTempsParseJsonObject(key, val, &options->temp, &options->tempConfig)) {
continue;
}
@@ -228,6 +253,7 @@ void ffInitPhysicalDiskOptions(FFPhysicalDiskOptions* options) {
ffStrbufInit(&options->namePrefix);
options->temp = false;
options->tempConfig = (FFColorRangeConfig) { 50, 70 };
options->hideType = FF_PHYSICALDISK_TYPE_UNKNOWN;
}
void ffDestroyPhysicalDiskOptions(FFPhysicalDiskOptions* options) {