Path: blob/main/sys/contrib/openzfs/tests/zfs-tests/cmd/threadsappend.c
48529 views
// SPDX-License-Identifier: CDDL-1.01/*2* CDDL HEADER START3*4* The contents of this file are subject to the terms of the5* 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.LICENSE9* or https://opensource.org/licenses/CDDL-1.0.10* See the License for the specific language governing permissions11* and limitations under the License.12*13* When distributing Covered Code, include this CDDL HEADER in each14* file and include the License file at usr/src/OPENSOLARIS.LICENSE.15* If applicable, add the following below this CDDL HEADER, with the16* fields enclosed by brackets "[]" replaced with your own identifying17* information: Portions Copyright [yyyy] [name of copyright owner]18*19* CDDL HEADER END20*/2122/*23* Copyright 2007 Sun Microsystems, Inc. All rights reserved.24* Use is subject to license terms.25*/2627/*28* Copyright (c) 2013 by Delphix. All rights reserved.29*/3031#include <sys/types.h>32#include <sys/stat.h>33#include <fcntl.h>34#include <pthread.h>35#include <string.h>36#include <stdio.h>37#include <unistd.h>38#include <stdlib.h>39#include <errno.h>4041/*42* The size of the output file, "go.out", should be 80*8192*2 = 131072043*44* $ cd /tmp; go; ls -l go.out45* done.46* -rwxr-xr-x 1 jdm staff 1310720 Apr 13 19:45 go.out47* $ cd /zfs; go; ls -l go.out48* done.49* -rwxr-xr-x 1 jdm staff 663552 Apr 13 19:45 go.out50*51* The file on zfs is short as it does not appear that zfs is making the52* implicit seek to EOF and the actual write atomic. From the SUSv353* interface spec, behavior is undefined if concurrent writes are performed54* from multi-processes to a single file. So I don't know if this is a55* standards violation, but I cannot find any such disclaimers in our56* man pages. This issue came up at a customer site in another context, and57* the suggestion was to open the file with O_APPEND, but that wouldn't58* help with zfs(see 4977529). Also see bug# 5031301.59*/6061static int outfd = 0;6263static void *64go(void *data)65{66int ret, i = 0, n = *(int *)data;67char buf[8192] = {0};68(void) memset(buf, n, sizeof (buf));6970for (i = 0; i < 80; i++) {71ret = write(outfd, buf, sizeof (buf));72if (ret != sizeof (buf))73perror("write");74}75return (NULL);76}7778static void79usage(void)80{81(void) fprintf(stderr,82"usage: zfs_threadsappend <file name>\n");83exit(1);84}8586int87main(int argc, char **argv)88{89pthread_t tid;90int ret = 0;91long ncpus = 0;92int i;9394if (argc != 2) {95usage();96}9798ncpus = sysconf(_SC_NPROCESSORS_ONLN);99if (ncpus < 0) {100(void) fprintf(stderr,101"Invalid return from sysconf(_SC_NPROCESSORS_ONLN)"102" : errno (decimal)=%d\n", errno);103exit(1);104}105if (ncpus < 2) {106(void) fprintf(stderr,107"Must execute this binary on a multi-processor system\n");108exit(1);109}110111outfd = open(argv[optind++], O_RDWR|O_CREAT|O_APPEND|O_TRUNC, 0777);112if (outfd == -1) {113(void) fprintf(stderr,114"zfs_threadsappend: "115"open(%s, O_RDWR|O_CREAT|O_APPEND|O_TRUNC, 0777)"116" failed\n", argv[optind]);117perror("open");118exit(1);119}120121for (i = 0; i < 2; i++) {122ret = pthread_create(&tid, NULL, go, (void *)&i);123if (ret != 0) {124(void) fprintf(stderr,125"zfs_threadsappend: thr_create(#%d) "126"failed error=%d\n", i+1, ret);127exit(1);128}129}130131while (pthread_join(tid, NULL) == 0)132continue;133134return (0);135}136137138