📄 tape.c
字号:
if (session->tape.fd == -1) { Error(LOG_ERR, "ndmpdTapeMtio: tape device is not open.\n"); reply.error = NDMP_DEV_NOT_OPEN_ERR; if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0) Error(LOG_ERR, "ndmpdTapeMtio: error sending ndmp_tape_mtio_reply.\n"); return; } switch (request->tape_op) { case NDMP_MTIO_FSF: tapeop.mt_op = MTFSF; break; case NDMP_MTIO_BSF: tapeop.mt_op = MTBSF; break; case NDMP_MTIO_FSR: tapeop.mt_op = MTFSR; break; case NDMP_MTIO_BSR: tapeop.mt_op = MTBSR; break; case NDMP_MTIO_REW: tapeop.mt_op = MTREW; break; case NDMP_MTIO_EOF: tapeop.mt_op = MTWEOF; break; case NDMP_MTIO_OFF: tapeop.mt_op = MTOFFL; break; default: reply.error = NDMP_ILLEGAL_ARGS_ERR; if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0) Error(LOG_ERR, "ndmpdTapeMtio: error sending ndmp_tape_mtio_reply.\n"); return; } tapeop.mt_count = request->count; err = ioctl(session->tape.fd, MTIOCTOP, &tapeop); /* * Ignore I/O errors since these usually are the result of * attempting to position past the beginning or end of the tape. * The residual count will be returned and can be used to * determine that the call was not completely successful. */ if (err < 0 && errno != EIO) { Error(LOG_ERR, "ndmpdTapeMtio: ioctl(MTIOCTOP) error: %s.\n", strerror(errno)); reply.error = NDMP_IO_ERR; if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0) Error(LOG_ERR, "ndmpdTapeMtio: error sending ndmp_tape_mtio_reply.\n"); return; } if (request->tape_op == NDMP_MTIO_REW || request->tape_op == NDMP_MTIO_OFF) { if (err < 0) reply.error = NDMP_IO_ERR; else reply.error = NDMP_NO_ERR; } else { if (ioctl(session->tape.fd, MTIOCGET, &mtstatus) < 0) { Error(LOG_ERR, "ndmpdTapeMtio: ioctl(MTIOGET) error: %s.\n", strerror(errno)); reply.error = NDMP_IO_ERR; if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0) Error(LOG_ERR, "ndmpdTapeMtio: error sending ndmp_tape_mtio_reply.\n"); return; } reply.resid_count = labs(mtstatus.mt_resid); reply.error = NDMP_NO_ERR; } if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0) Error(LOG_ERR, "ndmpdTapeMtio: error sending ndmp_tape_mtio_reply.\n");}/* * ndmpdTapeWrite * * This handler handles tape_write requests. * This interface is a non-buffered interface. Each write request * maps directly to a write to the tape device. It is the responsibility * of the NDMP client to pad the data to the desired record size. * It is the responsibility of the NDMP client to ensure that the * length is a multiple of the tape block size if the tape device * is in fixed block mode. * * Parameters: * connection (input) - connection handle. * body (input) - request message body. * * Returns: * void */voidndmpdTapeWrite(NdmpConnection connection, void* body){ ndmp_tape_write_request* request = (ndmp_tape_write_request*)body; ndmp_tape_write_reply reply; NdmpdSession* session = ndmpGetClientData(connection); ssize_t n; Debug(DBG_CAT_TAPE|DBG_FOC_FLOW, "ndmpdTapeWrite: len:%d.\n", request->data_out.data_out_len); memset((void*)&reply, 0, sizeof(reply)); if (session->tape.fd == -1) { Error(LOG_ERR, "ndmpdTapeWrite: tape device is not open.\n"); reply.error = NDMP_DEV_NOT_OPEN_ERR; if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0) Error(LOG_ERR, "sending ndmp_tape_write_reply.\n"); return; } if (session->tape.mode == NDMP_TAPE_READ_MODE) { Error(LOG_ERR, "ndmpdTapeWrite: tape device opened in read-only mode.\n"); reply.error = NDMP_WRITE_PROTECT_ERR; if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0) Error(LOG_ERR, "sending ndmp_tape_write_reply.\n"); return; } if (request->data_out.data_out_len == 0) { reply.error = NDMP_NO_ERR; if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0) Error(LOG_ERR, "sending ndmp_tape_write_reply.\n"); return; } n = write(session->tape.fd, request->data_out.data_out_val, request->data_out.data_out_len); if (n == 0) reply.error = NDMP_EOM_ERR; else if (n < 0) { Error(LOG_ERR, "ndmpdTapeWrite: write error: %s.\n", strerror(errno)); reply.error = NDMP_IO_ERR; } else { reply.count = n; reply.error = NDMP_NO_ERR; } if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0) Error(LOG_ERR, "ndmpdTapeWrite: error sending nampe_tape_write_reply.\n");}/* * ndmpdTapeRead * * This handler handles tape_read requests. * This interface is a non-buffered interface. Each read request * maps directly to a read to the tape device. It is the responsibility * of the NDMP client to issue read requests with a length that is at * least as large as the record size used write the tape. The tape driver * always reads a full record. Data is discarded if the read request is * smaller than the record size. * It is the responsibility of the NDMP client to ensure that the * length is a multiple of the tape block size if the tape device * is in fixed block mode. * * Parameters: * connection (input) - connection handle. * body (input) - request message body. * * Returns: * void */voidndmpdTapeRead(NdmpConnection connection, void* body){ ndmp_tape_read_request* request = (ndmp_tape_read_request *)body; ndmp_tape_read_reply reply; NdmpdSession* session = ndmpGetClientData(connection); ssize_t n; char* buf; Debug(DBG_CAT_TAPE|DBG_FOC_FLOW, "ndmpdTapeRead: len:%d.\n", request->count); memset((void*)&reply, 0, sizeof(reply)); if (session->tape.fd == -1) { Error(LOG_ERR, "ndmpdTapeRead: tape device is not open.\n"); reply.error = NDMP_DEV_NOT_OPEN_ERR; if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0) Error(LOG_ERR, "sending ndmp_tape_read_reply.\n"); return; } if (request->count == 0) { reply.error = NDMP_NO_ERR; if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0) Error(LOG_ERR, "sending ndmp_tape_read_reply.\n"); return; } if ((buf = (char *)malloc(request->count)) == 0) { Error(LOG_ERR, "ndmpdTapeRead: malloc error: %s.\n", strerror(errno)); reply.error = NDMP_NO_MEM_ERR; if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0) Error(LOG_ERR, "sending ndmp_tape_read_reply.\n"); return; } n = read(session->tape.fd, buf, request->count); if (n < 0) { Error(LOG_ERR, "ndmpdTapeRead: read error: %s.\n", strerror(errno)); reply.error = NDMP_IO_ERR; } else if (n == 0) reply.error = NDMP_EOF_ERR; else { reply.data_in.data_in_len = n; reply.data_in.data_in_val = buf; reply.error = NDMP_NO_ERR; } if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0) Error(LOG_ERR, "ndmpdTapeRead: sending ndmp_tape_read_reply.\n"); (void)free(buf);} /* * ndmpdTapeExecuteCdb * * This handler handles tape_execute_cdb requests. * * Parameters: * connection (input) - connection handle. * body (input) - request message body. * * Returns: * void */voidndmpdTapeExecuteCdb(NdmpConnection connection, void* body){ ndmp_tape_execute_cdb_request* request = (ndmp_tape_execute_cdb_request *)body; ndmp_tape_execute_cdb_reply reply; NdmpdSession* session = ndmpGetClientData(connection); Debug(DBG_CAT_TAPE|DBG_FOC_FLOW, "ndmpdTapeExecuteCdb: \n"); memset((void*)&reply, 0, sizeof(reply)); if (session->tape.fd == -1) { Error(LOG_ERR, "ndmpdTapeExecuteCdb: tape device is not open.\n"); reply.error = NDMP_DEV_NOT_OPEN_ERR; if (ndmpSendReply(connection, NDMP_NO_ERR, (void *)&reply) < 0) Error(LOG_ERR, "ndmpdTapeExecuteCdb: sending tape_execute_cdb reply.\n"); return; } executeCdb(session, session->tape.fd, request);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -