Factor out duplicated kernel dump code into dump_{start,finish}().

dump_start() and dump_finish() are responsible for writing kernel dump
headers, optionally writing the key when encryption is enabled, and
initializing the initial offset into the dump device.

Also remove the unused dump_pad(), and make some functions static now that
they're only called from kern_shutdown.c.

No functional change intended.

Reviewed by:	cem, def
Sponsored by:	Dell EMC Isilon
Differential Revision:	https://reviews.freebsd.org/D11584
This commit is contained in:
Mark Johnston 2017-08-18 03:52:35 +00:00
parent 9a61faf67d
commit 50ef60dabe
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=322644
10 changed files with 100 additions and 289 deletions

View File

@ -52,12 +52,6 @@ __FBSDID("$FreeBSD$");
CTASSERT(sizeof(struct kerneldumpheader) == 512);
/*
* Don't touch the first SIZEOF_METADATA bytes on the dump device. This
* is to protect us from metadata and to protect metadata from us.
*/
#define SIZEOF_METADATA (64*1024)
uint64_t *vm_page_dump;
int vm_page_dump_size;
@ -320,22 +314,8 @@ minidumpsys(struct dumperinfo *di)
}
dumpsize += PAGE_SIZE;
/* Determine dump offset on device. */
if (di->mediasize < SIZEOF_METADATA + dumpsize + di->blocksize * 2 +
kerneldumpcrypto_dumpkeysize(di->kdc)) {
error = E2BIG;
goto fail;
}
dumplo = di->mediaoffset + di->mediasize - dumpsize;
dumplo -= di->blocksize * 2;
dumplo -= kerneldumpcrypto_dumpkeysize(di->kdc);
progress = dumpsize;
/* Initialize kernel dump crypto. */
error = kerneldumpcrypto_init(di->kdc);
if (error)
goto fail;
/* Initialize mdhdr */
bzero(&mdhdr, sizeof(mdhdr));
strcpy(mdhdr.magic, MINIDUMP_MAGIC);
@ -353,17 +333,9 @@ minidumpsys(struct dumperinfo *di)
printf("Dumping %llu out of %ju MB:", (long long)dumpsize >> 20,
ptoa((uintmax_t)physmem) / 1048576);
/* Dump leader */
error = dump_write_header(di, &kdh, 0, dumplo);
if (error)
error = dump_start(di, &kdh, &dumplo);
if (error != 0)
goto fail;
dumplo += di->blocksize;
/* Dump key */
error = dump_write_key(di, 0, dumplo);
if (error)
goto fail;
dumplo += kerneldumpcrypto_dumpkeysize(di->kdc);
/* Dump my header */
bzero(&fakepd, sizeof(fakepd));
@ -447,14 +419,10 @@ minidumpsys(struct dumperinfo *di)
if (error)
goto fail;
/* Dump trailer */
error = dump_write_header(di, &kdh, 0, dumplo);
if (error)
error = dump_finish(di, &kdh, dumplo);
if (error != 0)
goto fail;
dumplo += di->blocksize;
/* Signal completion, signoff and exit stage left. */
dump_write(di, NULL, 0, 0, 0);
printf("\nDump complete\n");
return (0);

View File

