* Do some preliminary setup for a kernel dump: initialize state for encryption, * if requested, and make sure that we have enough space on the dump device. * * We set things up so that the dump ends before the last sector of the dump * device, at which the trailing header is written. * * +-----------+------+-----+----------------------------+------+ * | | lhdr | key | .
| 1569 | * dumpoff and take care of laying out the headers. |
| 1570 | */ |
| 1571 | int |
| 1572 | dump_start(struct dumperinfo *di, struct kerneldumpheader *kdh) |
| 1573 | { |
| 1574 | uint64_t dumpextent, span; |
| 1575 | uint32_t keysize; |
| 1576 | int error; |
| 1577 | |
| 1578 | #ifdef EKCD |
| 1579 | error = kerneldumpcrypto_init(di->kdcrypto); |
| 1580 | if (error != 0) |
| 1581 | return (error); |
| 1582 | keysize = kerneldumpcrypto_dumpkeysize(di->kdcrypto); |
| 1583 | #else |
| 1584 | error = 0; |
| 1585 | keysize = 0; |
| 1586 | #endif |
| 1587 | |
| 1588 | if (di->dumper_start != NULL) { |
| 1589 | error = di->dumper_start(di); |
| 1590 | } else { |
| 1591 | dumpextent = dtoh64(kdh->dumpextent); |
| 1592 | span = SIZEOF_METADATA + dumpextent + 2 * di->blocksize + |
| 1593 | keysize; |
| 1594 | if (di->mediasize < span) { |
| 1595 | if (di->kdcomp == NULL) |
| 1596 | return (E2BIG); |
| 1597 | |
| 1598 | /* |
| 1599 | * We don't yet know how much space the compressed dump |
| 1600 | * will occupy, so try to use the whole swap partition |
| 1601 | * (minus the first 64KB) in the hope that the |
| 1602 | * compressed dump will fit. If that doesn't turn out to |
| 1603 | * be enough, the bounds checking in dump_write() |
| 1604 | * will catch us and cause the dump to fail. |
| 1605 | */ |
| 1606 | dumpextent = di->mediasize - span + dumpextent; |
| 1607 | kdh->dumpextent = htod64(dumpextent); |
| 1608 | } |
| 1609 | |
| 1610 | /* |
| 1611 | * The offset at which to begin writing the dump. |
| 1612 | */ |
| 1613 | di->dumpoff = di->mediaoffset + di->mediasize - di->blocksize - |
| 1614 | dumpextent; |
| 1615 | } |
| 1616 | di->origdumpoff = di->dumpoff; |
| 1617 | return (error); |
| 1618 | } |
| 1619 | |
| 1620 | static int |
| 1621 | _dump_append(struct dumperinfo *di, void *virtual, vm_offset_t physical, |
no test coverage detected