+ break;
+
+ case PARTDONE: /* PARTDONE <handle> <label> <fileno> <kbytes> <stat> */
+ dp = serial2disk(result_argv[1]);
+ assert(dp == taper_disk);
+ if (result_argc != 6) {
+ error(_("error [taper PARTDONE result_argc != 6: %d]"),
+ result_argc);
+ /*NOTREACHED*/
+ }
+ if (!taper_first_label) {
+ taper_first_label = stralloc(result_argv[2]);
+ taper_first_fileno = OFF_T_ATOI(result_argv[3]);
+ }
+ taper_written = OFF_T_ATOI(result_argv[4]);
+ if (taper_written > sched(taper_disk)->act_size)
+ sched(taper_disk)->act_size = taper_written;
+
+ break;
+
+ case REQUEST_NEW_TAPE: /* REQUEST-NEW-TAPE <handle> */
+ if (result_argc != 2) {
+ error(_("error [taper REQUEST_NEW_TAPE result_argc != 2: %d]"),
+ result_argc);
+ /*NOTREACHED*/
+ }
+ taper_state &= ~TAPER_STATE_TAPE_STARTED;
+
+ if (current_tape >= conf_runtapes) {
+ taper_cmd(NO_NEW_TAPE, "runtapes volumes already written", NULL, 0, NULL);
+ log_add(L_WARNING,
+ _("Out of tapes; going into degraded mode."));
+ start_degraded_mode(&runq);
+ } else {
+ TapeAction result_tape_action;
+ char *why_no_new_tape;
+
+ taper_state |= TAPER_STATE_WAIT_FOR_TAPE;
+ result_tape_action = tape_action(&why_no_new_tape);
+ if (result_tape_action & TAPE_ACTION_NEW_TAPE) {
+ taper_cmd(NEW_TAPE, NULL, NULL, 0, NULL);
+ taper_state &= ~TAPER_STATE_WAIT_FOR_TAPE;
+ } else if (result_tape_action & TAPE_ACTION_NO_NEW_TAPE) {
+ taper_cmd(NO_NEW_TAPE, why_no_new_tape, NULL, 0, NULL);
+ taper_state &= ~TAPER_STATE_WAIT_FOR_TAPE;
+ start_degraded_mode(&runq);
+ }
+ }
+ break;
+
+ case NEW_TAPE: /* NEW-TAPE <handle> <label> */
+ if (result_argc != 3) {
+ error(_("error [taper NEW_TAPE result_argc != 3: %d]"),
+ result_argc);
+ /*NOTREACHED*/
+ }
+
+ /* Update our tape counter and reset tape_left */
+ current_tape++;
+ tape_left = tape_length;
+ taper_state |= TAPER_STATE_TAPE_STARTED;
+ break;
+
+ case NO_NEW_TAPE: /* NO-NEW-TAPE <handle> */
+ if (result_argc != 2) {
+ error(_("error [taper NO_NEW_TAPE result_argc != 2: %d]"),
+ result_argc);
+ /*NOTREACHED*/
+ }
+ start_degraded_mode(&runq);
+ break;
+
+ case DUMPER_STATUS: /* DUMPER-STATUS <handle> */
+ if (result_argc != 2) {
+ error(_("error [taper NO_NEW_TAPE result_argc != 2: %d]"),
+ result_argc);
+ /*NOTREACHED*/
+ }
+ if (taper_dumper->result == LAST_TOK) {
+ taper_sendresult = 1;
+ } else {
+ if( taper_dumper->result == DONE) {
+ taper_cmd(DONE, NULL, NULL, 0, NULL);
+ } else {
+ taper_cmd(FAILED, NULL, NULL, 0, NULL);
+ }
+ }
+ break;
+
+ case TAPE_ERROR: /* TAPE-ERROR <handle> <err mess> */
+ dp = serial2disk(result_argv[1]);
+ if (!taper_dumper)
+ free_serial(result_argv[1]);
+ qname = quote_string(dp->name);
+ g_printf(_("driver: finished-cmd time %s taper wrote %s:%s\n"),
+ walltime_str(curclock()), dp->host->hostname, qname);
+ amfree(qname);
+ fflush(stdout);
+ q = quote_string(result_argv[2]);
+ log_add(L_WARNING, _("Taper error: %s"), q);
+ amfree(q);
+ taper_tape_error = newstralloc(taper_tape_error, result_argv[2]);
+ /*FALLTHROUGH*/
+
+ case BOGUS:
+ if (cmd == BOGUS) {
+ log_add(L_WARNING, _("Taper protocol error"));
+ taper_tape_error = newstralloc(taper_tape_error, "BOGUS");
+ }
+ /*
+ * Since we received a taper error, we can't send anything more
+ * to the taper. Go into degraded mode to try to get everthing
+ * onto disk. Later, these dumps can be flushed to a new tape.
+ * The tape queue is zapped so that it appears empty in future
+ * checks. If there are dumps waiting for diskspace to be freed,
+ * cancel one.
+ */
+ if(!nodump) {
+ log_add(L_WARNING,
+ _("going into degraded mode because of taper component error."));
+ }
+ start_degraded_mode(&runq);
+ tapeq.head = tapeq.tail = NULL;
+ taper_busy = 0;
+ if(taper_ev_read != NULL) {
+ event_release(taper_ev_read);
+ taper_ev_read = NULL;
+ }
+ if(cmd != TAPE_ERROR) aclose(taper);
+ taper_result = cmd;
+
+ break;
+
+ default:
+ error(_("driver received unexpected token (%s) from taper"),
+ cmdstr[cmd]);
+ /*NOTREACHED*/
+ }
+
+ g_strfreev(result_argv);
+
+ if (taper_result != LAST_TOK) {
+ if(taper_dumper) {
+ if (taper_dumper->result != LAST_TOK) {
+ // Dumper already returned it's result
+ dumper_taper_result(taper_disk);
+ }
+ } else {
+ file_taper_result(taper_disk);
+ }
+ }
+
+ } while(areads_dataready(taper));
+}
+
+
+static void
+file_taper_result(
+ disk_t *dp)
+{
+ char *qname = quote_string(dp->name);
+
+ if (taper_result == DONE) {
+ update_info_taper(dp, taper_first_label, taper_first_fileno,
+ sched(dp)->level);
+ }