1662cb04cSPoul-Henning Kamp /*- 2*4d846d26SWarner Losh * SPDX-License-Identifier: BSD-2-Clause 31de7b4b8SPedro F. Giffuni * 4662cb04cSPoul-Henning Kamp * Copyright (c) 2005-2008 Poul-Henning Kamp 5662cb04cSPoul-Henning Kamp * All rights reserved. 6662cb04cSPoul-Henning Kamp * 7662cb04cSPoul-Henning Kamp * Redistribution and use in source and binary forms, with or without 8662cb04cSPoul-Henning Kamp * modification, are permitted provided that the following conditions 9662cb04cSPoul-Henning Kamp * are met: 10662cb04cSPoul-Henning Kamp * 1. Redistributions of source code must retain the above copyright 11662cb04cSPoul-Henning Kamp * notice, this list of conditions and the following disclaimer. 12662cb04cSPoul-Henning Kamp * 2. Redistributions in binary form must reproduce the above copyright 13662cb04cSPoul-Henning Kamp * notice, this list of conditions and the following disclaimer in the 14662cb04cSPoul-Henning Kamp * documentation and/or other materials provided with the distribution. 15662cb04cSPoul-Henning Kamp * 16662cb04cSPoul-Henning Kamp * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17662cb04cSPoul-Henning Kamp * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18662cb04cSPoul-Henning Kamp * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19662cb04cSPoul-Henning Kamp * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20662cb04cSPoul-Henning Kamp * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21662cb04cSPoul-Henning Kamp * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22662cb04cSPoul-Henning Kamp * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23662cb04cSPoul-Henning Kamp * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24662cb04cSPoul-Henning Kamp * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25662cb04cSPoul-Henning Kamp * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26662cb04cSPoul-Henning Kamp * SUCH DAMAGE. 27662cb04cSPoul-Henning Kamp * 28662cb04cSPoul-Henning Kamp * $FreeBSD$ 29662cb04cSPoul-Henning Kamp */ 30662cb04cSPoul-Henning Kamp 31662cb04cSPoul-Henning Kamp #include <assert.h> 32662cb04cSPoul-Henning Kamp #include <errno.h> 33662cb04cSPoul-Henning Kamp #include <stdio.h> 34662cb04cSPoul-Henning Kamp #include <string.h> 35662cb04cSPoul-Henning Kamp #include <unistd.h> 36662cb04cSPoul-Henning Kamp #include <fcntl.h> 37662cb04cSPoul-Henning Kamp #include <stdlib.h> 38662cb04cSPoul-Henning Kamp #include <sys/endian.h> 39662cb04cSPoul-Henning Kamp #include <sys/stat.h> 40662cb04cSPoul-Henning Kamp #include <sys/disk.h> 41662cb04cSPoul-Henning Kamp 42662cb04cSPoul-Henning Kamp #include "fifolog.h" 43662cb04cSPoul-Henning Kamp #include "libfifolog.h" 44662cb04cSPoul-Henning Kamp 45662cb04cSPoul-Henning Kamp const char * 466e482ac5SPoul-Henning Kamp fifolog_create(const char *fn, off_t size, ssize_t recsize) 47662cb04cSPoul-Henning Kamp { 48662cb04cSPoul-Henning Kamp int i, fd; 49818bc415SPoul-Henning Kamp ssize_t u; 50e10312caSPoul-Henning Kamp u_int uu; 51662cb04cSPoul-Henning Kamp off_t ms; 52662cb04cSPoul-Henning Kamp struct stat st; 53662cb04cSPoul-Henning Kamp char *buf; 54662cb04cSPoul-Henning Kamp int created; 55662cb04cSPoul-Henning Kamp 56662cb04cSPoul-Henning Kamp fd = open(fn, O_WRONLY | O_TRUNC | O_EXCL | O_CREAT, 0644); 57662cb04cSPoul-Henning Kamp if (fd < 0) { 58662cb04cSPoul-Henning Kamp created = 0; 59662cb04cSPoul-Henning Kamp fd = open(fn, O_WRONLY); 60662cb04cSPoul-Henning Kamp if (fd < 0) 61662cb04cSPoul-Henning Kamp return ("Could not open"); 62662cb04cSPoul-Henning Kamp } else 63662cb04cSPoul-Henning Kamp created = 1; 64662cb04cSPoul-Henning Kamp 65662cb04cSPoul-Henning Kamp /* Default sectorsize is 512 */ 66662cb04cSPoul-Henning Kamp if (recsize == 0) 67662cb04cSPoul-Henning Kamp recsize = 512; 68662cb04cSPoul-Henning Kamp 69662cb04cSPoul-Henning Kamp /* See what we got... */ 70662cb04cSPoul-Henning Kamp i = fstat(fd, &st); 71662cb04cSPoul-Henning Kamp assert(i == 0); 72662cb04cSPoul-Henning Kamp if (!S_ISBLK(st.st_mode) && 73662cb04cSPoul-Henning Kamp !S_ISCHR(st.st_mode) && 74662cb04cSPoul-Henning Kamp !S_ISREG(st.st_mode)) { 75662cb04cSPoul-Henning Kamp assert(!close (fd)); 76662cb04cSPoul-Henning Kamp return ("Wrong file type"); 77662cb04cSPoul-Henning Kamp } 78662cb04cSPoul-Henning Kamp 79662cb04cSPoul-Henning Kamp if(!created && S_ISREG(st.st_mode)) { 80662cb04cSPoul-Henning Kamp assert(!close (fd)); 81662cb04cSPoul-Henning Kamp return ("Wrong file type"); 82662cb04cSPoul-Henning Kamp } 83662cb04cSPoul-Henning Kamp 84662cb04cSPoul-Henning Kamp /* For raw disk with larger sectors: use 1 sector */ 85e10312caSPoul-Henning Kamp i = ioctl(fd, DIOCGSECTORSIZE, &uu); 86e10312caSPoul-Henning Kamp u = uu; 87662cb04cSPoul-Henning Kamp if (i == 0 && (u > recsize || (recsize % u) != 0)) 88662cb04cSPoul-Henning Kamp recsize = u; 89662cb04cSPoul-Henning Kamp 90662cb04cSPoul-Henning Kamp /* If no configured size, or too large for disk, use device size */ 91662cb04cSPoul-Henning Kamp i = ioctl(fd, DIOCGMEDIASIZE, &ms); 92662cb04cSPoul-Henning Kamp if (i == 0 && (size == 0 || size > ms)) 93662cb04cSPoul-Henning Kamp size = ms; 94662cb04cSPoul-Henning Kamp 95662cb04cSPoul-Henning Kamp if (size == 0 && S_ISREG(st.st_mode)) 96662cb04cSPoul-Henning Kamp size = st.st_size; 97662cb04cSPoul-Henning Kamp 98662cb04cSPoul-Henning Kamp if (size == 0) 99662cb04cSPoul-Henning Kamp size = recsize * (off_t)(24*60*60); 100662cb04cSPoul-Henning Kamp 101662cb04cSPoul-Henning Kamp if (S_ISREG(st.st_mode) && ftruncate(fd, size) < 0) 102662cb04cSPoul-Henning Kamp return ("Could not ftrunc"); 103662cb04cSPoul-Henning Kamp 10460e600c8SPedro F. Giffuni buf = calloc(1, recsize); 105662cb04cSPoul-Henning Kamp if (buf == NULL) 106662cb04cSPoul-Henning Kamp return ("Could not malloc"); 107662cb04cSPoul-Henning Kamp 108662cb04cSPoul-Henning Kamp strcpy(buf, FIFOLOG_FMT_MAGIC); /*lint !e64 */ 109662cb04cSPoul-Henning Kamp be32enc(buf + FIFOLOG_OFF_BS, recsize); 1106e482ac5SPoul-Henning Kamp if (recsize != pwrite(fd, buf, recsize, 0)) { 111662cb04cSPoul-Henning Kamp i = errno; 112662cb04cSPoul-Henning Kamp free(buf); 113662cb04cSPoul-Henning Kamp errno = i; 114662cb04cSPoul-Henning Kamp return ("Could not write first sector"); 115662cb04cSPoul-Henning Kamp } 116662cb04cSPoul-Henning Kamp memset(buf, 0, recsize); 117662cb04cSPoul-Henning Kamp if ((int)recsize != pwrite(fd, buf, recsize, recsize)) { 118662cb04cSPoul-Henning Kamp i = errno; 119662cb04cSPoul-Henning Kamp free(buf); 120662cb04cSPoul-Henning Kamp errno = i; 121662cb04cSPoul-Henning Kamp return ("Could not write second sector"); 122662cb04cSPoul-Henning Kamp } 123662cb04cSPoul-Henning Kamp free(buf); 124662cb04cSPoul-Henning Kamp assert(0 == close(fd)); 125662cb04cSPoul-Henning Kamp return (NULL); 126662cb04cSPoul-Henning Kamp } 127