Commit 31707708 authored by Evan Hunt's avatar Evan Hunt
Browse files

[master] portability fixes for map files

3598.	[cleanup]	Improved portability of map file code. [RT #33820]
parent 945ce145
3598. [cleanup] Improved portability of map file code. [RT #33820]
3597. [bug] Ensure automatic-resigning heaps are reconstructed
when loading zones in map format. [RT #33381]
......
......@@ -153,7 +153,7 @@ typedef isc_result_t (*dns_rbtfindcallback_t)(dns_rbtnode_t *node,
typedef isc_result_t (*dns_rbtdatawriter_t)(FILE *file,
unsigned char *data,
isc_uint32_t version,
void *arg,
isc_uint64_t *crc);
typedef isc_result_t (*dns_rbtdatafixer_t)(dns_rbtnode_t *rbtnode,
......@@ -689,8 +689,8 @@ dns_rbt_destroy2(dns_rbt_t **rbtp, unsigned int quantum);
* \li ISC_R_QUOTA if 'quantum' nodes have been destroyed.
*/
long
dns_rbt_serialize_align(long target);
off_t
dns_rbt_serialize_align(off_t target);
/*%<
* Align the provided integer to a pointer-size boundary.
* This should be used if, during serialization of data to a will-be
......@@ -700,7 +700,7 @@ dns_rbt_serialize_align(long target);
isc_result_t
dns_rbt_serialize_tree(FILE *file, dns_rbt_t *rbt,
dns_rbtdatawriter_t datawriter,
isc_uint32_t serial, long *offset);
void *writer_arg, off_t *offset);
/*%<
* Write out the RBT structure and its data to a file.
*
......
......@@ -387,7 +387,8 @@ journal_header_encode(journal_header_t *cooked, journal_rawheader_t *raw) {
static isc_result_t
journal_seek(dns_journal_t *j, isc_uint32_t offset) {
isc_result_t result;
result = isc_stdio_seek(j->fp, (long)offset, SEEK_SET);
result = isc_stdio_seek(j->fp, (off_t)offset, SEEK_SET);
if (result != ISC_R_SUCCESS) {
isc_log_write(JOURNAL_COMMON_LOGARGS, ISC_LOG_ERROR,
"%s: seek: %s", j->filename,
......
......@@ -156,7 +156,7 @@ serialize_node(FILE *file, dns_rbtnode_t *node, uintptr_t left,
static isc_result_t
serialize_nodes(FILE *file, dns_rbtnode_t *node, uintptr_t parent,
dns_rbtdatawriter_t datawriter, isc_uint32_t serial,
dns_rbtdatawriter_t datawriter, void *writer_arg,
uintptr_t *where, isc_uint64_t *crc);
/*
* The following functions allow you to get the actual address of a pointer
......@@ -420,7 +420,7 @@ write_header(FILE *file, dns_rbt_t *rbt, isc_uint64_t first_node_offset,
{
file_header_t header;
isc_result_t result;
long location;
off_t location;
if (FILE_VERSION[0] == '\0') {
memset(FILE_VERSION, 0, sizeof(FILE_VERSION));
......@@ -445,9 +445,7 @@ write_header(FILE *file, dns_rbt_t *rbt, isc_uint64_t first_node_offset,
header.crc = crc;
location = ftell(file);
if (location < 0)
return (ISC_R_FAILURE);
CHECK(isc_stdio_tell(file, &location));
location = dns_rbt_serialize_align(location);
CHECK(isc_stdio_seek(file, location, SEEK_SET));
CHECK(isc_stdio_write(&header, 1, sizeof(file_header_t), file, NULL));
......@@ -466,7 +464,7 @@ serialize_node(FILE *file, dns_rbtnode_t *node, uintptr_t left,
uintptr_t data, isc_uint64_t *crc)
{
dns_rbtnode_t temp_node;
long file_position;
off_t file_position;
unsigned char *node_data;
size_t datasize;
isc_result_t result;
......@@ -476,10 +474,7 @@ serialize_node(FILE *file, dns_rbtnode_t *node, uintptr_t left,
INSIST(node != NULL);
file_position = ftell(file);
if (file_position < 0)
return (ISC_R_FAILURE);
CHECK(isc_stdio_tell(file, &file_position));
file_position = dns_rbt_serialize_align(file_position);
CHECK(isc_stdio_seek(file, file_position, SEEK_SET));
......@@ -546,12 +541,11 @@ serialize_node(FILE *file, dns_rbtnode_t *node, uintptr_t left,
static isc_result_t
serialize_nodes(FILE *file, dns_rbtnode_t *node, uintptr_t parent,
dns_rbtdatawriter_t datawriter, isc_uint32_t serial,
dns_rbtdatawriter_t datawriter, void *writer_arg,
uintptr_t *where, isc_uint64_t *crc)
{
uintptr_t left = 0, right = 0, down = 0, data = 0;
long location = 0;
long offset_adjust;
off_t location = 0, offset_adjust;
isc_result_t result;
if (node == NULL) {
......@@ -561,14 +555,9 @@ serialize_nodes(FILE *file, dns_rbtnode_t *node, uintptr_t parent,
}
/* Reserve space for current node. */
location = ftell(file);
if (location < 0)
return (ISC_R_FAILURE);
CHECK(isc_stdio_tell(file, &location));
location = dns_rbt_serialize_align(location);
CHECK(isc_stdio_seek(file, location, SEEK_SET));
location = ftell(file);
if (location < 0)
return (ISC_R_FAILURE);
offset_adjust = dns_rbt_serialize_align(location + NODE_SIZE(node));
CHECK(isc_stdio_seek(file, offset_adjust, SEEK_SET));
......@@ -580,28 +569,21 @@ serialize_nodes(FILE *file, dns_rbtnode_t *node, uintptr_t parent,
* will break the way the crc hash is computed.
*/
CHECK(serialize_nodes(file, getleft(node, NULL), location,
datawriter, serial, &left, crc));
datawriter, writer_arg, &left, crc));
CHECK(serialize_nodes(file, getright(node, NULL), location,
datawriter, serial, &right, crc));
datawriter, writer_arg, &right, crc));
CHECK(serialize_nodes(file, getdown(node, NULL), location,
datawriter, serial, &down, crc));
datawriter, writer_arg, &down, crc));
if (node->data != NULL) {
long ret;
off_t ret;
ret = ftell(file);
if (ret < 0)
return (ISC_R_FAILURE);
CHECK(isc_stdio_tell(file, &ret));
ret = dns_rbt_serialize_align(ret);
CHECK(isc_stdio_seek(file, ret, SEEK_SET));
ret = ftell(file);
if (ret < 0)
return (ISC_R_FAILURE);
data = ret;
datawriter(file, node->data, serial, crc);
datawriter(file, node->data, writer_arg, crc);
}
/* Seek back to reserved space. */
......@@ -614,15 +596,15 @@ serialize_nodes(FILE *file, dns_rbtnode_t *node, uintptr_t parent,
CHECK(isc_stdio_seek(file, 0, SEEK_END));
if (where != NULL)
*where = location;
*where = (uintptr_t) location;
cleanup:
return (result);
}
long
dns_rbt_serialize_align(long target) {
long offset = target % 8;
off_t
dns_rbt_serialize_align(off_t target) {
off_t offset = target % 8;
if (offset == 0)
return (target);
......@@ -633,10 +615,10 @@ dns_rbt_serialize_align(long target) {
isc_result_t
dns_rbt_serialize_tree(FILE *file, dns_rbt_t *rbt,
dns_rbtdatawriter_t datawriter,
isc_uint32_t serial, long *offset)
void *writer_arg, off_t *offset)
{
isc_result_t result;
long header_position, node_position, end_position;
off_t header_position, node_position, end_position;
isc_uint64_t crc;
REQUIRE(file != NULL);
......@@ -645,24 +627,17 @@ dns_rbt_serialize_tree(FILE *file, dns_rbt_t *rbt,
isc_crc64_init(&crc);
header_position = ftell(file);
if (header_position < 0)
return (ISC_R_FAILURE);
CHECK(isc_stdio_tell(file, &header_position));
/* Write dummy header */
CHECK(dns_rbt_zero_header(file));
/* Serialize nodes */
node_position = ftell(file);
if (node_position < 0)
return (ISC_R_FAILURE);
CHECK(isc_stdio_tell(file, &node_position));
CHECK(serialize_nodes(file, rbt->root, 0, datawriter,
serial, NULL, &crc));
end_position = ftell(file);
if (end_position < 0)
return (ISC_R_FAILURE);
writer_arg, NULL, &crc));
CHECK(isc_stdio_tell(file, &end_position));
if (node_position == end_position) {
CHECK(isc_stdio_seek(file, header_position, SEEK_SET));
*offset = 0;
......
......@@ -511,7 +511,7 @@ struct dns_rbtdb {
* Base values for the mmap() code.
*/
void * mmap_location;
isc_uint64_t mmap_size;
size_t mmap_size;
/* Locked by tree_lock. */
dns_rbt_t * tree;
......@@ -1107,7 +1107,8 @@ free_rbtdb(dns_rbtdb_t *rbtdb, isc_boolean_t log, isc_event_t *event) {
isc_mem_detach(&rbtdb->hmctx);
if (rbtdb->mmap_location != NULL)
isc_file_munmap(rbtdb->mmap_location, (size_t) rbtdb->mmap_size);
isc_file_munmap(rbtdb->mmap_location,
(size_t) rbtdb->mmap_size);
isc_mem_putanddetach(&rbtdb->common.mctx, rbtdb, sizeof(*rbtdb));
isc_ondestroy_notify(&ondest, rbtdb);
......@@ -7093,12 +7094,12 @@ deserialize(void *arg, FILE *f, off_t offset) {
header = (rbtdb_file_header_t *)(base + offset);
rbtdb->mmap_location = base;
rbtdb->mmap_size = filesize;
rbtdb->mmap_size = (size_t) filesize;
rbtdb->origin_node = NULL;
if (header->tree != 0) {
result = dns_rbt_deserialize_tree(base, filesize,
(size_t) header->tree,
(off_t) header->tree,
rbtdb->common.mctx,
delete_callback, rbtdb,
rbt_datafixer, rbtdb,
......@@ -7118,7 +7119,7 @@ deserialize(void *arg, FILE *f, off_t offset) {
if (header->nsec != 0) {
result = dns_rbt_deserialize_tree(base, filesize,
(size_t) header->nsec,
(off_t) header->nsec,
rbtdb->common.mctx,
delete_callback, rbtdb,
rbt_datafixer, rbtdb,
......@@ -7134,7 +7135,7 @@ deserialize(void *arg, FILE *f, off_t offset) {
if (header->nsec3 != 0) {
result = dns_rbt_deserialize_tree(base, filesize,
(size_t) header->nsec3,
(off_t) header->nsec3,
rbtdb->common.mctx,
delete_callback, rbtdb,
rbt_datafixer, rbtdb,
......@@ -7241,18 +7242,24 @@ endload(dns_db_t *db, dns_rdatacallbacks_t *callbacks) {
* by the void *data pointer in the dns_rbtnode
*/
static isc_result_t
rbt_datawriter(FILE *rbtfile, unsigned char *data, isc_uint32_t serial,
rbt_datawriter(FILE *rbtfile, unsigned char *data, void *arg,
isc_uint64_t *crc)
{
rbtdb_version_t *version = (rbtdb_version_t *) arg;
rbtdb_serial_t serial;
rdatasetheader_t newheader;
rdatasetheader_t *header = (rdatasetheader_t *) data, *next;
size_t where, size, cooked;
off_t where, cooked;
size_t size;
unsigned char *p;
isc_result_t result;
static const char pad[sizeof(char *)];
isc_result_t result = ISC_R_SUCCESS;
char pad[sizeof(char *)];
REQUIRE(rbtfile != NULL);
REQUIRE(data != NULL);
REQUIRE(version != NULL);
serial = version->serial;
for (; header != NULL; header = next) {
next = header->next;
......@@ -7268,7 +7275,7 @@ rbt_datawriter(FILE *rbtfile, unsigned char *data, isc_uint32_t serial,
if (header == NULL)
continue;
where = ftell(rbtfile);
CHECK(isc_stdio_tell(rbtfile, &where));
size = dns_rdataslab_size((unsigned char *) header,
sizeof(rdatasetheader_t));
......@@ -7298,30 +7305,26 @@ rbt_datawriter(FILE *rbtfile, unsigned char *data, isc_uint32_t serial,
#endif
isc_crc64_update(crc, (unsigned char *) &newheader,
sizeof(rdatasetheader_t));
result = isc_stdio_write(&newheader,
sizeof(rdatasetheader_t), 1,
rbtfile, NULL);
if (result != ISC_R_SUCCESS)
return (result);
CHECK(isc_stdio_write(&newheader, sizeof(rdatasetheader_t), 1,
rbtfile, NULL));
isc_crc64_update(crc, p + sizeof(rdatasetheader_t),
size - sizeof(rdatasetheader_t));
result = isc_stdio_write(p + sizeof(rdatasetheader_t),
size - sizeof(rdatasetheader_t), 1, rbtfile, NULL);
if (result != ISC_R_SUCCESS)
return (result);
CHECK(isc_stdio_write(p + sizeof(rdatasetheader_t),
size - sizeof(rdatasetheader_t), 1,
rbtfile, NULL));
/*
* Pad to force alignment.
*/
if (cooked != size) {
result = isc_stdio_write(pad, cooked - size, 1,
rbtfile, NULL);
if (result != ISC_R_SUCCESS)
return (result);
if (size != (size_t) cooked) {
memset(pad, 0, sizeof(pad));
CHECK(isc_stdio_write(pad, cooked - size, 1,
rbtfile, NULL));
}
}
return (ISC_R_SUCCESS);
failure:
return (result);
}
/*
......@@ -7348,8 +7351,8 @@ rbtdb_zero_header(FILE *rbtfile) {
* itself that should be stored here.
*/
static isc_result_t
rbtdb_write_header(FILE *rbtfile, long tree_location, long nsec_location,
long nsec3_location)
rbtdb_write_header(FILE *rbtfile, off_t tree_location, off_t nsec_location,
off_t nsec3_location)
{
rbtdb_file_header_t header;
isc_result_t result;
......@@ -7365,9 +7368,9 @@ rbtdb_write_header(FILE *rbtfile, long tree_location, long nsec_location,
memcpy(header.version2, FILE_VERSION, sizeof(header.version2));
header.ptrsize = (isc_uint32_t) sizeof(void *);
header.bigendian = (1 == htonl(1)) ? 1 : 0;
header.tree = tree_location;
header.nsec = nsec_location;
header.nsec3 = nsec3_location;
header.tree = (isc_uint64_t) tree_location;
header.nsec = (isc_uint64_t) nsec_location;
header.nsec3 = (isc_uint64_t) nsec3_location;
result = isc_stdio_write(&header, 1, sizeof(rbtdb_file_header_t),
rbtfile, NULL);
fflush(rbtfile);
......@@ -7380,10 +7383,7 @@ serialize(dns_db_t *db, dns_dbversion_t *ver, FILE *rbtfile) {
rbtdb_version_t *version = (rbtdb_version_t *) ver;
dns_rbtdb_t *rbtdb;
isc_result_t result;
long tree_location;
long nsec_location;
long nsec3_location;
long header_location;
off_t tree_location, nsec_location, nsec3_location, header_location;
rbtdb = (dns_rbtdb_t *)db;
......@@ -7405,20 +7405,14 @@ serialize(dns_db_t *db, dns_dbversion_t *ver, FILE *rbtfile) {
* NOTE: need to do something better with the return codes, &= will
* not work.
*/
header_location = ftell(rbtfile);
if (header_location < 0)
return (ISC_R_FAILURE);
CHECK(isc_stdio_tell(rbtfile, &header_location));
CHECK(rbtdb_zero_header(rbtfile));
CHECK(dns_rbt_serialize_tree(rbtfile, rbtdb->tree, rbt_datawriter,
(isc_uint32_t) version->serial,
&tree_location));
version, &tree_location));
CHECK(dns_rbt_serialize_tree(rbtfile, rbtdb->nsec, rbt_datawriter,
(isc_uint32_t) version->serial,
&nsec_location));
version, &nsec_location));
CHECK(dns_rbt_serialize_tree(rbtfile, rbtdb->nsec3, rbt_datawriter,
(isc_uint32_t) version->serial,
&nsec3_location));
version, &nsec3_location));
CHECK(isc_stdio_seek(rbtfile, header_location, SEEK_SET));
CHECK(rbtdb_write_header(rbtfile, tree_location, nsec_location,
......
......@@ -46,6 +46,7 @@
#include <isc/os.h>
#include <isc/string.h>
#include <isc/socket.h>
#include <isc/stdio.h>
#include <isc/task.h>
#include <isc/timer.h>
#include <isc/util.h>
......@@ -106,20 +107,25 @@ delete_data(void *data, void *arg) {
}
static isc_result_t
write_data(FILE *file, unsigned char *datap, isc_uint32_t serial,
isc_uint64_t *crc) {
write_data(FILE *file, unsigned char *datap, void *arg, isc_uint64_t *crc) {
isc_result_t result;
size_t ret = 0;
data_holder_t *data = (data_holder_t *)datap;
data_holder_t temp;
uintptr_t where = ftell(file);
off_t where;
UNUSED(serial);
UNUSED(arg);
REQUIRE(file != NULL);
REQUIRE(crc != NULL);
REQUIRE(data != NULL);
REQUIRE((data->len == 0 && data->data == NULL) ||
(data->len != 0 && data->data != NULL));
result = isc_stdio_tell(file, &where);
if (result != ISC_R_SUCCESS)
return (result);
temp = *data;
temp.data = (data->len == 0
? NULL
......@@ -332,7 +338,8 @@ ATF_TC_BODY(serialize, tc) {
printf("serialization begins.\n");
rbtfile = fopen("./zone.bin", "w+b");
ATF_REQUIRE(rbtfile != NULL);
result = dns_rbt_serialize_tree(rbtfile, rbt, write_data, 0, &offset);
result = dns_rbt_serialize_tree(rbtfile, rbt, write_data, NULL,
&offset);
ATF_REQUIRE(result == ISC_R_SUCCESS);
dns_rbt_destroy(&rbt);
......@@ -400,7 +407,8 @@ ATF_TC_BODY(deserialize_corrupt, tc) {
add_test_data(mctx, rbt);
rbtfile = fopen("./zone.bin", "w+b");
ATF_REQUIRE(rbtfile != NULL);
result = dns_rbt_serialize_tree(rbtfile, rbt, write_data, 0, &offset);
result = dns_rbt_serialize_tree(rbtfile, rbt, write_data, NULL,
&offset);
ATF_REQUIRE(result == ISC_R_SUCCESS);
dns_rbt_destroy(&rbt);
......
......@@ -48,7 +48,11 @@ isc_stdio_close(FILE *f);
/*% Seek */
isc_result_t
isc_stdio_seek(FILE *f, long offset, int whence);
isc_stdio_seek(FILE *f, off_t offset, int whence);
/*% Tell */
isc_result_t
isc_stdio_tell(FILE *f, off_t *offsetp);
/*% Read */
isc_result_t
......
......@@ -58,6 +58,10 @@ isc___errno2result(int posixerrno, const char *file, unsigned int line) {
case ENFILE:
case EMFILE:
return (ISC_R_TOOMANYOPENFILES);
#ifdef EOVERFLOW
case EOVERFLOW:
return (ISC_R_RANGE);
#endif
case EPIPE:
#ifdef ECONNRESET
case ECONNRESET:
......
......@@ -24,6 +24,7 @@
#include <isc/stdio.h>
#include <isc/stat.h>
#include <isc/util.h>
#include "errno2result.h"
......@@ -50,16 +51,30 @@ isc_stdio_close(FILE *f) {
}
isc_result_t
isc_stdio_seek(FILE *f, long offset, int whence) {
isc_stdio_seek(FILE *f, off_t offset, int whence) {
int r;
r = fseek(f, offset, whence);
r = fseeko(f, offset, whence);
if (r == 0)
return (ISC_R_SUCCESS);
else
return (isc__errno2result(errno));
}
isc_result_t
isc_stdio_tell(FILE *f, off_t *offsetp) {
off_t r;
REQUIRE(offsetp != NULL);
r = ftello(f);
if (r >= 0) {
*offsetp = r;
return (ISC_R_SUCCESS);
} else
return (isc__errno2result(errno));
}
isc_result_t
isc_stdio_read(void *ptr, size_t size, size_t nmemb, FILE *f, size_t *nret) {
isc_result_t result = ISC_R_SUCCESS;
......
......@@ -57,6 +57,10 @@ isc__errno2resultx(int posixerrno, const char *file, int line) {
return (ISC_R_IOERROR);
case ENOMEM:
return (ISC_R_NOMEMORY);
#ifdef EOVERFLOW
case EOVERFLOW:
return (ISC_R_RANGE);
#endif
case ENFILE:
case EMFILE:
case WSAEMFILE:
......
......@@ -512,6 +512,7 @@ isc_stdio_open
isc_stdio_read
isc_stdio_seek
isc_stdio_sync
isc_stdio_tell
isc_stdio_write
isc_stdtime_get
isc_string_append
......
......@@ -23,6 +23,7 @@
#include <errno.h>
#include <isc/stdio.h>
#include <isc/util.h>
#include "errno2result.h"
......@@ -49,16 +50,30 @@ isc_stdio_close(FILE *f) {
}
isc_result_t
isc_stdio_seek(FILE *f, long offset, int whence) {
isc_stdio_seek(FILE *f, off_t offset, int whence) {
int r;
r = fseek(f, offset, whence);
r = fseeko(f, offset, whence);
if (r == 0)
return (ISC_R_SUCCESS);
else
return (isc__errno2result(errno));
}
isc_result_t
isc_stdio_tell(FILE *f, off_t *offsetp) {
off_t r;
REQUIRE(offsetp != NULL);
r = ftello(f);
if (r >= 0) {
*offsetp = r;
return (ISC_R_SUCCESS);
} else
return (isc__errno2result(errno));
}
isc_result_t
isc_stdio_read(void *ptr, size_t size, size_t nmemb, FILE *f, size_t *nret) {
isc_result_t result = ISC_R_SUCCESS;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment