1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
|
#include "physicaldisk.h"
#if __has_include(<libgeom.h>)
#include "common/strutil.h"
#include <devstat.h>
#include <memory.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/disk.h>
#include <libgeom.h>
const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options) {
struct gmesh geomTree;
if (geom_gettree(&geomTree) < 0) {
return "geom_gettree() failed";
}
if (geom_stats_open() < 0) {
return "geom_stats_open() failed";
}
void* snap = geom_stats_snapshot_get();
struct devstat* snapIter;
while ((snapIter = geom_stats_snapshot_next(snap)) != NULL) {
if (snapIter->device_type & DEVSTAT_TYPE_PASS) {
continue;
}
struct gident* geomId = geom_lookupid(&geomTree, snapIter->id);
if (geomId == NULL) {
continue;
}
if (geomId->lg_what != ISPROVIDER) {
continue;
}
struct gprovider* provider = (struct gprovider*) geomId->lg_ptr;
if (provider->lg_geom->lg_rank != 1) {
continue;
}
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_UNUSED) {
continue;
}
type |= FF_PHYSICALDISK_TYPE_UNUSED;
}
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreateS(provider->lg_name);
FF_STRBUF_AUTO_DESTROY identifier = ffStrbufCreate();
for (struct gconfig* ptr = provider->lg_config.lh_first; ptr; ptr = ptr->lg_config.le_next) {
if (ffStrEquals(ptr->lg_name, "descr")) {
ffStrbufSetS(&name, ptr->lg_val);
} else if (ffStrEquals(ptr->lg_name, "rotationrate") && !ffStrEquals(ptr->lg_val, "unknown")) {
type |= ffStrEquals(ptr->lg_val, "0") ? FF_PHYSICALDISK_TYPE_SSD : FF_PHYSICALDISK_TYPE_HDD;
} else if (ffStrEquals(ptr->lg_name, "ident")) {
ffStrbufSetS(&identifier, ptr->lg_val);
} else if (ffStrEquals(ptr->lg_name, "access")) {
if (ffStrEquals(ptr->lg_val, "read-only")) {
type |= FF_PHYSICALDISK_TYPE_READONLY;
} else if (ffStrEquals(ptr->lg_val, "read-write")) {
type |= FF_PHYSICALDISK_TYPE_READWRITE;
}
}
}
if (options->namePrefix.length && !ffStrbufStartsWith(&name, &options->namePrefix)) {
continue;
}
FFPhysicalDiskResult* device = FF_LIST_ADD(FFPhysicalDiskResult, *result);
ffStrbufInitF(&device->devPath, "/dev/%s", provider->lg_name);
ffStrbufInitMove(&device->serial, &identifier);
ffStrbufTrimSpace(&device->serial);
ffStrbufInit(&device->revision);
ffStrbufInit(&device->interconnect);
ffStrbufInitMove(&device->name, &name);
device->size = size;
device->temperature = FF_PHYSICALDISK_TEMP_UNSET;
switch (snapIter->device_type & DEVSTAT_TYPE_IF_MASK) {
case DEVSTAT_TYPE_IF_SCSI:
ffStrbufSetStatic(&device->interconnect, "SCSI");
break;
case DEVSTAT_TYPE_IF_IDE:
ffStrbufSetStatic(&device->interconnect, "IDE");
break;
case DEVSTAT_TYPE_IF_OTHER:
ffStrbufSetStatic(&device->interconnect, "OTHER");
break;
// https://github.com/freebsd/freebsd-src/commit/d282baddb0b029ca8466d23ac51e95c918442535
case 0x040 /*DEVSTAT_TYPE_IF_NVME*/:
ffStrbufSetStatic(&device->interconnect, "NVMe");
break;
}
if (!(device->type & FF_PHYSICALDISK_TYPE_READONLY) && !(device->type & FF_PHYSICALDISK_TYPE_READWRITE)) {
int acr = 1, acw = 1; // Number of partitions mounted for reading or writing
if (sscanf(provider->lg_mode, "r%dw%de%*d", &acr, &acw) == 2 && acr) {
type |= acw ? FF_PHYSICALDISK_TYPE_READWRITE : FF_PHYSICALDISK_TYPE_READONLY;
}
}
device->type = type;
}
geom_stats_snapshot_free(snap);
geom_stats_close();
return NULL;
}
#else
const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options) {
return "Fastfetch was compiled without libgeom support";
}
#endif
|