1d583b39bSJohn Wren Kennedy /*
2d583b39bSJohn Wren Kennedy  * CDDL HEADER START
3d583b39bSJohn Wren Kennedy  *
4d583b39bSJohn Wren Kennedy  * The contents of this file are subject to the terms of the
5d583b39bSJohn Wren Kennedy  * Common Development and Distribution License (the "License").
6d583b39bSJohn Wren Kennedy  * You may not use this file except in compliance with the License.
7d583b39bSJohn Wren Kennedy  *
8d583b39bSJohn Wren Kennedy  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9d583b39bSJohn Wren Kennedy  * or http://www.opensolaris.org/os/licensing.
10d583b39bSJohn Wren Kennedy  * See the License for the specific language governing permissions
11d583b39bSJohn Wren Kennedy  * and limitations under the License.
12d583b39bSJohn Wren Kennedy  *
13d583b39bSJohn Wren Kennedy  * When distributing Covered Code, include this CDDL HEADER in each
14d583b39bSJohn Wren Kennedy  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15d583b39bSJohn Wren Kennedy  * If applicable, add the following below this CDDL HEADER, with the
16d583b39bSJohn Wren Kennedy  * fields enclosed by brackets "[]" replaced with your own identifying
17d583b39bSJohn Wren Kennedy  * information: Portions Copyright [yyyy] [name of copyright owner]
18d583b39bSJohn Wren Kennedy  *
19d583b39bSJohn Wren Kennedy  * CDDL HEADER END
20d583b39bSJohn Wren Kennedy  */
21d583b39bSJohn Wren Kennedy 
22d583b39bSJohn Wren Kennedy /*
23d583b39bSJohn Wren Kennedy  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
24d583b39bSJohn Wren Kennedy  * Use is subject to license terms.
25d583b39bSJohn Wren Kennedy  */
26d583b39bSJohn Wren Kennedy 
27d583b39bSJohn Wren Kennedy /*
28d583b39bSJohn Wren Kennedy  * Assertion:
29d583b39bSJohn Wren Kennedy  *
30d583b39bSJohn Wren Kennedy  *	A read operation and directory update operation performed
31d583b39bSJohn Wren Kennedy  *      concurrently on the same directory can lead to deadlock
32d583b39bSJohn Wren Kennedy  *	on a UFS logging file system, but not on a ZFS file system.
33d583b39bSJohn Wren Kennedy  */
34d583b39bSJohn Wren Kennedy 
35d583b39bSJohn Wren Kennedy #include <sys/types.h>
36d583b39bSJohn Wren Kennedy #include <sys/stat.h>
37d583b39bSJohn Wren Kennedy #include <errno.h>
38d583b39bSJohn Wren Kennedy #include <fcntl.h>
39d583b39bSJohn Wren Kennedy #include <string.h>
40d583b39bSJohn Wren Kennedy #include <stdio.h>
41d583b39bSJohn Wren Kennedy #include <stdlib.h>
42d583b39bSJohn Wren Kennedy #include <unistd.h>
43d583b39bSJohn Wren Kennedy #define	TMP_DIR /tmp
44d583b39bSJohn Wren Kennedy 
45d583b39bSJohn Wren Kennedy static char dirpath[256];
46d583b39bSJohn Wren Kennedy 
47d583b39bSJohn Wren Kennedy int
main(int argc,char ** argv)48d583b39bSJohn Wren Kennedy main(int argc, char **argv)
49d583b39bSJohn Wren Kennedy {
50d583b39bSJohn Wren Kennedy 	char *cp1 = "";
51d583b39bSJohn Wren Kennedy 	int i = 0;
52d583b39bSJohn Wren Kennedy 	int ret = 0;
53d583b39bSJohn Wren Kennedy 	int testdd = 0;
54d583b39bSJohn Wren Kennedy 	pid_t pid;
55d583b39bSJohn Wren Kennedy 	static const int op_num = 5;
56d583b39bSJohn Wren Kennedy 
57d583b39bSJohn Wren Kennedy 	if (argc == 1) {
58d583b39bSJohn Wren Kennedy 		(void) printf("Usage: %s <mount point>\n", argv[0]);
59d583b39bSJohn Wren Kennedy 		exit(-1);
60d583b39bSJohn Wren Kennedy 	}
61d583b39bSJohn Wren Kennedy 	for (i = 0; i < 256; i++) {
62d583b39bSJohn Wren Kennedy 		dirpath[i] = 0;
63d583b39bSJohn Wren Kennedy 	}
64d583b39bSJohn Wren Kennedy 
65d583b39bSJohn Wren Kennedy 	cp1 = argv[1];
66*3382f241Sluozhengzheng 	if (strlen(cp1) >= (sizeof (dirpath) - strlen("TMP_DIR"))) {
67*3382f241Sluozhengzheng 		(void) printf("The string length of mount point is "
68*3382f241Sluozhengzheng 		    "too large\n");
69*3382f241Sluozhengzheng 		exit(-1);
70*3382f241Sluozhengzheng 	}
71d583b39bSJohn Wren Kennedy 	(void) strcpy(&dirpath[0], (const char *)cp1);
72d583b39bSJohn Wren Kennedy 	(void) strcat(&dirpath[strlen(dirpath)], "TMP_DIR");
73d583b39bSJohn Wren Kennedy 
74d583b39bSJohn Wren Kennedy 	ret = mkdir(dirpath, 0777);
75d583b39bSJohn Wren Kennedy 	if (ret != 0) {
76d583b39bSJohn Wren Kennedy 		if (errno != EEXIST) {
77d583b39bSJohn Wren Kennedy 			(void) printf("%s: mkdir(<%s>, 0777) failed: errno "
78d583b39bSJohn Wren Kennedy 			    "(decimal)=%d\n", argv[0], dirpath, errno);
79d583b39bSJohn Wren Kennedy 			exit(-1);
80d583b39bSJohn Wren Kennedy 		}
81d583b39bSJohn Wren Kennedy 	}
82d583b39bSJohn Wren Kennedy 	testdd = open(dirpath, O_RDONLY|O_RSYNC|O_SYNC|O_DSYNC);
83d583b39bSJohn Wren Kennedy 	if (testdd < 0) {
84d583b39bSJohn Wren Kennedy 		(void) printf("%s: open(<%s>, O_RDONLY|O_RSYNC|O_SYNC|O_DSYNC)"
85d583b39bSJohn Wren Kennedy 		    " failed: errno (decimal)=%d\n", argv[0], dirpath, errno);
86d583b39bSJohn Wren Kennedy 		exit(-1);
87d583b39bSJohn Wren Kennedy 	} else {
88d583b39bSJohn Wren Kennedy 		(void) close(testdd);
89d583b39bSJohn Wren Kennedy 	}
90d583b39bSJohn Wren Kennedy 	pid = fork();
91d583b39bSJohn Wren Kennedy 	if (pid > 0) {
92d583b39bSJohn Wren Kennedy 		int fd = open(dirpath, O_RDONLY|O_RSYNC|O_SYNC|O_DSYNC);
93d583b39bSJohn Wren Kennedy 		char buf[16];
94d583b39bSJohn Wren Kennedy 		int rdret;
95d583b39bSJohn Wren Kennedy 		int j = 0;
96d583b39bSJohn Wren Kennedy 
97d583b39bSJohn Wren Kennedy 		while (j < op_num) {
98d583b39bSJohn Wren Kennedy 			(void) sleep(1);
99d583b39bSJohn Wren Kennedy 			rdret = read(fd, buf, 16);
100d583b39bSJohn Wren Kennedy 			if (rdret == -1) {
101d583b39bSJohn Wren Kennedy 				(void) printf("readdir failed");
102d583b39bSJohn Wren Kennedy 			}
103d583b39bSJohn Wren Kennedy 			j++;
104d583b39bSJohn Wren Kennedy 		}
105d583b39bSJohn Wren Kennedy 	} else if (pid == 0) {
106d583b39bSJohn Wren Kennedy 		int fd = open(dirpath, O_RDONLY);
107d583b39bSJohn Wren Kennedy 		int chownret;
108d583b39bSJohn Wren Kennedy 		int k = 0;
109d583b39bSJohn Wren Kennedy 
110d583b39bSJohn Wren Kennedy 		while (k < op_num) {
111d583b39bSJohn Wren Kennedy 			(void) sleep(1);
112d583b39bSJohn Wren Kennedy 			chownret = fchown(fd, 0, 0);
113d583b39bSJohn Wren Kennedy 			if (chownret == -1) {
114d583b39bSJohn Wren Kennedy 				(void) printf("chown failed");
115d583b39bSJohn Wren Kennedy 			}
116d583b39bSJohn Wren Kennedy 
117d583b39bSJohn Wren Kennedy 			k++;
118d583b39bSJohn Wren Kennedy 		}
119d583b39bSJohn Wren Kennedy 	}
120d583b39bSJohn Wren Kennedy 
121d583b39bSJohn Wren Kennedy 	return (0);
122d583b39bSJohn Wren Kennedy }
123