From 411737a991774a59c714b218f0c86336ddd9b1f1 Mon Sep 17 00:00:00 2001 From: chrfranke <chrfranke@4ea69e1a-61f1-4043-bf83-b5c94c648137> Date: Mon, 26 Apr 2004 18:12:47 +0000 Subject: [PATCH] Cygwin smartd: Fixed crash on access of SCSI devices after fork() git-svn-id: https://smartmontools.svn.sourceforge.net/svnroot/smartmontools/trunk@1686 4ea69e1a-61f1-4043-bf83-b5c94c648137 --- sm5/CHANGELOG | 4 +++- sm5/os_win32.c | 28 ++++++++++++++++++++++------ sm5/os_win32.cpp | 28 ++++++++++++++++++++++------ 3 files changed, 47 insertions(+), 13 deletions(-) diff --git a/sm5/CHANGELOG b/sm5/CHANGELOG index cafb0886b..3c6d18aca 100644 --- a/sm5/CHANGELOG +++ b/sm5/CHANGELOG @@ -1,6 +1,6 @@ CHANGELOG for smartmontools -$Id: CHANGELOG,v 1.403 2004/04/24 16:43:48 pjwilliams Exp $ +$Id: CHANGELOG,v 1.404 2004/04/26 18:12:47 chrfranke Exp $ The most recent version of this file is: http://cvs.sourceforge.net/viewcvs.py/smartmontools/sm5/CHANGELOG?sortby=date&view=markup @@ -27,6 +27,8 @@ NOTES FOR FUTURE RELEASES: see TODO file. <ADDITIONS TO THE CHANGE LOG SHOULD BE ADDED JUST BELOW HERE, PLEASE> + [CF] Cygwin smartd: Fixed crash on access of SCSI devices after fork(). + [PW] Added TOSHIBA MK4018GAS and the following Maxtor drive families to knowndrives table: DiamondMax D540X-4G, Fireball 541DX, DiamondMax 3400 Ultra ATA, DiamondMax Plus 6800 Ultra ATA 66. diff --git a/sm5/os_win32.c b/sm5/os_win32.c index 5d28ad3b2..35a0b609d 100644 --- a/sm5/os_win32.c +++ b/sm5/os_win32.c @@ -38,7 +38,7 @@ extern int64_t bytes; // malloc() byte count #define ARGUSED(x) ((void)(x)) // Needed by '-V' option (CVS versioning) of smartd/smartctl -const char *os_XXXX_c_cvsid="$Id: os_win32.c,v 1.10 2004/04/07 10:11:34 chrfranke Exp $" +const char *os_XXXX_c_cvsid="$Id: os_win32.c,v 1.11 2004/04/26 18:12:47 chrfranke Exp $" ATACMDS_H_CVSID CONFIG_H_CVSID EXTERN_H_CVSID INT64_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID; @@ -800,7 +800,7 @@ typedef struct { ASPI_SRB_HEAD h; // 00: Header unsigned char target_id; // 08: Target ID unsigned char lun; // 09: LUN - unsigned char devtype; // 10: LUN + unsigned char devtype; // 10: Device type unsigned char reserved; // 11: Reserved } ASPI_SRB_DEVTYPE; @@ -877,6 +877,14 @@ static HINSTANCE h_aspi_dll; // DLL handle static UINT (* aspi_entry)(ASPI_SRB * srb); // ASPI entrypoint static unsigned num_aspi_adapters; +#ifdef __CYGWIN__ +// h_aspi_dll+aspi_entry is not inherited by Cygwin's fork() +static DWORD aspi_dll_pid; // PID of DLL owner to detect fork() +#define aspi_entry_valid() (aspi_entry && (aspi_dll_pid == GetCurrentProcessId())) +#else +#define aspi_entry_valid() (!!aspi_entry) +#endif + static int aspi_call(ASPI_SRB * srb) { @@ -903,6 +911,7 @@ static int aspi_call(ASPI_SRB * srb) static int aspi_open_dll(int verbose) { ASPI_SRB srb; + assert(!aspi_entry_valid()); // Check structure layout assert(sizeof(srb.h) == 8); @@ -923,7 +932,7 @@ static int aspi_open_dll(int verbose) } // Get ASPI entrypoint from winaspi.dll - if (!h_aspi_dll && !(h_aspi_dll = LoadLibraryA("WNASPI32.DLL"))) { + if (!(h_aspi_dll = LoadLibraryA("WNASPI32.DLL"))) { if (verbose) pout("Cannot load WNASPI32.DLL, Error=%ld\n", GetLastError()); h_aspi_dll = INVALID_HANDLE_VALUE; @@ -960,6 +969,12 @@ static int aspi_open_dll(int verbose) #ifdef _DEBUG pout("%u ASPI adapters on manager \"%.16s\"\n", num_aspi_adapters, srb.q.manager_id); #endif + +#ifdef __CYGWIN__ + // save PID to detect fork() in aspi_entry_valid() + aspi_dll_pid = GetCurrentProcessId(); +#endif + assert(aspi_entry_valid()); return 0; } @@ -1004,7 +1019,7 @@ static int aspi_open(unsigned adapter, unsigned id) return -1; } - if (!aspi_entry) { + if (!aspi_entry_valid()) { if (aspi_open_dll(1/*verbose*/)) return -1; } @@ -1024,6 +1039,7 @@ static int aspi_open(unsigned adapter, unsigned id) static void aspi_close(int fd) { + // No FreeLibrary(h_aspi_dll) to prevent problems with ASPI threads ARGUSED(fd); } @@ -1035,7 +1051,7 @@ static unsigned long aspi_scan() unsigned long drives = 0; unsigned ad, nad; - if (!aspi_entry) { + if (!aspi_entry_valid()) { if (aspi_open_dll(0/*quiet*/)) return 0; } @@ -1087,7 +1103,7 @@ int do_scsi_cmnd_io(int fd, struct scsi_cmnd_io * iop, int report) { ASPI_SRB srb; - if (!aspi_entry) + if (!aspi_entry_valid()) return -EBADF; if (!((fd & ~0xff) == 0x100)) return -EBADF; diff --git a/sm5/os_win32.cpp b/sm5/os_win32.cpp index be0e53d2a..59bbfa2f4 100644 --- a/sm5/os_win32.cpp +++ b/sm5/os_win32.cpp @@ -38,7 +38,7 @@ extern int64_t bytes; // malloc() byte count #define ARGUSED(x) ((void)(x)) // Needed by '-V' option (CVS versioning) of smartd/smartctl -const char *os_XXXX_c_cvsid="$Id: os_win32.cpp,v 1.10 2004/04/07 10:11:34 chrfranke Exp $" +const char *os_XXXX_c_cvsid="$Id: os_win32.cpp,v 1.11 2004/04/26 18:12:47 chrfranke Exp $" ATACMDS_H_CVSID CONFIG_H_CVSID EXTERN_H_CVSID INT64_H_CVSID SCSICMDS_H_CVSID UTILITY_H_CVSID; @@ -800,7 +800,7 @@ typedef struct { ASPI_SRB_HEAD h; // 00: Header unsigned char target_id; // 08: Target ID unsigned char lun; // 09: LUN - unsigned char devtype; // 10: LUN + unsigned char devtype; // 10: Device type unsigned char reserved; // 11: Reserved } ASPI_SRB_DEVTYPE; @@ -877,6 +877,14 @@ static HINSTANCE h_aspi_dll; // DLL handle static UINT (* aspi_entry)(ASPI_SRB * srb); // ASPI entrypoint static unsigned num_aspi_adapters; +#ifdef __CYGWIN__ +// h_aspi_dll+aspi_entry is not inherited by Cygwin's fork() +static DWORD aspi_dll_pid; // PID of DLL owner to detect fork() +#define aspi_entry_valid() (aspi_entry && (aspi_dll_pid == GetCurrentProcessId())) +#else +#define aspi_entry_valid() (!!aspi_entry) +#endif + static int aspi_call(ASPI_SRB * srb) { @@ -903,6 +911,7 @@ static int aspi_call(ASPI_SRB * srb) static int aspi_open_dll(int verbose) { ASPI_SRB srb; + assert(!aspi_entry_valid()); // Check structure layout assert(sizeof(srb.h) == 8); @@ -923,7 +932,7 @@ static int aspi_open_dll(int verbose) } // Get ASPI entrypoint from winaspi.dll - if (!h_aspi_dll && !(h_aspi_dll = LoadLibraryA("WNASPI32.DLL"))) { + if (!(h_aspi_dll = LoadLibraryA("WNASPI32.DLL"))) { if (verbose) pout("Cannot load WNASPI32.DLL, Error=%ld\n", GetLastError()); h_aspi_dll = INVALID_HANDLE_VALUE; @@ -960,6 +969,12 @@ static int aspi_open_dll(int verbose) #ifdef _DEBUG pout("%u ASPI adapters on manager \"%.16s\"\n", num_aspi_adapters, srb.q.manager_id); #endif + +#ifdef __CYGWIN__ + // save PID to detect fork() in aspi_entry_valid() + aspi_dll_pid = GetCurrentProcessId(); +#endif + assert(aspi_entry_valid()); return 0; } @@ -1004,7 +1019,7 @@ static int aspi_open(unsigned adapter, unsigned id) return -1; } - if (!aspi_entry) { + if (!aspi_entry_valid()) { if (aspi_open_dll(1/*verbose*/)) return -1; } @@ -1024,6 +1039,7 @@ static int aspi_open(unsigned adapter, unsigned id) static void aspi_close(int fd) { + // No FreeLibrary(h_aspi_dll) to prevent problems with ASPI threads ARGUSED(fd); } @@ -1035,7 +1051,7 @@ static unsigned long aspi_scan() unsigned long drives = 0; unsigned ad, nad; - if (!aspi_entry) { + if (!aspi_entry_valid()) { if (aspi_open_dll(0/*quiet*/)) return 0; } @@ -1087,7 +1103,7 @@ int do_scsi_cmnd_io(int fd, struct scsi_cmnd_io * iop, int report) { ASPI_SRB srb; - if (!aspi_entry) + if (!aspi_entry_valid()) return -EBADF; if (!((fd & ~0xff) == 0x100)) return -EBADF; -- GitLab