test/hotspot/jtreg/runtime/appcds/SharedArchiveConsistency.java
changeset 54927 1512d88b24c6
parent 54838 d7819bedfaaf
child 55694 7b7df2be6219
equal deleted inserted replaced
54926:d4e7ccaf1445 54927:1512d88b24c6
    69     public static int sp_used_offset;  // offset of CDSFileMapRegion::_used
    69     public static int sp_used_offset;  // offset of CDSFileMapRegion::_used
    70     public static int size_t_size;     // size of size_t
    70     public static int size_t_size;     // size of size_t
    71 
    71 
    72     public static File jsa;        // will be updated during test
    72     public static File jsa;        // will be updated during test
    73     public static File orgJsaFile; // kept the original file not touched.
    73     public static File orgJsaFile; // kept the original file not touched.
    74     public static String[] shared_region_name = {"MiscCode", "ReadWrite", "ReadOnly", "MiscData"};
    74     // The following should be consistent with the enum in the C++ MetaspaceShared class
       
    75     public static String[] shared_region_name = {
       
    76         "mc",          // MiscCode
       
    77         "rw",          // ReadWrite
       
    78         "ro",          // ReadOnly
       
    79         "md",          // MiscData
       
    80         "first_closed_archive",
       
    81         "last_closed_archive",
       
    82         "first_open_archive",
       
    83         "last_open_archive"
       
    84     };
       
    85 
    75     public static int num_regions = shared_region_name.length;
    86     public static int num_regions = shared_region_name.length;
    76     public static String[] matchMessages = {
    87     public static String[] matchMessages = {
    77         "Unable to use shared archive",
    88         "Unable to use shared archive",
    78         "An error has occurred while processing the shared archive file.",
    89         "An error has occurred while processing the shared archive file.",
    79         "Checksum verification failed.",
    90         "Checksum verification failed.",
   100     public static int getFileHeaderSize(FileChannel fc) throws Exception {
   111     public static int getFileHeaderSize(FileChannel fc) throws Exception {
   101         if (file_header_size != -1) {
   112         if (file_header_size != -1) {
   102             return file_header_size;
   113             return file_header_size;
   103         }
   114         }
   104         // this is not real header size, it is struct size
   115         // this is not real header size, it is struct size
       
   116         int int_size = wb.getOffsetForName("int_size");
   105         file_header_size = wb.getOffsetForName("file_header_size");
   117         file_header_size = wb.getOffsetForName("file_header_size");
   106         int offset_path_misc_info = wb.getOffsetForName("FileMapHeader::_paths_misc_info_size") -
   118         int offset_path_misc_info = wb.getOffsetForName("FileMapHeader::_paths_misc_info_size") -
   107             offset_magic;
   119             offset_magic;
   108         int path_misc_info_size   = (int)readInt(fc, offset_path_misc_info, size_t_size);
   120         int path_misc_info_size   = (int)readInt(fc, offset_path_misc_info, int_size);
   109         file_header_size += path_misc_info_size; //readInt(fc, offset_path_misc_info, size_t_size);
   121         file_header_size += path_misc_info_size; //readInt(fc, offset_path_misc_info, size_t_size);
   110         System.out.println("offset_path_misc_info = " + offset_path_misc_info);
   122         System.out.println("offset_path_misc_info = " + offset_path_misc_info);
   111         System.out.println("path_misc_info_size   = " + path_misc_info_size);
   123         System.out.println("path_misc_info_size   = " + path_misc_info_size);
   112         System.out.println("file_header_size      = " + file_header_size);
   124         System.out.println("file_header_size      = " + file_header_size);
   113         file_header_size = (int)align_up_page(file_header_size);
   125         file_header_size = (int)align_up_page(file_header_size);
   155         return FileChannel.open(jsa.toPath(), new HashSet<StandardOpenOption>(arry));
   167         return FileChannel.open(jsa.toPath(), new HashSet<StandardOpenOption>(arry));
   156     }
   168     }
   157 
   169 
   158     public static void modifyJsaContentRandomly() throws Exception {
   170     public static void modifyJsaContentRandomly() throws Exception {
   159         FileChannel fc = getFileChannel();
   171         FileChannel fc = getFileChannel();
   160         // corrupt random area in the data areas (MiscCode, ReadWrite, ReadOnly, MiscData)
   172         // corrupt random area in the data areas
   161         long[] used    = new long[num_regions];       // record used bytes
   173         long[] used    = new long[num_regions];       // record used bytes
   162         long start0, start, end, off;
   174         long start0, start, end, off;
   163         int used_offset, path_info_size;
   175         int used_offset, path_info_size;
   164 
   176 
   165         int bufSize;
   177         int bufSize;
   166         System.out.printf("%-12s%-12s%-12s%-12s%-12s\n", "Space Name", "Offset", "Used bytes", "Reg Start", "Random Offset");
   178         System.out.printf("%-24s%12s%12s%16s\n", "Space Name", "Used bytes", "Reg Start", "Random Offset");
   167         start0 = getFileHeaderSize(fc);
   179         start0 = getFileHeaderSize(fc);
   168         for (int i = 0; i < num_regions; i++) {
   180         for (int i = 0; i < num_regions; i++) {
   169             used_offset = sp_offset + CDSFileMapRegion_size * i + sp_used_offset;
   181             used[i] = get_region_used_size_aligned(fc, i);
   170             // read 'used'
       
   171             used[i] = readInt(fc, used_offset, size_t_size);
       
   172             start = start0;
   182             start = start0;
   173             for (int j = 0; j < i; j++) {
   183             for (int j = 0; j < i; j++) {
   174                 start += align_up_page(used[j]);
   184                 start += align_up_page(used[j]);
   175             }
   185             }
   176             end = start + used[i];
   186             end = start + used[i];
       
   187             if (start == end) {
       
   188                 continue; // Ignore empty regions
       
   189             }
   177             off = getRandomBetween(start, end);
   190             off = getRandomBetween(start, end);
   178             System.out.printf("%-12s%-12d%-12d%-12d%-12d\n", shared_region_name[i], used_offset, used[i], start, off);
   191             System.out.printf("%-24s%12d%12d%16d\n", shared_region_name[i], used[i], start, off);
   179             if (end - off < 1024) {
   192             if (end - off < 1024) {
   180                 bufSize = (int)(end - off + 1);
   193                 bufSize = (int)(end - off + 1);
   181             } else {
   194             } else {
   182                 bufSize = 1024;
   195                 bufSize = 1024;
   183             }
   196             }
   187         if (fc.isOpen()) {
   200         if (fc.isOpen()) {
   188             fc.close();
   201             fc.close();
   189         }
   202         }
   190     }
   203     }
   191 
   204 
   192     public static void modifyJsaContent() throws Exception {
   205     static long get_region_used_size_aligned(FileChannel fc, int region) throws Exception {
       
   206         long n = sp_offset + CDSFileMapRegion_size * region + sp_used_offset;
       
   207         long alignment = WhiteBox.getWhiteBox().metaspaceReserveAlignment();
       
   208         long used = readInt(fc, n, size_t_size);
       
   209         used = (used + alignment - 1) & ~(alignment - 1);
       
   210         return used;
       
   211     }
       
   212 
       
   213     public static boolean modifyJsaContent(int region) throws Exception {
   193         FileChannel fc = getFileChannel();
   214         FileChannel fc = getFileChannel();
   194         byte[] buf = new byte[4096];
   215         byte[] buf = new byte[4096];
   195         ByteBuffer bbuf = ByteBuffer.wrap(buf);
   216         ByteBuffer bbuf = ByteBuffer.wrap(buf);
   196 
   217 
   197         long total = 0L;
   218         long total = 0L;
   198         long used_offset = 0L;
       
   199         long[] used = new long[num_regions];
   219         long[] used = new long[num_regions];
   200         System.out.printf("%-12s%-12s\n", "Space name", "Used bytes");
   220         System.out.printf("%-24s%12s\n", "Space name", "Used bytes");
   201         for (int i = 0; i < num_regions; i++) {
   221         for (int i = 0; i < num_regions; i++) {
   202             used_offset = sp_offset + CDSFileMapRegion_size* i + sp_used_offset;
   222             used[i] = get_region_used_size_aligned(fc, i);
   203             // read 'used'
   223             System.out.printf("%-24s%12d\n", shared_region_name[i], used[i]);
   204             used[i] = readInt(fc, used_offset, size_t_size);
       
   205             System.out.printf("%-12s%-12d\n", shared_region_name[i], used[i]);
       
   206             total += used[i];
   224             total += used[i];
   207         }
   225         }
   208         System.out.printf("%-12s%-12d\n", "Total: ", total);
   226         System.out.printf("%-24s%12d\n", "Total: ", total);
   209         long corrupt_used_offset =  getFileHeaderSize(fc);
   227         long header_size = getFileHeaderSize(fc);
   210         System.out.println("Corrupt RO section, offset = " + corrupt_used_offset);
   228         long region_start_offset = header_size;
   211         while (used_offset < used[0]) {
   229         for (int i=0; i<region; i++) {
   212             writeData(fc, corrupt_used_offset, bbuf);
   230             region_start_offset += used[i];
       
   231         }
       
   232         if (used[region] == 0) {
       
   233             System.out.println("Region " + shared_region_name[region] + " is empty. Nothing to corrupt.");
       
   234             return false;
       
   235         }
       
   236         System.out.println("Corrupt " + shared_region_name[region] + " section, start = " + region_start_offset
       
   237                            + " (header_size + 0x" + Long.toHexString(region_start_offset-header_size) + ")");
       
   238         long bytes_written = 0L;
       
   239         while (bytes_written < used[region]) {
       
   240             writeData(fc, region_start_offset + bytes_written, bbuf);
   213             bbuf.clear();
   241             bbuf.clear();
   214             used_offset += 4096;
   242             bytes_written += 4096;
   215         }
   243         }
   216         fc.force(true);
   244         fc.force(true);
   217         if (fc.isOpen()) {
   245         if (fc.isOpen()) {
   218             fc.close();
   246             fc.close();
   219         }
   247         }
       
   248         return true;
   220     }
   249     }
   221 
   250 
   222     public static void modifyJsaHeader() throws Exception {
   251     public static void modifyJsaHeader() throws Exception {
   223         FileChannel fc = getFileChannel();
   252         FileChannel fc = getFileChannel();
   224         // screw up header info
   253         // screw up header info
   297 
   326 
   298     // dump with hello.jsa, then
   327     // dump with hello.jsa, then
   299     // read the jsa file
   328     // read the jsa file
   300     //   1) run normal
   329     //   1) run normal
   301     //   2) modify header
   330     //   2) modify header
   302     //   3) keep header correct but modify content
   331     //   3) keep header correct but modify content in each region specified by shared_region_name[]
   303     //   4) update both header and content, test
   332     //   4) update both header and content, test
   304     //   5) delete bytes in data begining
   333     //   5) delete bytes in data begining
   305     //   6) insert bytes in data begining
   334     //   6) insert bytes in data begining
   306     //   7) randomly corrupt data in four areas: RO, RW. MISC DATA, MISC CODE
   335     //   7) randomly corrupt data in each region specified by shared_region_name[]
   307     public static void main(String... args) throws Exception {
   336     public static void main(String... args) throws Exception {
   308         // must call to get offset info first!!!
   337         // must call to get offset info first!!!
   309         getFileOffsetInfo();
   338         getFileOffsetInfo();
   310         Path currentRelativePath = Paths.get("");
   339         Path currentRelativePath = Paths.get("");
   311         String currentDir = currentRelativePath.toAbsolutePath().toString();
   340         String currentDir = currentRelativePath.toAbsolutePath().toString();
   350         modifyJsaHeader();
   379         modifyJsaHeader();
   351         output = TestCommon.execCommon(execArgs);
   380         output = TestCommon.execCommon(execArgs);
   352         output.shouldContain("The shared archive file has the wrong version");
   381         output.shouldContain("The shared archive file has the wrong version");
   353         output.shouldNotContain("Checksum verification failed");
   382         output.shouldNotContain("Checksum verification failed");
   354 
   383 
       
   384         File newJsaFile = null;
   355         // modify content
   385         // modify content
   356         System.out.println("\n3. Corrupt Content, should fail\n");
   386         System.out.println("\n3. Corrupt Content, should fail\n");
   357 
   387         for (int i=0; i<num_regions; i++) {
   358         copyFile(orgJsaFile, jsa);
   388             newJsaFile = new File(TestCommon.getNewArchiveName(shared_region_name[i]));
   359         modifyJsaContent();
   389             copyFile(orgJsaFile, newJsaFile);
   360         testAndCheck(verifyExecArgs);
   390             if (modifyJsaContent(i)) {
       
   391                 testAndCheck(execArgs);
       
   392             }
       
   393         }
   361 
   394 
   362         // modify both header and content, test should fail
   395         // modify both header and content, test should fail
   363         System.out.println("\n4. Corrupt Header and Content, should fail\n");
   396         System.out.println("\n4. Corrupt Header and Content, should fail\n");
   364         copyFile(orgJsaFile, jsa);
   397         newJsaFile = new File(TestCommon.getNewArchiveName("header-and-content"));
       
   398         copyFile(orgJsaFile, newJsaFile);
   365         modifyJsaHeader();
   399         modifyJsaHeader();
   366         modifyJsaContent();  // this will not be reached since failed on header change first
   400         modifyJsaContent(0);  // this will not be reached since failed on header change first
   367         output = TestCommon.execCommon(execArgs);
   401         output = TestCommon.execCommon(execArgs);
   368         output.shouldContain("The shared archive file has the wrong version");
   402         output.shouldContain("The shared archive file has the wrong version");
   369         output.shouldNotContain("Checksum verification failed");
   403         output.shouldNotContain("Checksum verification failed");
   370 
   404 
   371         // delete bytes in data section
   405         // delete bytes in data section
   377         System.out.println("\n6. Insert bytes at beginning of data section, should fail\n");
   411         System.out.println("\n6. Insert bytes at beginning of data section, should fail\n");
   378         copyFile(orgJsaFile, jsa, false);
   412         copyFile(orgJsaFile, jsa, false);
   379         testAndCheck(verifyExecArgs);
   413         testAndCheck(verifyExecArgs);
   380 
   414 
   381         System.out.println("\n7. modify Content in random areas, should fail\n");
   415         System.out.println("\n7. modify Content in random areas, should fail\n");
   382         copyFile(orgJsaFile, jsa);
   416         newJsaFile = new File(TestCommon.getNewArchiveName("random-areas"));
       
   417         copyFile(orgJsaFile, newJsaFile);
   383         modifyJsaContentRandomly();
   418         modifyJsaContentRandomly();
   384         testAndCheck(verifyExecArgs);
   419         testAndCheck(verifyExecArgs);
   385     }
   420     }
   386 }
   421 }