11#include "physicaldisk.h"
22
33#include "common/io/io.h"
4+ #include "util/stringUtils.h"
45
56#include <OS.h>
67#include <StorageDefs.h>
78#include <Drivers.h>
89#include <sys/ioctl.h>
910
10- static const char * detectDisk (int dfd , const char * diskType , const char * diskId , FFlist * result )
11+ static const char * detectDisk (FFstrbuf * path , const char * diskType , FFlist * result )
1112{
12- char buffer [64 ];
13- snprintf (buffer , sizeof (buffer ), "%s/master/raw" , diskId );
14- FF_AUTO_CLOSE_FD int rawfd = openat (dfd , buffer , O_RDONLY );
15- if (rawfd < 0 )
16- {
17- snprintf (buffer , sizeof (buffer ), "%s/raw" , diskId );
18- rawfd = openat (dfd , buffer , O_RDONLY );
19- if (rawfd < 0 ) return "raw device file not found" ;
20- }
13+ FF_AUTO_CLOSE_FD int rawfd = open (path -> chars , O_RDONLY );
14+ if (rawfd < 0 ) return "detectDisk: open(rawfd) failed" ;
2115
2216 device_geometry geometry ;
2317 if (ioctl (rawfd , B_GET_GEOMETRY , & geometry , sizeof (geometry )) < 0 )
2418 return "ioctl(B_GET_GEOMETRY) failed" ;
2519
26- FFPhysicalDiskResult * device = (FFPhysicalDiskResult * ) ffListAdd (result );
27-
2820 char name [B_OS_NAME_LENGTH ];
29- if (ioctl (rawfd , B_GET_DEVICE_NAME , name , sizeof (name )) == 0 )
30- ffStrbufInitS (& device -> name , name );
31- else
21+ if (ioctl (rawfd , B_GET_DEVICE_NAME , name , sizeof (name )) != 0 )
3222 {
3323 // ioctl reports `not a tty` for NVME drives for some reason
34- ffStrbufInitF ( & device -> name , "Unknown %s drive" , diskType );
24+ snprintf ( name , sizeof ( name ) , "Unknown %s drive" , diskType );
3525 }
3626
37- ffStrbufInitF (& device -> devPath , "/dev/disk/%s/%s" , diskType , buffer );
27+ FFPhysicalDiskResult * device = (FFPhysicalDiskResult * ) ffListAdd (result );
28+ ffStrbufInitS (& device -> name , name );
29+ ffStrbufInitCopy (& device -> devPath , path );
3830 ffStrbufInit (& device -> serial );
3931 ffStrbufInit (& device -> revision );
4032 ffStrbufInitS (& device -> interconnect , diskType );
41- device -> temperature = 0.0 / 0.0 ;
33+ device -> temperature = FF_PHYSICALDISK_TEMP_UNSET ;
4234 device -> type = FF_PHYSICALDISK_TYPE_NONE ;
4335 device -> type |= (geometry .read_only ? FF_PHYSICALDISK_TYPE_READONLY : FF_PHYSICALDISK_TYPE_READWRITE ) |
4436 (geometry .removable ? FF_PHYSICALDISK_TYPE_REMOVABLE : FF_PHYSICALDISK_TYPE_FIXED );
@@ -47,19 +39,32 @@ static const char* detectDisk(int dfd, const char* diskType, const char* diskId,
4739 return NULL ;
4840}
4941
50- static const char * detectDiskType ( int dfd , const char * diskType , FFlist * result )
42+ static const char * searchRawDeviceFile ( FFstrbuf * path , const char * diskType , FFlist * result )
5143{
52- int newfd = openat (dfd , diskType , O_RDONLY );
53- if (newfd < 0 ) return "openat(dfd, diskType) failed" ;
54-
55- FF_AUTO_CLOSE_DIR DIR * dir = fdopendir (newfd );
56- if (!dir ) return "fdopendir(newfd) failed" ;
44+ FF_AUTO_CLOSE_DIR DIR * dir = opendir (path -> chars );
45+ if (!dir ) return "detectDiskType: opendir() failed" ;
46+ uint32_t baseLen = path -> length ;
5747
5848 struct dirent * entry ;
5949 while ((entry = readdir (dir )))
6050 {
6151 if (entry -> d_name [0 ] == '.' ) continue ;
62- detectDisk (newfd , diskType , entry -> d_name , result );
52+ ffStrbufAppendC (path , '/' );
53+ ffStrbufAppendS (path , entry -> d_name );
54+
55+ struct stat st ;
56+ if (stat (path -> chars , & st ) != 0 )
57+ {
58+ ffStrbufSubstrBefore (path , baseLen );
59+ continue ;
60+ }
61+
62+ if (S_ISDIR (st .st_mode ))
63+ searchRawDeviceFile (path , diskType , result );
64+ else if (ffStrEquals (entry -> d_name , "raw" ))
65+ detectDisk (path , diskType , result );
66+
67+ ffStrbufSubstrBefore (path , baseLen );
6368 }
6469 return NULL ;
6570}
@@ -69,11 +74,17 @@ const char* ffDetectPhysicalDisk(FFlist* result, FF_MAYBE_UNUSED FFPhysicalDiskO
6974 FF_AUTO_CLOSE_DIR DIR * dir = opendir ("/dev/disk" );
7075 if (!dir ) return "opendir(/dev/disk) failed" ;
7176
77+ FF_STRBUF_AUTO_DESTROY path = ffStrbufCreateA (64 );
78+ ffStrbufAppendS (& path , "/dev/disk/" );
79+ uint32_t baseLen = path .length ;
80+
7281 struct dirent * entry ;
7382 while ((entry = readdir (dir )))
7483 {
75- if (entry -> d_name [0 ] == '.' ) continue ;
76- detectDiskType (dirfd (dir ), entry -> d_name , result );
84+ if (entry -> d_name [0 ] == '.' || ffStrEquals (entry -> d_name , "virtual" )) continue ;
85+ ffStrbufAppendS (& path , entry -> d_name );
86+ searchRawDeviceFile (& path , entry -> d_name , result );
87+ ffStrbufSubstrBefore (& path , baseLen );
7788 }
7889
7990 return NULL ;
0 commit comments