1 /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
2  * Copyright by The HDF Group.                                               *
3  * Copyright by the Board of Trustees of the University of Illinois.         *
4  * All rights reserved.                                                      *
5  *                                                                           *
6  * This file is part of HDF5.  The full HDF5 copyright notice, including     *
7  * terms governing use, modification, and redistribution, is contained in    *
8  * the COPYING file, which can be found at the root of the source code       *
9  * distribution tree, or in https://support.hdfgroup.org/ftp/HDF5/releases.  *
10  * If you do not have access to either file, you may request a copy from     *
11  * help@hdfgroup.org.                                                        *
12  * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
13 
14 /* Programmer:  Robb Matzke <matzke@llnl.gov>
15  *              Tuesday, November 24, 1998
16  */
17 #include "h5test.h"
18 #include "H5srcdir.h"
19 #include "H5Iprivate.h"
20 
21 /*
22  * This file needs to access private datatypes from the H5O package.
23  * This file also needs to access the object header testing code.
24  */
25 #define H5O_PACKAGE
26 #define H5O_TESTING
27 #include "H5Opkg.h"
28 
29 /*
30  * This file needs to access private datatypes from the H5G package.
31  */
32 #define H5G_PACKAGE
33 #include "H5Gpkg.h"
34 
35 const char *FILENAME[] = {
36     "ohdr",
37     NULL
38 };
39 
40 /* The tbogus.h5 is generated from gen_bogus.c in HDF5 'test' directory.
41  * To get this data file, define H5O_ENABLE_BOGUS in src/H5Oprivate, rebuild
42  * the library and simply compile gen_bogus.c with that HDF5 library and run it.
43  */
44 #define FILE_BOGUS "tbogus.h5"
45 
46 /*
47  *  Verify that messages are moved forward into a "continuation message":
48  *	Create an object header with several continuation chunks
49  *	Remove a message in the last chunk
50  *	The remaining message(s) in the last chunk should be moved forward into the continuation message
51  *	The process will repeat when the continuation message is big enough to hold all the
52  *		messages in the last chunk.
53  *	Result: the number of chunks should be reduced
54  */
55 static herr_t
test_cont(char * filename,hid_t fapl)56 test_cont(char *filename, hid_t fapl)
57 {
58     hid_t	file=-1;
59     H5F_t	*f = NULL;
60     H5O_hdr_info_t hdr_info;
61     H5O_loc_t	oh_locA, oh_locB;
62     time_t	time_new;
63     const char	*short_name = "T";
64     const char	*long_name = "This is the message";
65     size_t	nchunks;
66 
67     TESTING("object header continuation block");
68 
69     HDmemset(&oh_locA, 0, sizeof(oh_locA));
70     HDmemset(&oh_locB, 0, sizeof(oh_locB));
71 
72     /* Create the file to operate on */
73     if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0) TEST_ERROR
74     if(NULL == (f = (H5F_t *)H5I_object(file))) FAIL_STACK_ERROR
75 
76     if(H5O_create(f, H5P_DATASET_XFER_DEFAULT, (size_t)H5O_MIN_SIZE, (size_t)0, H5P_GROUP_CREATE_DEFAULT, &oh_locA/*out*/) < 0)
77             FAIL_STACK_ERROR
78 
79     if(H5O_create(f, H5P_DATASET_XFER_DEFAULT, (size_t)H5O_MIN_SIZE, (size_t)0, H5P_GROUP_CREATE_DEFAULT, &oh_locB/*out*/) < 0)
80             FAIL_STACK_ERROR
81 
82     time_new = 11111111;
83 
84     if(H5O_msg_create(&oh_locA, H5O_NAME_ID, 0, 0, &long_name, H5P_DATASET_XFER_DEFAULT) < 0)
85 	FAIL_STACK_ERROR
86 
87     if(H5O_msg_create(&oh_locB, H5O_MTIME_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0)
88 	FAIL_STACK_ERROR
89     if(H5O_msg_create(&oh_locB, H5O_MTIME_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0)
90 	FAIL_STACK_ERROR
91     if(H5O_msg_create(&oh_locB, H5O_MTIME_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0)
92 	FAIL_STACK_ERROR
93 
94     if(H5O_msg_create(&oh_locA, H5O_MTIME_NEW_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0)
95 	FAIL_STACK_ERROR
96 
97     if(H5O_msg_create(&oh_locB, H5O_MTIME_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0)
98         FAIL_STACK_ERROR
99 
100     if(H5O_msg_create(&oh_locA, H5O_NAME_ID, 0, 0, &short_name, H5P_DATASET_XFER_DEFAULT) < 0)
101 	FAIL_STACK_ERROR
102 
103     if(1 != H5O_link(&oh_locA, 1, H5P_DATASET_XFER_DEFAULT))
104         FAIL_STACK_ERROR
105     if(1 != H5O_link(&oh_locB, 1, H5P_DATASET_XFER_DEFAULT))
106         FAIL_STACK_ERROR
107     if(H5AC_flush(f, H5P_DATASET_XFER_DEFAULT) < 0)
108 	FAIL_STACK_ERROR
109     if(H5O_expunge_chunks_test(&oh_locA, H5P_DATASET_XFER_DEFAULT) < 0)
110 	FAIL_STACK_ERROR
111 
112     if(H5O_get_hdr_info(&oh_locA, H5P_DATASET_XFER_DEFAULT, &hdr_info) < 0)
113 	FAIL_STACK_ERROR
114     nchunks = hdr_info.nchunks;
115 
116     /* remove the 1st H5O_NAME_ID message */
117     if(H5O_msg_remove(&oh_locA, H5O_NAME_ID, 0, FALSE, H5P_DATASET_XFER_DEFAULT) < 0)
118 	FAIL_STACK_ERROR
119 
120     if(H5O_get_hdr_info(&oh_locA, H5P_DATASET_XFER_DEFAULT, &hdr_info) < 0)
121 	FAIL_STACK_ERROR
122 
123     if(hdr_info.nchunks >= nchunks)
124 	TEST_ERROR
125 
126     if(H5O_close(&oh_locA) < 0)
127 	FAIL_STACK_ERROR
128     if(H5O_close(&oh_locB) < 0)
129 	FAIL_STACK_ERROR
130     if(H5Fclose(file) < 0)
131 	FAIL_STACK_ERROR
132 
133     PASSED();
134 
135 
136     return 0;
137 
138 error:
139     H5E_BEGIN_TRY {
140         H5O_close(&oh_locA);
141         H5O_close(&oh_locB);
142         H5Fclose(file);
143     } H5E_END_TRY;
144 
145     return -1;
146 } /* test_cont() */
147 
148 /*
149  *  Verify that object headers are held in the cache until they are linked
150  *      to a location in the graph, or assigned an ID.  This is done by
151  *      creating an object header, then forcing it out of the cache by creating
152  *      local heaps until the object header is evicted from the cache, then
153  *      modifying the object header.  The refcount on the object header is
154  *      checked as verifying that the object header has remained in the cache.
155  */
156 static herr_t
test_ohdr_cache(char * filename,hid_t fapl)157 test_ohdr_cache(char *filename, hid_t fapl)
158 {
159     hid_t	file = -1;              /* File ID */
160     hid_t       my_fapl;                /* FAPL ID */
161     hid_t       my_dxpl;                /* DXPL ID */
162     H5AC_cache_config_t mdc_config;     /* Metadata cache configuration info */
163     H5F_t	*f = NULL;              /* File handle */
164     H5HL_t      *lheap, *lheap2, *lheap3; /* Pointer to local heaps */
165     haddr_t     lheap_addr, lheap_addr2, lheap_addr3; /* Local heap addresses */
166     H5O_loc_t	oh_loc;                 /* Object header location */
167     time_t	time_new;               /* Time value for modification time message */
168     unsigned    rc;                     /* Refcount for object */
169 
170     TESTING("object header creation in cache");
171 
172     /* Make a copy of the FAPL */
173     if((my_fapl = H5Pcopy(fapl)) < 0)
174         FAIL_STACK_ERROR
175 
176     /* Tweak down the size of the metadata cache to only 64K */
177     mdc_config.version = H5AC__CURR_CACHE_CONFIG_VERSION;
178     if(H5Pget_mdc_config(my_fapl, &mdc_config) < 0)
179         FAIL_STACK_ERROR
180     mdc_config.set_initial_size = TRUE;
181     mdc_config.initial_size = 32 * 1024;
182     mdc_config.max_size = 64 * 1024;
183     mdc_config.min_size = 8 * 1024;
184     if(H5Pset_mdc_config(my_fapl, &mdc_config) < 0)
185         FAIL_STACK_ERROR
186 
187     /* Make a copy of the default DXPL */
188     if((my_dxpl = H5Pcopy(H5P_DATASET_XFER_DEFAULT)) < 0)
189         FAIL_STACK_ERROR
190 
191     /* Create the file to operate on */
192     if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, my_fapl)) < 0)
193         FAIL_STACK_ERROR
194     if(H5Pclose(my_fapl) < 0)
195 	FAIL_STACK_ERROR
196     if(NULL == (f = (H5F_t *)H5I_object(file)))
197         FAIL_STACK_ERROR
198 
199     /* Create object (local heap) that occupies most of cache */
200     if(H5HL_create(f, my_dxpl, (31 * 1024), &lheap_addr) < 0)
201         FAIL_STACK_ERROR
202 
203     /* Protect local heap (which actually pins it in the cache) */
204     if(NULL == (lheap = H5HL_protect(f, my_dxpl, lheap_addr, H5AC_READ)))
205         FAIL_STACK_ERROR
206 
207     /* Create an object header */
208     HDmemset(&oh_loc, 0, sizeof(oh_loc));
209     if(H5O_create(f, my_dxpl, (size_t)2048, (size_t)1, H5P_GROUP_CREATE_DEFAULT, &oh_loc/*out*/) < 0)
210         FAIL_STACK_ERROR
211 
212     /* Query object header information */
213     rc = 0;
214     if(H5O_get_rc(&oh_loc, my_dxpl, &rc) < 0)
215         FAIL_STACK_ERROR
216     if(0 != rc)
217         TEST_ERROR
218 
219     /* Create object (local heap) that occupies most of cache */
220     if(H5HL_create(f, my_dxpl, (31 * 1024), &lheap_addr2) < 0)
221         FAIL_STACK_ERROR
222 
223     /* Protect local heap (which actually pins it in the cache) */
224     if(NULL == (lheap2 = H5HL_protect(f, my_dxpl, lheap_addr2, H5AC_READ)))
225         FAIL_STACK_ERROR
226 
227     /* Unprotect local heap (which actually unpins it from the cache) */
228     if(H5HL_unprotect(lheap2) < 0)
229         FAIL_STACK_ERROR
230 
231     /* Create object header message in new object header */
232     time_new = 11111111;
233     if(H5O_msg_create(&oh_loc, H5O_MTIME_NEW_ID, 0, 0, &time_new, my_dxpl) < 0)
234         FAIL_STACK_ERROR
235 
236     /* Create object (local heap) that occupies most of cache */
237     if(H5HL_create(f, my_dxpl, (31 * 1024), &lheap_addr3) < 0)
238         FAIL_STACK_ERROR
239 
240     /* Protect local heap (which actually pins it in the cache) */
241     if(NULL == (lheap3 = H5HL_protect(f, my_dxpl, lheap_addr3, H5AC_READ)))
242         FAIL_STACK_ERROR
243 
244     /* Unprotect local heap (which actually unpins it from the cache) */
245     if(H5HL_unprotect(lheap3) < 0)
246         FAIL_STACK_ERROR
247 
248     /* Query object header information */
249     /* (Note that this is somewhat of a weak test, since it doesn't actually
250      *  verify that the object header was evicted from the cache, but it's
251      *  very difficult to verify when an entry is evicted from the cache in
252      *  a non-invasive way -QAK)
253      */
254     rc = 0;
255     if(H5O_get_rc(&oh_loc, my_dxpl, &rc) < 0)
256         FAIL_STACK_ERROR
257     if(0 != rc)
258         TEST_ERROR
259 
260     /* Decrement reference count o object header */
261     if(H5O_dec_rc_by_loc(&oh_loc, my_dxpl) < 0)
262         FAIL_STACK_ERROR
263 
264     /* Close object header created */
265     if(H5O_close(&oh_loc) < 0)
266         FAIL_STACK_ERROR
267 
268     /* Unprotect local heap (which actually unpins it from the cache) */
269     if(H5HL_unprotect(lheap) < 0)
270         FAIL_STACK_ERROR
271 
272     if(H5Pclose(my_dxpl) < 0)
273 	FAIL_STACK_ERROR
274     if(H5Fclose(file) < 0)
275 	FAIL_STACK_ERROR
276 
277     PASSED();
278 
279     return 0;
280 
281 error:
282     H5E_BEGIN_TRY {
283         H5Fclose(file);
284     } H5E_END_TRY;
285 
286     return -1;
287 } /* test_ohdr_cache() */
288 
289 /*
290  *  To test objects with unknown messages in a file with:
291  *  	a) H5O_BOGUS_VALID_ID:
292  *	   --the bogus_id is within the range of H5O_msg_class_g[]
293  *  	b) H5O_BOGUS_INVALID_ID:
294  *  	   --the bogus_id is outside the range of H5O_msg_class_g[]
295  *
296  *   The test file is FILE_BOGUS: "tbogus.h5" generated with gen_bogus.c
297  *   --objects that have unknown header messages with H5O_BOGUS_VALID_ID in "/"
298  *   --objects that have unknown header messages with H5O_BOGUS_INVALID_ID in "/group"
299  *
300  *   The test also uses the test file FILENAME[0] (ohdr.h5): the parameter "filename"
301  */
302 static herr_t
test_unknown(unsigned bogus_id,char * filename,hid_t fapl)303 test_unknown(unsigned bogus_id, char *filename, hid_t fapl)
304 {
305     hid_t fid = -1;	/* file ID */
306     hid_t gid = -1;	/* group ID */
307     hid_t did = -1;	/* Dataset ID */
308     hid_t sid = -1;     /* Dataspace ID */
309     hid_t aid = -1;     /* Attribute ID */
310     hid_t loc = -1;	/* location: file or group ID */
311     hid_t fid_bogus = -1;	/* bogus file ID */
312     hid_t gid_bogus = -1;	/* bogus group ID */
313     hid_t loc_bogus = -1;	/* location: bogus file or group ID */
314     char testfile[256];
315 
316     /* create a different name for a local copy of the data file to be
317        opened with rd/wr file permissions in case build and test are
318        done in the source directory. */
319     HDstrncpy(testfile, FILE_BOGUS, strlen(FILE_BOGUS));
320     testfile[strlen(FILE_BOGUS)]='\0';
321     HDstrncat(testfile, ".copy", 5);
322 
323     /* Make a copy of the data file from svn. */
324     if(h5_make_local_copy(FILE_BOGUS, testfile) < 0)
325       FAIL_STACK_ERROR
326 
327     TESTING("object with unknown header message and no flags set");
328 
329     /* Open filename */
330     if((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
331         FAIL_STACK_ERROR
332 
333     /* Open FILE_BOGUS */
334     if((fid_bogus = H5Fopen(testfile, H5F_ACC_RDONLY, H5P_DEFAULT)) < 0)
335         FAIL_STACK_ERROR
336 
337     /* Set up location ID depending on bogus_id */
338     if(bogus_id == H5O_BOGUS_INVALID_ID) {
339         /* Open "group" in FILE_BOGUS */
340         if((gid_bogus = H5Gopen2(fid_bogus, "group", H5P_DEFAULT)) < 0)
341             FAIL_STACK_ERROR
342         loc_bogus = gid_bogus;
343 
344         /* Create "group" in filename */
345         if((gid = H5Gcreate2(fid, "group", H5P_DEFAULT, H5P_DEFAULT, H5P_DEFAULT)) < 0)
346             FAIL_STACK_ERROR
347         loc = gid;
348 
349     } else { /* H5O_BOGUS_VALID_ID */
350         loc_bogus = fid_bogus;
351         loc = fid;
352     } /* end else */
353 
354    /* Open the dataset with the unknown header message, but no extra flags */
355     if((did = H5Dopen2(loc_bogus, "Dataset1", H5P_DEFAULT)) < 0)
356         FAIL_STACK_ERROR
357     if(H5Dclose(did) < 0)
358         FAIL_STACK_ERROR
359 
360     PASSED();
361 
362     TESTING("object in r/o file with unknown header message & 'fail if unknown and open for write' flag set");
363 
364     /* Open the dataset with the unknown header message, and "fail if unknown and open for write" flag */
365     if((did = H5Dopen2(loc_bogus, "Dataset2", H5P_DEFAULT)) < 0)
366         FAIL_STACK_ERROR
367     if(H5Dclose(did) < 0)
368         FAIL_STACK_ERROR
369 
370     PASSED();
371 
372     /* TESTING("object in r/o file with unknown header message & 'fail if unknown always' flag set"); */
373     /* There is no H5O_MSG_FLAG_FAIL_IF_UNKNOWN_ALWAYS */
374 
375     TESTING("object with unknown header message & 'mark if unknown' flag set");
376 
377     /* Copy object with "mark if unknown" flag on message into file (FILENAME[0]) that can be modified */
378     if(H5Ocopy(loc_bogus, "Dataset4", loc, "Dataset4", H5P_DEFAULT, H5P_DEFAULT) < 0)
379         FAIL_STACK_ERROR
380 
381     /* Closing: filename */
382     if(bogus_id == H5O_BOGUS_INVALID_ID)
383         if(H5Gclose(gid) < 0)
384             FAIL_STACK_ERROR
385     if(H5Fclose(fid) < 0)
386        FAIL_STACK_ERROR
387 
388     /* Re-open filename, with read-only permissions */
389     if((fid = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0)
390         FAIL_STACK_ERROR
391 
392     /* Set up location ID depending on bogus_id */
393     if(bogus_id == H5O_BOGUS_INVALID_ID) {
394         /* Open "group" in filename */
395         if((gid = H5Gopen2(fid, "group", H5P_DEFAULT)) < 0)
396             FAIL_STACK_ERROR
397         loc = gid;
398     } else
399         loc = fid;
400 
401     /* Open the dataset with the "mark if unknown" message */
402     if((did = H5Dopen2(loc, "Dataset4", H5P_DEFAULT)) < 0)
403         FAIL_STACK_ERROR
404 
405     /* Check that the "unknown" message was _NOT_ marked */
406     if(H5O_check_msg_marked_test(did, FALSE) < 0)
407         FAIL_STACK_ERROR
408 
409     /* Close the dataset */
410     if(H5Dclose(did) < 0)
411         FAIL_STACK_ERROR
412 
413     /* Close "group" in filename depending on bogus_id */
414     if(bogus_id == H5O_BOGUS_INVALID_ID)
415         if(H5Gclose(gid) < 0)
416             FAIL_STACK_ERROR
417 
418     /* Close filename (to flush change to object header) */
419     if(H5Fclose(fid) < 0)
420         FAIL_STACK_ERROR
421 
422     /* Re-open filename */
423     if((fid = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
424         FAIL_STACK_ERROR
425 
426     /* Set up location ID depending on bogus_id */
427     if(bogus_id == H5O_BOGUS_INVALID_ID) {
428         /* Open "group" in filename */
429         if((gid = H5Gopen2(fid, "group", H5P_DEFAULT)) < 0)
430             FAIL_STACK_ERROR
431         loc = gid;
432     } else
433         loc = fid;
434 
435     /* Open the dataset with the "mark if unknown" message */
436     if((did = H5Dopen2(loc, "Dataset4", H5P_DEFAULT)) < 0)
437         FAIL_STACK_ERROR
438 
439     /* Create data space */
440     if((sid = H5Screate(H5S_SCALAR)) < 0)
441         FAIL_STACK_ERROR
442 
443     /* Create an attribute, to get the object header into write access */
444     if((aid = H5Acreate2(did, "Attr", H5T_NATIVE_INT, sid, H5P_DEFAULT, H5P_DEFAULT)) < 0)
445         FAIL_STACK_ERROR
446 
447     /* Close dataspace */
448     if(H5Sclose(sid) < 0)
449         FAIL_STACK_ERROR
450 
451     /* Close attribute */
452     if(H5Aclose(aid) < 0)
453         FAIL_STACK_ERROR
454 
455     /* Close the dataset */
456     if(H5Dclose(did) < 0)
457         FAIL_STACK_ERROR
458 
459     /* Close "group" in filename depending on bogus_id */
460     if(bogus_id == H5O_BOGUS_INVALID_ID)
461         if(H5Gclose(gid) < 0)
462             FAIL_STACK_ERROR
463 
464     /* Close filename (to flush change to object header) */
465     if(H5Fclose(fid) < 0)
466         FAIL_STACK_ERROR
467 
468     /* Re-open filename */
469     if((fid = H5Fopen(filename, H5F_ACC_RDONLY, fapl)) < 0)
470         FAIL_STACK_ERROR
471 
472     /* Set up location ID depending on bogus_id */
473     if(bogus_id == H5O_BOGUS_INVALID_ID) {
474         /* Open "group" in filename */
475         if((gid = H5Gopen2(fid, "group", H5P_DEFAULT)) < 0)
476             FAIL_STACK_ERROR
477         loc = gid;
478     } else
479         loc = fid;
480 
481     /* Re-open the dataset with the "mark if unknown" message */
482     if((did = H5Dopen2(loc, "Dataset4", H5P_DEFAULT)) < 0)
483         FAIL_STACK_ERROR
484 
485     /* Check that the "unknown" message was marked */
486     if(H5O_check_msg_marked_test(did, TRUE) < 0)
487         FAIL_STACK_ERROR
488 
489     /* Close the dataset */
490     if(H5Dclose(did) < 0)
491         FAIL_STACK_ERROR
492 
493     /* Closing: filename */
494     if(bogus_id == H5O_BOGUS_INVALID_ID)
495         if(H5Gclose(gid) < 0)
496             FAIL_STACK_ERROR
497     if(H5Fclose(fid) < 0)
498         FAIL_STACK_ERROR
499 
500     PASSED();
501 
502     /* Closing: FILE_BOGUS */
503     if(bogus_id == H5O_BOGUS_INVALID_ID)
504         if(H5Gclose(gid_bogus) < 0)
505             FAIL_STACK_ERROR
506     if(H5Fclose(fid_bogus) < 0)
507         FAIL_STACK_ERROR
508 
509     TESTING("object in r/w file with unknown header message & 'fail if unknown and open for write' flag set");
510 
511     /* Open FILE_BOGUS with RW intent this time */
512     if((fid_bogus = H5Fopen(testfile, H5F_ACC_RDWR, H5P_DEFAULT)) < 0)
513         FAIL_STACK_ERROR
514 
515     /* Set up location ID */
516     if(bogus_id == H5O_BOGUS_INVALID_ID) {
517         /* Open "group" in FILE_BOGUS */
518         if((gid_bogus = H5Gopen2(fid_bogus, "group", H5P_DEFAULT)) < 0)
519             FAIL_STACK_ERROR
520         loc_bogus = gid_bogus;
521     } else
522         loc_bogus = fid_bogus;
523 
524     /* Attempt to open the dataset with the unknown header message, and "fail if unknown and open for write" flag */
525     H5E_BEGIN_TRY {
526         did = H5Dopen2(loc_bogus, "Dataset2", H5P_DEFAULT);
527     } H5E_END_TRY;
528     if(did >= 0) {
529         H5Dclose(did);
530         TEST_ERROR
531     } /* end if */
532 
533     PASSED();
534 
535     /* TESTING("object in r/w file with unknown header message & 'fail if unknown always' flag set"); */
536     /* There is no H5O_MSG_FLAG_FAIL_IF_UNKNOWN_ALWAYS */
537 
538     /* Closing: FILE_BOGUS */
539     if(bogus_id == H5O_BOGUS_INVALID_ID)
540         if(H5Gclose(gid_bogus) < 0)
541 	        FAIL_STACK_ERROR
542     if(H5Fclose(fid_bogus) < 0)
543         FAIL_STACK_ERROR
544 
545     PASSED();
546 
547     return SUCCEED;
548 
549 error:
550     H5E_BEGIN_TRY {
551         H5Fclose(fid);
552         H5Gclose(gid);
553         H5Fclose(fid_bogus);
554         H5Gclose(gid_bogus);
555         H5Dclose(did);
556         H5Sclose(sid);
557         H5Aclose(aid);
558     } H5E_END_TRY;
559 
560     return FAIL;
561 } /* test_unknown() */
562 
563 
564 /*-------------------------------------------------------------------------
565  * Function:	main
566  *
567  * Purpose:     Exercise private object header behavior and routines
568  *
569  * Return:	Success:        0
570  *		Failure:        1
571  *
572  * Programmer:	Robb Matzke
573  *              Tuesday, November 24, 1998
574  *
575  *-------------------------------------------------------------------------
576  */
577 int
main(void)578 main(void)
579 {
580     hid_t	fapl = -1, file = -1;
581     hid_t	dset = -1;
582     H5F_t	*f = NULL;
583     char	filename[1024];
584     H5O_hdr_info_t hdr_info;            /* Object info */
585     H5O_loc_t	oh_loc, oh_loc2;        /* Object header locations */
586     time_t	time_new, ro;
587     int         chunkno;                /* Chunk index for message */
588     int		i;                      /* Local index variable */
589     hbool_t     b;                      /* Index for "new format" loop */
590     herr_t      ret;                    /* Generic return value */
591 
592     /* Reset library */
593     h5_reset();
594     fapl = h5_fileaccess();
595     h5_fixname(FILENAME[0], fapl, filename, sizeof filename);
596 
597     /* Loop over old & new formats */
598     for(b = FALSE; b <= TRUE; b++) {
599         /* Display info about testing */
600         if(b)
601             HDputs("Using new file format:");
602         else
603             HDputs("Using default file format:");
604 
605         /* Set the format to use for the file */
606         if(H5Pset_libver_bounds(fapl, (b ? H5F_LIBVER_LATEST : H5F_LIBVER_EARLIEST), H5F_LIBVER_LATEST) < 0)
607             FAIL_STACK_ERROR
608 
609         /* test on object continuation block */
610         if(test_cont(filename, fapl) < 0)
611             FAIL_STACK_ERROR
612 
613         /* Create the file to operate on */
614         if((file = H5Fcreate(filename, H5F_ACC_TRUNC, H5P_DEFAULT, fapl)) < 0)
615             TEST_ERROR
616         if(NULL == (f = (H5F_t *)H5I_object(file)))
617             FAIL_STACK_ERROR
618 
619 
620         /*
621          * Test object header creation
622          * (using default group creation property list only because it's convenient)
623          */
624         TESTING("object header creation");
625         HDmemset(&oh_loc, 0, sizeof(oh_loc));
626         if(H5O_create(f, H5P_DATASET_XFER_DEFAULT, (size_t)64, (size_t)0, H5P_GROUP_CREATE_DEFAULT, &oh_loc/*out*/) < 0)
627             FAIL_STACK_ERROR
628         PASSED();
629 
630 
631         /* create a new message */
632         TESTING("message creation");
633         time_new = 11111111;
634         if(H5O_msg_create(&oh_loc, H5O_MTIME_NEW_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0)
635             FAIL_STACK_ERROR
636         if(1 != H5O_link(&oh_loc, 1, H5P_DATASET_XFER_DEFAULT))
637             FAIL_STACK_ERROR
638         if(H5AC_flush(f, H5P_DATASET_XFER_DEFAULT) < 0)
639             FAIL_STACK_ERROR
640         if(H5AC_expunge_entry(f, H5P_DATASET_XFER_DEFAULT, H5AC_OHDR, oh_loc.addr, H5AC__NO_FLAGS_SET) < 0)
641             FAIL_STACK_ERROR
642         if(NULL == H5O_msg_read(&oh_loc, H5O_MTIME_NEW_ID, &ro, H5P_DATASET_XFER_DEFAULT))
643             FAIL_STACK_ERROR
644         if(ro != time_new)
645             TEST_ERROR
646         PASSED();
647 
648 
649         /*
650          * Test modification of an existing message.
651          */
652         TESTING("message modification");
653         time_new = 33333333;
654         if(H5O_msg_write(&oh_loc, H5O_MTIME_NEW_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0)
655             FAIL_STACK_ERROR
656         if(H5AC_flush(f, H5P_DATASET_XFER_DEFAULT) < 0)
657             FAIL_STACK_ERROR
658         if(H5AC_expunge_entry(f, H5P_DATASET_XFER_DEFAULT, H5AC_OHDR, oh_loc.addr, H5AC__NO_FLAGS_SET) < 0)
659             FAIL_STACK_ERROR
660         if(NULL == H5O_msg_read(&oh_loc, H5O_MTIME_NEW_ID, &ro, H5P_DATASET_XFER_DEFAULT))
661             FAIL_STACK_ERROR
662         if(ro != time_new)
663             TEST_ERROR
664 
665         /* Make certain that chunk #0 in the object header can be encoded with a 1-byte size */
666         if(H5O_get_hdr_info(&oh_loc, H5P_DATASET_XFER_DEFAULT, &hdr_info) < 0)
667             FAIL_STACK_ERROR
668         if(hdr_info.space.total >=256)
669             TEST_ERROR
670 
671         PASSED();
672 
673         /*
674          * Test creation of a bunch of messages one after another to see
675          * what happens when the object header overflows in core.
676          * (Use 'old' MTIME message here, because it is large enough to be
677          *  replaced with a continuation message (the new one is too small)
678          *  and the library doesn't understand how to migrate more than one
679          *  message from an object header currently - QAK - 10/8/03)
680          */
681         TESTING("object header overflow in memory");
682         for(i = 0; i < 40; i++) {
683             time_new = (i + 1) * 1000 + 1000000;
684             if(H5O_msg_create(&oh_loc, H5O_MTIME_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0)
685                 FAIL_STACK_ERROR
686         } /* end for */
687         if(H5AC_flush(f, H5P_DATASET_XFER_DEFAULT) < 0)
688             FAIL_STACK_ERROR
689         if(H5AC_expunge_entry(f, H5P_DATASET_XFER_DEFAULT, H5AC_OHDR, oh_loc.addr, H5AC__NO_FLAGS_SET) < 0)
690             FAIL_STACK_ERROR
691 
692         /* Make certain that chunk #0 in the object header will be encoded with a 2-byte size */
693         if(H5O_get_hdr_info(&oh_loc, H5P_DATASET_XFER_DEFAULT, &hdr_info) < 0)
694             FAIL_STACK_ERROR
695         if(hdr_info.space.total < 256)
696             TEST_ERROR
697 
698         PASSED();
699 
700         /* Close & re-open file & object header */
701         /* (makes certain that an object header in the new format that transitions
702          *  between 1-byte chunk #0 size encoding and 2-byte chunk #0 size encoding
703          *  works correctly - QAK)
704          */
705         TESTING("close & re-open object header");
706         if(H5O_close(&oh_loc) < 0)
707             FAIL_STACK_ERROR
708         if(H5Fclose(file) < 0)
709             FAIL_STACK_ERROR
710         if((file = H5Fopen(filename, H5F_ACC_RDWR, fapl)) < 0)
711             FAIL_STACK_ERROR
712         if(NULL == (f = (H5F_t *)H5I_object(file)))
713             FAIL_STACK_ERROR
714         oh_loc.file = f;
715         if(H5O_open(&oh_loc) < 0)
716             FAIL_STACK_ERROR
717         PASSED();
718 
719         /*
720          * Test creation of a bunch of messages one after another to see
721          * what happens when the object header overflows on disk.
722          */
723         TESTING("object header overflow on disk");
724         for(i = 0; i < 10; i++) {
725             time_new = (i + 1) * 1000 + 10;
726             if(H5O_msg_create(&oh_loc, H5O_MTIME_NEW_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0)
727                 FAIL_STACK_ERROR
728             if(H5AC_flush(f, H5P_DATASET_XFER_DEFAULT) < 0)
729                 FAIL_STACK_ERROR
730             if(H5AC_expunge_entry(f, H5P_DATASET_XFER_DEFAULT, H5AC_OHDR, oh_loc.addr, H5AC__NO_FLAGS_SET) < 0)
731                 FAIL_STACK_ERROR
732         } /* end for */
733         PASSED();
734 
735         /*
736          * Delete all time messages.
737          */
738         TESTING("message deletion");
739         if(H5O_msg_remove(&oh_loc, H5O_MTIME_NEW_ID, H5O_ALL, TRUE, H5P_DATASET_XFER_DEFAULT) < 0)
740             FAIL_STACK_ERROR
741         if(H5O_msg_remove(&oh_loc, H5O_MTIME_ID, H5O_ALL, TRUE, H5P_DATASET_XFER_DEFAULT) < 0)
742             FAIL_STACK_ERROR
743         if(H5O_msg_read(&oh_loc, H5O_MTIME_NEW_ID, &ro, H5P_DATASET_XFER_DEFAULT))
744             FAIL_STACK_ERROR
745         if(H5O_msg_read(&oh_loc, H5O_MTIME_ID, &ro, H5P_DATASET_XFER_DEFAULT))
746             FAIL_STACK_ERROR
747         PASSED();
748 
749 
750         /*
751          * Constant message handling.
752          * (can't write to them, but should be able to remove them)
753          */
754         TESTING("constant message handling");
755         time_new = 22222222;
756         if(H5O_msg_create(&oh_loc, H5O_MTIME_NEW_ID, H5O_MSG_FLAG_CONSTANT, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0)
757             FAIL_STACK_ERROR
758         if(H5AC_flush(f, H5P_DATASET_XFER_DEFAULT) < 0)
759             FAIL_STACK_ERROR
760         if(H5AC_expunge_entry(f, H5P_DATASET_XFER_DEFAULT, H5AC_OHDR, oh_loc.addr, H5AC__NO_FLAGS_SET) < 0)
761             FAIL_STACK_ERROR
762         if(NULL == H5O_msg_read(&oh_loc, H5O_MTIME_NEW_ID, &ro, H5P_DATASET_XFER_DEFAULT))
763             FAIL_STACK_ERROR
764         if(ro != time_new)
765             TEST_ERROR
766         time_new = 33333333;
767         H5E_BEGIN_TRY {
768             ret = H5O_msg_write(&oh_loc, H5O_MTIME_NEW_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT);
769         } H5E_END_TRY;
770         if(ret >= 0)
771             TEST_ERROR
772         if(H5O_msg_remove(&oh_loc, H5O_MTIME_NEW_ID, H5O_ALL, TRUE, H5P_DATASET_XFER_DEFAULT) < 0)
773             FAIL_STACK_ERROR
774         PASSED();
775 
776 
777         /* release resources */
778         TESTING("object header closing");
779         if(H5O_close(&oh_loc) < 0)
780             FAIL_STACK_ERROR
781         PASSED();
782 
783         /*
784          * Test moving message to first chunk
785          */
786         TESTING("locking messages");
787         HDmemset(&oh_loc, 0, sizeof(oh_loc));
788         if(H5O_create(f, H5P_DATASET_XFER_DEFAULT, (size_t)64, (size_t)0, H5P_GROUP_CREATE_DEFAULT, &oh_loc/*out*/) < 0)
789             FAIL_STACK_ERROR
790         if(1 != H5O_link(&oh_loc, 1, H5P_DATASET_XFER_DEFAULT))
791             FAIL_STACK_ERROR
792 
793         /* Create second object header, to guarantee that first object header uses multiple chunks */
794         HDmemset(&oh_loc2, 0, sizeof(oh_loc2));
795         if(H5O_create(f, H5P_DATASET_XFER_DEFAULT, (size_t)64, (size_t)0, H5P_GROUP_CREATE_DEFAULT, &oh_loc2/*out*/) < 0)
796             FAIL_STACK_ERROR
797         if(1 != H5O_link(&oh_loc2, 1, H5P_DATASET_XFER_DEFAULT))
798             FAIL_STACK_ERROR
799 
800         /* Fill object header with messages, creating multiple chunks */
801         for(i = 0; i < 10; i++) {
802             time_new = (i + 1) * 1000 + 10;
803             if(H5O_msg_create(&oh_loc, H5O_MTIME_NEW_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0)
804                 FAIL_STACK_ERROR
805         } /* end for */
806 
807         /* Get # of object header chunks */
808         if(H5O_get_hdr_info(&oh_loc, H5P_DATASET_XFER_DEFAULT, &hdr_info) < 0)
809             FAIL_STACK_ERROR
810         if(hdr_info.nchunks != 2)
811             TEST_ERROR
812 
813         /* Add message to lock to object header */
814         time_new = 11111111;
815         if(H5O_msg_create(&oh_loc, H5O_MTIME_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0)
816             FAIL_STACK_ERROR
817 
818         /* Verify chunk index for message */
819         if((chunkno = H5O_msg_get_chunkno(&oh_loc, H5O_MTIME_ID, H5P_DATASET_XFER_DEFAULT)) < 0)
820             FAIL_STACK_ERROR
821         if(chunkno != 1)
822             TEST_ERROR
823 
824         /* Lock the message into the chunk */
825         if(H5O_msg_lock(&oh_loc, H5O_MTIME_ID, H5P_DATASET_XFER_DEFAULT) < 0)
826             FAIL_STACK_ERROR
827 
828         /* Attempt to lock the message twice */
829         H5E_BEGIN_TRY {
830             ret = H5O_msg_lock(&oh_loc, H5O_MTIME_ID, H5P_DATASET_XFER_DEFAULT);
831         } H5E_END_TRY;
832         if(ret >= 0)
833             TEST_ERROR
834 
835         /* Delete all the other messages, which would move the message into
836          * chunk #0, if it wasn't locked
837          */
838         if(H5O_msg_remove(&oh_loc, H5O_MTIME_NEW_ID, H5O_ALL, TRUE, H5P_DATASET_XFER_DEFAULT) < 0)
839             FAIL_STACK_ERROR
840 
841         /* Verify chunk index for message */
842         if((chunkno = H5O_msg_get_chunkno(&oh_loc, H5O_MTIME_ID, H5P_DATASET_XFER_DEFAULT)) < 0)
843             FAIL_STACK_ERROR
844         if(chunkno != 1)
845             TEST_ERROR
846 
847         /* Unlock the message */
848         if(H5O_msg_unlock(&oh_loc, H5O_MTIME_ID, H5P_DATASET_XFER_DEFAULT) < 0)
849             FAIL_STACK_ERROR
850 
851         /* Attempt to unlock the message twice */
852         H5E_BEGIN_TRY {
853             ret = H5O_msg_unlock(&oh_loc, H5O_MTIME_ID, H5P_DATASET_XFER_DEFAULT);
854         } H5E_END_TRY;
855         if(ret >= 0)
856             TEST_ERROR
857 
858         /* Close object headers */
859         if(H5O_close(&oh_loc2) < 0)
860             FAIL_STACK_ERROR
861         if(H5O_close(&oh_loc) < 0)
862             FAIL_STACK_ERROR
863 
864         /* Open first object header */
865         HDmemset(&oh_loc, 0, sizeof(oh_loc));
866         if(H5O_create(f, H5P_DATASET_XFER_DEFAULT, (size_t)64, (size_t)0, H5P_GROUP_CREATE_DEFAULT, &oh_loc/*out*/) < 0)
867             FAIL_STACK_ERROR
868         if(1 != H5O_link(&oh_loc, 1, H5P_DATASET_XFER_DEFAULT))
869             FAIL_STACK_ERROR
870 
871         /* Create second object header, to guarantee that first object header uses multiple chunks */
872         HDmemset(&oh_loc2, 0, sizeof(oh_loc2));
873         if(H5O_create(f, H5P_DATASET_XFER_DEFAULT, (size_t)64, (size_t)0, H5P_GROUP_CREATE_DEFAULT, &oh_loc2/*out*/) < 0)
874             FAIL_STACK_ERROR
875         if(1 != H5O_link(&oh_loc2, 1, H5P_DATASET_XFER_DEFAULT))
876             FAIL_STACK_ERROR
877 
878         /* Add message to move to object header */
879         time_new = 11111111;
880         if(H5O_msg_create(&oh_loc, H5O_MTIME_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0)
881             FAIL_STACK_ERROR
882 
883         /* Verify chunk index for message */
884         if((chunkno = H5O_msg_get_chunkno(&oh_loc, H5O_MTIME_ID, H5P_DATASET_XFER_DEFAULT)) < 0)
885             FAIL_STACK_ERROR
886         if(chunkno != 0)
887             TEST_ERROR
888 
889         /* Lock the message into the chunk */
890         if(H5O_msg_lock(&oh_loc, H5O_MTIME_ID, H5P_DATASET_XFER_DEFAULT) < 0)
891             FAIL_STACK_ERROR
892 
893         /* Fill object header with messages, creating multiple chunks */
894         /* (would normally move locked message to new chunk) */
895         for(i = 0; i < 10; i++) {
896             time_new = (i + 1) * 1000 + 10;
897             if(H5O_msg_create(&oh_loc, H5O_MTIME_NEW_ID, 0, 0, &time_new, H5P_DATASET_XFER_DEFAULT) < 0)
898                 FAIL_STACK_ERROR
899         } /* end for */
900 
901         /* Get # of object header chunks */
902         if(H5O_get_hdr_info(&oh_loc, H5P_DATASET_XFER_DEFAULT, &hdr_info) < 0)
903             FAIL_STACK_ERROR
904         if(hdr_info.nchunks != 2)
905             TEST_ERROR
906 
907         /* Verify chunk index for message */
908         if((chunkno = H5O_msg_get_chunkno(&oh_loc, H5O_MTIME_ID, H5P_DATASET_XFER_DEFAULT)) < 0)
909             FAIL_STACK_ERROR
910         if(chunkno != 0)
911             TEST_ERROR
912 
913         /* Unlock the message */
914         if(H5O_msg_unlock(&oh_loc, H5O_MTIME_ID, H5P_DATASET_XFER_DEFAULT) < 0)
915             FAIL_STACK_ERROR
916 
917         /* Close object headers */
918         if(H5O_close(&oh_loc2) < 0)
919             FAIL_STACK_ERROR
920         if(H5O_close(&oh_loc) < 0)
921             FAIL_STACK_ERROR
922 
923         PASSED();
924 
925          /* Close the file we created */
926         if(H5Fclose(file) < 0)
927             TEST_ERROR
928 
929         /* Test reading datasets with undefined object header messages
930          * and the various "fail/mark if unknown" object header message flags
931          */
932         HDputs("Accessing objects with unknown header messages: H5O_BOGUS_VALID_ID");
933         if(test_unknown(H5O_BOGUS_VALID_ID, filename, fapl) < 0)
934             TEST_ERROR
935         HDputs("Accessing objects with unknown header messages: H5O_BOGUS_INVALID_ID");
936         if(test_unknown(H5O_BOGUS_INVALID_ID, filename, fapl) < 0)
937             TEST_ERROR
938 
939         /* Test object header creation metadata cache issues */
940         if(test_ohdr_cache(filename, fapl) < 0)
941             TEST_ERROR
942     } /* end for */
943 
944     /* Verify symbol table messages are cached */
945     if(h5_verify_cached_stabs(FILENAME, fapl) < 0) TEST_ERROR
946 
947     puts("All object header tests passed.");
948     h5_cleanup(FILENAME, fapl);
949     return(0);
950 
951 error:
952     puts("*** TESTS FAILED ***");
953     H5E_BEGIN_TRY {
954         H5Fclose(file);
955     } H5E_END_TRY;
956 
957     return(1);
958 } /* end main() */
959 
960