196c8483aSYuri Pankov /*
296c8483aSYuri Pankov * This file and its contents are supplied under the terms of the
396c8483aSYuri Pankov * Common Development and Distribution License ("CDDL"), version 1.0.
496c8483aSYuri Pankov * You may only use this file in accordance with the terms of version
596c8483aSYuri Pankov * 1.0 of the CDDL.
696c8483aSYuri Pankov *
796c8483aSYuri Pankov * A full copy of the text of the CDDL should have accompanied this
896c8483aSYuri Pankov * source. A copy of the CDDL is also available via the Internet at
996c8483aSYuri Pankov * http://www.illumos.org/license/CDDL.
1096c8483aSYuri Pankov */
1196c8483aSYuri Pankov
1296c8483aSYuri Pankov /*
1396c8483aSYuri Pankov * Copyright 2012 Jilin Xpd <jilinxpd@gmail.com>
1496c8483aSYuri Pankov * Copyright 2018 Nexenta Systems, Inc.
15*dc5e7685SJohn Levon * Copyright (c) 2018, Joyent, Inc.
1696c8483aSYuri Pankov */
1796c8483aSYuri Pankov
1896c8483aSYuri Pankov /*
1996c8483aSYuri Pankov * Using mmap, make a file and padding it with random chars.
2096c8483aSYuri Pankov */
2196c8483aSYuri Pankov
2296c8483aSYuri Pankov #include <sys/mman.h>
2396c8483aSYuri Pankov #include <sys/types.h>
2496c8483aSYuri Pankov #include <sys/stat.h>
2596c8483aSYuri Pankov #include <fcntl.h>
2696c8483aSYuri Pankov #include <stdio.h>
2796c8483aSYuri Pankov #include <stdlib.h>
2896c8483aSYuri Pankov #include <unistd.h>
2996c8483aSYuri Pankov #include <string.h>
3096c8483aSYuri Pankov #include <errno.h>
3196c8483aSYuri Pankov #include <time.h>
3296c8483aSYuri Pankov
3396c8483aSYuri Pankov void
usage(void)3496c8483aSYuri Pankov usage(void)
3596c8483aSYuri Pankov {
3696c8483aSYuri Pankov fprintf(stderr,
3796c8483aSYuri Pankov "usage: mkfile_mmap -n <size>[b|k|m|g] -f <filename>\n");
3896c8483aSYuri Pankov exit(1);
3996c8483aSYuri Pankov }
4096c8483aSYuri Pankov
4196c8483aSYuri Pankov int
main(int argc,char ** argv)4296c8483aSYuri Pankov main(int argc, char **argv)
4396c8483aSYuri Pankov {
4496c8483aSYuri Pankov char *suffix;
4596c8483aSYuri Pankov char *filename = NULL;
4696c8483aSYuri Pankov char *file_addr;
4796c8483aSYuri Pankov char *p, *q;
4896c8483aSYuri Pankov off_t offset;
4996c8483aSYuri Pankov size_t filesize;
5096c8483aSYuri Pankov size_t blksize;
5196c8483aSYuri Pankov size_t numblks;
5296c8483aSYuri Pankov size_t cnt = 1;
5396c8483aSYuri Pankov size_t mul = 1;
5496c8483aSYuri Pankov size_t i;
5596c8483aSYuri Pankov int mret = 0;
5696c8483aSYuri Pankov int c, fid;
5796c8483aSYuri Pankov
5896c8483aSYuri Pankov /*
5996c8483aSYuri Pankov * parse arguments
6096c8483aSYuri Pankov */
6196c8483aSYuri Pankov while ((c = getopt(argc, argv, "n:f:")) != -1) {
6296c8483aSYuri Pankov switch (c) {
6396c8483aSYuri Pankov case 'n':
6496c8483aSYuri Pankov cnt = (size_t)strtoul(optarg, &suffix, 0);
6596c8483aSYuri Pankov if (cnt == 0)
6696c8483aSYuri Pankov goto bad_n_arg;
6796c8483aSYuri Pankov switch (*suffix) {
6896c8483aSYuri Pankov case '\0':
6996c8483aSYuri Pankov case 'b':
7096c8483aSYuri Pankov mul = 1;
7196c8483aSYuri Pankov break;
7296c8483aSYuri Pankov case 'k':
7396c8483aSYuri Pankov mul = 1024;
7496c8483aSYuri Pankov break;
7596c8483aSYuri Pankov case 'm':
7696c8483aSYuri Pankov mul = (1024 * 1024);
7796c8483aSYuri Pankov break;
7896c8483aSYuri Pankov case 'g':
7996c8483aSYuri Pankov mul = (1024 * 1024 * 1024);
8096c8483aSYuri Pankov break;
8196c8483aSYuri Pankov default:
8296c8483aSYuri Pankov bad_n_arg:
8396c8483aSYuri Pankov fprintf(stderr, "-n %s: invalid size\n",
8496c8483aSYuri Pankov optarg);
8596c8483aSYuri Pankov return (1);
8696c8483aSYuri Pankov }
8796c8483aSYuri Pankov cnt = cnt * mul;
8896c8483aSYuri Pankov break;
8996c8483aSYuri Pankov
9096c8483aSYuri Pankov case 'f': /* target file */
9196c8483aSYuri Pankov filename = optarg;
9296c8483aSYuri Pankov break;
9396c8483aSYuri Pankov
9496c8483aSYuri Pankov case ':': /* missing optarg */
9596c8483aSYuri Pankov fprintf(stderr,
9696c8483aSYuri Pankov "Option -%c requires an arg\n", optopt);
9796c8483aSYuri Pankov usage();
9896c8483aSYuri Pankov break;
9996c8483aSYuri Pankov case '?':
10096c8483aSYuri Pankov fprintf(stderr,
10196c8483aSYuri Pankov "Unrecognized option: -%c\n", optopt);
10296c8483aSYuri Pankov usage();
10396c8483aSYuri Pankov break;
10496c8483aSYuri Pankov }
10596c8483aSYuri Pankov }
10696c8483aSYuri Pankov
10796c8483aSYuri Pankov /* open test file */
10896c8483aSYuri Pankov fid = open(filename, O_RDWR | O_CREAT | O_TRUNC,
10996c8483aSYuri Pankov S_IRUSR | S_IWUSR | S_IROTH | S_IWOTH);
11096c8483aSYuri Pankov if (fid == -1) {
11196c8483aSYuri Pankov fprintf(stderr, "open %s error=%d\n", filename, errno);
11296c8483aSYuri Pankov mret = 1;
11396c8483aSYuri Pankov goto exit3;
11496c8483aSYuri Pankov }
11596c8483aSYuri Pankov
11696c8483aSYuri Pankov /* extend file */
11796c8483aSYuri Pankov filesize = cnt;
11896c8483aSYuri Pankov if (ftruncate(fid, filesize) == -1) {
11996c8483aSYuri Pankov fprintf(stderr, "ftrunc %s error=%d\n", filename, errno);
12096c8483aSYuri Pankov mret = 1;
12196c8483aSYuri Pankov goto exit2;
12296c8483aSYuri Pankov }
12396c8483aSYuri Pankov
12496c8483aSYuri Pankov #define K 1024
12596c8483aSYuri Pankov
12696c8483aSYuri Pankov blksize = 64 * K * K;
12796c8483aSYuri Pankov numblks = (filesize + blksize - 1) / blksize;
12896c8483aSYuri Pankov for (i = 0; i < numblks && mret == 0; i++) {
12996c8483aSYuri Pankov
13096c8483aSYuri Pankov offset = i*blksize;
13196c8483aSYuri Pankov if (offset + blksize > filesize)
13296c8483aSYuri Pankov blksize = filesize - offset;
13396c8483aSYuri Pankov
13496c8483aSYuri Pankov /* map file */
13596c8483aSYuri Pankov file_addr = mmap(NULL, blksize,
13696c8483aSYuri Pankov PROT_READ | PROT_WRITE, MAP_SHARED, fid, offset);
13796c8483aSYuri Pankov if (file_addr == MAP_FAILED) {
13896c8483aSYuri Pankov fprintf(stderr, "mmap %s error=%d\n", filename, errno);
13996c8483aSYuri Pankov mret = 1;
14096c8483aSYuri Pankov break;
14196c8483aSYuri Pankov }
14296c8483aSYuri Pankov
143*dc5e7685SJohn Levon /* tag each block (to aid debug) */
144*dc5e7685SJohn Levon p = file_addr;
145*dc5e7685SJohn Levon q = file_addr + blksize - K;
14696c8483aSYuri Pankov memset(p, ' ', K);
147*dc5e7685SJohn Levon snprintf(p, K, "\nblk=%d\n\n", i);
14896c8483aSYuri Pankov p += K;
149*dc5e7685SJohn Levon
150*dc5e7685SJohn Levon /* fill something into mapped addr */
151*dc5e7685SJohn Levon while (p < q) {
152*dc5e7685SJohn Levon memset(p, ' ', K);
153*dc5e7685SJohn Levon snprintf(p, K, "\noff=0x%x\n\n",
154*dc5e7685SJohn Levon (i * blksize) + (p - file_addr));
155*dc5e7685SJohn Levon p += K;
156*dc5e7685SJohn Levon }
15796c8483aSYuri Pankov
15896c8483aSYuri Pankov /* sync mapped pages to file */
15996c8483aSYuri Pankov if (msync(file_addr, blksize, MS_SYNC) == -1) {
16096c8483aSYuri Pankov fprintf(stderr, "msync %s error=%d\n", filename, errno);
16196c8483aSYuri Pankov mret = 1;
16296c8483aSYuri Pankov }
16396c8483aSYuri Pankov
16496c8483aSYuri Pankov /* unmap file */
16596c8483aSYuri Pankov if (munmap(file_addr, blksize) == -1) {
16696c8483aSYuri Pankov fprintf(stderr, "unmap %s error=%d\n", filename, errno);
16796c8483aSYuri Pankov mret = 1;
16896c8483aSYuri Pankov }
16996c8483aSYuri Pankov }
17096c8483aSYuri Pankov
17196c8483aSYuri Pankov /* close file */
17296c8483aSYuri Pankov exit2:
17396c8483aSYuri Pankov close(fid);
17496c8483aSYuri Pankov exit3:
17596c8483aSYuri Pankov return (mret);
17696c8483aSYuri Pankov }
177