diff --git a/sm5/CHANGELOG b/sm5/CHANGELOG index 888f47e0d88e746a20692accb00719bd69ae11e5..1c21b7dac34f5d046be9bb19eb6f2a98c4e86903 100644 --- a/sm5/CHANGELOG +++ b/sm5/CHANGELOG @@ -1,6 +1,6 @@ CHANGELOG for smartmontools -$Id: CHANGELOG,v 1.627 2007/07/26 20:58:50 chrfranke Exp $ +$Id: CHANGELOG,v 1.628 2007/07/28 13:17:38 chrfranke Exp $ The most recent version of this file is: http://smartmontools.cvs.sourceforge.net/smartmontools/sm5/CHANGELOG?view=markup @@ -33,6 +33,10 @@ NOTES FOR FUTURE RELEASES: see TODO file. <DEVELOPERS: ADDITIONS TO THE CHANGE LOG GO JUST BELOW HERE, PLEASE> + [CF] Windows: Added automatic ATA/SCSI device type detection and + SCSI device scanning. The device names '/dev/sdX' and + '/dev/pd<n>' now work for both ATA and SCSI disks. + [CF] smartctl: Added ability to parse '-r ataioctl,2' output from stdin ('-') and simulate the ATA commands for testing purposes. diff --git a/sm5/os_win32.cpp b/sm5/os_win32.cpp index 65998f1de8477a1db89b43c90d6360d0584e4281..fd8b01159cc4219e716bea5d72e92470dcc878e0 100644 --- a/sm5/os_win32.cpp +++ b/sm5/os_win32.cpp @@ -44,7 +44,7 @@ extern int64_t bytes; // malloc() byte count // Needed by '-V' option (CVS versioning) of smartd/smartctl -const char *os_XXXX_c_cvsid="$Id: os_win32.cpp,v 1.55 2007/07/22 19:38:44 chrfranke Exp $" +const char *os_XXXX_c_cvsid="$Id: os_win32.cpp,v 1.56 2007/07/28 13:17:38 chrfranke Exp $" ATACMDS_H_CVSID CONFIG_H_CVSID EXTERN_H_CVSID INT64_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID; @@ -135,10 +135,13 @@ const char * get_os_version_str() } +static int get_controller_type(int phydrive, int logdrive); + #define ATARAID_FDOFFSET 0x0200 static int ata_open(int phydrive, int logdrive, const char * options, int port); static void ata_close(int fd); +static int ata_scan_win9x(unsigned long * drives); static int ata_scan(unsigned long * drives, int * rdriveno, unsigned long * rdrives); static const char * ata_get_def_options(void); @@ -157,6 +160,7 @@ static int aspi_scan(unsigned long * drives); static int spt_open(int pd_num, int ld_num, int tape_num, int sub_addr); static void spt_close(int fd); +static int spt_scan(unsigned long * drives); static int is_permissive() @@ -193,22 +197,25 @@ int guess_device_type (const char * dev_name) dev_name = skipdev(dev_name); if (!strncmp(dev_name, "hd", 2)) return CONTROLLER_ATA; - if (drive_letter(dev_name) >= 0) - return CONTROLLER_ATA; if (!strncmp(dev_name, "tw_cli", 6)) return CONTROLLER_ATA; if (!strncmp(dev_name, "scsi", 4)) return CONTROLLER_SCSI; - if (!strncmp(dev_name, "sd", 2)) - return CONTROLLER_SCSI; - if (!strncmp(dev_name, "pd", 2)) - return CONTROLLER_SCSI; if (!strncmp(dev_name, "st", 2)) return CONTROLLER_SCSI; if (!strncmp(dev_name, "nst", 3)) return CONTROLLER_SCSI; if (!strncmp(dev_name, "tape", 4)) return CONTROLLER_SCSI; + int logdrive = drive_letter(dev_name); + if (logdrive >= 0) + return get_controller_type(-1, logdrive); + char drive[1+1] = ""; + if (sscanf(dev_name, "sd%1[a-z]", drive) == 1) + return get_controller_type(drive[0]-'a', -1); + int phydrive = -1; + if (sscanf(dev_name, "pd%d", &phydrive) == 1 && phydrive >= 0) + return get_controller_type(phydrive, -1); return CONTROLLER_UNKNOWN; } @@ -229,17 +236,32 @@ int make_device_names (char*** devlist, const char* type) rdriveno[0] = rdriveno[1] = -1; rdrives[0] = rdrives[1] = 0; + bool win9x = is_win9x(); if (!strcmp(type, "ATA")) { // bit i set => drive i present - n = ata_scan(drives, rdriveno, rdrives); - path = "/dev/hda"; + if (win9x) { + n = ata_scan_win9x(drives); + path = "/dev/hda"; + } + else { + n = ata_scan(drives, rdriveno, rdrives); + path = "/dev/sda"; + } nmax = 10; } else if (!strcmp(type, "SCSI")) { - // bit i set => drive with ID (i & 0x7) on adapter (i >> 3) present - n = aspi_scan(drives); - path = "/dev/scsi00"; - nmax = 10*8; + if (win9x) { + // bit i set => drive with ID (i & 0x7) on adapter (i >> 3) present + n = aspi_scan(drives); + path = "/dev/scsi00"; + nmax = 10*8; + } + else { + // bit i set => drive i present + n = spt_scan(drives); + path = "/dev/sda"; + nmax = 10; + } } else return -1; @@ -264,7 +286,7 @@ int make_device_names (char*** devlist, const char* type) if (!(rdrives[ci] & (1L << pi))) continue; char rpath[20]; - sprintf(rpath, "/dev/hd%c,%u", 'a'+j, pi); + sprintf(rpath, "/dev/sd%c,%u", 'a'+j, pi); sz = strlen(rpath)+1; char * s = (char *)malloc(sz); bytes += sz; strcpy(s, rpath); @@ -304,19 +326,25 @@ int deviceopen(const char * pathname, char *type) int len = strlen(pathname); if (!strcmp(type, "ATA")) { - // hd[a-j](:[saicp]+)? => Physical drive 0-25, with options + // [sh]d[a-z](:[saicp]+)? => Physical drive 0-25, with options char drive[1+1] = "", options[7+1] = ""; int n1 = -1, n2 = -1; - if ( sscanf(pathname, "hd%1[a-z]%n:%6[saicmp]%n", drive, &n1, options, &n2) >= 1 - && ((n1 == len && !options[0]) || n2 == len) ) { + if ( sscanf(pathname, "%*[sh]d%1[a-z]%n:%6[saicmp]%n", drive, &n1, options, &n2) >= 1 + && ((n1 == len && !options[0]) || n2 == len) ) { return ata_open(drive[0] - 'a', -1, options, -1); } - // hd[a-j],N(:[saicp]+)? => Physical drive 0-25, RAID port N, with options + // [sh]d[a-z],N(:[saicp]+)? => Physical drive 0-25, RAID port N, with options drive[0] = 0; options[0] = 0; n1 = -1; n2 = -1; unsigned port = ~0; - if ( sscanf(pathname, "hd%1[a-z],%u%n:%7[saicmp3]%n", drive, &port, &n1, options, &n2) >= 2 - && port < 32 && ((n1 == len && !options[0]) || n2 == len) ) { + if ( sscanf(pathname, "%*[sh]d%1[a-z],%u%n:%7[saicmp3]%n", drive, &port, &n1, options, &n2) >= 2 + && port < 32 && ((n1 == len && !options[0]) || n2 == len) ) { return ata_open(drive[0] - 'a', -1, options, port); } + // pd<m>,N => Physical drive <m>, RAID port N + int phydrive = -1; port = ~0; n1 = -1; n2 = -1; + if ( sscanf(pathname, "pd%d%n,%u%n", &phydrive, &n1, &port, &n2) >= 1 + && phydrive >= 0 && ((n1 == len && (int)port < 0) || (n2 == len && port < 32))) { + return ata_open(phydrive, -1, "", (int)port); + } // [a-zA-Z]: => Physical drive behind logical drive 0-25 int logdrive = drive_letter(pathname); if (logdrive >= 0) { @@ -1587,6 +1615,162 @@ static int tw_cli_command_interface(smart_command_set command, int /*select*/, c } +///////////////////////////////////////////////////////////////////////////// + +// IOCTL_STORAGE_QUERY_PROPERTY + +#define FILE_DEVICE_MASS_STORAGE 0x0000002d +#define IOCTL_STORAGE_BASE FILE_DEVICE_MASS_STORAGE +#define FILE_ANY_ACCESS 0 + +#define IOCTL_STORAGE_QUERY_PROPERTY \ + CTL_CODE(IOCTL_STORAGE_BASE, 0x0500, METHOD_BUFFERED, FILE_ANY_ACCESS) + +typedef enum _STORAGE_BUS_TYPE { + BusTypeUnknown = 0x00, + BusTypeScsi = 0x01, + BusTypeAtapi = 0x02, + BusTypeAta = 0x03, + BusType1394 = 0x04, + BusTypeSsa = 0x05, + BusTypeFibre = 0x06, + BusTypeUsb = 0x07, + BusTypeRAID = 0x08, + BusTypeiScsi = 0x09, + BusTypeSas = 0x0A, + BusTypeSata = 0x0B, + BusTypeSd = 0x0C, + BusTypeMmc = 0x0D, + BusTypeMax = 0x0E, + BusTypeMaxReserved = 0x7F +} STORAGE_BUS_TYPE, *PSTORAGE_BUS_TYPE; + +typedef struct _STORAGE_DEVICE_DESCRIPTOR { + ULONG Version; + ULONG Size; + UCHAR DeviceType; + UCHAR DeviceTypeModifier; + BOOLEAN RemovableMedia; + BOOLEAN CommandQueueing; + ULONG VendorIdOffset; + ULONG ProductIdOffset; + ULONG ProductRevisionOffset; + ULONG SerialNumberOffset; + STORAGE_BUS_TYPE BusType; + ULONG RawPropertiesLength; + UCHAR RawDeviceProperties[1]; +} STORAGE_DEVICE_DESCRIPTOR, *PSTORAGE_DEVICE_DESCRIPTOR; + +typedef enum _STORAGE_QUERY_TYPE { + PropertyStandardQuery = 0, + PropertyExistsQuery, + PropertyMaskQuery, + PropertyQueryMaxDefined +} STORAGE_QUERY_TYPE, *PSTORAGE_QUERY_TYPE; + +typedef enum _STORAGE_PROPERTY_ID { + StorageDeviceProperty = 0, + StorageAdapterProperty, + StorageDeviceIdProperty, + StorageDeviceUniqueIdProperty, + StorageDeviceWriteCacheProperty, + StorageMiniportProperty, + StorageAccessAlignmentProperty +} STORAGE_PROPERTY_ID, *PSTORAGE_PROPERTY_ID; + +typedef struct _STORAGE_PROPERTY_QUERY { + STORAGE_PROPERTY_ID PropertyId; + STORAGE_QUERY_TYPE QueryType; + UCHAR AdditionalParameters[1]; +} STORAGE_PROPERTY_QUERY, *PSTORAGE_PROPERTY_QUERY; + + +///////////////////////////////////////////////////////////////////////////// + +// Return STORAGE_BUS_TYPE for device, BusTypeUnknown on error. +// (HANDLE does not need any access rights, therefore this works +// without admin rights) + +static STORAGE_BUS_TYPE ioctl_get_storage_bus_type(HANDLE hdevice) +{ + STORAGE_PROPERTY_QUERY query = {StorageDeviceProperty, PropertyStandardQuery, 0}; + + union { + STORAGE_DEVICE_DESCRIPTOR dev; + char raw[256]; + } prop; + memset(&prop, 0, sizeof(prop)); + + DWORD num_out; + if (!DeviceIoControl(hdevice, IOCTL_STORAGE_QUERY_PROPERTY, + &query, sizeof(query), &prop, sizeof(prop), &num_out, NULL)) { + if (con->reportataioctl > 1 || con->reportscsiioctl > 1) + pout(" IOCTL_STORAGE_QUERY_PROPERTY failed, Error=%ld\n", GetLastError()); + return BusTypeUnknown; + } + + if (con->reportataioctl > 1 || con->reportscsiioctl > 1) { + pout(" IOCTL_STORAGE_QUERY_PROPERTY returns:\n" + " Vendor: \"%s\"\n" + " Product: \"%s\"\n" + " Revision: \"%s\"\n" + " Removable: %s\n" + " BusType: 0x%02x\n", + (prop.dev.VendorIdOffset ? prop.raw+prop.dev.VendorIdOffset : ""), + (prop.dev.ProductIdOffset ? prop.raw+prop.dev.ProductIdOffset : ""), + (prop.dev.ProductRevisionOffset ? prop.raw+prop.dev.ProductRevisionOffset : ""), + (prop.dev.RemovableMedia? "Yes":"No"), prop.dev.BusType + ); + } + return prop.dev.BusType; +} + +// get CONTROLLER_* for open handle +static int get_controller_type(HANDLE hdevice) +{ + STORAGE_BUS_TYPE type = ioctl_get_storage_bus_type(hdevice); + switch (type) { + case BusTypeAta: + case BusTypeSata: + return CONTROLLER_ATA; + case BusTypeScsi: + case BusTypeiScsi: + case BusTypeSas: + return CONTROLLER_SCSI; + default: + return CONTROLLER_UNKNOWN; + } + /*NOTREACHED*/ +} + +// get CONTROLLER_* for device path +static int get_controller_type(const char * path) +{ + HANDLE h = CreateFileA(path, 0/*NO ACCESS*/, FILE_SHARE_READ|FILE_SHARE_WRITE, + NULL, OPEN_EXISTING, 0, NULL); + if (h == INVALID_HANDLE_VALUE) + return CONTROLLER_UNKNOWN; + if (con->reportataioctl > 1 || con->reportscsiioctl > 1) + pout(" %s: successfully opened\n", path); + int type = get_controller_type(h); + CloseHandle(h); + return type; +} + +// get CONTROLLER_* for physical or logical drive number +static int get_controller_type(int phydrive, int logdrive) +{ + char path[30]; + if (phydrive >= 0) + snprintf (path, sizeof(path)-1, "\\\\.\\PhysicalDrive%d", phydrive); + else if (logdrive >= 0) + snprintf(path, sizeof(path)-1, "\\\\.\\%c:", 'A'+logdrive); + else + return CONTROLLER_UNKNOWN; + return get_controller_type(path); +} + + ///////////////////////////////////////////////////////////////////////////// // Call GetDevicePowerState() if available (Win98/ME/2000/XP/2003) @@ -1863,65 +2047,98 @@ static void ata_close(int /*fd*/) } +// Scan for ATA drives on Win9x/ME, fill bitmask of drives present, return #drives + +static int ata_scan_win9x(unsigned long * drives) +{ + // Open device + const char devpath[] = "\\\\.\\SMARTVSD"; + HANDLE h = CreateFileA(devpath, GENERIC_READ|GENERIC_WRITE, + FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0); + if (h == INVALID_HANDLE_VALUE) { + if (con->reportataioctl > 1) + pout(" %s: Open failed, Error=%ld\n", devpath, GetLastError()); + return 0; // SMARTVSD.VXD missing or no ATA devices + } + + // Get drive map + GETVERSIONOUTPARAMS vers; memset(&vers, 0, sizeof(vers)); + DWORD num_out; + if (!DeviceIoControl(h, SMART_GET_VERSION, + NULL, 0, &vers, sizeof(vers), &num_out, NULL)) { + if (con->reportataioctl) + pout(" %s: SMART_GET_VERSION failed, Error=%ld\n", devpath, GetLastError()); + CloseHandle(h); + return 0; // Should not happen + } + CloseHandle(h); + + if (con->reportataioctl) { + pout(" %s: SMART_GET_VERSION (%ld bytes):\n" + " Vers = %d.%d, Caps = 0x%lx, DeviceMap = 0x%02x\n", + devpath, num_out, vers.bVersion, vers.bRevision, + vers.fCapabilities, vers.bIDEDeviceMap); + } + + // Check ATA device presence, remove ATAPI devices + drives[0] = (vers.bIDEDeviceMap & 0xf) & ~((vers.bIDEDeviceMap >> 4) & 0xf); + return (drives[0]&1) + ((drives[0]>>1)&1) + ((drives[0]>>2)&1) + ((drives[0]>>3)&1); +} + + // Scan for ATA drives, fill bitmask of drives present, return #drives static int ata_scan(unsigned long * drives, int * rdriveno, unsigned long * rdrives) { - bool win9x = is_win9x(); int cnt = 0; for (int i = 0; i <= 9; i++) { - char devpath[30]; - GETVERSIONOUTPARAMS vers; - const GETVERSIONINPARAMS_EX & vers_ex = (const GETVERSIONINPARAMS_EX &)vers; - DWORD num_out; - HANDLE h; - if (win9x) - strcpy(devpath, "\\\\.\\SMARTVSD"); - else - snprintf(devpath, sizeof(devpath)-1, "\\\\.\\PhysicalDrive%d", i); - // Open device - if ((h = CreateFileA(devpath, - GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE, - NULL, OPEN_EXISTING, 0, 0)) == INVALID_HANDLE_VALUE) { + char devpath[30]; + snprintf(devpath, sizeof(devpath)-1, "\\\\.\\PhysicalDrive%d", i); + HANDLE h = CreateFileA(devpath, GENERIC_READ|GENERIC_WRITE, + FILE_SHARE_READ|FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, 0); + if (h == INVALID_HANDLE_VALUE) { if (con->reportataioctl > 1) pout(" %s: Open failed, Error=%ld\n", devpath, GetLastError()); - if (win9x) - break; // SMARTVSD.VXD missing or no ATA devices - continue; // Disk not found or access denied (break;?) + continue; } + if (con->reportataioctl) + pout(" %s: successfully opened\n", devpath); - // Get drive map - memset(&vers, 0, sizeof(vers)); - if (!DeviceIoControl(h, SMART_GET_VERSION, - NULL, 0, &vers, sizeof(vers), &num_out, NULL)) { - if (con->reportataioctl) - pout(" %s: SMART_GET_VERSION failed, Error=%ld\n", devpath, GetLastError()); + // Skip SCSI + int type = get_controller_type(h); + if (type == CONTROLLER_SCSI) { // ATA RAID may return CONTROLLER_UNKNOWN CloseHandle(h); - if (win9x) - break; // Should not happen - continue; // Non ATA disk or no SMART ioctl support (possibly SCSI disk) + continue; } - CloseHandle(h); + // Try SMART_GET_VERSION + GETVERSIONOUTPARAMS vers; memset(&vers, 0, sizeof(vers)); + const GETVERSIONINPARAMS_EX & vers_ex = (const GETVERSIONINPARAMS_EX &)vers; + DWORD num_out; + BOOL smart_ok = DeviceIoControl(h, SMART_GET_VERSION, + NULL, 0, &vers, sizeof(vers), &num_out, NULL); if (con->reportataioctl) { - pout(" %s: SMART_GET_VERSION (%ld bytes):\n" - " Vers = %d.%d, Caps = 0x%lx, DeviceMap = 0x%02x\n", - devpath, num_out, vers.bVersion, vers.bRevision, - vers.fCapabilities, vers.bIDEDeviceMap); - if (vers_ex.wIdentifier == SMART_VENDOR_3WARE) - pout(" Identifier = %04x(3WARE), ControllerId=%u, DeviceMapEx = 0x%08lx\n", - vers_ex.wIdentifier, vers_ex.wControllerId, vers_ex.dwDeviceMapEx); + if (!smart_ok) + pout(" %s: SMART_GET_VERSION failed, Error=%ld\n", devpath, GetLastError()); + else { + pout(" %s: SMART_GET_VERSION (%ld bytes):\n" + " Vers = %d.%d, Caps = 0x%lx, DeviceMap = 0x%02x\n", + devpath, num_out, vers.bVersion, vers.bRevision, + vers.fCapabilities, vers.bIDEDeviceMap); + if (vers_ex.wIdentifier == SMART_VENDOR_3WARE) + pout(" Identifier = %04x(3WARE), ControllerId=%u, DeviceMapEx = 0x%08lx\n", + vers_ex.wIdentifier, vers_ex.wControllerId, vers_ex.dwDeviceMapEx); + } } + CloseHandle(h); - if (win9x) { - // Check ATA device presence, remove ATAPI devices - drives[0] = (vers.bIDEDeviceMap & 0xf) & ~((vers.bIDEDeviceMap >> 4) & 0xf); - cnt = (drives[0]&1) + ((drives[0]>>1)&1) + ((drives[0]>>2)&1) + ((drives[0]>>3)&1); - break; - } + // If SMART_GET_VERSION failed, driver may support ATA_PASS_THROUGH instead + if (!(smart_ok || type == CONTROLLER_ATA)) + continue; - if (vers_ex.wIdentifier == SMART_VENDOR_3WARE) { + // Interpret RAID drive map if present + if (smart_ok && vers_ex.wIdentifier == SMART_VENDOR_3WARE) { // Skip if more than 2 controllers or logical drive from this controller already seen if (vers_ex.wControllerId >= 2 || rdriveno[vers_ex.wControllerId] >= 0) continue; @@ -1939,7 +2156,7 @@ static int ata_scan(unsigned long * drives, int * rdriveno, unsigned long * rdri cnt += pcnt-1; } - // ATA drive exists and driver supports SMART ioctl + // Driver supports SMART_GET_VERSION or STORAGE_QUERY_PROPERTY returns ATA/SATA drives[0] |= (1L << i); cnt++; } @@ -2842,7 +3059,7 @@ static int spt_open(int pd_num, int ld_num, int tape_num, int sub_addr) } sdip->h_spt_ioctl = h; return k + SPT_FDOFFSET; - + err_out: spt_dev_arr[k] = NULL; free(sdip); @@ -2871,6 +3088,20 @@ static void spt_close(int fd) } +static int spt_scan(unsigned long * drives) +{ + int cnt = 0; + for (int i = 0; i <= 9; i++) { + if (get_controller_type(i, -1) != CONTROLLER_SCSI) + continue; + // STORAGE_QUERY_PROPERTY returned SCSI/SAS/... + drives[0] |= (1L << i); + cnt++; + } + return cnt; +} + + #define IOCTL_SCSI_PASS_THROUGH_DIRECT \ CTL_CODE(IOCTL_SCSI_BASE, 0x0405, METHOD_BUFFERED, FILE_READ_ACCESS | FILE_WRITE_ACCESS) diff --git a/sm5/smartctl.8.in b/sm5/smartctl.8.in index 40e64d3f19f7424a27da3045e3a0e3e0c0308830..1eaa4f128d1cf4cfea8d729d2e6298be9796a725 100644 --- a/sm5/smartctl.8.in +++ b/sm5/smartctl.8.in @@ -1,7 +1,7 @@ .ig Copyright (C) 2002-7 Bruce Allen <smartmontools-support@lists.sourceforge.net> - $Id: smartctl.8.in,v 1.101 2007/07/26 20:58:50 chrfranke Exp $ + $Id: smartctl.8.in,v 1.102 2007/07/28 13:17:38 chrfranke Exp $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free @@ -89,20 +89,21 @@ accessed via a patched SMARTVSE.VXD (see INSTALL file for details). Use the form \fB"/dev/scsi[0\-9][0\-f]"\fP for SCSI devices via an aspi dll on ASPI adapter 0\-9, ID 0\-15. The prefix \fB"/dev/"\fP is optional. .IP \fBWINDOWS\ NT4/2000/XP/2003/Vista\fP: 9 -Use the form \fB"/dev/hd[a\-z]"\fP for IDE/(S)ATA disks -"\\\\.\\PhysicalDrive[0\-25]". Use \fB"/dev/sd[a\-z]"\fP for SCSI disks -"\\\\.\\PhysicalDrive[0\-25]" (where "a" maps to "0"). SCSI disks can -also be referred to as \fB"/dev/pd[0\-255]"\fP for +Use the forms \fB"/dev/sd[a\-z]"\fP for IDE/(S)ATA and SCSI disks +"\\\\.\\PhysicalDrive[0\-25]" (where "a" maps to "0"). +These disks can also be referred to as \fB"/dev/pd[0\-255]"\fP for "\\\\.\\PhysicalDrive[0\-255]". +ATA disks can also be referred to as \fB"/dev/hd[a\-z]"\fP for +"\\\\.\\PhysicalDrive[0\-25]". Use one the forms \fB"/dev/tape[0\-255]"\fP, \fB"/dev/st[0\-255]"\fP, or \fB"/dev/nst[0\-255]"\fP for SCSI tape drives "\\\\.\\Tape[0\-255]". Alternatively, drive letters \fB"X:"\fP or \fB"X:\\"\fP may be used to specify the physical drive behind a mounted partition. -For disks behind 3ware 9000 controllers use \fB"/dev/hd[a\-z],N"\fP where +For disks behind 3ware 9000 controllers use \fB"/dev/sd[a\-z],N"\fP where N specifies the disk number (3ware \'port\') behind the controller -providing the logical drive (\'unit\') specified by \fB"/dev/hd[a\-z]"\fP. +providing the logical drive (\'unit\') specified by \fB"/dev/sd[a\-z]"\fP. Alternatively, use \fB"/dev/tw_cli/cx/py"\fP for controller x, port y to run the \'tw_cli\' tool and parse the output. This provides limited monitoring (\'\-i\', \'\-c\', \'\-A\' below) if SMART support is missing @@ -1499,7 +1500,7 @@ these documents may be found in the References section of the .SH CVS ID OF THIS PAGE: -$Id: smartctl.8.in,v 1.101 2007/07/26 20:58:50 chrfranke Exp $ +$Id: smartctl.8.in,v 1.102 2007/07/28 13:17:38 chrfranke Exp $ .\" Local Variables: .\" mode: nroff .\" End: diff --git a/sm5/smartd.8.in b/sm5/smartd.8.in index a54d6332a75fbade27e10f5eab84d636a3ff79f5..e4de9f07acf5342219048bb3f7237dce46aaf4c1 100644 --- a/sm5/smartd.8.in +++ b/sm5/smartd.8.in @@ -1,7 +1,7 @@ .ig Copyright (C) 2002-7 Bruce Allen <smartmontools-support@lists.sourceforge.net> -$Id: smartd.8.in,v 1.116 2007/07/20 21:00:43 chrfranke Exp $ +$Id: smartd.8.in,v 1.117 2007/07/28 13:17:38 chrfranke Exp $ This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -101,28 +101,21 @@ Examine all entries \fB"/dev/rdsk/c?t?d?s?"\fP for IDE/ATA and SCSI disk devices, and entries \fB"/dev/rmt/*"\fP for SCSI tape devices. .IP \fBDARWIN:\fP 9 The IOService plane is scanned for ATA block storage devices. -.IP \fBWINDOWS:\fP 9 -Examine all entries \fB"/dev/hd[a-j]"\fP ("\\\\.\\PhysicalDrive[0-9]") -for IDE/ATA devices on WinNT4/2000/XP, \fB"/dev/hd[a-d]"\fP -(bitmask from "\\\\.\\SMARTVSD") for IDE/ATA devices on Win95/98/98SE/ME. -Examines all entries \fB"/dev/scsi[0\-9][0\-f]"\fP for SCSI devices +.IP \fBWINDOWS\ 9x/ME\fP: 9 +Examine all entries \fB"/dev/hd[a-d]"\fP (bitmask +from "\\\\.\\SMARTVSD") for IDE/ATA devices. +Examine all entries \fB"/dev/scsi[0\-9][0\-f]"\fP for SCSI devices on ASPI adapter 0\-9, ID 0\-15. +.IP \fBWINDOWS\ NT4/2000/XP/2003/Vista\fP: 9 +Examine all entries \fB"/dev/sd[a-j]"\fP ("\\\\.\\PhysicalDrive[0-9]") +for IDE/(S)ATA and SCSI disk devices + If a 3ware 9000 controller is installed, examine all entries -\fB"/dev/hdX,N"\fP for the first logical drive (\'unit\' -\fB"/dev/hdX"\fP) and all physical disks (\'ports\' \fB",N"\fP) +\fB"/dev/sdX,N"\fP for the first logical drive (\'unit\' +\fB"/dev/sdX"\fP) and all physical disks (\'ports\' \fB",N"\fP) detected behind this controller. Same for a second controller if present. - -The following forms are not scanned for but can be given explicitly in the -configuration file and only apply to WinNT4/2000/XP/2003. The -form \fB"/dev/sd[a\-z]"\fP can be given for SCSI -disks "\\\\.\\PhysicalDrive[0\-25]" (where "a" maps to "0"). Additionally -the form \fB"/dev/pd[0\-255]"\fP can be given for SCSI -disks "\\\\.\\PhysicalDrive[0\-255]". -One the forms \fB"/dev/tape[0\-255]"\fP, \fB"/dev/st[0\-255]"\fP, -or \fB"/dev/nst[0\-255]"\fP can be given for SCSI tape -drives "\\\\.\\Tape[0\-255]". .IP \fBCYGWIN\fP: 9 -See "WINDOWS" above. +See "WINDOWS NT4/2000/XP/2003/Vista" above. .IP \fBOS/2,eComStation\fP: 9 Use the form \fB"/dev/hd[a\-z]"\fP for IDE/ATA devices. .PP @@ -1958,4 +1951,4 @@ smartmontools home page at \fBhttp://smartmontools.sourceforge.net/#references\f .SH CVS ID OF THIS PAGE: -$Id: smartd.8.in,v 1.116 2007/07/20 21:00:43 chrfranke Exp $ +$Id: smartd.8.in,v 1.117 2007/07/28 13:17:38 chrfranke Exp $