1 /*
2  *   Copyright (c) International Business Machines  Corp., 2004
3  *
4  *   This program is free software;  you can redistribute it and/or modify
5  *   it under the terms of the GNU General Public License as published by
6  *   the Free Software Foundation; either version 2 of the License, or
7  *   (at your option) any later version.
8  *
9  *   This program is distributed in the hope that it will be useful,
10  *   but WITHOUT ANY WARRANTY;  without even the implied warranty of
11  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
12  *   the GNU General Public License for more details.
13  *
14  *   You should have received a copy of the GNU General Public License
15  *   along with this program;  if not, write to the Free Software
16  *   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
17  */
18 
19 /*
20  * TEST CASE	: pmr_post.c
21  *
22  * VARIATIONS	: 15
23  *
24  * API'S TESTED	: dm_get_region
25  *
26  * NOTES	: The first variation of this test case, when run after
27  * 		  pmr_pre and rebooting, verifies that persistent managed
28  * 		  regions work
29  */
30 #include <string.h>
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <errno.h>
34 #include <pthread.h>
35 #include <unistd.h>
36 #include <sys/mount.h>
37 #include <sys/stat.h>
38 #include <fcntl.h>
39 #include "dm_test.h"
40 
41 pthread_t tid;
42 dm_sessid_t sid;
43 char dmMsgBuf[4096];
44 char command[4096];
45 char *mountPt;
46 char *deviceNm;
47 char DummyFile[FILENAME_MAX];
48 char DummySubdir[FILENAME_MAX];
49 
50 #define TMP_FILELEN 10000
51 
52 void *Thread(void *);
53 
LogRegions(dm_region_t * rgns,u_int nelem)54 void LogRegions(dm_region_t * rgns, u_int nelem)
55 {
56 	int i;
57 
58 	DMLOG_PRINT(DMLVL_DEBUG, "Regions:\n");
59 	for (i = 0; i < nelem; i++) {
60 		DMLOG_PRINT(DMLVL_DEBUG,
61 			    "  region %d: offset %lld, size %lld, flags %d\n",
62 			    i, rgns[i].rg_offset, rgns[i].rg_size,
63 			    rgns[i].rg_flags);
64 	}
65 }
66 
main(int argc,char ** argv)67 int main(int argc, char **argv)
68 {
69 
70 	char *varstr;
71 	int i;
72 	int rc;
73 	char *szSessionInfo = "dm_test session info";
74 	dm_eventset_t events;
75 	char buf[MSG_DATALEN];
76 
77 	DMOPT_PARSE(argc, argv);
78 	DMLOG_START();
79 
80 	DMEV_ZERO(events);
81 	DMEV_SET(DM_EVENT_MOUNT, events);
82 
83 	/* CANNOT DO ANYTHING WITHOUT SUCCESSFUL INITIALIZATION */
84 	if ((rc = dm_init_service(&varstr)) != 0) {
85 		DMLOG_PRINT(DMLVL_ERR,
86 			    "dm_init_service failed! (rc = %d, errno = %d)\n",
87 			    rc, errno);
88 		DM_EXIT();
89 	} else if ((rc = dm_create_session(DM_NO_SESSION, szSessionInfo, &sid))
90 		   == -1) {
91 		DMLOG_PRINT(DMLVL_ERR,
92 			    "dm_create_session failed! (rc = %d, errno = %d)\n",
93 			    rc, errno);
94 		DM_EXIT();
95 	} else
96 	    if ((rc =
97 		 dm_set_disp(sid, DM_GLOBAL_HANP, DM_GLOBAL_HLEN, DM_NO_TOKEN,
98 			     &events, DM_EVENT_MAX)) == -1) {
99 		DMLOG_PRINT(DMLVL_ERR,
100 			    "dm_set_disp failed! (rc = %d, errno = %d)\n", rc,
101 			    errno);
102 		dm_destroy_session(sid);
103 		DM_EXIT();
104 	} else if ((rc = pthread_create(&tid, NULL, Thread, NULL)) != 0) {
105 		DMLOG_PRINT(DMLVL_ERR,
106 			    "pthread_create failed! (rc = %d, errno = %d)\n",
107 			    rc, errno);
108 		dm_destroy_session(sid);
109 		DM_EXIT();
110 	} else if ((rc = dmimpl_mount(&mountPt, &deviceNm)) == -1) {
111 		DMLOG_PRINT(DMLVL_ERR,
112 			    "dmimpl_mount failed! (rc = %d, errno = %d)\n", rc,
113 			    errno);
114 		dm_destroy_session(sid);
115 		DM_EXIT();
116 	} else {
117 		int fd;
118 
119 		sprintf(DummyFile, "%s/%s", mountPt, DUMMY_FILE);
120 		sprintf(DummySubdir, "%s/%s", mountPt, DUMMY_SUBDIR);
121 
122 		/* DO NOT REMOVE DummyFile, IT HAS THE REGIONS FOR FIRST VAR */
123 		remove(DummySubdir);
124 
125 		fd = open(DUMMY_FILE, O_RDWR | O_CREAT, DUMMY_FILE_RW_MODE);
126 		if (fd != -1) {
127 			for (i = 0; i < (TMP_FILELEN / DUMMY_STRLEN); i++) {
128 				if (write(fd, DUMMY_STRING, DUMMY_STRLEN) !=
129 				    DUMMY_STRLEN) {
130 					rc = -1;
131 					break;
132 				}
133 			}
134 		} else {
135 			rc = -1;
136 		}
137 		if (rc == 0) {
138 			rc = close(fd);
139 		}
140 		if (rc == -1) {
141 			DMLOG_PRINT(DMLVL_ERR,
142 				    "creating dummy file failed! (rc = %d, errno = %d)\n",
143 				    rc, errno);
144 			dm_destroy_session(sid);
145 			DM_EXIT();
146 		}
147 	}
148 
149 	/* This is what kicks off the test case, variations done in thread */
150 	memcpy(buf, MSG_DATA, MSG_DATALEN);
151 	rc = dm_send_msg(sid, DM_MSGTYPE_SYNC, MSG_DATALEN, buf);
152 	if (rc == -1) {
153 		DMLOG_PRINT(DMLVL_ERR,
154 			    "dm_send_msg failed! (rc = %d, errno = %d)\n", rc,
155 			    errno);
156 	}
157 
158 	rc = umount(mountPt);
159 	if (rc == -1) {
160 		DMLOG_PRINT(DMLVL_ERR, "umount failed! (rc = %d, errno = %d)\n",
161 			    rc, errno);
162 	}
163 
164 	pthread_join(tid, NULL);
165 
166 	rc = dm_destroy_session(sid);
167 	if (rc == -1) {
168 		DMLOG_PRINT(DMLVL_ERR,
169 			    "dm_destroy_session failed! (rc = %d, errno = %d)\n",
170 			    rc, errno);
171 	}
172 
173 	remove(DUMMY_FILE);
174 
175 	DMLOG_STOP();
176 
177 	tst_exit();
178 }
179 
DoTest()180 void DoTest()
181 {
182 
183 	int rc;
184 	char *szFuncName;
185 
186 	DMLOG_PRINT(DMLVL_DEBUG,
187 		    "Starting DMAPI persistent managed regions test\n");
188 
189 	szFuncName = "dm_get_region";
190 
191 	/*
192 	 * TEST    : dm_get_region - persistent, Part II
193 	 * EXPECTED: rc = 0, nelem = 5
194 	 */
195 	if (DMVAR_EXEC(GET_REGION_BASE + 1)) {
196 		int fd;
197 		void *hanp;
198 		size_t hlen;
199 		u_int nelem;
200 		dm_region_t regbuf[PMR_NUM_REGIONS];
201 		int varStatus;
202 		int i;
203 
204 		/* Variation set up */
205 		if ((fd = open(DummyFile, O_RDWR)) == -1) {
206 			/* No clean up */
207 		} else if ((rc = dm_fd_to_handle(fd, &hanp, &hlen)) == -1) {
208 			close(fd);
209 			remove(DummyFile);
210 		}
211 		if (fd == -1 || rc == -1) {
212 			DMLOG_PRINT(DMLVL_DEBUG,
213 				    "Unable to set up variation! (errno = %d)\n",
214 				    errno);
215 			DMVAR_SKIP();
216 		} else {
217 			/* Variation */
218 			DMLOG_PRINT(DMLVL_DEBUG, "%s(persistent, Part II)\n",
219 				    szFuncName);
220 			rc = dm_get_region(sid, hanp, hlen, DM_NO_TOKEN,
221 					   sizeof(regbuf) / sizeof(dm_region_t),
222 					   regbuf, &nelem);
223 			if (rc == 0) {
224 				DMLOG_PRINT(DMLVL_DEBUG, "nelem = %d\n", nelem);
225 			}
226 			varStatus = DMSTAT_PASS;
227 			if (rc != 0) {
228 				DMLOG_PRINT(DMLVL_ERR,
229 					    "%s returned unexpected rc = %d (errno = %d)\n",
230 					    szFuncName, rc, errno);
231 				varStatus = DMSTAT_FAIL;
232 			} else if (nelem != PMR_NUM_REGIONS) {
233 				DMLOG_PRINT(DMLVL_ERR,
234 					    "Number of regions NOT correct! (%d vs %d)\n",
235 					    nelem, PMR_NUM_REGIONS);
236 				varStatus = DMSTAT_FAIL;
237 			} else {
238 				DMLOG_PRINT(DMLVL_DEBUG,
239 					    "%s returned expected rc = %d\n",
240 					    szFuncName, rc, errno);
241 				DMLOG_PRINT(DMLVL_DEBUG, "nelem = %d\n", rc,
242 					    errno);
243 				LogRegions(regbuf, nelem);
244 
245 				for (i = 0; i < PMR_NUM_REGIONS; i++) {
246 					if (regbuf[i].rg_offset !=
247 					    dm_PMR_regbuf[i].rg_offset) {
248 						DMLOG_PRINT(DMLVL_ERR,
249 							    "region %d offset NOT correct! (%lld vs %d)\n",
250 							    i,
251 							    regbuf[i].rg_offset,
252 							    dm_PMR_regbuf[i].
253 							    rg_offset);
254 						varStatus = DMSTAT_FAIL;
255 					}
256 					if (regbuf[i].rg_size !=
257 					    dm_PMR_regbuf[i].rg_size) {
258 						DMLOG_PRINT(DMLVL_ERR,
259 							    "region %d size NOT correct! (%lld vs %d)\n",
260 							    i,
261 							    regbuf[i].rg_size,
262 							    dm_PMR_regbuf[i].
263 							    rg_size);
264 						varStatus = DMSTAT_FAIL;
265 					}
266 					if (regbuf[i].rg_flags !=
267 					    dm_PMR_regbuf[i].rg_flags) {
268 						DMLOG_PRINT(DMLVL_ERR,
269 							    "region %d flags NOT correct! (%lld vs %d)\n",
270 							    i,
271 							    regbuf[i].rg_flags,
272 							    dm_PMR_regbuf[i].
273 							    rg_flags);
274 						varStatus = DMSTAT_FAIL;
275 					}
276 				}
277 			}
278 			DMVAR_END(varStatus);
279 
280 			/* Variation clean up */
281 			EVENT_DELIVERY_DELAY;
282 			rc = close(fd);
283 			rc |= remove(DummyFile);
284 			if (rc == -1) {
285 				DMLOG_PRINT(DMLVL_DEBUG,
286 					    "Unable to clean up variation! (errno = %d)\n",
287 					    errno);
288 			}
289 			dm_handle_free(hanp, hlen);
290 		}
291 	}
292 
293 	/*
294 	 * TEST    : dm_get_region - invalid sid
295 	 * EXPECTED: rc = -1, errno = EINVAL
296 	 */
297 	if (DMVAR_EXEC(GET_REGION_BASE + 2)) {
298 		int fd;
299 		void *hanp;
300 		size_t hlen;
301 		u_int nelemin, nelemout;
302 		dm_region_t regbuf;
303 		dm_boolean_t exactflag;
304 
305 		/* Variation set up */
306 		nelemin = 1;
307 		memset(&regbuf, 0, sizeof(regbuf));
308 
309 		sprintf(command, "cp %s %s", DUMMY_FILE, DummyFile);
310 		if ((rc = system(command)) == -1) {
311 			/* No clean up */
312 		} else
313 		    if ((fd =
314 			 open(DummyFile, O_RDWR | O_CREAT,
315 			      DUMMY_FILE_RW_MODE)) == -1) {
316 			remove(DummyFile);
317 		} else if ((rc = dm_fd_to_handle(fd, &hanp, &hlen)) == -1) {
318 			close(fd);
319 			remove(DummyFile);
320 		} else
321 		    if ((rc =
322 			 dm_set_region(sid, hanp, hlen, DM_NO_TOKEN, nelemin,
323 				       &regbuf, &exactflag)) == -1) {
324 			close(fd);
325 			remove(DummyFile);
326 			dm_handle_free(hanp, hlen);
327 		}
328 		if (rc == -1 || fd == -1) {
329 			DMLOG_PRINT(DMLVL_DEBUG,
330 				    "Unable to set up variation! (errno = %d)\n",
331 				    errno);
332 			DMVAR_SKIP();
333 		} else {
334 			/* Variation */
335 			DMLOG_PRINT(DMLVL_DEBUG, "%s(invalid sid)\n",
336 				    szFuncName);
337 			rc = dm_get_region(INVALID_ADDR, hanp, hlen,
338 					   DM_NO_TOKEN, nelemin, &regbuf,
339 					   &nelemout);
340 			DMVAR_ENDFAILEXP(szFuncName, -1, rc, EINVAL);
341 
342 			/* Variation clean up */
343 			rc = close(fd);
344 			rc |= remove(DummyFile);
345 			if (rc == -1) {
346 				DMLOG_PRINT(DMLVL_DEBUG,
347 					    "Unable to clean up variation! (errno = %d)\n",
348 					    errno);
349 			}
350 			dm_handle_free(hanp, hlen);
351 		}
352 	}
353 
354 	/*
355 	 * TEST    : dm_get_region - invalid hanp
356 	 * EXPECTED: rc = -1, errno = EFAULT
357 	 */
358 	if (DMVAR_EXEC(GET_REGION_BASE + 3)) {
359 		int fd;
360 		void *hanp;
361 		size_t hlen;
362 		u_int nelemin, nelemout;
363 		dm_region_t regbuf;
364 		dm_boolean_t exactflag;
365 
366 		/* Variation set up */
367 		nelemin = 1;
368 		memset(&regbuf, 0, sizeof(regbuf));
369 
370 		sprintf(command, "cp %s %s", DUMMY_FILE, DummyFile);
371 		if ((rc = system(command)) == -1) {
372 			/* No clean up */
373 		} else
374 		    if ((fd =
375 			 open(DummyFile, O_RDWR | O_CREAT,
376 			      DUMMY_FILE_RW_MODE)) == -1) {
377 			remove(DummyFile);
378 		} else if ((rc = dm_fd_to_handle(fd, &hanp, &hlen)) == -1) {
379 			close(fd);
380 			remove(DummyFile);
381 		} else
382 		    if ((rc =
383 			 dm_set_region(sid, hanp, hlen, DM_NO_TOKEN, nelemin,
384 				       &regbuf, &exactflag)) == -1) {
385 			close(fd);
386 			remove(DummyFile);
387 			dm_handle_free(hanp, hlen);
388 		}
389 		if (rc == -1 || fd == -1) {
390 			DMLOG_PRINT(DMLVL_DEBUG,
391 				    "Unable to set up variation! (errno = %d)\n",
392 				    errno);
393 			DMVAR_SKIP();
394 		} else {
395 			/* Variation */
396 			DMLOG_PRINT(DMLVL_DEBUG, "%s(invalid hanp)\n",
397 				    szFuncName);
398 			rc = dm_get_region(sid, (void *)INVALID_ADDR, hlen,
399 					   DM_NO_TOKEN, nelemin, &regbuf,
400 					   &nelemout);
401 			DMVAR_ENDFAILEXP(szFuncName, -1, rc, EFAULT);
402 
403 			/* Variation clean up */
404 			rc = close(fd);
405 			rc |= remove(DummyFile);
406 			if (rc == -1) {
407 				DMLOG_PRINT(DMLVL_DEBUG,
408 					    "Unable to clean up variation! (errno = %d)\n",
409 					    errno);
410 			}
411 			dm_handle_free(hanp, hlen);
412 		}
413 	}
414 
415 	/*
416 	 * TEST    : dm_get_region - invalid hlen
417 	 * EXPECTED: rc = -1, errno = EBADF
418 	 */
419 	if (DMVAR_EXEC(GET_REGION_BASE + 4)) {
420 		int fd;
421 		void *hanp;
422 		size_t hlen;
423 		u_int nelemin, nelemout;
424 		dm_region_t regbuf;
425 		dm_boolean_t exactflag;
426 
427 		/* Variation set up */
428 		nelemin = 1;
429 		memset(&regbuf, 0, sizeof(regbuf));
430 
431 		sprintf(command, "cp %s %s", DUMMY_FILE, DummyFile);
432 		if ((rc = system(command)) == -1) {
433 			/* No clean up */
434 		} else
435 		    if ((fd =
436 			 open(DummyFile, O_RDWR | O_CREAT,
437 			      DUMMY_FILE_RW_MODE)) == -1) {
438 			remove(DummyFile);
439 		} else if ((rc = dm_fd_to_handle(fd, &hanp, &hlen)) == -1) {
440 			close(fd);
441 			remove(DummyFile);
442 		} else
443 		    if ((rc =
444 			 dm_set_region(sid, hanp, hlen, DM_NO_TOKEN, nelemin,
445 				       &regbuf, &exactflag)) == -1) {
446 			close(fd);
447 			remove(DummyFile);
448 			dm_handle_free(hanp, hlen);
449 		}
450 		if (rc == -1 || fd == -1) {
451 			DMLOG_PRINT(DMLVL_DEBUG,
452 				    "Unable to set up variation! (errno = %d)\n",
453 				    errno);
454 			DMVAR_SKIP();
455 		} else {
456 			/* Variation */
457 			DMLOG_PRINT(DMLVL_DEBUG, "%s(invalid hlen)\n",
458 				    szFuncName);
459 			rc = dm_get_region(sid, hanp, INVALID_ADDR, DM_NO_TOKEN,
460 					   nelemin, &regbuf, &nelemout);
461 			DMVAR_ENDFAILEXP(szFuncName, -1, rc, EBADF);
462 
463 			/* Variation clean up */
464 			rc = close(fd);
465 			rc |= remove(DummyFile);
466 			if (rc == -1) {
467 				DMLOG_PRINT(DMLVL_DEBUG,
468 					    "Unable to clean up variation! (errno = %d)\n",
469 					    errno);
470 			}
471 			dm_handle_free(hanp, hlen);
472 		}
473 	}
474 
475 	/*
476 	 * TEST    : dm_get_region - invalid token
477 	 * EXPECTED: rc = -1, errno = EINVAL
478 	 */
479 	if (DMVAR_EXEC(GET_REGION_BASE + 5)) {
480 		int fd;
481 		void *hanp;
482 		size_t hlen;
483 		u_int nelemin, nelemout;
484 		dm_region_t regbuf;
485 		dm_boolean_t exactflag;
486 
487 		/* Variation set up */
488 		nelemin = 1;
489 		memset(&regbuf, 0, sizeof(regbuf));
490 
491 		sprintf(command, "cp %s %s", DUMMY_FILE, DummyFile);
492 		if ((rc = system(command)) == -1) {
493 			/* No clean up */
494 		} else
495 		    if ((fd =
496 			 open(DummyFile, O_RDWR | O_CREAT,
497 			      DUMMY_FILE_RW_MODE)) == -1) {
498 			remove(DummyFile);
499 		} else if ((rc = dm_fd_to_handle(fd, &hanp, &hlen)) == -1) {
500 			close(fd);
501 			remove(DummyFile);
502 		} else
503 		    if ((rc =
504 			 dm_set_region(sid, hanp, hlen, DM_NO_TOKEN, nelemin,
505 				       &regbuf, &exactflag)) == -1) {
506 			close(fd);
507 			remove(DummyFile);
508 			dm_handle_free(hanp, hlen);
509 		}
510 		if (rc == -1 || fd == -1) {
511 			DMLOG_PRINT(DMLVL_DEBUG,
512 				    "Unable to set up variation! (errno = %d)\n",
513 				    errno);
514 			DMVAR_SKIP();
515 		} else {
516 			/* Variation */
517 			DMLOG_PRINT(DMLVL_DEBUG, "%s(invalid token)\n",
518 				    szFuncName);
519 			rc = dm_get_region(sid, hanp, hlen, INVALID_ADDR,
520 					   nelemin, &regbuf, &nelemout);
521 			DMVAR_ENDFAILEXP(szFuncName, -1, rc, EINVAL);
522 
523 			/* Variation clean up */
524 			rc = close(fd);
525 			rc |= remove(DummyFile);
526 			if (rc == -1) {
527 				DMLOG_PRINT(DMLVL_DEBUG,
528 					    "Unable to clean up variation! (errno = %d)\n",
529 					    errno);
530 			}
531 			dm_handle_free(hanp, hlen);
532 		}
533 	}
534 
535 	/*
536 	 * TEST    : dm_get_region - invalid regbufp
537 	 * EXPECTED: rc = -1, errno = EFAULT
538 	 */
539 	if (DMVAR_EXEC(GET_REGION_BASE + 6)) {
540 		int fd;
541 		void *hanp;
542 		size_t hlen;
543 		u_int nelemin, nelemout;
544 		dm_region_t regbuf;
545 		dm_boolean_t exactflag;
546 
547 		/* Variation set up */
548 		nelemin = 1;
549 		memset(&regbuf, 0, sizeof(regbuf));
550 
551 		sprintf(command, "cp %s %s", DUMMY_FILE, DummyFile);
552 		if ((rc = system(command)) == -1) {
553 			/* No clean up */
554 		} else
555 		    if ((fd =
556 			 open(DummyFile, O_RDWR | O_CREAT,
557 			      DUMMY_FILE_RW_MODE)) == -1) {
558 			remove(DummyFile);
559 		} else if ((rc = dm_fd_to_handle(fd, &hanp, &hlen)) == -1) {
560 			close(fd);
561 			remove(DummyFile);
562 		} else
563 		    if ((rc =
564 			 dm_set_region(sid, hanp, hlen, DM_NO_TOKEN, nelemin,
565 				       &regbuf, &exactflag)) == -1) {
566 			close(fd);
567 			remove(DummyFile);
568 			dm_handle_free(hanp, hlen);
569 		}
570 		if (rc == -1 || fd == -1) {
571 			DMLOG_PRINT(DMLVL_DEBUG,
572 				    "Unable to set up variation! (errno = %d)\n",
573 				    errno);
574 			DMVAR_SKIP();
575 		} else {
576 			/* Variation */
577 			DMLOG_PRINT(DMLVL_DEBUG, "%s(invalid regbufp)\n",
578 				    szFuncName);
579 			rc = dm_get_region(sid, hanp, hlen, DM_NO_TOKEN,
580 					   nelemin,
581 					   (dm_region_t *) INVALID_ADDR,
582 					   &nelemout);
583 			DMVAR_ENDFAILEXP(szFuncName, -1, rc, EFAULT);
584 
585 			/* Variation clean up */
586 			rc = close(fd);
587 			rc |= remove(DummyFile);
588 			if (rc == -1) {
589 				DMLOG_PRINT(DMLVL_DEBUG,
590 					    "Unable to clean up variation! (errno = %d)\n",
591 					    errno);
592 			}
593 			dm_handle_free(hanp, hlen);
594 		}
595 	}
596 
597 	/*
598 	 * TEST    : dm_get_region - invalid nelemp
599 	 * EXPECTED: rc = -1, errno = EFAULT
600 	 */
601 	if (DMVAR_EXEC(GET_REGION_BASE + 7)) {
602 		int fd;
603 		void *hanp;
604 		size_t hlen;
605 		u_int nelemin;
606 		dm_region_t regbuf;
607 		dm_boolean_t exactflag;
608 
609 		/* Variation set up */
610 		nelemin = 1;
611 		memset(&regbuf, 0, sizeof(regbuf));
612 
613 		sprintf(command, "cp %s %s", DUMMY_FILE, DummyFile);
614 		if ((rc = system(command)) == -1) {
615 			/* No clean up */
616 		} else
617 		    if ((fd =
618 			 open(DummyFile, O_RDWR | O_CREAT,
619 			      DUMMY_FILE_RW_MODE)) == -1) {
620 			remove(DummyFile);
621 		} else if ((rc = dm_fd_to_handle(fd, &hanp, &hlen)) == -1) {
622 			close(fd);
623 			remove(DummyFile);
624 		} else
625 		    if ((rc =
626 			 dm_set_region(sid, hanp, hlen, DM_NO_TOKEN, nelemin,
627 				       &regbuf, &exactflag)) == -1) {
628 			close(fd);
629 			remove(DummyFile);
630 			dm_handle_free(hanp, hlen);
631 		}
632 		if (rc == -1 || fd == -1) {
633 			DMLOG_PRINT(DMLVL_DEBUG,
634 				    "Unable to set up variation! (errno = %d)\n",
635 				    errno);
636 			DMVAR_SKIP();
637 		} else {
638 			/* Variation */
639 			DMLOG_PRINT(DMLVL_DEBUG, "%s(invalid nelemp)\n",
640 				    szFuncName);
641 			rc = dm_get_region(sid, hanp, hlen, DM_NO_TOKEN,
642 					   nelemin, &regbuf,
643 					   (u_int *) INVALID_ADDR);
644 			DMVAR_ENDFAILEXP(szFuncName, -1, rc, EFAULT);
645 
646 			/* Variation clean up */
647 			rc = close(fd);
648 			rc |= remove(DummyFile);
649 			if (rc == -1) {
650 				DMLOG_PRINT(DMLVL_DEBUG,
651 					    "Unable to clean up variation! (errno = %d)\n",
652 					    errno);
653 			}
654 			dm_handle_free(hanp, hlen);
655 		}
656 	}
657 
658 	/*
659 	 * TEST    : dm_get_region - DM_SO_SESSION sid
660 	 * EXPECTED: rc = -1, errno = EINVAL
661 	 */
662 	if (DMVAR_EXEC(GET_REGION_BASE + 8)) {
663 		int fd;
664 		void *hanp;
665 		size_t hlen;
666 		u_int nelemin, nelemout;
667 		dm_region_t regbuf;
668 		dm_boolean_t exactflag;
669 
670 		/* Variation set up */
671 		nelemin = 1;
672 		memset(&regbuf, 0, sizeof(regbuf));
673 
674 		sprintf(command, "cp %s %s", DUMMY_FILE, DummyFile);
675 		if ((rc = system(command)) == -1) {
676 			/* No clean up */
677 		} else
678 		    if ((fd =
679 			 open(DummyFile, O_RDWR | O_CREAT,
680 			      DUMMY_FILE_RW_MODE)) == -1) {
681 			remove(DummyFile);
682 		} else if ((rc = dm_fd_to_handle(fd, &hanp, &hlen)) == -1) {
683 			close(fd);
684 			remove(DummyFile);
685 		} else
686 		    if ((rc =
687 			 dm_set_region(sid, hanp, hlen, DM_NO_TOKEN, nelemin,
688 				       &regbuf, &exactflag)) == -1) {
689 			close(fd);
690 			remove(DummyFile);
691 			dm_handle_free(hanp, hlen);
692 		}
693 		if (rc == -1 || fd == -1) {
694 			DMLOG_PRINT(DMLVL_DEBUG,
695 				    "Unable to set up variation! (errno = %d)\n",
696 				    errno);
697 			DMVAR_SKIP();
698 		} else {
699 			/* Variation */
700 			DMLOG_PRINT(DMLVL_DEBUG, "%s(DM_NO_SESSION sid)\n",
701 				    szFuncName);
702 			rc = dm_get_region(DM_NO_SESSION, hanp, hlen,
703 					   DM_NO_TOKEN, nelemin, &regbuf,
704 					   &nelemout);
705 			DMVAR_ENDFAILEXP(szFuncName, -1, rc, EINVAL);
706 
707 			/* Variation clean up */
708 			rc = close(fd);
709 			rc |= remove(DummyFile);
710 			if (rc == -1) {
711 				DMLOG_PRINT(DMLVL_DEBUG,
712 					    "Unable to clean up variation! (errno = %d)\n",
713 					    errno);
714 			}
715 			dm_handle_free(hanp, hlen);
716 		}
717 	}
718 
719 	/*
720 	 * TEST    : dm_get_region - global handle
721 	 * EXPECTED: rc = -1, errno = EBADF
722 	 */
723 	if (DMVAR_EXEC(GET_REGION_BASE + 9)) {
724 		int fd;
725 		void *hanp;
726 		size_t hlen;
727 		u_int nelemin, nelemout;
728 		dm_region_t regbuf;
729 		dm_boolean_t exactflag;
730 
731 		/* Variation set up */
732 		nelemin = 1;
733 		memset(&regbuf, 0, sizeof(regbuf));
734 
735 		sprintf(command, "cp %s %s", DUMMY_FILE, DummyFile);
736 		if ((rc = system(command)) == -1) {
737 			/* No clean up */
738 		} else
739 		    if ((fd =
740 			 open(DummyFile, O_RDWR | O_CREAT,
741 			      DUMMY_FILE_RW_MODE)) == -1) {
742 			remove(DummyFile);
743 		} else if ((rc = dm_fd_to_handle(fd, &hanp, &hlen)) == -1) {
744 			close(fd);
745 			remove(DummyFile);
746 		} else
747 		    if ((rc =
748 			 dm_set_region(sid, hanp, hlen, DM_NO_TOKEN, nelemin,
749 				       &regbuf, &exactflag)) == -1) {
750 			close(fd);
751 			remove(DummyFile);
752 			dm_handle_free(hanp, hlen);
753 		}
754 		if (rc == -1 || fd == -1) {
755 			DMLOG_PRINT(DMLVL_DEBUG,
756 				    "Unable to set up variation! (errno = %d)\n",
757 				    errno);
758 			DMVAR_SKIP();
759 		} else {
760 			/* Variation */
761 			DMLOG_PRINT(DMLVL_DEBUG, "%s(global handle)\n",
762 				    szFuncName);
763 			rc = dm_get_region(sid, DM_GLOBAL_HANP, DM_GLOBAL_HLEN,
764 					   DM_NO_TOKEN, nelemin, &regbuf,
765 					   &nelemout);
766 			if (rc == -1 && errno == EBADF) {
767 				DMLOG_PRINT(DMLVL_DEBUG, "nelem = %d\n",
768 					    nelemout);
769 			}
770 			DMVAR_ENDFAILEXP(szFuncName, -1, rc, EBADF);
771 
772 			/* Variation clean up */
773 			rc = close(fd);
774 			rc |= remove(DummyFile);
775 			if (rc == -1) {
776 				DMLOG_PRINT(DMLVL_DEBUG,
777 					    "Unable to clean up variation! (errno = %d)\n",
778 					    errno);
779 			}
780 			dm_handle_free(hanp, hlen);
781 		}
782 	}
783 
784 	/*
785 	 * TEST    : dm_get_region - directory handle
786 	 * EXPECTED: rc = -1, errno = EINVAL
787 	 */
788 	if (DMVAR_EXEC(GET_REGION_BASE + 10)) {
789 		void *hanp;
790 		size_t hlen;
791 		u_int nelemin, nelemout;
792 		dm_region_t regbuf;
793 
794 		/* Variation set up */
795 		nelemin = 1;
796 		memset(&regbuf, 0, sizeof(regbuf));
797 
798 		if ((rc = mkdir(DummySubdir, DUMMY_DIR_RW_MODE)) == -1) {
799 			/* No clean up */
800 		} else if ((rc = dm_path_to_handle(DummySubdir, &hanp, &hlen))
801 			   == -1) {
802 			rmdir(DummySubdir);
803 		}
804 		if (rc == -1) {
805 			DMLOG_PRINT(DMLVL_DEBUG,
806 				    "Unable to set up variation! (errno = %d)\n",
807 				    errno);
808 			DMVAR_SKIP();
809 		} else {
810 			/* Variation */
811 			DMLOG_PRINT(DMLVL_DEBUG, "%s(dir handle)\n",
812 				    szFuncName);
813 			rc = dm_get_region(sid, hanp, hlen, DM_NO_TOKEN,
814 					   nelemin, &regbuf, &nelemout);
815 			DMVAR_ENDFAILEXP(szFuncName, -1, rc, EINVAL);
816 
817 			/* Variation clean up */
818 			rc = rmdir(DummySubdir);
819 			if (rc == -1) {
820 				DMLOG_PRINT(DMLVL_DEBUG,
821 					    "Unable to clean up variation! (errno = %d)\n",
822 					    errno);
823 			}
824 			dm_handle_free(hanp, hlen);
825 		}
826 	}
827 
828 	/*
829 	 * TEST    : dm_get_region - fs handle
830 	 * EXPECTED: rc = -1, errno = EINVAL
831 	 */
832 	if (DMVAR_EXEC(GET_REGION_BASE + 11)) {
833 		void *hanp;
834 		size_t hlen;
835 		u_int nelemin, nelemout;
836 		dm_region_t regbuf;
837 
838 		/* Variation set up */
839 		nelemin = 1;
840 		memset(&regbuf, 0, sizeof(regbuf));
841 
842 		if ((rc = mkdir(DummySubdir, DUMMY_DIR_RW_MODE)) == -1) {
843 			/* No clean up */
844 		} else if ((rc = dm_path_to_fshandle(DummySubdir, &hanp, &hlen))
845 			   == -1) {
846 			rmdir(DummySubdir);
847 		}
848 		if (rc == -1) {
849 			DMLOG_PRINT(DMLVL_DEBUG,
850 				    "Unable to set up variation! (errno = %d)\n",
851 				    errno);
852 			DMVAR_SKIP();
853 		} else {
854 			/* Variation */
855 			DMLOG_PRINT(DMLVL_DEBUG, "%s(fs handle)\n", szFuncName);
856 			rc = dm_get_region(sid, hanp, hlen, DM_NO_TOKEN,
857 					   nelemin, &regbuf, &nelemout);
858 			DMVAR_ENDFAILEXP(szFuncName, -1, rc, EINVAL);
859 
860 			/* Variation clean up */
861 			rc = rmdir(DummySubdir);
862 			if (rc == -1) {
863 				DMLOG_PRINT(DMLVL_DEBUG,
864 					    "Unable to clean up variation! (errno = %d)\n",
865 					    errno);
866 			}
867 			dm_handle_free(hanp, hlen);
868 		}
869 	}
870 
871 	/*
872 	 * TEST    : dm_get_region - nelem 0
873 	 * EXPECTED: rc = 0
874 	 */
875 	if (DMVAR_EXEC(GET_REGION_BASE + 11)) {
876 		int fd;
877 		void *hanp;
878 		size_t hlen;
879 		u_int nelemin, nelemout;
880 		dm_region_t regbuf;
881 
882 		/* Variation set up */
883 		nelemin = 0;
884 
885 		sprintf(command, "cp %s %s", DUMMY_FILE, DummyFile);
886 		if ((rc = system(command)) == -1) {
887 			/* No clean up */
888 		} else
889 		    if ((fd =
890 			 open(DummyFile, O_RDWR | O_CREAT,
891 			      DUMMY_FILE_RW_MODE)) == -1) {
892 			remove(DummyFile);
893 		} else if ((rc = dm_fd_to_handle(fd, &hanp, &hlen)) == -1) {
894 			close(fd);
895 			remove(DummyFile);
896 		}
897 		if (rc == -1 || fd == -1) {
898 			DMLOG_PRINT(DMLVL_DEBUG,
899 				    "Unable to set up variation! (errno = %d)\n",
900 				    errno);
901 			DMVAR_SKIP();
902 		} else {
903 			/* Variation */
904 			DMLOG_PRINT(DMLVL_DEBUG, "%s(nelem 0)\n", szFuncName);
905 			rc = dm_get_region(sid, hanp, hlen, DM_NO_TOKEN,
906 					   nelemin, &regbuf, &nelemout);
907 			if (rc == 0) {
908 				DMLOG_PRINT(DMLVL_DEBUG, "nelem = %d\n",
909 					    nelemout);
910 				if (nelemin == nelemout) {
911 					DMLOG_PRINT(DMLVL_DEBUG,
912 						    "%s passed with expected rc = %d\n",
913 						    szFuncName, 0);
914 					DMVAR_PASS();
915 				} else {
916 					DMLOG_PRINT(DMLVL_ERR,
917 						    "%s failed with expected rc = %d but unexpected nelemp (%d vs %d)\n",
918 						    szFuncName, 0, nelemin,
919 						    nelemout);
920 					DMVAR_FAIL();
921 				}
922 			} else {
923 				DMLOG_PRINT(DMLVL_ERR,
924 					    "%s failed with unexpected rc = %d (errno = %d)\n",
925 					    szFuncName, rc, errno);
926 				DMVAR_FAIL();
927 			}
928 
929 			/* Variation clean up */
930 			rc = close(fd);
931 			rc |= remove(DummyFile);
932 			if (rc == -1) {
933 				DMLOG_PRINT(DMLVL_DEBUG,
934 					    "Unable to clean up variation! (errno = %d)\n",
935 					    errno);
936 			}
937 			dm_handle_free(hanp, hlen);
938 		}
939 	}
940 
941 	/*
942 	 * TEST    : dm_get_region - nelem 1
943 	 * EXPECTED: rc = 0
944 	 */
945 	if (DMVAR_EXEC(GET_REGION_BASE + 12)) {
946 		int fd;
947 		void *hanp;
948 		size_t hlen;
949 		u_int nelemin, nelemout;
950 		dm_region_t regbufin, regbufout;
951 		dm_boolean_t exactflag;
952 
953 		/* Variation set up */
954 		nelemin = 1;
955 		memset(&regbufin, 0, sizeof(regbufin));
956 
957 		sprintf(command, "cp %s %s", DUMMY_FILE, DummyFile);
958 		if ((rc = system(command)) == -1) {
959 			/* No clean up */
960 		} else
961 		    if ((fd =
962 			 open(DummyFile, O_RDWR | O_CREAT,
963 			      DUMMY_FILE_RW_MODE)) == -1) {
964 			remove(DummyFile);
965 		} else if ((rc = dm_fd_to_handle(fd, &hanp, &hlen)) == -1) {
966 			close(fd);
967 			remove(DummyFile);
968 		} else
969 		    if ((rc =
970 			 dm_set_region(sid, hanp, hlen, DM_NO_TOKEN, nelemin,
971 				       &regbufin, &exactflag)) == -1) {
972 			close(fd);
973 			remove(DummyFile);
974 			dm_handle_free(hanp, hlen);
975 		}
976 		if (rc == -1 || fd == -1) {
977 			DMLOG_PRINT(DMLVL_DEBUG,
978 				    "Unable to set up variation! (errno = %d)\n",
979 				    errno);
980 			DMVAR_SKIP();
981 		} else {
982 			/* Variation */
983 			DMLOG_PRINT(DMLVL_DEBUG, "%s(nelem 1)\n", szFuncName);
984 			rc = dm_get_region(sid, hanp, hlen, DM_NO_TOKEN,
985 					   nelemin, &regbufout, &nelemout);
986 			if (rc == 0) {
987 				DMLOG_PRINT(DMLVL_DEBUG, "nelem = %d\n",
988 					    nelemout);
989 				if (nelemin == nelemout) {
990 					if (memcmp
991 					    (&regbufin, &regbufout,
992 					     sizeof(dm_region_t)) == 0) {
993 						DMLOG_PRINT(DMLVL_DEBUG,
994 							    "%s passed with expected rc = %d\n",
995 							    szFuncName, 0);
996 						DMVAR_PASS();
997 					} else {
998 						DMLOG_PRINT(DMLVL_ERR,
999 							    "%s failed with expected rc = %d but unexpected regions\n",
1000 							    szFuncName, 0);
1001 						DMLOG_PRINT(DMLVL_DEBUG,
1002 							    "Region in:\n");
1003 						LogRegions(&regbufin, nelemin);
1004 						DMLOG_PRINT(DMLVL_DEBUG,
1005 							    "Region out:\n");
1006 						LogRegions(&regbufout,
1007 							   nelemout);
1008 						DMVAR_FAIL();
1009 					}
1010 				} else {
1011 					DMLOG_PRINT(DMLVL_ERR,
1012 						    "%s failed with expected rc = %d but unexpected nelemp (%d vs %d)\n",
1013 						    szFuncName, 0, nelemin,
1014 						    nelemout);
1015 					DMVAR_FAIL();
1016 				}
1017 			} else {
1018 				DMLOG_PRINT(DMLVL_ERR,
1019 					    "%s failed with unexpected rc = %d (errno = %d)\n",
1020 					    szFuncName, rc, errno);
1021 				DMVAR_FAIL();
1022 			}
1023 
1024 			/* Variation clean up */
1025 			rc = close(fd);
1026 			rc |= remove(DummyFile);
1027 			if (rc == -1) {
1028 				DMLOG_PRINT(DMLVL_DEBUG,
1029 					    "Unable to clean up variation! (errno = %d)\n",
1030 					    errno);
1031 			}
1032 			dm_handle_free(hanp, hlen);
1033 		}
1034 	}
1035 
1036 	/*
1037 	 * TEST    : dm_get_region - nelem 2
1038 	 * EXPECTED: rc = 0
1039 	 */
1040 	if (DMVAR_EXEC(GET_REGION_BASE + 13)) {
1041 #ifdef MULTIPLE_REGIONS
1042 		int fd;
1043 		void *hanp;
1044 		size_t hlen;
1045 		u_int nelemin, nelemout;
1046 		dm_region_t regbufin[2], regbufout[2];
1047 		dm_boolean_t exactflag;
1048 
1049 		/* Variation set up */
1050 		nelemin = 2;
1051 		regbufin[0].rg_offset = 0;
1052 		regbufin[0].rg_size = 1000;
1053 		regbufin[0].rg_flags = DM_REGION_READ;
1054 		regbufin[1].rg_offset = 2000;
1055 		regbufin[1].rg_size = 1000;
1056 		regbufin[1].rg_flags = DM_REGION_WRITE;
1057 
1058 		sprintf(command, "cp %s %s", DUMMY_FILE, DummyFile);
1059 		if ((rc = system(command)) == -1) {
1060 			/* No clean up */
1061 		} else
1062 		    if ((fd =
1063 			 open(DummyFile, O_RDWR | O_CREAT,
1064 			      DUMMY_FILE_RW_MODE)) == -1) {
1065 			remove(DummyFile);
1066 		} else if ((rc = dm_fd_to_handle(fd, &hanp, &hlen)) == -1) {
1067 			close(fd);
1068 			remove(DummyFile);
1069 		} else
1070 		    if ((rc =
1071 			 dm_set_region(sid, hanp, hlen, DM_NO_TOKEN, nelemin,
1072 				       regbufin, &exactflag)) == -1) {
1073 			close(fd);
1074 			remove(DummyFile);
1075 			dm_handle_free(hanp, hlen);
1076 		}
1077 		if (rc == -1 || fd == -1) {
1078 			DMLOG_PRINT(DMLVL_DEBUG,
1079 				    "Unable to set up variation! (errno = %d)\n",
1080 				    errno);
1081 			DMVAR_SKIP();
1082 		} else {
1083 			/* Variation */
1084 			DMLOG_PRINT(DMLVL_DEBUG, "%s(nelem 2)\n", szFuncName);
1085 			rc = dm_get_region(sid, hanp, hlen, DM_NO_TOKEN,
1086 					   nelemin, regbufout, &nelemout);
1087 			if (rc == 0) {
1088 				DMLOG_PRINT(DMLVL_DEBUG, "nelem = %d\n",
1089 					    nelemout);
1090 				if (nelemin == nelemout) {
1091 					if (memcmp
1092 					    (&regbufin, &regbufout,
1093 					     sizeof(dm_region_t)) == 0) {
1094 						DMLOG_PRINT(DMLVL_DEBUG,
1095 							    "%s passed with expected rc = %d\n",
1096 							    szFuncName, 0);
1097 						DMVAR_PASS();
1098 					} else {
1099 						DMLOG_PRINT(DMLVL_ERR,
1100 							    "%s failed with expected rc = %d but unexpected regions\n",
1101 							    szFuncName, 0);
1102 						DMLOG_PRINT(DMLVL_DEBUG,
1103 							    "Region in:\n");
1104 						LogRegions(regbufin, nelemin);
1105 						DMLOG_PRINT(DMLVL_DEBUG,
1106 							    "Region out:\n");
1107 						LogRegions(regbufout, nelemout);
1108 						DMVAR_FAIL();
1109 					}
1110 				} else {
1111 					DMLOG_PRINT(DMLVL_ERR,
1112 						    "%s failed with expected rc = %d but unexpected nelemp (%d vs %d)\n",
1113 						    szFuncName, 0, nelemin,
1114 						    nelemout);
1115 					DMVAR_FAIL();
1116 				}
1117 			} else {
1118 				DMLOG_PRINT(DMLVL_ERR,
1119 					    "%s failed with unexpected rc = %d (errno = %d)\n",
1120 					    szFuncName, rc, errno);
1121 				DMVAR_FAIL();
1122 			}
1123 
1124 			/* Variation clean up */
1125 			rc = close(fd);
1126 			rc |= remove(DummyFile);
1127 			if (rc == -1) {
1128 				DMLOG_PRINT(DMLVL_DEBUG,
1129 					    "Unable to clean up variation! (errno = %d)\n",
1130 					    errno);
1131 			}
1132 			dm_handle_free(hanp, hlen);
1133 		}
1134 #else
1135 		DMLOG_PRINT(DMLVL_WARN,
1136 			    "Test case not built with MULTIPLE_REGIONS defined\n");
1137 		DMVAR_SKIP();
1138 #endif
1139 	}
1140 
1141 	/*
1142 	 * TEST    : dm_get_region - regbuf too small
1143 	 * EXPECTED: rc = -1, errno = E2BIG
1144 	 */
1145 	if (DMVAR_EXEC(GET_REGION_BASE + 14)) {
1146 		int fd;
1147 		void *hanp;
1148 		size_t hlen;
1149 		u_int nelemin, nelemout;
1150 		dm_region_t regbufin[2], regbufout[1];
1151 		dm_boolean_t exactflag;
1152 
1153 		/* Variation set up */
1154 #ifdef MULTIPLE_REGIONS
1155 		nelemin = 2;
1156 		regbufin[0].rg_offset = 0;
1157 		regbufin[0].rg_size = 1000;
1158 		regbufin[0].rg_flags = DM_REGION_READ;
1159 		regbufin[1].rg_offset = 2000;
1160 		regbufin[1].rg_size = 1000;
1161 		regbufin[1].rg_flags = DM_REGION_WRITE;
1162 #else
1163 		nelemin = 1;
1164 		regbufin[0].rg_offset = 0;
1165 		regbufin[0].rg_size = 1000;
1166 		regbufin[0].rg_flags = DM_REGION_READ;
1167 #endif
1168 
1169 		sprintf(command, "cp %s %s", DUMMY_FILE, DummyFile);
1170 		if ((rc = system(command)) == -1) {
1171 			/* No clean up */
1172 		} else
1173 		    if ((fd =
1174 			 open(DummyFile, O_RDWR | O_CREAT,
1175 			      DUMMY_FILE_RW_MODE)) == -1) {
1176 			remove(DummyFile);
1177 		} else if ((rc = dm_fd_to_handle(fd, &hanp, &hlen)) == -1) {
1178 			close(fd);
1179 			remove(DummyFile);
1180 		} else
1181 		    if ((rc =
1182 			 dm_set_region(sid, hanp, hlen, DM_NO_TOKEN, nelemin,
1183 				       regbufin, &exactflag)) == -1) {
1184 			close(fd);
1185 			remove(DummyFile);
1186 			dm_handle_free(hanp, hlen);
1187 		}
1188 		if (rc == -1 || fd == -1) {
1189 			DMLOG_PRINT(DMLVL_DEBUG,
1190 				    "Unable to set up variation! (errno = %d)\n",
1191 				    errno);
1192 			DMVAR_SKIP();
1193 		} else {
1194 			/* Variation */
1195 			DMLOG_PRINT(DMLVL_DEBUG, "%s(regbuf too small)\n",
1196 				    szFuncName);
1197 			rc = dm_get_region(sid, hanp, hlen, DM_NO_TOKEN,
1198 					   nelemin - 1, regbufout, &nelemout);
1199 			if (rc == -1) {
1200 				if (errno == E2BIG) {
1201 					DMLOG_PRINT(DMLVL_DEBUG, "nelem = %d\n",
1202 						    nelemout);
1203 					if (nelemout == nelemin) {
1204 						DMLOG_PRINT(DMLVL_DEBUG,
1205 							    "%s passed with expected rc = %d and expected errno = %d\n",
1206 							    szFuncName, rc,
1207 							    errno);
1208 						DMVAR_PASS();
1209 					} else {
1210 						DMLOG_PRINT(DMLVL_ERR,
1211 							    "%s failed with expected rc = %d and expected errno = %d but unexpected nelemp (%d vs %d)\n",
1212 							    szFuncName, rc,
1213 							    errno, nelemout,
1214 							    nelemin);
1215 						DMVAR_FAIL();
1216 					}
1217 				} else {
1218 					DMLOG_PRINT(DMLVL_ERR,
1219 						    "%s failed with expected rc = %d but unexpected errno = %d\n",
1220 						    szFuncName, rc, errno);
1221 					DMVAR_FAIL();
1222 				}
1223 			} else {
1224 				DMLOG_PRINT(DMLVL_ERR,
1225 					    "%s failed with unexpected rc = %d\n",
1226 					    szFuncName, rc);
1227 				DMVAR_FAIL();
1228 			}
1229 
1230 			/* Variation clean up */
1231 			rc = close(fd);
1232 			rc |= remove(DummyFile);
1233 			if (rc == -1) {
1234 				DMLOG_PRINT(DMLVL_DEBUG,
1235 					    "Unable to clean up variation! (errno = %d)\n",
1236 					    errno);
1237 			}
1238 			dm_handle_free(hanp, hlen);
1239 		}
1240 	}
1241 
1242 }
1243 
Thread(void * parm)1244 void *Thread(void *parm)
1245 {
1246 	int rc;
1247 	size_t dmMsgBufLen;
1248 	dm_eventmsg_t *dmMsg;
1249 	int bMounted = DM_FALSE;
1250 	dm_eventtype_t type;
1251 	dm_token_t token;
1252 	dm_eventset_t events;
1253 	dm_response_t response;
1254 
1255 	do {
1256 		/* Loop until message received (wait could be interrupted) */
1257 		do {
1258 			DMLOG_PRINT(DMLVL_DEBUG, "Waiting for event...\n");
1259 			dmMsgBufLen = 0;
1260 
1261 			rc = dm_get_events(sid, 1, DM_EV_WAIT, sizeof(dmMsgBuf),
1262 					   dmMsgBuf, &dmMsgBufLen);
1263 			DMLOG_PRINT(DMLVL_DEBUG,
1264 				    "... dm_get_events returned %d (errno %d)\n",
1265 				    rc, errno);
1266 		} while ((rc == -1) && (errno == EINTR) && (dmMsgBufLen == 0));
1267 
1268 		if (rc) {
1269 			DMLOG_PRINT(DMLVL_ERR,
1270 				    "dm_get_events failed with rc = %d, errno = %d\n",
1271 				    rc, errno);
1272 			dm_destroy_session(sid);
1273 			DM_EXIT();
1274 		} else {
1275 			dmMsg = (dm_eventmsg_t *) dmMsgBuf;
1276 			token = dmMsg->ev_token;
1277 			type = dmMsg->ev_type;
1278 
1279 			DMLOG_PRINT(DMLVL_DEBUG, "Received message %d\n", type);
1280 		}
1281 
1282 		if (type == DM_EVENT_MOUNT) {
1283 			/* SPECIAL CASE: need to set bMounted and response */
1284 			dm_mount_event_t *me =
1285 			    DM_GET_VALUE(dmMsg, ev_data, dm_mount_event_t *);
1286 			void *lhanp = DM_GET_VALUE(me, me_handle1, void *);
1287 			size_t lhlen = DM_GET_LEN(me, me_handle1);
1288 
1289 			bMounted = dm_handle_is_valid(lhanp, lhlen);
1290 
1291 			rc = dm_request_right(sid, lhanp, lhlen, token,
1292 					      DM_RR_WAIT, DM_RIGHT_EXCL);
1293 			if (rc == -1) {
1294 				DMLOG_PRINT(DMLVL_ERR,
1295 					    "dm_request_right failed! (rc = %d, errno = %d)\n",
1296 					    rc, errno);
1297 				dm_destroy_session(sid);
1298 				DM_EXIT();
1299 			}
1300 
1301 			DMEV_ZERO(events);
1302 			DMEV_SET(DM_EVENT_UNMOUNT, events);
1303 			rc = dm_set_disp(sid, lhanp, lhlen, token, &events,
1304 					 DM_EVENT_MAX);
1305 			if (rc == -1) {
1306 				DMLOG_PRINT(DMLVL_ERR,
1307 					    "dm_set_disp failed! (rc = %d, errno = %d)\n",
1308 					    rc, errno);
1309 				dm_destroy_session(sid);
1310 				DM_EXIT();
1311 			}
1312 
1313 			rc = dm_set_eventlist(sid, lhanp, lhlen, token, &events,
1314 					      DM_EVENT_MAX);
1315 			if (rc == -1) {
1316 				DMLOG_PRINT(DMLVL_ERR,
1317 					    "dm_set_eventlist failed! (rc = %d, errno = %d)\n",
1318 					    rc, errno);
1319 				dm_destroy_session(sid);
1320 				DM_EXIT();
1321 			}
1322 
1323 			rc = dm_release_right(sid, lhanp, lhlen, token);
1324 			if (rc == -1) {
1325 				DMLOG_PRINT(DMLVL_ERR,
1326 					    "dm_request_right failed! (rc = %d, errno = %d)\n",
1327 					    rc, errno);
1328 				dm_destroy_session(sid);
1329 				DM_EXIT();
1330 			}
1331 
1332 			response = DM_RESP_CONTINUE;
1333 		} else if (type == DM_EVENT_UNMOUNT) {
1334 			/* SPECIAL CASE: need to set response and bMounted */
1335 			dm_namesp_event_t *nse =
1336 			    DM_GET_VALUE(dmMsg, ev_data, dm_namesp_event_t *);
1337 
1338 			if (nse->ne_retcode == 0) {
1339 				bMounted = DM_FALSE;
1340 			}
1341 
1342 			response = DM_RESP_CONTINUE;
1343 		} else if (type == DM_EVENT_USER) {
1344 			DMLOG_PRINT(DMLVL_DEBUG, "Message is DM_EVENT_USER\n");
1345 
1346 			DoTest();
1347 
1348 			response = DM_RESP_CONTINUE;
1349 		} else {
1350 			DMLOG_PRINT(DMLVL_ERR, "Message is unexpected!\n");
1351 			response = DM_RESP_ABORT;
1352 		}
1353 
1354 		if (response != DM_RESP_INVALID) {
1355 			DMLOG_PRINT(DMLVL_DEBUG,
1356 				    "Responding to message %d with %d\n", type,
1357 				    response);
1358 			rc = dm_respond_event(sid, token, response,
1359 					      response ==
1360 					      DM_RESP_ABORT ? ABORT_ERRNO : 0,
1361 					      0, NULL);
1362 		}
1363 	} while (bMounted);
1364 
1365 	pthread_exit(0);
1366 }
1367