@ -53,12 +53,6 @@ __FBSDID("$FreeBSD$");
CTASSERT(sizeof(struct kerneldumpheader) == 512);
/*
* Don't touch the first SIZEOF_METADATA bytes on the dump device. This
* is to protect us from metadata and to protect metadata from us.
*/
#define SIZEOF_METADATA (64*1024)
uint32_t *vm_page_dump;
int vm_page_dump_size;
@ -219,7 +213,6 @@ minidumpsys(struct dumperinfo *di)
dumpsize = ptesize;
dumpsize += round_page(msgbufp->msg_size);
dumpsize += round_page(vm_page_dump_size);
for (i = 0; i < vm_page_dump_size / sizeof(*vm_page_dump); i++) {
bits = vm_page_dump[i];
while (bits) {
@ -234,26 +227,10 @@ minidumpsys(struct dumperinfo *di)
bits &= ~(1ul << bit);
}
}
dumpsize += PAGE_SIZE;
/* Determine dump offset on device. */
if (di->mediasize < SIZEOF_METADATA + dumpsize + di->blocksize * 2 +
kerneldumpcrypto_dumpkeysize(di->kdc)) {
error = ENOSPC;
goto fail;
}
dumplo = di->mediaoffset + di->mediasize - dumpsize;
dumplo -= di->blocksize * 2;
dumplo -= kerneldumpcrypto_dumpkeysize(di->kdc);
progress = dumpsize;
/* Initialize kernel dump crypto. */
error = kerneldumpcrypto_init(di->kdc);
if (error)
goto fail;
/* Initialize mdhdr */
bzero(&mdhdr, sizeof(mdhdr));
strcpy(mdhdr.magic, MINIDUMP_MAGIC);
@ -274,17 +251,9 @@ minidumpsys(struct dumperinfo *di)
printf("Physical memory: %u MB\n", ptoa((uintmax_t)physmem) / 1048576);
printf("Dumping %llu MB:", (long long)dumpsize >> 20);
/* Dump leader */
error = dump_write_header(di, &kdh, 0, dumplo);
if (error)
error = dump_start(di, &kdh, &dumplo);
if (error != 0)
goto fail;
dumplo += di->blocksize;
/* Dump key */
error = dump_write_key(di, 0, dumplo);
if (error)
goto fail;
dumplo += kerneldumpcrypto_dumpkeysize(di->kdc);
/* Dump my header */
bzero(dumpbuf, sizeof(dumpbuf));
@ -360,14 +329,10 @@ minidumpsys(struct dumperinfo *di)
if (error)
goto fail;
/* Dump trailer */
error = dump_write_header(di, &kdh, 0, dumplo);
if (error)
error = dump_finish(di, &kdh, dumplo);
if (error != 0)
goto fail;
dumplo += di->blocksize;
/* Signal completion, signoff and exit stage left. */
dump_write(di, NULL, 0, 0, 0);
printf("\nDump complete\n");
return (0);
@ -377,7 +342,7 @@ minidumpsys(struct dumperinfo *di)
if (error == ECANCELED)
printf("\nDump aborted\n");
else if (error == ENOSPC)
else if (error == E2BIG || error == ENOSPC)
printf("\nDump failed. Partition too small.\n");
else
printf("\n** DUMP FAILED (ERROR %d) **\n", error);

View File

@ -58,12 +58,6 @@ __FBSDID("$FreeBSD$");
CTASSERT(sizeof(struct kerneldumpheader) == 512);
/*
* Don't touch the first SIZEOF_METADATA bytes on the dump device. This
* is to protect us from metadata and to protect metadata from us.
*/
#define SIZEOF_METADATA (64*1024)
uint64_t *vm_page_dump;
int vm_page_dump_size;
@ -281,22 +275,8 @@ minidumpsys(struct dumperinfo *di)
}
dumpsize += PAGE_SIZE;
/* Determine dump offset on device. */
if (di->mediasize < SIZEOF_METADATA + dumpsize + di->blocksize * 2 +
kerneldumpcrypto_dumpkeysize(di->kdc)) {
error = E2BIG;
goto fail;
}
dumplo = di->mediaoffset + di->mediasize - dumpsize;
dumplo -= di->blocksize * 2;
dumplo -= kerneldumpcrypto_dumpkeysize(di->kdc);
progress = dumpsize;
/* Initialize kernel dump crypto. */
error = kerneldumpcrypto_init(di->kdc);
if (error)
goto fail;
/* Initialize mdhdr */
bzero(&mdhdr, sizeof(mdhdr));
strcpy(mdhdr.magic, MINIDUMP_MAGIC);
@ -315,17 +295,9 @@ minidumpsys(struct dumperinfo *di)
printf("Dumping %llu out of %ju MB:", (long long)dumpsize >> 20,
ptoa((uintmax_t)physmem) / 1048576);
/* Dump leader */
error = dump_write_header(di, &kdh, 0, dumplo);
if (error)
error = dump_start(di, &kdh, &dumplo);
if (error != 0)
goto fail;
dumplo += di->blocksize;
/* Dump key */
error = dump_write_key(di, 0, dumplo);
if (error)
goto fail;
dumplo += kerneldumpcrypto_dumpkeysize(di->kdc);
/* Dump my header */
bzero(&tmpbuffer, sizeof(tmpbuffer));
@ -423,18 +395,14 @@ minidumpsys(struct dumperinfo *di)
if (error)
goto fail;
/* Dump trailer */
error = dump_write_header(di, &kdh, 0, dumplo);
if (error)
error = dump_finish(di, &kdh, dumplo);
if (error != 0)
goto fail;
dumplo += di->blocksize;
/* Signal completion, signoff and exit stage left. */
dump_write(di, NULL, 0, 0, 0);
printf("\nDump complete\n");
return (0);
fail:
fail:
if (error < 0)
error = -error;

