+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]
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,
* \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
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.
*
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,
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
{
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));
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));
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;
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));
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) {
}
/* 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));
* 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. */
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);
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);
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;
* 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;
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);
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,
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,
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,
* 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;
if (header == NULL)
continue;
- where = ftell(rbtfile);
+ CHECK(isc_stdio_tell(rbtfile, &where));
size = dns_rdataslab_size((unsigned char *) header,
sizeof(rdatasetheader_t));
#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);
}
/*
* 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;
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);
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;
* 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,
#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>
}
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
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);
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);
/*% 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
case ENFILE:
case EMFILE:
return (ISC_R_TOOMANYOPENFILES);
+#ifdef EOVERFLOW
+ case EOVERFLOW:
+ return (ISC_R_RANGE);
+#endif
case EPIPE:
#ifdef ECONNRESET
case ECONNRESET:
#include <isc/stdio.h>
#include <isc/stat.h>
+#include <isc/util.h>
#include "errno2result.h"
}
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;
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:
isc_stdio_read
isc_stdio_seek
isc_stdio_sync
+isc_stdio_tell
isc_stdio_write
isc_stdtime_get
isc_string_append
#include <errno.h>
#include <isc/stdio.h>
+#include <isc/util.h>
#include "errno2result.h"
}
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;