From: Kern Sibbald Date: Sat, 13 Aug 2005 15:22:33 +0000 (+0000) Subject: - Add drive specification to mount, unmount, release, label, X-Git-Tag: Release-1.38.0~193 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=bd3751e33acd166b8e3bfe15039054c177f77203;p=bacula%2Fbacula - Add drive specification to mount, unmount, release, label, and relabel for Autochangers. Note Dir<->SD protocol has changed. git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@2311 91ce42f0-d328-0410-95d8-f526ca767f89 --- diff --git a/bacula/kernstodo b/bacula/kernstodo index 5efb120c15..f89e82461b 100644 --- a/bacula/kernstodo +++ b/bacula/kernstodo @@ -28,37 +28,6 @@ Document: - Pruning with Admin job. - Restore of all files for a Job or set of jobs even if the file records have been removed from the catalog. -========= probably not in 1.38 ============= - - MaximumPartSize = bytes (SD, Device resource) - Defines the maximum part size. - - Requires Mount = Yes/No (SD, Device resource) - Defines if the device require to be mounted to be read, and if it - must be written in a special way. If it set, the following directives - must be defined in the same Device resource: - + Mount Point = directory - Directory where the device must be mounted. - + Mount Command = name-string - Command that must be executed to mount the device. Before the command - is executed, %a is replaced with the Archive Device, and %m with the - Mount Point. - + Unmount Command = name-string - Command that must be executed to unmount the device. Before the - command is executed, %a is replaced with the Archive Device, and - %m with the Mount Point. - + Write Part Command = name-string - Command that must be executed to write a part to the device. Before - the command is executed, %a is replaced with the Archive Device, %m - with the Mount Point, %n with the current part number (0-based), - and %v with the current part filename. - + Free Space Command = name-string - Command that must be executed to check how much free space is left - on the device. Before the command is executed, %a is replaced with - the Archive Device, %m with the Mount Point, %n with the current part - number (0-based), and %v with the current part filename. - - Write Part After Job = Yes/No (DIR, Job Resource, and Schedule Resource) - If this directive is set to yes (default no), a new part file will be - created after the job is finished. -======= For 1.39: - Look at NDMP diff --git a/bacula/kes-1.37 b/bacula/kes-1.37 index a91b554111..c1e16ae882 100644 --- a/bacula/kes-1.37 +++ b/bacula/kes-1.37 @@ -3,6 +3,12 @@ General: +Changes to 1.37.36: +13Aug05 +- Add drive specification to mount, unmount, release, label, + and relabel for Autochangers. Note Dir<->SD protocol has + changed. + Changes to 1.37.35: 12Aug05 - Disable parts of NLS as the configure does not work here. diff --git a/bacula/src/dird/protos.h b/bacula/src/dird/protos.h index 0d983686fa..b6a3513de2 100644 --- a/bacula/src/dird/protos.h +++ b/bacula/src/dird/protos.h @@ -186,7 +186,7 @@ void start_prompt(UAContext *ua, const char *msg); void add_prompt(UAContext *ua, const char *prompt); int do_prompt(UAContext *ua, const char *automsg, const char *msg, char *prompt, int max_prompt); CAT *get_catalog_resource(UAContext *ua); -STORE *get_storage_resource(UAContext *ua, int use_default); +STORE *get_storage_resource(UAContext *ua, bool use_default); int get_media_type(UAContext *ua, char *MediaType, int max_media); bool get_pool_dbr(UAContext *ua, POOL_DBR *pr); int get_client_dbr(UAContext *ua, CLIENT_DBR *cr); diff --git a/bacula/src/dird/ua_cmds.c b/bacula/src/dird/ua_cmds.c index 04f8672e78..692a7b69ed 100644 --- a/bacula/src/dird/ua_cmds.c +++ b/bacula/src/dird/ua_cmds.c @@ -222,7 +222,7 @@ static int add_cmd(UAContext *ua, const char *cmd) } /* Get media type */ - if ((store = get_storage_resource(ua, 0)) != NULL) { + if ((store = get_storage_resource(ua, false/*no default*/)) != NULL) { bstrncpy(mr.MediaType, store->media_type, sizeof(mr.MediaType)); } else if (!get_media_type(ua, mr.MediaType, sizeof(mr.MediaType))) { return 1; @@ -813,7 +813,7 @@ static int setdebug_cmd(UAContext *ua, const char *cmd) return 1; } } - store = get_storage_resource(ua, 0); + store = get_storage_resource(ua, false/*no default*/); if (store) { do_storage_setdebug(ua, store, level, trace_flag); return 1; @@ -835,7 +835,7 @@ static int setdebug_cmd(UAContext *ua, const char *cmd) set_trace(trace_flag); break; case 1: - store = get_storage_resource(ua, 0); + store = get_storage_resource(ua, false/*no default*/); if (store) { do_storage_setdebug(ua, store, level, trace_flag); } @@ -1246,19 +1246,21 @@ static void do_mount_cmd(UAContext *ua, const char *command) BSOCK *sd; JCR *jcr = ua->jcr; char dev_name[MAX_NAME_LENGTH]; + int drive; if (!open_db(ua)) { return; } Dmsg2(120, "%s: %s\n", command, ua->UA_sock->msg); - store = get_storage_resource(ua, 1); + store = get_storage_resource(ua, true/*use default*/); if (!store) { return; } + drive = ua->int32_val; - Dmsg2(120, "Found storage, MediaType=%s DevName=%s\n", - store->media_type, store->dev_name()); + Dmsg3(120, "Found storage, MediaType=%s DevName=%s drive=%d\n", + store->media_type, store->dev_name(), drive); set_storage(jcr, store); if (!connect_to_storage_daemon(jcr, 10, SDConnectTimeout, 1)) { @@ -1268,7 +1270,7 @@ static void do_mount_cmd(UAContext *ua, const char *command) sd = jcr->store_bsock; bstrncpy(dev_name, store->dev_name(), sizeof(dev_name)); bash_spaces(dev_name); - bnet_fsend(sd, "%s %s", command, dev_name); + bnet_fsend(sd, "%s %s drive=%d", command, dev_name, drive); while (bnet_recv(sd) >= 0) { bsendmsg(ua, "%s", sd->msg); } @@ -1278,7 +1280,7 @@ static void do_mount_cmd(UAContext *ua, const char *command) } /* - * mount [storage | device] + * mount [storage=] [drive=nn] */ static int mount_cmd(UAContext *ua, const char *cmd) { @@ -1288,7 +1290,7 @@ static int mount_cmd(UAContext *ua, const char *cmd) /* - * unmount [storage | device] + * unmount [storage=] [drive=nn] */ static int unmount_cmd(UAContext *ua, const char *cmd) { @@ -1298,7 +1300,7 @@ static int unmount_cmd(UAContext *ua, const char *cmd) /* - * release [storage | device] + * release [storage=] [drive=nn] */ static int release_cmd(UAContext *ua, const char *cmd) { diff --git a/bacula/src/dird/ua_label.c b/bacula/src/dird/ua_label.c index 408f04f540..41e6a6ed08 100644 --- a/bacula/src/dird/ua_label.c +++ b/bacula/src/dird/ua_label.c @@ -34,15 +34,15 @@ typedef struct s_vol_list { /* Forward referenced functions */ static int do_label(UAContext *ua, const char *cmd, int relabel); -static void label_from_barcodes(UAContext *ua); +static void label_from_barcodes(UAContext *ua, int drive); static bool send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr, - POOL_DBR *pr, int relabel, bool media_record_exits); + POOL_DBR *pr, int relabel, bool media_record_exits, int drive); static vol_list_t *get_vol_list_from_SD(UAContext *ua, bool scan); static void free_vol_list(vol_list_t *vol_list); static bool is_cleaning_tape(UAContext *ua, MEDIA_DBR *mr, POOL_DBR *pr); static BSOCK *open_sd_bsock(UAContext *ua); static void close_sd_bsock(UAContext *ua); -static char *get_volume_name_from_SD(UAContext *ua, int Slot); +static char *get_volume_name_from_SD(UAContext *ua, int Slot, int drive); static int get_num_slots_from_SD(UAContext *ua); @@ -156,6 +156,7 @@ int update_slots(UAContext *ua) char *slot_list; bool scan; int max_slots; + int drive = -1; if (!open_db(ua)) { @@ -205,7 +206,7 @@ int update_slots(UAContext *ua) free(vl->VolName); vl->VolName = NULL; } - vl->VolName = get_volume_name_from_SD(ua, vl->Slot); + vl->VolName = get_volume_name_from_SD(ua, vl->Slot, drive); Dmsg2(100, "Got Vol=%s from SD for Slot=%d\n", vl->VolName, vl->Slot); } slot_list[vl->Slot] = 0; /* clear Slot */ @@ -285,6 +286,7 @@ static int do_label(UAContext *ua, const char *cmd, int relabel) bool print_reminder = true; int ok = FALSE; int i; + int drive; bool media_record_exists = false; static const char *barcode_keyword[] = { "barcode", @@ -296,14 +298,15 @@ static int do_label(UAContext *ua, const char *cmd, int relabel) if (!open_db(ua)) { return 1; } - store = get_storage_resource(ua, 1); + store = get_storage_resource(ua, true/*use default*/); if (!store) { return 1; } + drive = ua->int32_val; set_storage(ua->jcr, store); if (!relabel && find_arg_keyword(ua, barcode_keyword) >= 0) { - label_from_barcodes(ua); + label_from_barcodes(ua, drive); return 1; } @@ -389,7 +392,7 @@ checkName: } } - ok = send_label_request(ua, &mr, &omr, &pr, relabel, media_record_exists); + ok = send_label_request(ua, &mr, &omr, &pr, relabel, media_record_exists, drive); if (ok) { sd = ua->jcr->store_bsock; @@ -412,7 +415,7 @@ checkName: bstrncpy(dev_name, store->dev_name(), sizeof(dev_name)); bsendmsg(ua, _("Requesting to mount %s ...\n"), dev_name); bash_spaces(dev_name); - bnet_fsend(sd, "mount %s", dev_name); + bnet_fsend(sd, "mount %s drive=%d", dev_name, drive); unbash_spaces(dev_name); while (bnet_recv(sd) >= 0) { bsendmsg(ua, "%s", sd->msg); @@ -443,7 +446,7 @@ checkName: * Request SD to send us the slot:barcodes, then wiffle * through them all labeling them. */ -static void label_from_barcodes(UAContext *ua) +static void label_from_barcodes(UAContext *ua, int drive) { STORE *store = ua->jcr->store; POOL_DBR pr; @@ -548,7 +551,7 @@ static void label_from_barcodes(UAContext *ua) bstrncpy(mr.MediaType, store->media_type, sizeof(mr.MediaType)); mr.Slot = vl->Slot; - send_label_request(ua, &mr, &omr, &pr, 0, media_record_exists); + send_label_request(ua, &mr, &omr, &pr, 0, media_record_exists, drive); } @@ -600,7 +603,8 @@ bool is_volume_name_legal(UAContext *ua, const char *name) * NOTE! This routine opens the SD socket but leaves it open */ static bool send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr, - POOL_DBR *pr, int relabel, bool media_record_exists) + POOL_DBR *pr, int relabel, bool media_record_exists, + int drive) { BSOCK *sd; char dev_name[MAX_NAME_LENGTH]; @@ -616,17 +620,21 @@ static bool send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr, bash_spaces(pr->Name); if (relabel) { bash_spaces(omr->VolumeName); - bnet_fsend(sd, "relabel %s OldName=%s NewName=%s PoolName=%s MediaType=%s Slot=%d", - dev_name, omr->VolumeName, mr->VolumeName, pr->Name, mr->MediaType, mr->Slot); + bnet_fsend(sd, "relabel %s OldName=%s NewName=%s PoolName=%s " + "MediaType=%s Slot=%d drive=%d", + dev_name, omr->VolumeName, mr->VolumeName, pr->Name, + mr->MediaType, mr->Slot, drive); bsendmsg(ua, _("Sending relabel command from \"%s\" to \"%s\" ...\n"), omr->VolumeName, mr->VolumeName); } else { - bnet_fsend(sd, "label %s VolumeName=%s PoolName=%s MediaType=%s Slot=%d", - dev_name, mr->VolumeName, pr->Name, mr->MediaType, mr->Slot); + bnet_fsend(sd, "label %s VolumeName=%s PoolName=%s MediaType=%s " + "Slot=%d drive=%d", + dev_name, mr->VolumeName, pr->Name, mr->MediaType, + mr->Slot, drive); bsendmsg(ua, _("Sending label command for Volume \"%s\" Slot %d ...\n"), mr->VolumeName, mr->Slot); - Dmsg5(100, "label %s VolumeName=%s PoolName=%s MediaType=%s Slot=%d\n", - dev_name, mr->VolumeName, pr->Name, mr->MediaType, mr->Slot); + Dmsg6(100, "label %s VolumeName=%s PoolName=%s MediaType=%s Slot=%d drive=%d\n", + dev_name, mr->VolumeName, pr->Name, mr->MediaType, mr->Slot, drive); } while (bnet_recv(sd) >= 0) { @@ -695,7 +703,7 @@ static void close_sd_bsock(UAContext *ua) } } -static char *get_volume_name_from_SD(UAContext *ua, int Slot) +static char *get_volume_name_from_SD(UAContext *ua, int Slot, int drive) { STORE *store = ua->jcr->store; BSOCK *sd; @@ -710,7 +718,7 @@ static char *get_volume_name_from_SD(UAContext *ua, int Slot) bstrncpy(dev_name, store->dev_name(), sizeof(dev_name)); bash_spaces(dev_name); /* Ask for autochanger list of volumes */ - bnet_fsend(sd, _("readlabel %s Slot=%d\n"), dev_name, Slot); + bnet_fsend(sd, _("readlabel %s Slot=%d drive=%d\n"), dev_name, Slot, drive); Dmsg1(100, "Sent: %s", sd->msg); /* Get Volume name in this Slot */ diff --git a/bacula/src/dird/ua_select.c b/bacula/src/dird/ua_select.c index 5409ee49b3..2b576d5f34 100644 --- a/bacula/src/dird/ua_select.c +++ b/bacula/src/dird/ua_select.c @@ -756,7 +756,7 @@ done: * If use_default is set, we assume that any keyword without a value * is the name of the Storage resource wanted. */ -STORE *get_storage_resource(UAContext *ua, int use_default) +STORE *get_storage_resource(UAContext *ua, bool use_default) { char *store_name = NULL; STORE *store = NULL; @@ -765,13 +765,16 @@ STORE *get_storage_resource(UAContext *ua, int use_default) int i; char ed1[50]; - + ua->int32_val = -2; /* dummy */ for (i=1; iargc; i++) { + if (strcasecmp("drive", ua->argk[i]) == 0 && ua->argv[i]) { + ua->int32_val = atoi(ua->argv[i]); + } if (use_default && !ua->argv[i]) { /* Ignore slots, scan and barcode(s) keywords */ - if (strncasecmp("scan", ua->argk[i], 4) == 0 || - strncasecmp("barcode", ua->argk[i], 7) == 0 || - strncasecmp("slots", ua->argk[i], 5) == 0) { + if (strcasecmp("scan", ua->argk[i]) == 0 || + strcasecmp("barcode", ua->argk[i]) == 0 || + strcasecmp("slots", ua->argk[i]) == 0) { continue; } /* Default argument is storage */ @@ -836,6 +839,15 @@ STORE *get_storage_resource(UAContext *ua, int use_default) if (!store) { store = select_storage_resource(ua); } + /* Get drive for autochanger if possible */ + if (store && store->autochanger && ua->int32_val == -2) { + ua->cmd[0] = 0; + if (!get_cmd(ua, _("Enter autochanger drive [0]: "))) { + ua->int32_val = -1; /* None */ + } else { + ua->int32_val = atoi(ua->cmd); + } + } return store; } diff --git a/bacula/src/stored/dircmd.c b/bacula/src/stored/dircmd.c index 9166d1fd6e..7f40b79971 100644 --- a/bacula/src/stored/dircmd.c +++ b/bacula/src/stored/dircmd.c @@ -73,7 +73,7 @@ static bool mount_cmd(JCR *jcr); static bool unmount_cmd(JCR *jcr); static bool autochanger_cmd(JCR *sjcr); static bool do_label(JCR *jcr, int relabel); -static DEVICE *find_device(JCR *jcr, POOL_MEM &dev_name); +static DEVICE *find_device(JCR *jcr, POOL_MEM &dev_name, int drive); static void read_volume_label(JCR *jcr, DEVICE *dev, int Slot); static void label_volume_if_ok(JCR *jcr, DEVICE *dev, char *oldname, char *newname, char *poolname, @@ -308,20 +308,24 @@ static bool do_label(JCR *jcr, int relabel) DEVICE *dev; bool ok = false; int slot; + int drive; newname = get_memory(dir->msglen+1); oldname = get_memory(dir->msglen+1); poolname = get_memory(dir->msglen+1); mtype = get_memory(dir->msglen+1); if (relabel) { - if (sscanf(dir->msg, "relabel %127s OldName=%127s NewName=%127s PoolName=%127s MediaType=%127s Slot=%d", - dev_name.c_str(), oldname, newname, poolname, mtype, &slot) == 6) { + if (sscanf(dir->msg, "relabel %127s OldName=%127s NewName=%127s PoolName=%127s " + "MediaType=%127s Slot=%d drive=%d", + dev_name.c_str(), oldname, newname, poolname, mtype, + &slot, &drive) == 7) { ok = true; } } else { *oldname = 0; - if (sscanf(dir->msg, "label %127s VolumeName=%127s PoolName=%127s MediaType=%127s Slot=%d", - dev_name.c_str(), newname, poolname, mtype, &slot) == 5) { + if (sscanf(dir->msg, "label %127s VolumeName=%127s PoolName=%127s " + "MediaType=%127s Slot=%d drive=%d", + dev_name.c_str(), newname, poolname, mtype, &slot, &drive) == 6) { ok = true; } } @@ -330,7 +334,7 @@ static bool do_label(JCR *jcr, int relabel) unbash_spaces(oldname); unbash_spaces(poolname); unbash_spaces(mtype); - dev = find_device(jcr, dev_name); + dev = find_device(jcr, dev_name, drive); if (dev) { P(dev->mutex); /* Use P to avoid indefinite block */ if (!dev->is_open()) { @@ -474,7 +478,7 @@ static bool read_label(DCR *dcr) return ok; } -static DEVICE *find_device(JCR *jcr, POOL_MEM &devname) +static DEVICE *find_device(JCR *jcr, POOL_MEM &devname, int drive) { DEVRES *device; AUTOCHANGER *changer; @@ -517,9 +521,11 @@ static DEVICE *find_device(JCR *jcr, POOL_MEM &devname) if (!device->dev->autoselect) { continue; /* device is not available */ } - Dmsg1(20, "Found changer device %s\n", device->hdr.name); - found = true; - break; + if (drive < 0 || drive == (int)device->dev->drive_index) { + Dmsg1(20, "Found changer device %s\n", device->hdr.name); + found = true; + break; + } } break; /* we found it but could not open a device */ } @@ -543,9 +549,10 @@ static bool mount_cmd(JCR *jcr) BSOCK *dir = jcr->dir_bsock; DEVICE *dev; DCR *dcr; + int drive; - if (sscanf(dir->msg, "mount %127s", devname.c_str()) == 1) { - dev = find_device(jcr, devname); + if (sscanf(dir->msg, "mount %127s drive=%d", devname.c_str(), &drive) == 2) { + dev = find_device(jcr, devname, drive); dcr = jcr->dcr; if (dev) { P(dev->mutex); /* Use P to avoid indefinite block */ @@ -663,9 +670,10 @@ static bool unmount_cmd(JCR *jcr) POOL_MEM devname; BSOCK *dir = jcr->dir_bsock; DEVICE *dev; + int drive; - if (sscanf(dir->msg, "unmount %127s", devname.c_str()) == 1) { - dev = find_device(jcr, devname); + if (sscanf(dir->msg, "unmount %127s drive=%d", devname.c_str(), &drive) == 2) { + dev = find_device(jcr, devname, drive); if (dev) { P(dev->mutex); /* Use P to avoid indefinite block */ if (!dev->is_open()) { @@ -732,9 +740,10 @@ static bool release_cmd(JCR *jcr) POOL_MEM devname; BSOCK *dir = jcr->dir_bsock; DEVICE *dev; + int drive; - if (sscanf(dir->msg, "release %127s", devname.c_str()) == 1) { - dev = find_device(jcr, devname); + if (sscanf(dir->msg, "release %127s drive=%d", devname.c_str(), &drive) == 2) { + dev = find_device(jcr, devname, drive); if (dev) { P(dev->mutex); /* Use P to avoid indefinite block */ if (!dev->is_open()) { @@ -800,17 +809,15 @@ static bool autochanger_cmd(JCR *jcr) ok = true; } if (ok) { - dev = find_device(jcr, devname); + dev = find_device(jcr, devname, -1); dcr = jcr->dcr; if (dev) { P(dev->mutex); /* Use P to avoid indefinite block */ if (!dev->is_tape()) { bnet_fsend(dir, _("3995 Device %s is not an autochanger.\n"), dev->print_name()); - } else if (!dev->is_open()) { - autochanger_cmd(dcr, dir, cmd); /* Under certain "safe" conditions, we can steal the lock */ - } else if (dev->can_steal_lock()) { + } else if (!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); @@ -839,9 +846,11 @@ static bool readlabel_cmd(JCR *jcr) BSOCK *dir = jcr->dir_bsock; DEVICE *dev; int Slot; + int drive; - if (sscanf(dir->msg, "readlabel %127s Slot=%d", devname.c_str(), &Slot) == 2) { - dev = find_device(jcr, devname); + if (sscanf(dir->msg, "readlabel %127s Slot=%d drive=%d", devname.c_str(), + &Slot, &drive) == 3) { + dev = find_device(jcr, devname, drive); if (dev) { P(dev->mutex); /* Use P to avoid indefinite block */ if (!dev->is_open()) { diff --git a/bacula/src/version.h b/bacula/src/version.h index 619d25ca99..c01e52562b 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -1,8 +1,8 @@ /* */ #undef VERSION -#define VERSION "1.37.35" -#define BDATE "12 August 2005" -#define LSMDATE "12Aug05" +#define VERSION "1.37.36" +#define BDATE "13 August 2005" +#define LSMDATE "13Aug05" /* Debug flags */ #undef DEBUG