Skip to content

Commit e53acf4

Browse files
committed
Disk (Linux): detect physical type
1 parent 18233a2 commit e53acf4

File tree

5 files changed

+53
-15
lines changed

5 files changed

+53
-15
lines changed

src/detection/disk/disk.h

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77

88
typedef enum FFDiskPhysicalType
99
{
10-
FF_DISK_TYPE_UNKNOWN,
11-
FF_DISK_TYPE_HDD,
12-
FF_DISK_TYPE_SSD,
10+
FF_DISK_PHYSICAL_TYPE_UNKNOWN,
11+
FF_DISK_PHYSICAL_TYPE_HDD,
12+
FF_DISK_PHYSICAL_TYPE_SSD,
1313
} FFDiskPhysicalType;
1414

1515
typedef struct FFDisk

src/detection/disk/disk_bsd.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,7 +71,7 @@ const char* ffDetectDisksImpl(FFlist* disks)
7171
#endif
7272

7373
FFDisk* disk = ffListAdd(disks);
74-
disk->physicalType = FF_DISK_TYPE_UNKNOWN;
74+
disk->physicalType = FF_DISK_PHYSICAL_TYPE_UNKNOWN;
7575

7676
disk->bytesTotal = fs->f_blocks * fs->f_bsize;
7777
disk->bytesFree = (uint64_t)fs->f_bfree * fs->f_bsize;

src/detection/disk/disk_linux.c

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ static bool isSubvolume(const FFlist* disks, FFDisk* currentDisk)
195195
return false;
196196
}
197197

198-
static bool isRemovable(FFDisk* currentDisk)
198+
static bool detectPhysicalTypeAndReturnRemovable(FFDisk* currentDisk)
199199
{
200200
// https://stackoverflow.com/a/73302025
201201
// 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)
218218

219219
if (!ffStrStartsWith(partitionName, entry->d_name)) continue;
220220

221-
// /sys/block/sdx/removable
222221
ffStrbufAppendS(&basePath, entry->d_name);
222+
index = basePath.length;
223+
// /sys/block/sdx/queue/rotational
224+
ffStrbufAppendS(&basePath, "/queue/rotational");
225+
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
226+
if (ffReadFileBuffer(basePath.chars, &buffer))
227+
currentDisk->physicalType = ffStrbufEqualS(&buffer, "1") ? FF_DISK_PHYSICAL_TYPE_HDD : FF_DISK_PHYSICAL_TYPE_SSD;
228+
else
229+
currentDisk->physicalType = FF_DISK_PHYSICAL_TYPE_UNKNOWN;
230+
ffStrbufSubstrBefore(&basePath, index);
231+
232+
// /sys/block/sdx/removable
223233
ffStrbufAppendS(&basePath, "/removable");
224234

225-
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
226235
return ffReadFileBuffer(basePath.chars, &buffer) && ffStrbufEqualS(&buffer, "1");
227236
}
228237

@@ -231,7 +240,10 @@ static bool isRemovable(FFDisk* currentDisk)
231240

232241
static void detectType(const FFlist* disks, FFDisk* currentDisk)
233242
{
234-
if(isRemovable(currentDisk))
243+
bool isRemovable = detectPhysicalTypeAndReturnRemovable(currentDisk);
244+
245+
if(currentDisk->type != FF_DISK_VOLUME_TYPE_NONE) return;
246+
if(isRemovable)
235247
currentDisk->type = FF_DISK_VOLUME_TYPE_EXTERNAL_BIT;
236248
else if(isSubvolume(disks, currentDisk))
237249
currentDisk->type = FF_DISK_VOLUME_TYPE_SUBVOLUME_BIT;
@@ -277,7 +289,7 @@ const char* ffDetectDisksImpl(FFlist* disks)
277289
//We have a valid device, add it to the list
278290
FFDisk* disk = ffListAdd(disks);
279291
disk->type = FF_DISK_VOLUME_TYPE_NONE;
280-
disk->physicalType = FF_DISK_TYPE_UNKNOWN;
292+
disk->physicalType = FF_DISK_PHYSICAL_TYPE_UNKNOWN;
281293

282294
//detect mountFrom
283295
ffStrbufInitS(&disk->mountFrom, device->mnt_fsname);
@@ -293,8 +305,7 @@ const char* ffDetectDisksImpl(FFlist* disks)
293305
detectName(disk); // Also detects external devices
294306

295307
//detect type
296-
if (disk->type == FF_DISK_VOLUME_TYPE_NONE)
297-
detectType(disks, disk);
308+
detectType(disks, disk);
298309

299310
//Detects stats
300311
detectStats(disk);

src/detection/disk/disk_windows.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ const char* ffDetectDisksImpl(FFlist* disks)
2929

3030
wchar_t volumeName[64];
3131

32-
disk->physicalType = FF_DISK_TYPE_UNKNOWN;
32+
disk->physicalType = FF_DISK_PHYSICAL_TYPE_UNKNOWN;
3333
if(mountpoint[1] == ':')
3434
{
3535
memcpy(volumeName, L"\\\\.\\ :", sizeof(L"\\\\.\\ :"));
@@ -51,7 +51,7 @@ const char* ffDetectDisksImpl(FFlist* disks)
5151
NULL,
5252
NULL
5353
))
54-
disk->physicalType = dspd.IncursSeekPenalty ? FF_DISK_TYPE_HDD : FF_DISK_TYPE_SSD;
54+
disk->physicalType = dspd.IncursSeekPenalty ? FF_DISK_PHYSICAL_TYPE_HDD : FF_DISK_PHYSICAL_TYPE_SSD;
5555
}
5656
}
5757

