Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve robustness of drive type auto-detection on Linux #343

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 60 additions & 12 deletions linux/DtaDevOS.cpp
Original file line number Diff line number Diff line change
@@ -24,12 +24,14 @@ along with sedutil. If not, see <http://www.gnu.org/licenses/>.
#include <fnmatch.h>
#include <fcntl.h>
#include <sys/ioctl.h>
#include <sys/sysmacros.h>
#include <scsi/sg.h>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#include <unistd.h>
#include <linux/hdreg.h>
#include <linux/major.h>
#include <errno.h>
#include <vector>
#include <fstream>
@@ -60,23 +62,69 @@ void DtaDevOS::init(const char * devref)
memset(&disk_info, 0, sizeof(OPAL_DiskInfo));
dev = devref;

if (!strncmp(devref, "/dev/nvme", 9))
struct stat st;
if (stat(devref, &st) < 0)
{
// DtaDevLinuxNvme *NvmeDrive = new DtaDevLinuxNvme();
drive = new DtaDevLinuxNvme();
LOG(E) << "DtaDevOS::init ERROR - failed to stat " << devref;
isOpen = FALSE;
return;
}
else if (!strncmp(devref, "/dev/s", 6))
switch (st.st_mode & S_IFMT)
{
// DtaDevLinuxSata *SataDrive = new DtaDevLinuxSata();
drive = new DtaDevLinuxSata();
case S_IFBLK: // block device
{
switch (major(st.st_rdev))
{
case SCSI_DISK0_MAJOR:
case SCSI_DISK1_MAJOR:
case SCSI_DISK2_MAJOR:
case SCSI_DISK3_MAJOR:
case SCSI_DISK4_MAJOR:
case SCSI_DISK5_MAJOR:
case SCSI_DISK6_MAJOR:
case SCSI_DISK7_MAJOR:
case SCSI_DISK8_MAJOR:
case SCSI_DISK9_MAJOR:
case SCSI_DISK10_MAJOR:
case SCSI_DISK11_MAJOR:
case SCSI_DISK12_MAJOR:
case SCSI_DISK13_MAJOR:
case SCSI_DISK14_MAJOR:
case SCSI_DISK15_MAJOR:
{
// DtaDevLinuxSata *SataDrive = new DtaDevLinuxSata();
drive = new DtaDevLinuxSata();
goto init;
}
}
break;
}
case S_IFCHR: // character device
{
char path[PATH_MAX];
snprintf(path, sizeof path, "/sys/dev/char/%u:%u/device/driver", major(st.st_rdev), minor(st.st_rdev));
ssize_t r;
if ((r = readlink(path, path, sizeof path - 1)) < 0)
{
LOG(E) << "DtaDevOS::init ERROR - failed to readlink " << path;
isOpen = FALSE;
return;
}
path[r] = '\0'; // readlink does not append a null terminator
if (strcmp(basename(path), "nvme") == 0)
{
// DtaDevLinuxNvme *NvmeDrive = new DtaDevLinuxNvme();
drive = new DtaDevLinuxNvme();
goto init;
}
break;
}
}
else
{
LOG(E) << "DtaDevOS::init ERROR - unknown drive type";
isOpen = FALSE;
return;
}
LOG(E) << "DtaDevOS::init ERROR - unknown drive type";
isOpen = FALSE;
return;

init:
if (drive->init(devref))
{
isOpen = TRUE;