View File

@ -47,12 +47,6 @@ __FBSDID("$FreeBSD$");
CTASSERT(sizeof(struct kerneldumpheader) == 512);
/*
* Don't touch the first SIZEOF_METADATA bytes on the dump device. This
* is to protect us from metadata and to protect metadata from us.
*/
#define SIZEOF_METADATA (64*1024)
#define MD_ALIGN(x) (((off_t)(x) + PAGE_MASK) & ~PAGE_MASK)
#define DEV_ALIGN(x) roundup2((off_t)(x), DEV_BSIZE)
@ -244,22 +238,8 @@ minidumpsys(struct dumperinfo *di)
}
dumpsize += PAGE_SIZE;
/* Determine dump offset on device. */
if (di->mediasize < SIZEOF_METADATA + dumpsize + di->blocksize * 2 +
kerneldumpcrypto_dumpkeysize(di->kdc)) {
error = ENOSPC;
goto fail;
}
dumplo = di->mediaoffset + di->mediasize - dumpsize;
dumplo -= di->blocksize * 2;
dumplo -= kerneldumpcrypto_dumpkeysize(di->kdc);
progress = dumpsize;
/* Initialize kernel dump crypto. */
error = kerneldumpcrypto_init(di->kdc);
if (error)
goto fail;
/* Initialize mdhdr */
bzero(&mdhdr, sizeof(mdhdr));
strcpy(mdhdr.magic, MINIDUMP_MAGIC);
@ -278,17 +258,9 @@ minidumpsys(struct dumperinfo *di)
printf("Physical memory: %ju MB\n", ptoa((uintmax_t)physmem) / 1048576);
printf("Dumping %llu MB:", (long long)dumpsize >> 20);
/* Dump leader */
error = dump_write_header(di, &kdh, 0, dumplo);
if (error)
error = dump_start(di, &kdh, &dumplo);
if (error != 0)
goto fail;
dumplo += di->blocksize;
/* Dump key */
error = dump_write_key(di, 0, dumplo);
if (error)
goto fail;
dumplo += kerneldumpcrypto_dumpkeysize(di->kdc);
/* Dump my header */
bzero(&fakept, sizeof(fakept));
@ -362,14 +334,10 @@ minidumpsys(struct dumperinfo *di)
if (error)
goto fail;
/* Dump trailer */
error = dump_write_header(di, &kdh, 0, dumplo);
if (error)
error = dump_finish(di, &kdh, dumplo);
if (error != 0)
goto fail;
dumplo += di->blocksize;
/* Signal completion, signoff and exit stage left. */
dump_write(di, NULL, 0, 0, 0);
printf("\nDump complete\n");
return (0);
@ -379,7 +347,7 @@ minidumpsys(struct dumperinfo *di)
if (error == ECANCELED)
printf("\nDump aborted\n");
else if (error == ENOSPC)
else if (error == E2BIG || error == ENOSPC)
printf("\nDump failed. Partition too small.\n");
else
printf("\n** DUMP FAILED (ERROR %d) **\n", error);

View File

