提交 6cc49f11 编写于 作者: S sherman

6929479: Add a system property sun.zip.disableMemoryMapping to disable mmap use in ZipFile

Summary: system property sun.zip.disableMemoryMapping to disable mmap use
Reviewed-by: alanb
上级 62a3fc4b
...@@ -36,6 +36,8 @@ import java.util.Enumeration; ...@@ -36,6 +36,8 @@ import java.util.Enumeration;
import java.util.Set; import java.util.Set;
import java.util.HashSet; import java.util.HashSet;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import java.security.AccessController;
import sun.security.action.GetPropertyAction;
import static java.util.zip.ZipConstants64.*; import static java.util.zip.ZipConstants64.*;
/** /**
...@@ -78,6 +80,17 @@ class ZipFile implements ZipConstants, Closeable { ...@@ -78,6 +80,17 @@ class ZipFile implements ZipConstants, Closeable {
private static native void initIDs(); private static native void initIDs();
private static final boolean usemmap;
static {
// A system prpperty to disable mmap use to avoid vm crash when
// in-use zip file is accidently overwritten by others.
String prop = AccessController.doPrivileged(
new GetPropertyAction("sun.zip.disableMemoryMapping"));
usemmap = (prop == null ||
!(prop.length() == 0 || prop.equalsIgnoreCase("true")));
}
/** /**
* Opens a zip file for reading. * Opens a zip file for reading.
* *
...@@ -196,7 +209,7 @@ class ZipFile implements ZipConstants, Closeable { ...@@ -196,7 +209,7 @@ class ZipFile implements ZipConstants, Closeable {
throw new NullPointerException("charset is null"); throw new NullPointerException("charset is null");
this.zc = ZipCoder.get(charset); this.zc = ZipCoder.get(charset);
long t0 = System.nanoTime(); long t0 = System.nanoTime();
jzfile = open(name, mode, file.lastModified()); jzfile = open(name, mode, file.lastModified(), usemmap);
sun.misc.PerfCounter.getZipFileOpenTime().addElapsedTimeFrom(t0); sun.misc.PerfCounter.getZipFileOpenTime().addElapsedTimeFrom(t0);
sun.misc.PerfCounter.getZipFileCount().increment(); sun.misc.PerfCounter.getZipFileCount().increment();
this.name = name; this.name = name;
...@@ -673,8 +686,8 @@ class ZipFile implements ZipConstants, Closeable { ...@@ -673,8 +686,8 @@ class ZipFile implements ZipConstants, Closeable {
} }
private static native long open(String name, int mode, long lastModified) private static native long open(String name, int mode, long lastModified,
throws IOException; boolean usemmap) throws IOException;
private static native int getTotal(long jzfile); private static native int getTotal(long jzfile);
private static native int read(long jzfile, long jzentry, private static native int read(long jzfile, long jzentry,
long pos, byte[] b, int off, int len); long pos, byte[] b, int off, int len);
......
...@@ -81,7 +81,8 @@ ThrowZipException(JNIEnv *env, const char *msg) ...@@ -81,7 +81,8 @@ ThrowZipException(JNIEnv *env, const char *msg)
JNIEXPORT jlong JNICALL JNIEXPORT jlong JNICALL
Java_java_util_zip_ZipFile_open(JNIEnv *env, jclass cls, jstring name, Java_java_util_zip_ZipFile_open(JNIEnv *env, jclass cls, jstring name,
jint mode, jlong lastModified) jint mode, jlong lastModified,
jboolean usemmap)
{ {
const char *path = JNU_GetStringPlatformChars(env, name, 0); const char *path = JNU_GetStringPlatformChars(env, name, 0);
char *msg = 0; char *msg = 0;
...@@ -109,7 +110,7 @@ Java_java_util_zip_ZipFile_open(JNIEnv *env, jclass cls, jstring name, ...@@ -109,7 +110,7 @@ Java_java_util_zip_ZipFile_open(JNIEnv *env, jclass cls, jstring name,
goto finally; goto finally;
} }
#endif #endif
zip = ZIP_Put_In_Cache(path, zfd, &msg, lastModified); zip = ZIP_Put_In_Cache0(path, zfd, &msg, lastModified, usemmap);
} }
if (zip != 0) { if (zip != 0) {
......
...@@ -251,11 +251,16 @@ freeZip(jzfile *zip) ...@@ -251,11 +251,16 @@ freeZip(jzfile *zip)
if (zip->lock != NULL) MDESTROY(zip->lock); if (zip->lock != NULL) MDESTROY(zip->lock);
free(zip->name); free(zip->name);
freeCEN(zip); freeCEN(zip);
#ifdef USE_MMAP #ifdef USE_MMAP
if (zip->maddr != NULL) munmap((char *)zip->maddr, zip->mlen); if (zip->usemmap) {
#else if (zip->maddr != NULL)
free(zip->cencache.data); munmap((char *)zip->maddr, zip->mlen);
} else
#endif #endif
{
free(zip->cencache.data);
}
if (zip->comment != NULL) if (zip->comment != NULL)
free(zip->comment); free(zip->comment);
if (zip->zfd != -1) ZFILE_Close(zip->zfd); if (zip->zfd != -1) ZFILE_Close(zip->zfd);
...@@ -585,6 +590,7 @@ readCEN(jzfile *zip, jint knownTotal) ...@@ -585,6 +590,7 @@ readCEN(jzfile *zip, jint knownTotal)
ZIP_FORMAT_ERROR("invalid END header (bad central directory offset)"); ZIP_FORMAT_ERROR("invalid END header (bad central directory offset)");
#ifdef USE_MMAP #ifdef USE_MMAP
if (zip->usemmap) {
/* On Solaris & Linux prior to JDK 6, we used to mmap the whole jar file to /* On Solaris & Linux prior to JDK 6, we used to mmap the whole jar file to
* read the jar file contents. However, this greatly increased the perceived * read the jar file contents. However, this greatly increased the perceived
* footprint numbers because the mmap'ed pages were adding into the totals shown * footprint numbers because the mmap'ed pages were adding into the totals shown
...@@ -623,11 +629,14 @@ readCEN(jzfile *zip, jint knownTotal) ...@@ -623,11 +629,14 @@ readCEN(jzfile *zip, jint knownTotal)
} }
} }
cenbuf = zip->maddr + cenpos - offset; cenbuf = zip->maddr + cenpos - offset;
#else } else
#endif
{
if ((cenbuf = malloc((size_t) cenlen)) == NULL || if ((cenbuf = malloc((size_t) cenlen)) == NULL ||
(readFullyAt(zip->zfd, cenbuf, cenlen, cenpos) == -1)) (readFullyAt(zip->zfd, cenbuf, cenlen, cenpos) == -1))
goto Catch; goto Catch;
#endif }
cenend = cenbuf + cenlen; cenend = cenbuf + cenlen;
/* Initialize zip file data structures based on the total number /* Initialize zip file data structures based on the total number
...@@ -700,9 +709,11 @@ readCEN(jzfile *zip, jint knownTotal) ...@@ -700,9 +709,11 @@ readCEN(jzfile *zip, jint knownTotal)
cenpos = -1; cenpos = -1;
Finally: Finally:
#ifndef USE_MMAP #ifdef USE_MMAP
free(cenbuf); if (!zip->usemmap)
#endif #endif
free(cenbuf);
return cenpos; return cenpos;
} }
...@@ -782,8 +793,16 @@ ZIP_Get_From_Cache(const char *name, char **pmsg, jlong lastModified) ...@@ -782,8 +793,16 @@ ZIP_Get_From_Cache(const char *name, char **pmsg, jlong lastModified)
* If a zip error occurs, then *pmsg will be set to the error message text if * If a zip error occurs, then *pmsg will be set to the error message text if
* pmsg != 0. Otherwise, *pmsg will be set to NULL. * pmsg != 0. Otherwise, *pmsg will be set to NULL.
*/ */
jzfile * jzfile *
ZIP_Put_In_Cache(const char *name, ZFILE zfd, char **pmsg, jlong lastModified) ZIP_Put_In_Cache(const char *name, ZFILE zfd, char **pmsg, jlong lastModified)
{
return ZIP_Put_In_Cache0(name, zfd, pmsg, lastModified, JNI_TRUE);
}
jzfile *
ZIP_Put_In_Cache0(const char *name, ZFILE zfd, char **pmsg, jlong lastModified,
jboolean usemmap)
{ {
static char errbuf[256]; static char errbuf[256];
jlong len; jlong len;
...@@ -793,6 +812,9 @@ ZIP_Put_In_Cache(const char *name, ZFILE zfd, char **pmsg, jlong lastModified) ...@@ -793,6 +812,9 @@ ZIP_Put_In_Cache(const char *name, ZFILE zfd, char **pmsg, jlong lastModified)
return NULL; return NULL;
} }
#ifdef USE_MMAP
zip->usemmap = usemmap;
#endif
zip->refs = 1; zip->refs = 1;
zip->lastModified = lastModified; zip->lastModified = lastModified;
...@@ -877,8 +899,6 @@ ZIP_Close(jzfile *zip) ...@@ -877,8 +899,6 @@ ZIP_Close(jzfile *zip)
return; return;
} }
#ifndef USE_MMAP
/* Empirically, most CEN headers are smaller than this. */ /* Empirically, most CEN headers are smaller than this. */
#define AMPLE_CEN_HEADER_SIZE 160 #define AMPLE_CEN_HEADER_SIZE 160
...@@ -928,7 +948,6 @@ sequentialAccessReadCENHeader(jzfile *zip, jlong cenpos) ...@@ -928,7 +948,6 @@ sequentialAccessReadCENHeader(jzfile *zip, jlong cenpos)
cache->pos = cenpos; cache->pos = cenpos;
return cen; return cen;
} }
#endif /* not USE_MMAP */
typedef enum { ACCESS_RANDOM, ACCESS_SEQUENTIAL } AccessHint; typedef enum { ACCESS_RANDOM, ACCESS_SEQUENTIAL } AccessHint;
...@@ -953,14 +972,17 @@ newEntry(jzfile *zip, jzcell *zc, AccessHint accessHint) ...@@ -953,14 +972,17 @@ newEntry(jzfile *zip, jzcell *zc, AccessHint accessHint)
ze->comment = NULL; ze->comment = NULL;
#ifdef USE_MMAP #ifdef USE_MMAP
if (zip->usemmap) {
cen = (char*) zip->maddr + zc->cenpos - zip->offset; cen = (char*) zip->maddr + zc->cenpos - zip->offset;
#else } else
#endif
{
if (accessHint == ACCESS_RANDOM) if (accessHint == ACCESS_RANDOM)
cen = readCENHeader(zip, zc->cenpos, AMPLE_CEN_HEADER_SIZE); cen = readCENHeader(zip, zc->cenpos, AMPLE_CEN_HEADER_SIZE);
else else
cen = sequentialAccessReadCENHeader(zip, zc->cenpos); cen = sequentialAccessReadCENHeader(zip, zc->cenpos);
if (cen == NULL) goto Catch; if (cen == NULL) goto Catch;
#endif }
nlen = CENNAM(cen); nlen = CENNAM(cen);
elen = CENEXT(cen); elen = CENEXT(cen);
...@@ -976,7 +998,6 @@ newEntry(jzfile *zip, jzcell *zc, AccessHint accessHint) ...@@ -976,7 +998,6 @@ newEntry(jzfile *zip, jzcell *zc, AccessHint accessHint)
if ((ze->name = malloc(nlen + 1)) == NULL) goto Catch; if ((ze->name = malloc(nlen + 1)) == NULL) goto Catch;
memcpy(ze->name, cen + CENHDR, nlen); memcpy(ze->name, cen + CENHDR, nlen);
ze->name[nlen] = '\0'; ze->name[nlen] = '\0';
if (elen > 0) { if (elen > 0) {
char *extra = cen + CENHDR + nlen; char *extra = cen + CENHDR + nlen;
...@@ -1037,9 +1058,10 @@ newEntry(jzfile *zip, jzcell *zc, AccessHint accessHint) ...@@ -1037,9 +1058,10 @@ newEntry(jzfile *zip, jzcell *zc, AccessHint accessHint)
ze = NULL; ze = NULL;
Finally: Finally:
#ifndef USE_MMAP #ifdef USE_MMAP
if (cen != NULL && accessHint == ACCESS_RANDOM) free(cen); if (!zip->usemmap)
#endif #endif
if (cen != NULL && accessHint == ACCESS_RANDOM) free(cen);
return ze; return ze;
} }
......
...@@ -45,9 +45,6 @@ ...@@ -45,9 +45,6 @@
* Header sizes including signatures * Header sizes including signatures
*/ */
#ifdef USE_MMAP
#define SIGSIZ 4
#endif
#define LOCHDR 30 #define LOCHDR 30
#define EXTHDR 16 #define EXTHDR 16
#define CENHDR 46 #define CENHDR 46
...@@ -211,9 +208,9 @@ typedef struct jzfile { /* Zip file */ ...@@ -211,9 +208,9 @@ typedef struct jzfile { /* Zip file */
jlong mlen; /* length (in bytes) mmaped */ jlong mlen; /* length (in bytes) mmaped */
jlong offset; /* offset of the mmapped region from the jlong offset; /* offset of the mmapped region from the
start of the file. */ start of the file. */
#else jboolean usemmap; /* if mmap is used. */
cencache cencache; /* CEN header cache */
#endif #endif
cencache cencache; /* CEN header cache */
ZFILE zfd; /* open file descriptor */ ZFILE zfd; /* open file descriptor */
void *lock; /* read lock */ void *lock; /* read lock */
char *comment; /* zip file comment */ char *comment; /* zip file comment */
...@@ -259,6 +256,9 @@ ZIP_Get_From_Cache(const char *name, char **pmsg, jlong lastModified); ...@@ -259,6 +256,9 @@ ZIP_Get_From_Cache(const char *name, char **pmsg, jlong lastModified);
jzfile * jzfile *
ZIP_Put_In_Cache(const char *name, ZFILE zfd, char **pmsg, jlong lastModified); ZIP_Put_In_Cache(const char *name, ZFILE zfd, char **pmsg, jlong lastModified);
jzfile *
ZIP_Put_In_Cache0(const char *name, ZFILE zfd, char **pmsg, jlong lastModified, jboolean usemmap);
void JNICALL void JNICALL
ZIP_Close(jzfile *zip); ZIP_Close(jzfile *zip);
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册