Disk (Linux): detect physical type

This commit is contained in:
李通洲
2023-09-30 20:32:14 +08:00
parent 18233a27c5
commit e53acf42ec
5 changed files with 53 additions and 15 deletions
+3 -3
View File
@@ -7,9 +7,9 @@
typedef enum FFDiskPhysicalType
{
FF_DISK_TYPE_UNKNOWN,
FF_DISK_TYPE_HDD,
FF_DISK_TYPE_SSD,
FF_DISK_PHYSICAL_TYPE_UNKNOWN,
FF_DISK_PHYSICAL_TYPE_HDD,
FF_DISK_PHYSICAL_TYPE_SSD,
} FFDiskPhysicalType;
typedef struct FFDisk
+1 -1
View File
@@ -71,7 +71,7 @@ const char* ffDetectDisksImpl(FFlist* disks)
#endif
FFDisk* disk = ffListAdd(disks);
disk->physicalType = FF_DISK_TYPE_UNKNOWN;
disk->physicalType = FF_DISK_PHYSICAL_TYPE_UNKNOWN;
disk->bytesTotal = fs->f_blocks * fs->f_bsize;
disk->bytesFree = (uint64_t)fs->f_bfree * fs->f_bsize;
+18 -7
View File
@@ -195,7 +195,7 @@ static bool isSubvolume(const FFlist* disks, FFDisk* currentDisk)
return false;
}
static bool isRemovable(FFDisk* currentDisk)
static bool detectPhysicalTypeAndReturnRemovable(FFDisk* currentDisk)
{
// https://stackoverflow.com/a/73302025
// Note my USB mobile hard disk isn't detected as removable, but my USB flash disk does.
@@ -218,11 +218,20 @@ static bool isRemovable(FFDisk* currentDisk)
if (!ffStrStartsWith(partitionName, entry->d_name)) continue;
// /sys/block/sdx/removable
ffStrbufAppendS(&basePath, entry->d_name);
index = basePath.length;
// /sys/block/sdx/queue/rotational
ffStrbufAppendS(&basePath, "/queue/rotational");
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
if (ffReadFileBuffer(basePath.chars, &buffer))
currentDisk->physicalType = ffStrbufEqualS(&buffer, "1") ? FF_DISK_PHYSICAL_TYPE_HDD : FF_DISK_PHYSICAL_TYPE_SSD;
else
currentDisk->physicalType = FF_DISK_PHYSICAL_TYPE_UNKNOWN;
ffStrbufSubstrBefore(&basePath, index);
// /sys/block/sdx/removable
ffStrbufAppendS(&basePath, "/removable");
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
return ffReadFileBuffer(basePath.chars, &buffer) && ffStrbufEqualS(&buffer, "1");
}
@@ -231,7 +240,10 @@ static bool isRemovable(FFDisk* currentDisk)
static void detectType(const FFlist* disks, FFDisk* currentDisk)
{
if(isRemovable(currentDisk))
bool isRemovable = detectPhysicalTypeAndReturnRemovable(currentDisk);
if(currentDisk->type != FF_DISK_VOLUME_TYPE_NONE) return;
if(isRemovable)
currentDisk->type = FF_DISK_VOLUME_TYPE_EXTERNAL_BIT;
else if(isSubvolume(disks, currentDisk))
currentDisk->type = FF_DISK_VOLUME_TYPE_SUBVOLUME_BIT;
@@ -277,7 +289,7 @@ const char* ffDetectDisksImpl(FFlist* disks)
//We have a valid device, add it to the list
FFDisk* disk = ffListAdd(disks);
disk->type = FF_DISK_VOLUME_TYPE_NONE;
disk->physicalType = FF_DISK_TYPE_UNKNOWN;
disk->physicalType = FF_DISK_PHYSICAL_TYPE_UNKNOWN;
//detect mountFrom
ffStrbufInitS(&disk->mountFrom, device->mnt_fsname);
@@ -293,8 +305,7 @@ const char* ffDetectDisksImpl(FFlist* disks)
detectName(disk); // Also detects external devices
//detect type
if (disk->type == FF_DISK_VOLUME_TYPE_NONE)
detectType(disks, disk);
detectType(disks, disk);
//Detects stats
detectStats(disk);
+2 -2
View File
@@ -29,7 +29,7 @@ const char* ffDetectDisksImpl(FFlist* disks)
wchar_t volumeName[64];
disk->physicalType = FF_DISK_TYPE_UNKNOWN;
disk->physicalType = FF_DISK_PHYSICAL_TYPE_UNKNOWN;
if(mountpoint[1] == ':')
{
memcpy(volumeName, L"\\\\.\\ :", sizeof(L"\\\\.\\ :"));
@@ -51,7 +51,7 @@ const char* ffDetectDisksImpl(FFlist* disks)
NULL,
NULL
))
disk->physicalType = dspd.IncursSeekPenalty ? FF_DISK_TYPE_HDD : FF_DISK_TYPE_SSD;
disk->physicalType = dspd.IncursSeekPenalty ? FF_DISK_PHYSICAL_TYPE_HDD : FF_DISK_PHYSICAL_TYPE_SSD;
}
}
+29 -2
View File
@@ -6,7 +6,7 @@
#include "modules/disk/disk.h"
#include "util/stringUtils.h"
#define FF_DISK_NUM_FORMAT_ARGS 10
#define FF_DISK_NUM_FORMAT_ARGS 11
#pragma GCC diagnostic ignored "-Wsign-conversion"
static void printDisk(FFDiskOptions* options, const FFDisk* disk)
@@ -111,6 +111,19 @@ static void printDisk(FFDiskOptions* options, const FFDisk* disk)
bool isExternal = !!(disk->type & FF_DISK_VOLUME_TYPE_EXTERNAL_BIT);
bool isHidden = !!(disk->type & FF_DISK_VOLUME_TYPE_HIDDEN_BIT);
bool isReadOnly = !!(disk->type & FF_DISK_VOLUME_TYPE_READONLY_BIT);
const char* physicalType;
switch(disk->physicalType)
{
case FF_DISK_PHYSICAL_TYPE_HDD:
physicalType = "HDD";
break;
case FF_DISK_PHYSICAL_TYPE_SSD:
physicalType = "SSD";
break;
default:
physicalType = "Unknown";
break;
}
ffPrintFormatString(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY, FF_DISK_NUM_FORMAT_ARGS, (FFformatarg[]){
{FF_FORMAT_ARG_TYPE_STRBUF, &usedPretty},
{FF_FORMAT_ARG_TYPE_STRBUF, &totalPretty},
@@ -123,6 +136,7 @@ static void printDisk(FFDiskOptions* options, const FFDisk* disk)
{FF_FORMAT_ARG_TYPE_STRBUF, &disk->filesystem},
{FF_FORMAT_ARG_TYPE_STRBUF, &disk->name},
{FF_FORMAT_ARG_TYPE_BOOL, &isReadOnly},
{FF_FORMAT_ARG_TYPE_STRING, physicalType}
});
}
}
@@ -403,7 +417,7 @@ void ffGenerateDiskJson(FFDiskOptions* options, yyjson_mut_doc* doc, yyjson_mut_
yyjson_mut_obj_add_strbuf(doc, obj, "mountpoint", &item->mountpoint);
yyjson_mut_obj_add_strbuf(doc, obj, "mountFrom", &item->mountFrom);
yyjson_mut_obj_add_strbuf(doc, obj, "name", &item->name);
yyjson_mut_val* typeArr = yyjson_mut_obj_add_arr(doc, obj, "type");
yyjson_mut_val* typeArr = yyjson_mut_obj_add_arr(doc, obj, "volumeType");
if(item->type & FF_DISK_VOLUME_TYPE_REGULAR_BIT)
yyjson_mut_arr_add_str(doc, typeArr, "Regular");
if(item->type & FF_DISK_VOLUME_TYPE_EXTERNAL_BIT)
@@ -414,6 +428,19 @@ void ffGenerateDiskJson(FFDiskOptions* options, yyjson_mut_doc* doc, yyjson_mut_
yyjson_mut_arr_add_str(doc, typeArr, "Hidden");
if(item->type & FF_DISK_VOLUME_TYPE_READONLY_BIT)
yyjson_mut_arr_add_str(doc, typeArr, "Read-only");
switch(item->physicalType)
{
case FF_DISK_PHYSICAL_TYPE_HDD:
yyjson_mut_obj_add_str(doc, obj, "physicalType", "HDD");
break;
case FF_DISK_PHYSICAL_TYPE_SSD:
yyjson_mut_obj_add_str(doc, obj, "physicalType", "SSD");
break;
default:
yyjson_mut_obj_add_null(doc, obj, "physicalType");
break;
}
}
FF_LIST_FOR_EACH(FFDisk, item, disks)