From: Oliver Kurth Date: Fri, 15 Sep 2017 18:23:51 +0000 (-0700) Subject: Emphatically close virtual disk. X-Git-Tag: stable-10.2.0~94 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=d4a5693af649e7c8f87667c60b7e6575b15faa0e;p=thirdparty%2Fopen-vm-tools.git Emphatically close virtual disk. Sometimes I/O stack modules return EBUSY during teardown. This may be due to an external process opening files at inopportune moments. The workaround is to retry the affected operations. --- diff --git a/open-vm-tools/lib/file/file.c b/open-vm-tools/lib/file/file.c index 45418dddc..1bed237bf 100644 --- a/open-vm-tools/lib/file/file.c +++ b/open-vm-tools/lib/file/file.c @@ -287,6 +287,49 @@ File_UnlinkNoFollow(const char *pathName) // IN: } +/* + *---------------------------------------------------------------------- + * + * File_UnlinkRetry -- + * + * Unlink the file, retrying on EBUSY on ESX, up to given timeout. + * + * Results: + * Return 0 if the unlink is successful. Otherwise, return -1. + * + * Side effects: + * The file is removed. + * + *---------------------------------------------------------------------- + */ + +int +File_UnlinkRetry(const char *pathName, // IN: + uint32 maxWaitTimeMilliSec) // IN: +{ + int ret; + + if (vmx86_server) { + uint32 const unlinkWait = 300; + uint32 waitMilliSec = 0; + + do { + ret = FileDeletion(pathName, TRUE); + if (ret != EBUSY || waitMilliSec >= maxWaitTimeMilliSec) { + break; + } + Log(LGPFX" %s: %s after %u ms\n", __FUNCTION__, pathName, unlinkWait); + Util_Usleep(unlinkWait * 1000); + waitMilliSec += unlinkWait; + } while (TRUE); + } else { + ret = FileDeletion(pathName, TRUE); + } + + return ret == 0 ? 0 : -1; +} + + /* *---------------------------------------------------------------------- * diff --git a/open-vm-tools/lib/include/file.h b/open-vm-tools/lib/include/file.h index aef9932a5..1a498adee 100644 --- a/open-vm-tools/lib/include/file.h +++ b/open-vm-tools/lib/include/file.h @@ -55,6 +55,7 @@ extern "C" { #define FILE_SEARCHPATHTOKEN ";" +#define FILE_UNLINK_DEFAULT_WAIT_MS 2000 /* * Opaque, platform-specific stucture for supporting the directory walking API. @@ -151,6 +152,9 @@ int File_UnlinkDelayed(const char *pathName); int File_UnlinkNoFollow(const char *pathName); +int File_UnlinkRetry(const char *pathName, + uint32 maxWaitTimeMilliSec); + void File_SplitName(const char *pathName, char **volume, char **dir,