@ -49,12 +49,6 @@ __FBSDID("$FreeBSD$");
CTASSERT(sizeof(struct kerneldumpheader) == 512);
/*
* Don't touch the first SIZEOF_METADATA bytes on the dump device. This
* is to protect us from metadata and to protect metadata from us.
*/
#define SIZEOF_METADATA (64*1024)
#define MD_ALIGN(x) roundup2((off_t)(x), PAGE_SIZE)
off_t dumplo;
@ -347,38 +341,15 @@ dumpsys_generic(struct dumperinfo *di)
dumpsize += fileofs;
hdrgap = fileofs - roundup2((off_t)hdrsz, di->blocksize);
/* Determine dump offset on device. */
if (di->mediasize < SIZEOF_METADATA + dumpsize + di->blocksize * 2 +
kerneldumpcrypto_dumpkeysize(di->kdc)) {
error = ENOSPC;
goto fail;
}
dumplo = di->mediaoffset + di->mediasize - dumpsize;
dumplo -= di->blocksize * 2;
dumplo -= kerneldumpcrypto_dumpkeysize(di->kdc);
/* Initialize kernel dump crypto. */
error = kerneldumpcrypto_init(di->kdc);
if (error)
goto fail;
mkdumpheader(&kdh, KERNELDUMPMAGIC, KERNELDUMP_ARCH_VERSION, dumpsize,
kerneldumpcrypto_dumpkeysize(di->kdc), di->blocksize);
printf("Dumping %ju MB (%d chunks)\n", (uintmax_t)dumpsize >> 20,
ehdr.e_phnum - DUMPSYS_NUM_AUX_HDRS);
/* Dump leader */
error = dump_write_header(di, &kdh, 0, dumplo);
if (error)
error = dump_start(di, &kdh, &dumplo);
if (error != 0)
goto fail;
dumplo += di->blocksize;
/* Dump key */
error = dump_write_key(di, 0, dumplo);
if (error)
goto fail;
dumplo += kerneldumpcrypto_dumpkeysize(di->kdc);
/* Dump ELF header */
error = dumpsys_buf_write(di, (char*)&ehdr, sizeof(ehdr));
@ -410,14 +381,10 @@ dumpsys_generic(struct dumperinfo *di)
if (error < 0)
goto fail;
/* Dump trailer */
error = dump_write_header(di, &kdh, 0, dumplo);
if (error)
error = dump_finish(di, &kdh, dumplo);
if (error != 0)
goto fail;
dumplo += di->blocksize;
/* Signal completion, signoff and exit stage left. */
dump_write(di, NULL, 0, 0, 0);
printf("\nDump complete\n");
return (0);
@ -427,7 +394,7 @@ dumpsys_generic(struct dumperinfo *di)
if (error == ECANCELED)
printf("\nDump aborted\n");
else if (error == ENOSPC)
else if (error == E2BIG || error == ENOSPC)
printf("\nDump failed. Partition too small.\n");
else
printf("\n** DUMP FAILED (ERROR %d) **\n", error);

View File