src/modules/disk/disk.c

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
#include "modules/disk/disk.h"
77
#include "util/stringUtils.h"
88

9-
#define FF_DISK_NUM_FORMAT_ARGS 10
9+
#define FF_DISK_NUM_FORMAT_ARGS 11
1010
#pragma GCC diagnostic ignored "-Wsign-conversion"
1111

1212
static void printDisk(FFDiskOptions* options, const FFDisk* disk)
@@ -111,6 +111,19 @@ static void printDisk(FFDiskOptions* options, const FFDisk* disk)
111111
bool isExternal = !!(disk->type & FF_DISK_VOLUME_TYPE_EXTERNAL_BIT);
112112
bool isHidden = !!(disk->type & FF_DISK_VOLUME_TYPE_HIDDEN_BIT);
113113
bool isReadOnly = !!(disk->type & FF_DISK_VOLUME_TYPE_READONLY_BIT);
114+
const char* physicalType;
115+
switch(disk->physicalType)
116+
{
117+
case FF_DISK_PHYSICAL_TYPE_HDD:
118+
physicalType = "HDD";
119+
break;
120+
case FF_DISK_PHYSICAL_TYPE_SSD:
121+
physicalType = "SSD";
122+
break;
123+
default:
124+
physicalType = "Unknown";
125+
break;
126+
}
114127
ffPrintFormatString(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY, FF_DISK_NUM_FORMAT_ARGS, (FFformatarg[]){
115128
{FF_FORMAT_ARG_TYPE_STRBUF, &usedPretty},
116129
{FF_FORMAT_ARG_TYPE_STRBUF, &totalPretty},
@@ -123,6 +136,7 @@ static void printDisk(FFDiskOptions* options, const FFDisk* disk)
123136
{FF_FORMAT_ARG_TYPE_STRBUF, &disk->filesystem},
124137
{FF_FORMAT_ARG_TYPE_STRBUF, &disk->name},
125138
{FF_FORMAT_ARG_TYPE_BOOL, &isReadOnly},
139+
{FF_FORMAT_ARG_TYPE_STRING, physicalType}
126140
});
127141
}
128142
}
@@ -403,7 +417,7 @@ void ffGenerateDiskJson(FFDiskOptions* options, yyjson_mut_doc* doc, yyjson_mut_
403417
yyjson_mut_obj_add_strbuf(doc, obj, "mountpoint", &item->mountpoint);
404418
yyjson_mut_obj_add_strbuf(doc, obj, "mountFrom", &item->mountFrom);
405419
yyjson_mut_obj_add_strbuf(doc, obj, "name", &item->name);
406-
yyjson_mut_val* typeArr = yyjson_mut_obj_add_arr(doc, obj, "type");
420+
yyjson_mut_val* typeArr = yyjson_mut_obj_add_arr(doc, obj, "volumeType");
407421
if(item->type & FF_DISK_VOLUME_TYPE_REGULAR_BIT)
408422
yyjson_mut_arr_add_str(doc, typeArr, "Regular");
409423
if(item->type & FF_DISK_VOLUME_TYPE_EXTERNAL_BIT)
@@ -414,6 +428,19 @@ void ffGenerateDiskJson(FFDiskOptions* options, yyjson_mut_doc* doc, yyjson_mut_
414428
yyjson_mut_arr_add_str(doc, typeArr, "Hidden");
415429
if(item->type & FF_DISK_VOLUME_TYPE_READONLY_BIT)
416430
yyjson_mut_arr_add_str(doc, typeArr, "Read-only");
431+
432+
switch(item->physicalType)
433+
{
434+
case FF_DISK_PHYSICAL_TYPE_HDD:
435+
yyjson_mut_obj_add_str(doc, obj, "physicalType", "HDD");
436+
break;
437+
case FF_DISK_PHYSICAL_TYPE_SSD:
438+
yyjson_mut_obj_add_str(doc, obj, "physicalType", "SSD");
439+
break;
440+
default:
441+
yyjson_mut_obj_add_null(doc, obj, "physicalType");
442+
break;
443+
}
417444
}
418445

419446
FF_LIST_FOR_EACH(FFDisk, item, disks)

0 commit comments

Comments
 (0)