在系统出现故障或执行检查点操作时,dump(9E) 入口点会将部分虚拟地址空间直接复制到指定的设备。请参见 cpr(7) 和 dump(9E) 手册页。dump(9E) 入口点必须在不使用中断的情况下能够执行该操作。
dump() 的参数如下所示:
转储设备的设备编号
开始转储的内核虚拟地址
设备上的第一个目标块
要转储的块数
static int
xxdump(dev_t dev, caddr_t addr, daddr_t blkno, int nblk)
{
struct xxstate *xsp;
struct buf *bp;
struct scsi_pkt *pkt;
int rval;
int instance;
instance = getminor(dev);
xsp = ddi_get_soft_state(statep, instance);
if (tgt->suspended) {
(void) pm_raise_power(DEVINFO(tgt), 0, 1);
}
bp = getrbuf(KM_NOSLEEP);
if (bp == NULL) {
return (EIO);
}
/* Calculate block number relative to partition. */
bp->b_un.b_addr = addr;
bp->b_edev = dev;
bp->b_bcount = nblk * DEV_BSIZE;
bp->b_flags = B_WRITE | B_BUSY;
bp->b_blkno = blkno;
pkt = scsi_init_pkt(ROUTE(tgt), NULL, bp, CDB_GROUP1,
sizeof (struct scsi_arq_status),
sizeof (struct bst_pkt_private), 0, NULL_FUNC, NULL);
if (pkt == NULL) {
freerbuf(bp);
return (EIO);
}
(void) scsi_setup_cdb((union scsi_cdb *)pkt->pkt_cdbp,
SCMD_WRITE_G1, blkno, nblk, 0);
/*
* While dumping in polled mode, other cmds might complete
* and these should not be resubmitted. we set the
* dumping flag here which prevents requeueing cmds.
*/
tgt->dumping = 1;
rval = scsi_poll(pkt);
tgt->dumping = 0;
scsi_destroy_pkt(pkt);
freerbuf(bp);
if (rval != DDI_SUCCESS) {
rval = EIO;
}
return (rval);
}