xref: /freebsd/sys/contrib/openzfs/cmd/zstream/zstream_util.c (revision 80aae8a3f8aa70712930664572be9e6885dc0be7)
1*80aae8a3SMartin Matuska // SPDX-License-Identifier: CDDL-1.0
2*80aae8a3SMartin Matuska /*
3*80aae8a3SMartin Matuska  * CDDL HEADER START
4*80aae8a3SMartin Matuska  *
5*80aae8a3SMartin Matuska  * This file and its contents are supplied under the terms of the
6*80aae8a3SMartin Matuska  * Common Development and Distribution License ("CDDL"), version 1.0.
7*80aae8a3SMartin Matuska  * You may only use this file in accordance with the terms of version
8*80aae8a3SMartin Matuska  * 1.0 of the CDDL.
9*80aae8a3SMartin Matuska  *
10*80aae8a3SMartin Matuska  * A full copy of the text of the CDDL should have accompanied this
11*80aae8a3SMartin Matuska  * source.  A copy of the CDDL is also available via the Internet at
12*80aae8a3SMartin Matuska  * http://www.illumos.org/license/CDDL.
13*80aae8a3SMartin Matuska  *
14*80aae8a3SMartin Matuska  * CDDL HEADER END
15*80aae8a3SMartin Matuska  */
16*80aae8a3SMartin Matuska 
17*80aae8a3SMartin Matuska /*
18*80aae8a3SMartin Matuska  * Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
19*80aae8a3SMartin Matuska  * Copyright (c) 2011, 2020 by Delphix. All rights reserved.
20*80aae8a3SMartin Matuska  * Copyright (c) 2012, Joyent, Inc. All rights reserved.
21*80aae8a3SMartin Matuska  * Copyright (c) 2012 Pawel Jakub Dawidek <pawel@dawidek.net>.
22*80aae8a3SMartin Matuska  * All rights reserved
23*80aae8a3SMartin Matuska  * Copyright (c) 2013 Steven Hartland. All rights reserved.
24*80aae8a3SMartin Matuska  * Copyright 2015, OmniTI Computer Consulting, Inc. All rights reserved.
25*80aae8a3SMartin Matuska  * Copyright 2016 Igor Kozhukhov <ikozhukhov@gmail.com>
26*80aae8a3SMartin Matuska  * Copyright (c) 2018, loli10K <ezomori.nozomu@gmail.com>. All rights reserved.
27*80aae8a3SMartin Matuska  * Copyright (c) 2019 Datto Inc.
28*80aae8a3SMartin Matuska  * Copyright (c) 2024, Klara, Inc.
29*80aae8a3SMartin Matuska  */
30*80aae8a3SMartin Matuska 
31*80aae8a3SMartin Matuska #include <sys/debug.h>
32*80aae8a3SMartin Matuska #include <stddef.h>
33*80aae8a3SMartin Matuska #include <errno.h>
34*80aae8a3SMartin Matuska #include <unistd.h>
35*80aae8a3SMartin Matuska #include <stdlib.h>
36*80aae8a3SMartin Matuska #include <stdio.h>
37*80aae8a3SMartin Matuska #include <string.h>
38*80aae8a3SMartin Matuska #include <zfs_fletcher.h>
39*80aae8a3SMartin Matuska #include "zstream_util.h"
40*80aae8a3SMartin Matuska 
41*80aae8a3SMartin Matuska /*
42*80aae8a3SMartin Matuska  * From libzfs_sendrecv.c
43*80aae8a3SMartin Matuska  */
44*80aae8a3SMartin Matuska int
dump_record(dmu_replay_record_t * drr,void * payload,size_t payload_len,zio_cksum_t * zc,int outfd)45*80aae8a3SMartin Matuska dump_record(dmu_replay_record_t *drr, void *payload, size_t payload_len,
46*80aae8a3SMartin Matuska     zio_cksum_t *zc, int outfd)
47*80aae8a3SMartin Matuska {
48*80aae8a3SMartin Matuska 	ASSERT3U(offsetof(dmu_replay_record_t, drr_u.drr_checksum.drr_checksum),
49*80aae8a3SMartin Matuska 	    ==, sizeof (dmu_replay_record_t) - sizeof (zio_cksum_t));
50*80aae8a3SMartin Matuska 	fletcher_4_incremental_native(drr,
51*80aae8a3SMartin Matuska 	    offsetof(dmu_replay_record_t, drr_u.drr_checksum.drr_checksum), zc);
52*80aae8a3SMartin Matuska 	if (drr->drr_type != DRR_BEGIN) {
53*80aae8a3SMartin Matuska 		ASSERT(ZIO_CHECKSUM_IS_ZERO(&drr->drr_u.
54*80aae8a3SMartin Matuska 		    drr_checksum.drr_checksum));
55*80aae8a3SMartin Matuska 		drr->drr_u.drr_checksum.drr_checksum = *zc;
56*80aae8a3SMartin Matuska 	}
57*80aae8a3SMartin Matuska 	fletcher_4_incremental_native(&drr->drr_u.drr_checksum.drr_checksum,
58*80aae8a3SMartin Matuska 	    sizeof (zio_cksum_t), zc);
59*80aae8a3SMartin Matuska 	if (write(outfd, drr, sizeof (*drr)) == -1)
60*80aae8a3SMartin Matuska 		return (errno);
61*80aae8a3SMartin Matuska 	if (payload_len != 0) {
62*80aae8a3SMartin Matuska 		fletcher_4_incremental_native(payload, payload_len, zc);
63*80aae8a3SMartin Matuska 		if (write(outfd, payload, payload_len) == -1)
64*80aae8a3SMartin Matuska 			return (errno);
65*80aae8a3SMartin Matuska 	}
66*80aae8a3SMartin Matuska 	return (0);
67*80aae8a3SMartin Matuska }
68*80aae8a3SMartin Matuska 
69*80aae8a3SMartin Matuska void *
safe_malloc(size_t size)70*80aae8a3SMartin Matuska safe_malloc(size_t size)
71*80aae8a3SMartin Matuska {
72*80aae8a3SMartin Matuska 	void *rv = malloc(size);
73*80aae8a3SMartin Matuska 	if (rv == NULL) {
74*80aae8a3SMartin Matuska 		(void) fprintf(stderr, "Error: failed to allocate %zu bytes\n",
75*80aae8a3SMartin Matuska 		    size);
76*80aae8a3SMartin Matuska 		exit(1);
77*80aae8a3SMartin Matuska 	}
78*80aae8a3SMartin Matuska 	return (rv);
79*80aae8a3SMartin Matuska }
80*80aae8a3SMartin Matuska 
81*80aae8a3SMartin Matuska void *
safe_calloc(size_t size)82*80aae8a3SMartin Matuska safe_calloc(size_t size)
83*80aae8a3SMartin Matuska {
84*80aae8a3SMartin Matuska 	void *rv = calloc(1, size);
85*80aae8a3SMartin Matuska 	if (rv == NULL) {
86*80aae8a3SMartin Matuska 		(void) fprintf(stderr,
87*80aae8a3SMartin Matuska 		    "Error: failed to allocate %zu bytes\n", size);
88*80aae8a3SMartin Matuska 		exit(1);
89*80aae8a3SMartin Matuska 	}
90*80aae8a3SMartin Matuska 	return (rv);
91*80aae8a3SMartin Matuska }
92*80aae8a3SMartin Matuska 
93*80aae8a3SMartin Matuska /*
94*80aae8a3SMartin Matuska  * Safe version of fread(), exits on error.
95*80aae8a3SMartin Matuska  */
96*80aae8a3SMartin Matuska int
sfread(void * buf,size_t size,FILE * fp)97*80aae8a3SMartin Matuska sfread(void *buf, size_t size, FILE *fp)
98*80aae8a3SMartin Matuska {
99*80aae8a3SMartin Matuska 	int rv = fread(buf, size, 1, fp);
100*80aae8a3SMartin Matuska 	if (rv == 0 && ferror(fp)) {
101*80aae8a3SMartin Matuska 		(void) fprintf(stderr, "Error while reading file: %s\n",
102*80aae8a3SMartin Matuska 		    strerror(errno));
103*80aae8a3SMartin Matuska 		exit(1);
104*80aae8a3SMartin Matuska 	}
105*80aae8a3SMartin Matuska 	return (rv);
106*80aae8a3SMartin Matuska }
107