]> git.proxmox.com Git - mirror_zfs-debian.git/blob - tests/zfs-tests/cmd/mktree/mktree.c
New upstream version 0.7.9
[mirror_zfs-debian.git] / tests / zfs-tests / cmd / mktree / mktree.c
1 /*
2 * CDDL HEADER START
3 *
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
24 * Use is subject to license terms.
25 */
26
27 #include <errno.h>
28 #include <stdio.h>
29 #include <stdlib.h>
30 #include <unistd.h>
31 #include <string.h>
32 #include <fcntl.h>
33 #include <sys/xattr.h>
34 #include <sys/stat.h>
35 #include <sys/types.h>
36 #include <sys/param.h>
37
38 #define TYPE_D 'D'
39 #define TYPE_F 'F'
40
41 static char fdname[MAXPATHLEN] = {0};
42 static char *pbasedir = NULL;
43 static int nlevel = 2;
44 static int ndir = 2;
45 static int nfile = 2;
46
47 static void usage(char *this);
48 static void crtfile(char *pname);
49 static char *getfdname(char *pdir, char type, int level, int dir, int file);
50 static int mktree(char *pbasedir, int level);
51
52 int
53 main(int argc, char *argv[])
54 {
55 int c, ret;
56
57 while ((c = getopt(argc, argv, "b:l:d:f:")) != -1) {
58 switch (c) {
59 case 'b':
60 pbasedir = optarg;
61 break;
62 case 'l':
63 nlevel = atoi(optarg);
64 break;
65 case 'd':
66 ndir = atoi(optarg);
67 break;
68 case 'f':
69 nfile = atoi(optarg);
70 break;
71 case '?':
72 usage(argv[0]);
73 }
74 }
75 if (nlevel < 0 || ndir < 0 || nfile < 0 || pbasedir == NULL) {
76 usage(argv[0]);
77 }
78
79 ret = mktree(pbasedir, 1);
80
81 return (ret);
82 }
83
84 static void
85 usage(char *this)
86 {
87 (void) fprintf(stderr,
88 "\tUsage: %s -b <base_dir> -l [nlevel] -d [ndir] -f [nfile]\n",
89 this);
90 exit(1);
91 }
92
93 static int
94 mktree(char *pdir, int level)
95 {
96 int d, f;
97 char dname[MAXPATHLEN] = {0};
98 char fname[MAXPATHLEN] = {0};
99
100 if (level > nlevel) {
101 return (1);
102 }
103
104 for (d = 0; d < ndir; d++) {
105 (void) memset(dname, '\0', sizeof (dname));
106 (void) strcpy(dname, getfdname(pdir, TYPE_D, level, d, 0));
107
108 if (mkdir(dname, 0777) != 0) {
109 (void) fprintf(stderr, "mkdir(%s) failed."
110 "\n[%d]: %s.\n",
111 dname, errno, strerror(errno));
112 exit(errno);
113 }
114
115 /*
116 * No sub-directory need be created, only create files in it.
117 */
118 if (mktree(dname, level+1) != 0) {
119 for (f = 0; f < nfile; f++) {
120 (void) memset(fname, '\0', sizeof (fname));
121 (void) strcpy(fname,
122 getfdname(dname, TYPE_F, level+1, d, f));
123 crtfile(fname);
124 }
125 }
126 }
127
128 for (f = 0; f < nfile; f++) {
129 (void) memset(fname, '\0', sizeof (fname));
130 (void) strcpy(fname, getfdname(pdir, TYPE_F, level, d, f));
131 crtfile(fname);
132 }
133
134 return (0);
135 }
136
137 static char *
138 getfdname(char *pdir, char type, int level, int dir, int file)
139 {
140 size_t size = sizeof (fdname);
141 if (snprintf(fdname, size, "%s/%c-l%dd%df%d", pdir, type, level, dir,
142 file) >= size) {
143 (void) fprintf(stderr, "fdname truncated\n");
144 exit(EINVAL);
145 }
146 return (fdname);
147 }
148
149 static void
150 crtfile(char *pname)
151 {
152 int fd = -1;
153 int i, size;
154 char *context = "0123456789ABCDF";
155 char *pbuf;
156
157 if (pname == NULL) {
158 exit(1);
159 }
160
161 size = sizeof (char) * 1024;
162 pbuf = (char *)valloc(size);
163 for (i = 0; i < size / strlen(context); i++) {
164 int offset = i * strlen(context);
165 (void) snprintf(pbuf+offset, size-offset, "%s", context);
166 }
167
168 if ((fd = open(pname, O_CREAT|O_RDWR, 0777)) < 0) {
169 (void) fprintf(stderr, "open(%s, O_CREAT|O_RDWR, 0777) failed."
170 "\n[%d]: %s.\n", pname, errno, strerror(errno));
171 exit(errno);
172 }
173 if (write(fd, pbuf, 1024) < 1024) {
174 (void) fprintf(stderr, "write(fd, pbuf, 1024) failed."
175 "\n[%d]: %s.\n", errno, strerror(errno));
176 exit(errno);
177 }
178
179 if (fsetxattr(fd, "user.xattr", pbuf, 1024, 0) < 0) {
180 (void) fprintf(stderr, "fsetxattr(fd, \"xattr\", pbuf, "
181 "1024, 0) failed.\n[%d]: %s.\n", errno, strerror(errno));
182 exit(errno);
183 }
184
185 (void) close(fd);
186 free(pbuf);
187 }