X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=bacula%2Fsrc%2Fstored%2Fdircmd.c;h=f83263105b618a22451ed0ca75751f3ab17213d0;hb=22a5d43f2bf48e4d5c056dc17bd7cff90d84290e;hp=e6d4b289ed3e766bce1bd380f8bd800ab451a12f;hpb=ffc5ea462dedafd258de0e4e325eaa51618723fc;p=bacula%2Fbacula diff --git a/bacula/src/stored/dircmd.c b/bacula/src/stored/dircmd.c index e6d4b289ed..f83263105b 100644 --- a/bacula/src/stored/dircmd.c +++ b/bacula/src/stored/dircmd.c @@ -43,8 +43,6 @@ extern BSOCK *filed_chan; extern int r_first, r_last; extern struct s_res resources[]; -extern char my_name[]; -extern time_t daemon_start_time; extern struct s_last_job last_job; extern bool init_done; @@ -192,7 +190,7 @@ void *handle_connection_request(void *arg) if ((bnet_stat = bnet_recv(bs)) <= 0) { break; /* connection terminated */ } - Dmsg1(199, "msg); + Dmsg1(199, "msg); /* Ensure that device initialization is complete */ while (!init_done) { bmicrosleep(1, 0); @@ -209,7 +207,7 @@ void *handle_connection_request(void *arg) Dmsg1(200, "Do command: %s\n", cmds[i].cmd); if (!cmds[i].func(jcr)) { /* do command */ quit = true; /* error, get out */ - Dmsg1(190, "Command %s requsts quit\n", cmds[i].cmd); + Dmsg1(190, "Command %s reqeusts quit\n", cmds[i].cmd); } found = true; /* indicate command found */ break; @@ -262,13 +260,13 @@ static bool cancel_cmd(JCR *cjcr) if (!(jcr=get_jcr_by_full_name(Job))) { bnet_fsend(dir, _("3904 Job %s not found.\n"), Job); } else { - P(jcr->mutex); + jcr->lock(); oldStatus = jcr->JobStatus; set_jcr_job_status(jcr, JS_Canceled); if (!jcr->authenticated && oldStatus == JS_WaitFD) { pthread_cond_signal(&jcr->job_start_wait); /* wake waiting thread */ } - V(jcr->mutex); + jcr->unlock(); if (jcr->file_bsock) { bnet_sig(jcr->file_bsock, BNET_TERMINATE); } @@ -281,6 +279,7 @@ static bool cancel_cmd(JCR *cjcr) pthread_cond_broadcast(&jcr->read_dcr->dev->wait_next_vol); pthread_cond_broadcast(&wait_device_release); } + Jmsg(jcr, M_INFO, 0, _("Job marked to be canceled.\n")); bnet_fsend(dir, _("3000 Job %s marked to be canceled.\n"), jcr->Job); free_jcr(jcr); } @@ -392,11 +391,15 @@ static void label_volume_if_ok(DCR *dcr, char *oldname, DEVICE *dev = dcr->dev; int label_status; int mode; + const char *volname = (relabel == 1) ? oldname : newname; + char ed1[50]; steal_device_lock(dev, &hold, BST_WRITING_LABEL); Dmsg1(100, "Stole device %s lock, writing label.\n", dev->print_name()); - if (!try_autoload_device(dcr->jcr, slot, newname)) { + + Dmsg0(90, "try_autoload_device - looking for volume_info\n"); + if (!try_autoload_device(dcr->jcr, slot, volname)) { goto bail_out; /* error */ } @@ -406,15 +409,23 @@ static void label_volume_if_ok(DCR *dcr, char *oldname, } else { mode = CREATE_READ_WRITE; } + + if (relabel) { + dev->truncating = true; /* let open() know we will truncate it */ + } + /* Set old volume name for open if relabeling */ + bstrncpy(dcr->VolCatInfo.VolCatName, volname, sizeof(dcr->VolCatInfo.VolCatName)); if (dev->open(dcr, mode) < 0) { bnet_fsend(dir, _("3910 Unable to open device %s: ERR=%s\n"), dev->print_name(), dev->strerror()); - return; + goto bail_out; } /* See what we have for a Volume */ label_status = read_dev_volume_label(dcr); + /* Set new volume name */ + bstrncpy(dcr->VolCatInfo.VolCatName, newname, sizeof(dcr->VolCatInfo.VolCatName)); switch(label_status) { case VOL_NAME_ERROR: case VOL_VERSION_ERROR: @@ -436,21 +447,22 @@ static void label_volume_if_ok(DCR *dcr, char *oldname, bnet_fsend(dir, _("3922 Cannot relabel an ANSI/IBM labeled Volume.\n")); break; } - free_volume(dev); /* release old volume name */ /* Fall through wanted! */ case VOL_IO_ERROR: case VOL_NO_LABEL: - if (!write_new_volume_label_to_dev(dcr, newname, poolname)) { - bnet_fsend(dir, _("3912 Failed to label Volume: ERR=%s\n"), strerror_dev(dev)); + if (!write_new_volume_label_to_dev(dcr, newname, poolname, + relabel, true /* write dvd now */)) { + bnet_fsend(dir, _("3912 Failed to label Volume: ERR=%s\n"), dev->bstrerror()); break; } bstrncpy(dcr->VolumeName, newname, sizeof(dcr->VolumeName)); /* The following 3000 OK label. string is scanned in ua_label.c */ - bnet_fsend(dir, "3000 OK label. Volume=%s Device=%s\n", - newname, dev->print_name()); + bnet_fsend(dir, "3000 OK label. VolBytes=%s DVD=%d Volume=\"%s\" Device=%s\n", + edit_uint64(dev->VolCatInfo.VolCatBytes, ed1), + dev->is_dvd()?1:0, newname, dev->print_name()); break; case VOL_NO_MEDIA: - bnet_fsend(dir, _("3912 Failed to label Volume: ERR=%s\n"), strerror_dev(dev)); + bnet_fsend(dir, _("3912 Failed to label Volume: ERR=%s\n"), dev->bstrerror()); break; default: bnet_fsend(dir, _("3913 Cannot label Volume. " @@ -582,8 +594,15 @@ static bool mount_cmd(JCR *jcr) DEVICE *dev; DCR *dcr; int drive; + int slot = 0; + bool ok; - if (sscanf(dir->msg, "mount %127s drive=%d", devname.c_str(), &drive) == 2) { + ok = sscanf(dir->msg, "mount %127s drive=%d slot=%d", devname.c_str(), + &drive, &slot) == 3; + if (!ok) { + ok = sscanf(dir->msg, "mount %127s drive=%d", devname.c_str(), &drive) == 2; + } + if (ok) { dcr = find_device(jcr, devname, drive); if (dcr) { dev = dcr->dev; @@ -603,10 +622,13 @@ static bool mount_cmd(JCR *jcr) /* In both of these two cases, we (the user) unmounted the Volume */ case BST_UNMOUNTED_WAITING_FOR_SYSOP: case BST_UNMOUNTED: + if (dev->is_autochanger() && slot > 0) { + try_autoload_device(jcr, slot, ""); + } /* We freed the device, so reopen it and wake any waiting threads */ if (dev->open(dcr, OPEN_READ_ONLY) < 0) { bnet_fsend(dir, _("3901 open device failed: ERR=%s\n"), - strerror_dev(dev)); + dev->bstrerror()); if (dev->dev_blocked == BST_UNMOUNTED) { /* We blocked the device, so unblock it */ Dmsg0(100, "Unmounted. Unblocking device\n"); @@ -647,6 +669,9 @@ static bool mount_cmd(JCR *jcr) break; case BST_NOT_BLOCKED: + if (dev->is_autochanger() && slot > 0) { + try_autoload_device(jcr, slot, ""); + } if (dev->is_open()) { if (dev->is_labeled()) { bnet_fsend(dir, _("3001 Device %s is mounted with Volume \"%s\"\n"), @@ -659,7 +684,7 @@ static bool mount_cmd(JCR *jcr) } else if (dev->is_tape()) { if (dev->open(dcr, OPEN_READ_ONLY) < 0) { bnet_fsend(dir, _("3901 open device failed: ERR=%s\n"), - strerror_dev(dev)); + dev->bstrerror()); break; } read_label(dcr); @@ -676,7 +701,7 @@ static bool mount_cmd(JCR *jcr) bnet_fsend(dir, _("3002 Device %s is mounted.\n"), dev->print_name()); } else { - bnet_fsend(dir, _("3907 %s"), strerror_dev(dev)); + bnet_fsend(dir, _("3907 %s"), dev->bstrerror()); } } else { /* must be file */ bnet_fsend(dir, _("3906 File device %s is always mounted.\n"), @@ -722,19 +747,31 @@ static bool unmount_cmd(JCR *jcr) if (!dev->is_busy()) { unload_autochanger(jcr->dcr, -1); } - Dmsg0(90, "Device already unmounted\n"); - bnet_fsend(dir, _("3901 Device %s is already unmounted.\n"), - dev->print_name()); - + if (dev->is_dvd()) { + if (unmount_dvd(dev, 0)) { + bnet_fsend(dir, _("3002 Device %s unmounted.\n"), + dev->print_name()); + } else { + bnet_fsend(dir, _("3907 %s"), dev->bstrerror()); + } + } else { + Dmsg0(90, "Device already unmounted\n"); + bnet_fsend(dir, _("3901 Device %s is already unmounted.\n"), + dev->print_name()); + } } else if (dev->dev_blocked == BST_WAITING_FOR_SYSOP) { Dmsg2(90, "%d waiter dev_block=%d. doing unmount\n", dev->num_waiting, dev->dev_blocked); if (!unload_autochanger(jcr->dcr, -1)) { dev->close(); } - dev->dev_blocked = BST_UNMOUNTED_WAITING_FOR_SYSOP; - bnet_fsend(dir, _("3001 Device %s unmounted.\n"), - dev->print_name()); + if (dev->is_dvd() && !unmount_dvd(dev, 0)) { + bnet_fsend(dir, _("3907 %s"), dev->bstrerror()); + } else { + dev->dev_blocked = BST_UNMOUNTED_WAITING_FOR_SYSOP; + bnet_fsend(dir, _("3001 Device %s unmounted.\n"), + dev->print_name()); + } } else if (dev->dev_blocked == BST_DOING_ACQUIRE) { bnet_fsend(dir, _("3902 Device %s is busy in acquire.\n"), @@ -759,8 +796,12 @@ static bool unmount_cmd(JCR *jcr) if (!unload_autochanger(jcr->dcr, -1)) { dev->close(); } - bnet_fsend(dir, _("3002 Device %s unmounted.\n"), - dev->print_name()); + if (dev->is_dvd() && !unmount_dvd(dev, 0)) { + bnet_fsend(dir, _("3907 %s"), dev->bstrerror()); + } else { + bnet_fsend(dir, _("3002 Device %s unmounted.\n"), + dev->print_name()); + } } V(dev->mutex); free_dcr(dcr); @@ -857,27 +898,32 @@ static bool changer_cmd(JCR *jcr) DCR *dcr; const char *cmd = NULL; bool ok = false; + /* + * A safe_cmd may call autochanger script but does not load/unload + * slots so it can be done at the same time that the drive is open. + */ + bool safe_cmd = false; if (sscanf(dir->msg, "autochanger list %127s", devname.c_str()) == 1) { cmd = "list"; - ok = true; + safe_cmd = ok = true; } else if (sscanf(dir->msg, "autochanger slots %127s", devname.c_str()) == 1) { cmd = "slots"; - ok = true; + safe_cmd = ok = true; } else if (sscanf(dir->msg, "autochanger drives %127s", devname.c_str()) == 1) { cmd = "drives"; - ok = true; + safe_cmd = ok = true; } if (ok) { dcr = find_device(jcr, devname, -1); if (dcr) { dev = dcr->dev; P(dev->mutex); /* Use P to avoid indefinite block */ - if (!dev->is_tape()) { + if (!dev->device->changer_res) { bnet_fsend(dir, _("3995 Device %s is not an autochanger.\n"), dev->print_name()); /* Under certain "safe" conditions, we can steal the lock */ - } else if (!dev->is_open() || dev->can_steal_lock()) { + } else if (safe_cmd || !dev->is_open() || dev->can_steal_lock()) { autochanger_cmd(dcr, dir, cmd); } else if (dev->is_busy() || dev->is_blocked()) { send_dir_busy_message(dir, dev);