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 * 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 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 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