1*f38cb554SJohn Wren Kennedy /*
2*f38cb554SJohn Wren Kennedy * CDDL HEADER START
3*f38cb554SJohn Wren Kennedy *
4*f38cb554SJohn Wren Kennedy * The contents of this file are subject to the terms of the
5*f38cb554SJohn Wren Kennedy * Common Development and Distribution License (the "License").
6*f38cb554SJohn Wren Kennedy * You may not use this file except in compliance with the License.
7*f38cb554SJohn Wren Kennedy *
8*f38cb554SJohn Wren Kennedy * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9*f38cb554SJohn Wren Kennedy * or http://www.opensolaris.org/os/licensing.
10*f38cb554SJohn Wren Kennedy * See the License for the specific language governing permissions
11*f38cb554SJohn Wren Kennedy * and limitations under the License.
12*f38cb554SJohn Wren Kennedy *
13*f38cb554SJohn Wren Kennedy * When distributing Covered Code, include this CDDL HEADER in each
14*f38cb554SJohn Wren Kennedy * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15*f38cb554SJohn Wren Kennedy * If applicable, add the following below this CDDL HEADER, with the
16*f38cb554SJohn Wren Kennedy * fields enclosed by brackets "[]" replaced with your own identifying
17*f38cb554SJohn Wren Kennedy * information: Portions Copyright [yyyy] [name of copyright owner]
18*f38cb554SJohn Wren Kennedy *
19*f38cb554SJohn Wren Kennedy * CDDL HEADER END
20*f38cb554SJohn Wren Kennedy */
21*f38cb554SJohn Wren Kennedy
22*f38cb554SJohn Wren Kennedy /*
23*f38cb554SJohn Wren Kennedy * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
24*f38cb554SJohn Wren Kennedy * Use is subject to license terms.
25*f38cb554SJohn Wren Kennedy */
26*f38cb554SJohn Wren Kennedy
27*f38cb554SJohn Wren Kennedy /*
28*f38cb554SJohn Wren Kennedy * Copyright (c) 2013 by Delphix. All rights reserved.
29*f38cb554SJohn Wren Kennedy */
30*f38cb554SJohn Wren Kennedy
31*f38cb554SJohn Wren Kennedy #include <sys/types.h>
32*f38cb554SJohn Wren Kennedy #include <sys/stat.h>
33*f38cb554SJohn Wren Kennedy #include <fcntl.h>
34*f38cb554SJohn Wren Kennedy #include <thread.h>
35*f38cb554SJohn Wren Kennedy #include <string.h>
36*f38cb554SJohn Wren Kennedy #include <stdio.h>
37*f38cb554SJohn Wren Kennedy #include <unistd.h>
38*f38cb554SJohn Wren Kennedy #include <stdlib.h>
39*f38cb554SJohn Wren Kennedy #include <errno.h>
40*f38cb554SJohn Wren Kennedy
41*f38cb554SJohn Wren Kennedy /*
42*f38cb554SJohn Wren Kennedy * The size of the output file, "go.out", should be 80*8192*2 = 1310720
43*f38cb554SJohn Wren Kennedy *
44*f38cb554SJohn Wren Kennedy * $ cd /tmp; go; ls -l go.out
45*f38cb554SJohn Wren Kennedy * done.
46*f38cb554SJohn Wren Kennedy * -rwxr-xr-x 1 jdm staff 1310720 Apr 13 19:45 go.out
47*f38cb554SJohn Wren Kennedy * $ cd /zfs; go; ls -l go.out
48*f38cb554SJohn Wren Kennedy * done.
49*f38cb554SJohn Wren Kennedy * -rwxr-xr-x 1 jdm staff 663552 Apr 13 19:45 go.out
50*f38cb554SJohn Wren Kennedy *
51*f38cb554SJohn Wren Kennedy * The file on zfs is short as it does not appear that zfs is making the
52*f38cb554SJohn Wren Kennedy * implicit seek to EOF and the actual write atomic. From the SUSv3
53*f38cb554SJohn Wren Kennedy * interface spec, behavior is undefined if concurrent writes are performed
54*f38cb554SJohn Wren Kennedy * from multi-processes to a single file. So I don't know if this is a
55*f38cb554SJohn Wren Kennedy * standards violation, but I cannot find any such disclaimers in our
56*f38cb554SJohn Wren Kennedy * man pages. This issue came up at a customer site in another context, and
57*f38cb554SJohn Wren Kennedy * the suggestion was to open the file with O_APPEND, but that wouldn't
58*f38cb554SJohn Wren Kennedy * help with zfs(see 4977529). Also see bug# 5031301.
59*f38cb554SJohn Wren Kennedy */
60*f38cb554SJohn Wren Kennedy
61*f38cb554SJohn Wren Kennedy static int outfd = 0;
62*f38cb554SJohn Wren Kennedy
63*f38cb554SJohn Wren Kennedy static void *
go(void * data)64*f38cb554SJohn Wren Kennedy go(void *data)
65*f38cb554SJohn Wren Kennedy {
66*f38cb554SJohn Wren Kennedy int i = 0, n = *(int *)data;
67*f38cb554SJohn Wren Kennedy char buf[8192] = {0};
68*f38cb554SJohn Wren Kennedy (void) memset(buf, n, sizeof (buf));
69*f38cb554SJohn Wren Kennedy
70*f38cb554SJohn Wren Kennedy for (i = 0; i < 80; i++) {
71*f38cb554SJohn Wren Kennedy (void) write(outfd, buf, sizeof (buf));
72*f38cb554SJohn Wren Kennedy }
73*f38cb554SJohn Wren Kennedy return (NULL);
74*f38cb554SJohn Wren Kennedy }
75*f38cb554SJohn Wren Kennedy
76*f38cb554SJohn Wren Kennedy static void
usage()77*f38cb554SJohn Wren Kennedy usage()
78*f38cb554SJohn Wren Kennedy {
79*f38cb554SJohn Wren Kennedy (void) fprintf(stderr,
80*f38cb554SJohn Wren Kennedy "usage: zfs_threadsappend <file name>\n");
81*f38cb554SJohn Wren Kennedy exit(1);
82*f38cb554SJohn Wren Kennedy }
83*f38cb554SJohn Wren Kennedy
84*f38cb554SJohn Wren Kennedy int
main(int argc,char ** argv)85*f38cb554SJohn Wren Kennedy main(int argc, char **argv)
86*f38cb554SJohn Wren Kennedy {
87*f38cb554SJohn Wren Kennedy int ret = 0;
88*f38cb554SJohn Wren Kennedy long ncpus = 0;
89*f38cb554SJohn Wren Kennedy int i;
90*f38cb554SJohn Wren Kennedy
91*f38cb554SJohn Wren Kennedy if (argc != 2) {
92*f38cb554SJohn Wren Kennedy usage();
93*f38cb554SJohn Wren Kennedy }
94*f38cb554SJohn Wren Kennedy
95*f38cb554SJohn Wren Kennedy ncpus = sysconf(_SC_NPROCESSORS_ONLN);
96*f38cb554SJohn Wren Kennedy if (ncpus < 0) {
97*f38cb554SJohn Wren Kennedy (void) fprintf(stderr,
98*f38cb554SJohn Wren Kennedy "Invalid return from sysconf(_SC_NPROCESSORS_ONLN)"
99*f38cb554SJohn Wren Kennedy " : errno (decimal)=%d\n", errno);
100*f38cb554SJohn Wren Kennedy exit(1);
101*f38cb554SJohn Wren Kennedy }
102*f38cb554SJohn Wren Kennedy if (ncpus < 2) {
103*f38cb554SJohn Wren Kennedy (void) fprintf(stderr,
104*f38cb554SJohn Wren Kennedy "Must execute this binary on a multi-processor system\n");
105*f38cb554SJohn Wren Kennedy exit(1);
106*f38cb554SJohn Wren Kennedy }
107*f38cb554SJohn Wren Kennedy
108*f38cb554SJohn Wren Kennedy outfd = open(argv[optind++], O_RDWR|O_CREAT|O_APPEND|O_TRUNC, 0777);
109*f38cb554SJohn Wren Kennedy if (outfd == -1) {
110*f38cb554SJohn Wren Kennedy (void) fprintf(stderr,
111*f38cb554SJohn Wren Kennedy "zfs_threadsappend: "
112*f38cb554SJohn Wren Kennedy "open(%s, O_RDWR|O_CREAT|O_APPEND|O_TRUNC, 0777)"
113*f38cb554SJohn Wren Kennedy " failed\n", argv[optind]);
114*f38cb554SJohn Wren Kennedy perror("open");
115*f38cb554SJohn Wren Kennedy exit(1);
116*f38cb554SJohn Wren Kennedy }
117*f38cb554SJohn Wren Kennedy
118*f38cb554SJohn Wren Kennedy for (i = 0; i < 2; i++) {
119*f38cb554SJohn Wren Kennedy ret = thr_create(NULL, 0, go, (void *)&i, 0, NULL);
120*f38cb554SJohn Wren Kennedy if (ret != 0) {
121*f38cb554SJohn Wren Kennedy (void) fprintf(stderr,
122*f38cb554SJohn Wren Kennedy "zfs_threadsappend: thr_create(#%d) "
123*f38cb554SJohn Wren Kennedy "failed error=%d\n", i+1, ret);
124*f38cb554SJohn Wren Kennedy exit(1);
125*f38cb554SJohn Wren Kennedy }
126*f38cb554SJohn Wren Kennedy }
127*f38cb554SJohn Wren Kennedy
128*f38cb554SJohn Wren Kennedy while (thr_join(0, NULL, NULL) == 0)
129*f38cb554SJohn Wren Kennedy continue;
130*f38cb554SJohn Wren Kennedy
131*f38cb554SJohn Wren Kennedy return (0);
132*f38cb554SJohn Wren Kennedy }
133