+
+/*
+ * This test exercises the autochanger
+ */
+static int autochanger_test()
+{
+ POOLMEM *results, *changer;
+ int slot, status, loaded;
+ int timeout = 120;
+ int sleep_time = 0;
+
+ if (!dev_cap(dev, CAP_AUTOCHANGER)) {
+ return 1;
+ }
+ if (!(jcr->device && jcr->device->changer_name && jcr->device->changer_command)) {
+ Pmsg0(-1, "\nAutochanger enabled, but no name or no command device specified.\n");
+ return 1;
+ }
+
+ Pmsg0(-1, "\nTo test the autochanger you must have a blank tape in Slot 1.\n"
+ "I'm going to write on it.\n");
+ if (!get_cmd("\nDo you wish to continue with the Autochanger test? (y/n): ")) {
+ return 0;
+ }
+ if (cmd[0] != 'y' && cmd[0] != 'Y') {
+ return 0;
+ }
+
+ Pmsg0(-1, _("\n\n=== Autochanger test ===\n\n"));
+
+ results = get_pool_memory(PM_MESSAGE);
+ changer = get_pool_memory(PM_FNAME);
+
+try_again:
+ slot = 1;
+ jcr->VolCatInfo.Slot = slot;
+ /* Find out what is loaded, zero means device is unloaded */
+ Pmsg0(-1, _("3301 Issuing autochanger \"loaded\" command.\n"));
+ changer = edit_device_codes(jcr, changer, jcr->device->changer_command,
+ "loaded");
+ status = run_program(changer, timeout, results);
+ Dmsg3(100, "run_prog: %s stat=%d result=%s\n", changer, status, results);
+ if (status == 0) {
+ loaded = atoi(results);
+ } else {
+ Pmsg1(-1, _("3991 Bad autochanger \"load slot\" status=%d.\n"), status);
+ loaded = -1; /* force unload */
+ goto bail_out;
+ }
+ if (loaded) {
+ Pmsg1(-1, "Slot %d loaded. I am going to unload it.\n", loaded);
+ } else {
+ Pmsg0(-1, "Nothing loaded into the drive. OK.\n");
+ }
+ Dmsg1(100, "Results from loaded query=%s\n", results);
+ if (loaded) {
+ offline_or_rewind_dev(dev);
+ /* We are going to load a new tape, so close the device */
+ force_close_dev(dev);
+ Pmsg0(-1, _("3302 Issuing autochanger \"unload\" command.\n"));
+ changer = edit_device_codes(jcr, changer,
+ jcr->device->changer_command, "unload");
+ status = run_program(changer, timeout, NULL);
+ Pmsg2(-1, "unload status=%s %d\n", status==0?"OK":"Bad", status);
+ }
+
+ /*
+ * Load the Slot 1
+ */
+ Pmsg1(-1, _("3303 Issuing autochanger \"load slot %d\" command.\n"), slot);
+ changer = edit_device_codes(jcr, changer, jcr->device->changer_command, "load");
+ Dmsg1(200, "Changer=%s\n", changer);
+ status = run_program(changer, timeout, NULL);
+ if (status == 0) {
+ Pmsg1(-1, _("3304 Autochanger \"load slot %d\" status is OK.\n"), slot);
+ } else {
+ Pmsg1(-1, _("3992 Bad autochanger \"load slot\" status=%d.\n"), status);
+ goto bail_out;
+ }
+
+ if (!open_the_device()) {
+ goto bail_out;
+ }
+ bmicrosleep(sleep_time, 0);
+ if (!rewind_dev(dev)) {
+ Pmsg1(0, "Bad status from rewind. ERR=%s\n", strerror_dev(dev));
+ clrerror_dev(dev, -1);
+ Pmsg0(-1, "\nThe test failed, probably because you need to put\n"
+ "a longer sleep time in the mtx-script in the load) case.\n"
+ "Adding a 30 second sleep and trying again ...\n");
+ sleep_time += 30;
+ goto try_again;
+ } else {
+ Pmsg1(0, "Rewound %s\n", dev_name(dev));
+ }
+
+ if ((status = weof_dev(dev, 1)) < 0) {
+ Pmsg2(0, "Bad status from weof %d. ERR=%s\n", status, strerror_dev(dev));
+ goto bail_out;
+ } else {
+ Pmsg1(0, "Wrote EOF to %s\n", dev_name(dev));
+ }
+
+ if (sleep_time) {
+ Pmsg1(-1, "\nThe test worked this time. Please add:\n\n"
+ " sleep %d\n\n"
+ "to your mtx-changer script in the load) case.\n\n",
+ sleep_time);
+ } else {
+ Pmsg0(-1, "\nThe test autochanger worked!!\n\n");
+ }
+
+ free_pool_memory(changer);
+ free_pool_memory(results);
+ return 1;
+
+
+bail_out:
+ free_pool_memory(changer);
+ free_pool_memory(results);
+ Pmsg0(-1, "You must correct this error or the Autochanger will not work.\n");
+ return -2;
+}
+
+static void autochangercmd()
+{
+ autochanger_test();
+}
+
+
+/*
+ * This test assumes that the append test has been done,
+ * then it tests the fsf function.
+ */
+static int fsf_test()
+{
+ bool set_off = false;
+
+ Pmsg0(-1, _("\n\n=== Forward space files test ===\n\n"
+ "This test is essential to Bacula.\n\n"
+ "I'm going to write five files then test forward spacing\n\n"));
+ argc = 1;
+ rewindcmd();
+ wrcmd();
+ weofcmd(); /* end file 0 */
+ wrcmd();
+ wrcmd();
+ weofcmd(); /* end file 1 */
+ wrcmd();
+ wrcmd();
+ wrcmd();
+ weofcmd(); /* end file 2 */
+ wrcmd();
+ wrcmd();
+ weofcmd(); /* end file 3 */
+ wrcmd();
+ weofcmd(); /* end file 4 */
+
+test_again:
+ rewindcmd();
+ Pmsg0(0, _("Now forward spacing 1 file.\n"));
+ if (!fsf_dev(dev, 1)) {
+ Pmsg1(0, "Bad status from fsr. ERR=%s\n", strerror_dev(dev));
+ goto bail_out;
+ }
+ Pmsg2(-1, _("We should be in file 1. I am at file %d. This is %s\n"),
+ dev->file, dev->file == 1 ? "correct!" : "NOT correct!!!!");
+
+ if (dev->file != 1) {
+ goto bail_out;
+ }
+
+ Pmsg0(0, _("Now forward spacing 2 files.\n"));
+ if (!fsf_dev(dev, 2)) {
+ Pmsg1(0, "Bad status from fsr. ERR=%s\n", strerror_dev(dev));
+ goto bail_out;
+ }
+ Pmsg2(-1, _("We should be in file 3. I am at file %d. This is %s\n"),
+ dev->file, dev->file == 3 ? "correct!" : "NOT correct!!!!");
+
+ if (dev->file != 3) {
+ goto bail_out;
+ }
+
+ rewindcmd();
+ Pmsg0(0, _("Now forward spacing 4 files.\n"));
+ if (!fsf_dev(dev, 4)) {
+ Pmsg1(0, "Bad status from fsr. ERR=%s\n", strerror_dev(dev));
+ goto bail_out;
+ }
+ Pmsg2(-1, _("We should be in file 4. I am at file %d. This is %s\n"),
+ dev->file, dev->file == 4 ? "correct!" : "NOT correct!!!!");
+
+ if (dev->file != 4) {
+ goto bail_out;
+ }
+ if (set_off) {
+ Pmsg0(-1, "The test worked this time. Please add:\n\n"
+ " Fast Forward Space File = no\n\n"
+ "to your Device resource for this drive.\n");
+ }
+ return 1;
+
+bail_out:
+ Pmsg0(-1, _("\nThe forward space file test failed.\n"));
+ if (dev_cap(dev, CAP_FASTFSF)) {
+ Pmsg0(-1, "You have Fast Forward Space File enabled.\n"
+ "I am turning it off then retring the test.\n");
+ dev->capabilities &= ~CAP_FASTFSF;
+ set_off = true;
+ goto test_again;
+ }
+ Pmsg0(-1, "You must correct this error or Bacula will not work.\n");
+ return -2;
+}
+
+
+
+
+