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.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or https://opensource.org/licenses/CDDL-1.0.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
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]
23 * Copyright (c) 2022 by Triad National Security, LLC
26 #include "file_common.h"
28 #include <sys/sysmacros.h>
30 static char *filename
= NULL
;
31 static int expected_offset
= -1;
32 static int blocksize
= 131072; /* 128KiB */
33 static int numblocks
= 8;
34 static const char *execname
= "file_append";
35 static int use_odirect
= 0;
40 (void) fprintf(stderr
,
41 "usage %s -f filename -e expected_offset [-b blocksize] \n"
42 " [-n numblocks] [-d use_odirect] [-h help]\n"
44 "Opens a file using O_APPEND and writes numblocks blocksize\n"
45 "blocks to filename.\n"
46 "Checks if expected_offst == lseek(fd, 0, SEEK_CUR)).\n"
48 " filename: File to open with O_APPEND and write to.\n"
49 " expected_offset: Expected file offset after writing\n"
50 " blocksize numblocks to filename\n"
51 " blocksize: Size of each block to writei (must be at\n"
52 " least >= 512). If using use_odirect (-d)\n"
53 " must be a mutltiple of _SC_PAGE_SIZE\n"
54 " numblocks: Total number of blocksized blocks to\n"
56 " use_odirect: Open file using O_DIRECT.\n"
57 " help: Print usage information and exit.\n"
59 " Required parameters:\n"
64 " blocksize -> 131072 (128 KiB)\n"
66 " use_odirect -> False\n",
72 parse_options(int argc
, char *argv
[])
77 extern int optind
, optopt
;
79 while ((c
= getopt(argc
, argv
, "b:de:f:hn:")) != -1) {
82 blocksize
= atoi(optarg
);
88 expected_offset
= atoi(optarg
);
97 numblocks
= atoi(optarg
);
100 (void) fprintf(stderr
,
101 "Option -%c requires an operand\n",
107 (void) fprintf(stderr
,
108 "Unrecognized option: -%c\n", optopt
);
117 if (use_odirect
&& ((blocksize
% sysconf(_SC_PAGE_SIZE
)) != 0)) {
118 (void) fprintf(stderr
,
119 "blocksize parameter invalid when using O_DIRECT.\n");
123 if (blocksize
< 512 || expected_offset
< 0 || filename
== NULL
||
125 (void) fprintf(stderr
,
126 "Required parameters(s) missing or invalid value for "
133 main(int argc
, char *argv
[])
136 const char *datapattern
= "0xf00ba3";
138 int fd_flags
= O_WRONLY
| O_CREAT
| O_APPEND
;
142 parse_options(argc
, argv
);
145 fd_flags
|= O_DIRECT
;
147 fd
= open(filename
, fd_flags
, 0666);
149 (void) fprintf(stderr
, "%s: %s: ", execname
, filename
);
154 err
= posix_memalign((void **)&buf
, sysconf(_SC_PAGE_SIZE
),
158 (void) fprintf(stderr
,
159 "%s: %s\n", execname
, strerror(err
));
163 /* Putting known data pattern in buffer */
164 int left
= blocksize
;
166 size_t amt
= MIN(strlen(datapattern
), left
);
167 memcpy(&buf
[buf_offset
], datapattern
, amt
);
172 for (int i
= 0; i
< numblocks
; i
++) {
173 int wrote
= write(fd
, buf
, blocksize
);
175 if (wrote
!= blocksize
) {
179 (void) fprintf(stderr
,
180 "%s: unexpected short write, wrote %d "
181 "byte, expected %d\n", execname
, wrote
,
188 /* Getting current file offset */
189 off_t off
= lseek(fd
, 0, SEEK_CUR
);
192 perror("output seek");
194 } else if (off
!= expected_offset
) {
195 (void) fprintf(stderr
,
196 "%s: expected offset %d but current offset in %s is set "
197 "to %ld\n", execname
, expected_offset
, filename
,