@ -897,7 +897,7 @@ kerneldumpcrypto_create(size_t blocksize, uint8_t encryption,
}
#endif /* EKCD */
int
static int
kerneldumpcrypto_init(struct kerneldumpcrypto *kdc)
{
#ifndef EKCD
@ -1180,21 +1180,7 @@ dump_raw_write_pad(struct dumperinfo *di, void *virtual, vm_offset_t physical,
return (dump_raw_write(di, buf, physical, offset, *size));
}
int
dump_write_pad(struct dumperinfo *di, void *virtual, vm_offset_t physical,
off_t offset, size_t length, size_t *size)
{
void *buf;
int error;
error = dump_pad(di, virtual, length, &buf, size);
if (error != 0)
return (error);
return (dump_write(di, buf, physical, offset, *size));
}
int
static int
dump_write_header(struct dumperinfo *di, struct kerneldumpheader *kdh,
vm_offset_t physical, off_t offset)
{
@ -1208,7 +1194,7 @@ dump_write_header(struct dumperinfo *di, struct kerneldumpheader *kdh,
return (ret);
}
int
static int
dump_write_key(struct dumperinfo *di, vm_offset_t physical, off_t offset)
{
#ifndef EKCD
@ -1225,6 +1211,64 @@ dump_write_key(struct dumperinfo *di, vm_offset_t physical, off_t offset)
#endif /* !EKCD */
}
/*
* Don't touch the first SIZEOF_METADATA bytes on the dump device. This is to
* protect us from metadata and metadata from us.
*/
#define SIZEOF_METADATA (64 * 1024)
/*
* Do some preliminary setup for a kernel dump: verify that we have enough space
* on the dump device, write the leading header, and optionally write the crypto
* key.
*/
int
dump_start(struct dumperinfo *di, struct kerneldumpheader *kdh, off_t *dumplop)
{
uint64_t dumpsize;
int error;
error = kerneldumpcrypto_init(di->kdc);
if (error != 0)
return (error);
dumpsize = dtoh64(kdh->dumplength) + 2 * di->blocksize +
kerneldumpcrypto_dumpkeysize(di->kdc);
if (di->mediasize < SIZEOF_METADATA + dumpsize)
return (E2BIG);
*dumplop = di->mediaoffset + di->mediasize - dumpsize;
error = dump_write_header(di, kdh, 0, *dumplop);
if (error != 0)
return (error);
*dumplop += di->blocksize;
error = dump_write_key(di, 0, *dumplop);
if (error != 0)
return (error);
*dumplop += kerneldumpcrypto_dumpkeysize(di->kdc);
return (0);
}
/*
* Write the trailing kernel dump header and signal to the lower layers that the
* dump has completed.
*/
int
dump_finish(struct dumperinfo *di, struct kerneldumpheader *kdh, off_t dumplo)
{
int error;
error = dump_write_header(di, kdh, 0, dumplo);
if (error != 0)
return (error);
(void)dump_write(di, NULL, 0, 0, 0);
return (0);
}
void
mkdumpheader(struct kerneldumpheader *kdh, char *magic, uint32_t archver,
uint64_t dumplen, uint32_t dumpkeysize, uint32_t blksz)

View File

@ -52,18 +52,11 @@ __FBSDID("$FreeBSD$");
CTASSERT(sizeof(struct kerneldumpheader) == 512);
/*
* Don't touch the first SIZEOF_METADATA bytes on the dump device. This
* is to protect us from metadata and to protect metadata from us.
*/
#define SIZEOF_METADATA (64*1024)
uint32_t *vm_page_dump;
int vm_page_dump_size;
static struct kerneldumpheader kdh;
static off_t dumplo;
static off_t origdumplo;
/* Handle chunked writes. */
static uint64_t counter, progress, dumpsize;
@ -241,7 +234,6 @@ minidumpsys(struct dumperinfo *di)
dumpsize = ptesize;
dumpsize += round_page(msgbufp->msg_size);
dumpsize += round_page(vm_page_dump_size);
for (i = 0; i < vm_page_dump_size / sizeof(*vm_page_dump); i++) {
bits = vm_page_dump[i];
while (bits) {
@ -256,26 +248,10 @@ minidumpsys(struct dumperinfo *di)
bits &= ~(1ul << bit);
}
}
dumpsize += PAGE_SIZE;
/* Determine dump offset on device. */
if (di->mediasize < SIZEOF_METADATA + dumpsize + di->blocksize * 2 +
kerneldumpcrypto_dumpkeysize(di->kdc)) {
error = ENOSPC;
goto fail;
}
origdumplo = dumplo = di->mediaoffset + di->mediasize - dumpsize;
dumplo -= di->blocksize * 2;
dumplo -= kerneldumpcrypto_dumpkeysize(di->kdc);
progress = dumpsize;
/* Initialize kernel dump crypto. */
error = kerneldumpcrypto_init(di->kdc);
if (error)
goto fail;
/* Initialize mdhdr */
bzero(&mdhdr, sizeof(mdhdr));
strcpy(mdhdr.magic, MINIDUMP_MAGIC);
@ -291,17 +267,9 @@ minidumpsys(struct dumperinfo *di)
printf("Dumping %llu out of %ju MB:", (long long)dumpsize >> 20,
ptoa((uintmax_t)physmem) / 1048576);
/* Dump leader */
error = dump_write_header(di, &kdh, 0, dumplo);
if (error)
error = dump_start(di, &kdh, &dumplo);
if (error != 0)
goto fail;
dumplo += di->blocksize;
/* Dump key */
error = dump_write_key(di, 0, dumplo);
if (error)
goto fail;
dumplo += kerneldumpcrypto_dumpkeysize(di->kdc);
/* Dump my header */
bzero(tmpbuffer, sizeof(tmpbuffer));
@ -329,8 +297,7 @@ minidumpsys(struct dumperinfo *di)
if (!count) {
prev_pte = (vm_offset_t)pte;
count++;
}
else {
} else {
if ((vm_offset_t)pte == (prev_pte + count * PAGE_SIZE))
count++;
else {
@ -368,14 +335,10 @@ minidumpsys(struct dumperinfo *di)
}
}
/* Dump trailer */
error = dump_write_header(di, &kdh, 0, dumplo);
if (error)
error = dump_finish(di, &kdh, dumplo);
if (error != 0)
goto fail;
dumplo += di->blocksize;
/* Signal completion, signoff and exit stage left. */
dump_write(di, NULL, 0, 0, 0);
printf("\nDump complete\n");
return (0);
@ -385,7 +348,7 @@ minidumpsys(struct dumperinfo *di)
if (error == ECANCELED)
printf("\nDump aborted\n");
else if (error == ENOSPC)
else if (error == E2BIG || error == ENOSPC)
printf("\nDump failed. Partition too small.\n");
else
printf("\n** DUMP FAILED (ERROR %d) **\n", error);

View File

@ -78,7 +78,7 @@ dumpsys(struct dumperinfo *di)
{
static struct kerneldumpheader kdh;
struct sparc64_dump_hdr hdr;
vm_size_t size, totsize, hdrsize;
vm_size_t size, hdrsize;
int error, i, nreg;
/* Set up dump_map and calculate dump size. */
@ -94,40 +94,14 @@ dumpsys(struct dumperinfo *di)
DEV_BSIZE);
size += hdrsize;
totsize = size + 2 * di->blocksize +
kerneldumpcrypto_dumpkeysize(di->kdc);
if (totsize > di->mediasize) {
printf("Insufficient space on device (need %ld, have %ld), "
"refusing to dump.\n", (long)totsize,
(long)di->mediasize);
error = ENOSPC;
goto fail;
}
/* Determine dump offset on device. */
dumplo = di->mediaoffset + di->mediasize - totsize;
/* Initialize kernel dump crypto. */
error = kerneldumpcrypto_init(di->kdc);
if (error)
goto fail;
mkdumpheader(&kdh, KERNELDUMPMAGIC, KERNELDUMP_SPARC64_VERSION, size,
kerneldumpcrypto_dumpkeysize(di->kdc), di->blocksize);
printf("Dumping %lu MB (%d chunks)\n", (u_long)(size >> 20), nreg);
/* Dump leader */
error = dump_write_header(di, &kdh, 0, dumplo);
if (error)
error = dump_start(di, &kdh, &dumplo);
if (error != 0)
goto fail;
dumplo += di->blocksize;
/* Dump key */
error = dump_write_key(di, 0, dumplo);
if (error)
goto fail;
dumplo += kerneldumpcrypto_dumpkeysize(di->kdc);
/* Dump the private header. */
hdr.dh_hdr_size = hdrsize;
@ -154,14 +128,10 @@ dumpsys(struct dumperinfo *di)
if (error < 0)
goto fail;
/* Dump trailer */
error = dump_write_header(di, &kdh, 0, dumplo);
if (error)
error = dump_finish(di, &kdh, dumplo);
if (error != 0)
goto fail;
dumplo += di->blocksize;
/* Signal completion, signoff and exit stage left. */
dump_write(di, NULL, 0, 0, 0);
printf("\nDump complete\n");
return (0);

View File

@ -342,12 +342,11 @@ struct dumperinfo {
int set_dumper(struct dumperinfo *di, const char *devname, struct thread *td,
uint8_t encrypt, const uint8_t *key, uint32_t encryptedkeysize,
const uint8_t *encryptedkey);
int dump_start(struct dumperinfo *di, struct kerneldumpheader *kdh,
off_t *dumplop);
int dump_finish(struct dumperinfo *di, struct kerneldumpheader *kdh,
off_t dumplo);
int dump_write(struct dumperinfo *, void *, vm_offset_t, off_t, size_t);
int dump_write_pad(struct dumperinfo *, void *, vm_offset_t, off_t, size_t,
size_t *);
int dump_write_header(struct dumperinfo *di, struct kerneldumpheader *kdh,
vm_offset_t physical, off_t offset);
int dump_write_key(struct dumperinfo *di, vm_offset_t physical, off_t offset);
int doadump(boolean_t);
extern int dumping; /* system is dumping */

View File

@ -125,7 +125,6 @@ struct dump_pa {
vm_paddr_t pa_size;
};
int kerneldumpcrypto_init(struct kerneldumpcrypto *kdc);
uint32_t kerneldumpcrypto_dumpkeysize(const struct kerneldumpcrypto *kdc);
void mkdumpheader(struct kerneldumpheader *kdh, char *magic, uint32_t archver,