+/* check that the tape is a valid amanda tape
+ Returns TRUE if all tests passed; FALSE otherwise. */
+static gboolean test_tape_status(FILE * outf) {
+ int tape_status;
+ Device * device;
+ GValue property_value;
+ char * label = NULL;
+ char * tapename = NULL;
+ ReadLabelStatusFlags label_status;
+
+ bzero(&property_value, sizeof(property_value));
+
+ tapename = getconf_str(CNF_TAPEDEV);
+ g_return_val_if_fail(tapename != NULL, FALSE);
+
+ device_api_init();
+
+ if (!getconf_seen(CNF_TPCHANGER) && getconf_int(CNF_RUNTAPES) != 1) {
+ g_fprintf(outf,
+ _("WARNING: if a tape changer is not available, runtapes "
+ "must be set to 1\n"));
+ g_fprintf(outf, _("Change the value of the \"runtapes\" parameter in "
+ "amanda.conf or configure a tape changer\n"));
+ }
+
+ tape_status = taper_scan(NULL, &label, &datestamp, &tapename, NULL,
+ FILE_taperscan_output_callback, outf,
+ NULL, NULL);
+ if (tape_status < 0) {
+ tape_t *exptape = lookup_last_reusable_tape(0);
+ g_fprintf(outf, _(" (expecting "));
+ if(exptape != NULL) g_fprintf(outf, _("tape %s or "), exptape->label);
+ g_fprintf(outf, _("a new tape)\n"));
+ amfree(label);
+ return FALSE;
+ }
+
+ device = device_open(tapename);
+
+ if (device == NULL) {
+ g_fprintf(outf, "ERROR: Could not open tape device.\n");
+ amfree(label);
+ return FALSE;
+ }
+
+ device_set_startup_properties_from_config(device);
+ label_status = device_read_label(device);
+
+ if (tape_status == 3 &&
+ !(label_status & READ_LABEL_STATUS_VOLUME_UNLABELED)) {
+ if (label_status == READ_LABEL_STATUS_SUCCESS) {
+ g_fprintf(outf, "WARNING: Volume was unlabeled, but now "
+ "is labeled \"%s\".\n", device->volume_label);
+ }
+ } else if (label_status != READ_LABEL_STATUS_SUCCESS && tape_status != 3) {
+ char * errstr =
+ g_english_strjoinv_and_free
+ (g_flags_nick_to_strv(label_status &
+ (~READ_LABEL_STATUS_VOLUME_UNLABELED),
+ READ_LABEL_STATUS_FLAGS_TYPE), "or");
+ g_fprintf(outf, "WARNING: Reading label the second time failed: "
+ "One of %s.\n", errstr);
+ g_free(errstr);
+ } else if (tape_status != 3 &&
+ (device->volume_label == NULL || label == NULL ||
+ strcmp(device->volume_label, label) != 0)) {
+ g_fprintf(outf, "WARNING: Label mismatch on re-read: "
+ "Got %s first, then %s.\n", label, device->volume_label);
+ }
+
+ /* If we can't get this property, it's not an error. Maybe the device
+ * doesn't support this property, or needs an actual volume to know
+ * for sure. */
+ if (device_property_get(device, PROPERTY_MEDIUM_TYPE, &property_value)) {
+ g_assert(G_VALUE_TYPE(&property_value) == MEDIA_ACCESS_MODE_TYPE);
+ if (g_value_get_enum(&property_value) ==
+ MEDIA_ACCESS_MODE_WRITE_ONLY) {
+ g_fprintf(outf, "WARNING: Media access mode is WRITE_ONLY, "
+ "dumps will be thrown away.\n");
+ }
+ }
+
+ if (overwrite) {
+ char *timestamp = get_undef_timestamp();
+ if (!device_start(device, ACCESS_WRITE, label, timestamp)) {
+ if (tape_status == 3) {
+ g_fprintf(outf, "ERROR: Could not label brand new tape.\n");
+ } else {
+ g_fprintf(outf,
+ "ERROR: tape %s label ok, but is not writable.\n",
+ label);
+ }
+ amfree(timestamp);
+ amfree(label);
+ g_object_unref(device);
+ return FALSE;
+ } else { /* Write succeeded. */
+ if (tape_status != 3) {
+ g_fprintf(outf, "Tape %s is writable; rewrote label.\n", label);
+ } else {
+ g_fprintf(outf, "Wrote label %s to brand new tape.\n", label);
+ }
+ }
+ amfree(timestamp);
+ } else { /* !overwrite */
+ g_fprintf(outf, "NOTE: skipping tape-writable test\n");
+ if (tape_status == 3) {
+ g_fprintf(outf,
+ "Found a brand new tape, will label it %s.\n",
+ label);
+ } else {
+ g_fprintf(outf, "Tape %s label ok\n", label);
+ }
+ }
+ g_object_unref(device);
+ amfree(label);
+ return TRUE;
+}
+