From: Kern Sibbald Date: Mon, 7 Apr 2003 13:07:49 +0000 (+0000) Subject: Implement update slots command X-Git-Tag: Release-1.30~41 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=ea7a3095983e859272a7e8a90fd5fc7af6547c75;p=bacula%2Fbacula Implement update slots command git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@426 91ce42f0-d328-0410-95d8-f526ca767f89 --- diff --git a/bacula/kernstodo b/bacula/kernstodo index 629994c64e..5d700d6d66 100644 --- a/bacula/kernstodo +++ b/bacula/kernstodo @@ -20,8 +20,7 @@ Testing to do: (painful) - multiple simultaneous Volumes For 1.30 release: -- Label barcodes prints - Storage resource barcodes: not found +- Update volume=Test01 requests pool, then lists volumes. - Add IP address to authentication failures. Implement M_SECURITY message class. - Remove kern and kelvin from mysql_grant... diff --git a/bacula/src/dird/protos.h b/bacula/src/dird/protos.h index 5364cc1311..bb35959ff6 100644 --- a/bacula/src/dird/protos.h +++ b/bacula/src/dird/protos.h @@ -111,7 +111,7 @@ void start_prompt(UAContext *ua, char *msg); void add_prompt(UAContext *ua, char *prompt); int do_prompt(UAContext *ua, char *msg, char *prompt, int max_prompt); CAT *get_catalog_resource(UAContext *ua); -STORE *get_storage_resource(UAContext *ua, char *cmd, int use_default); +STORE *get_storage_resource(UAContext *ua, int use_default); int get_media_type(UAContext *ua, char *MediaType, int max_media); int 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 e3ca14c7b5..0c479ccd7c 100644 --- a/bacula/src/dird/ua_cmds.c +++ b/bacula/src/dird/ua_cmds.c @@ -60,6 +60,7 @@ extern int purgecmd(UAContext *ua, char *cmd); extern int restorecmd(UAContext *ua, char *cmd); extern int labelcmd(UAContext *ua, char *cmd); extern int relabelcmd(UAContext *ua, char *cmd); +extern int update_slots(UAContext *ua); /* ua_label.c */ /* Forward referenced functions */ static int addcmd(UAContext *ua, char *cmd), createcmd(UAContext *ua, char *cmd), cancelcmd(UAContext *ua, char *cmd); @@ -211,7 +212,7 @@ static int addcmd(UAContext *ua, char *cmd) } /* Get media type */ - if ((store = get_storage_resource(ua, cmd, 0)) != NULL) { + if ((store = get_storage_resource(ua, 0)) != NULL) { strcpy(mr.MediaType, store->media_type); } else if (!get_media_type(ua, mr.MediaType, sizeof(mr.MediaType))) { return 1; @@ -595,9 +596,10 @@ Use update to change it.\n"), pool->hdr.name); static int updatecmd(UAContext *ua, char *cmd) { static char *kw[] = { - N_("media"), - N_("volume"), - N_("pool"), + N_("media"), /* 0 */ + N_("volume"), /* 1 */ + N_("pool"), /* 2 */ + N_("slots"), /* 3 */ NULL}; if (!open_db(ua)) { @@ -612,6 +614,9 @@ static int updatecmd(UAContext *ua, char *cmd) case 2: update_pool(ua); return 1; + case 3: + update_slots(ua); + return 1; default: break; } @@ -619,6 +624,7 @@ static int updatecmd(UAContext *ua, char *cmd) start_prompt(ua, _("Update choice:\n")); add_prompt(ua, _("Volume parameters")); add_prompt(ua, _("Pool from resource")); + add_prompt(ua, _("Slots from autochanger")); switch (do_prompt(ua, _("Choose catalog item to update"), NULL, 0)) { case 0: update_volume(ua); @@ -626,6 +632,9 @@ static int updatecmd(UAContext *ua, char *cmd) case 1: update_pool(ua); break; + case 2: + update_slots(ua); + break; default: break; } @@ -1134,7 +1143,7 @@ static int setdebugcmd(UAContext *ua, char *cmd) return 1; } } - store = get_storage_resource(ua, cmd, 0); + store = get_storage_resource(ua, 0); if (store) { do_storage_setdebug(ua, store, level); return 1; @@ -1155,7 +1164,7 @@ static int setdebugcmd(UAContext *ua, char *cmd) debug_level = level; break; case 1: - store = get_storage_resource(ua, cmd, 0); + store = get_storage_resource(ua, 0); if (store) { do_storage_setdebug(ua, store, level); } @@ -1294,7 +1303,7 @@ static void do_mount_cmd(int mount, UAContext *ua, char *cmd) } Dmsg1(120, "mount: %s\n", ua->UA_sock->msg); - store = get_storage_resource(ua, cmd, 1); + store = get_storage_resource(ua, 1); if (!store) { return; } diff --git a/bacula/src/dird/ua_label.c b/bacula/src/dird/ua_label.c index 47dbba13a5..a27a844dd1 100644 --- a/bacula/src/dird/ua_label.c +++ b/bacula/src/dird/ua_label.c @@ -30,12 +30,21 @@ #include "bacula.h" #include "dird.h" +/* Slot list definition */ +typedef struct s_vol_list { + struct s_vol_list *next; + char *VolName; + int Slot; +} vol_list_t; + + /* Forward referenced functions */ static int do_label(UAContext *ua, char *cmd, int relabel); static void label_from_barcodes(UAContext *ua); static int is_legal_volume_name(UAContext *ua, char *name); static int send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr, POOL_DBR *pr, int relabel); +static vol_list_t *get_slot_list_from_SD(UAContext *ua); /* @@ -54,6 +63,77 @@ int relabelcmd(UAContext *ua, char *cmd) } +/* + * Update Slots corresponding to Volumes in autochanger + */ +int update_slots(UAContext *ua) +{ + STORE *store; + vol_list_t *vl, *vol_list = NULL; + MEDIA_DBR mr; + + if (!open_db(ua)) { + return 1; + } + store = get_storage_resource(ua, 1); + if (!store) { + return 1; + } + ua->jcr->store = store; + + vol_list = get_slot_list_from_SD(ua); + + + if (!vol_list) { + bsendmsg(ua, _("No Volumes found to label, or no barcodes.\n")); + goto bail_out; + } + + /* Walk through the list updating the media records */ + for (vl=vol_list; vl; vl=vl->next) { + + memset(&mr, 0, sizeof(mr)); + bstrncpy(mr.VolumeName, vl->VolName, sizeof(mr.VolumeName)); + if (db_get_media_record(ua->jcr, ua->db, &mr)) { + if (mr.Slot != vl->Slot) { + mr.Slot = vl->Slot; + if (!db_update_media_record(ua->jcr, ua->db, &mr)) { + bsendmsg(ua, _("%s\n"), db_strerror(ua->db)); + } else { + bsendmsg(ua, _( + "Catalog record for Volume \"%s\" updated to reference slot %d.\n"), + mr.Slot); + } + } else { + bsendmsg(ua, _("Catalog record for Volume \"%s\" is up to date.\n"), + mr.VolumeName); + } + continue; + } else { + bsendmsg(ua, _("Record for Volume \"%s\" not found in catalog.\n"), + mr.VolumeName); + } + } + + +bail_out: + /* Free list */ + for (vl=vol_list; vl; ) { + vol_list_t *ovl; + free(vl->VolName); + ovl = vl; + vl = vl->next; + free(ovl); + } + + if (ua->jcr->store_bsock) { + bnet_sig(ua->jcr->store_bsock, BNET_TERMINATE); + bnet_close(ua->jcr->store_bsock); + ua->jcr->store_bsock = NULL; + } + return 1; +} + /* * Common routine for both label and relabel */ @@ -84,7 +164,7 @@ static int do_label(UAContext *ua, char *cmd, int relabel) if (!open_db(ua)) { return 1; } - store = get_storage_resource(ua, cmd, 1); + store = get_storage_resource(ua, 1); if (!store) { return 1; } @@ -224,78 +304,12 @@ checkName: static void label_from_barcodes(UAContext *ua) { STORE *store = ua->jcr->store; - BSOCK *sd; POOL_DBR pr; - char dev_name[MAX_NAME_LENGTH]; MEDIA_DBR mr, omr; - typedef struct s_vol_list { - struct s_vol_list *next; - char *VolName; - int Slot; - } vol_list_t; - vol_list_t *vol_list = NULL; - vol_list_t *vl; + vol_list_t *vl, *vol_list = NULL; - bsendmsg(ua, _("Connecting to Storage daemon %s at %s:%d ...\n"), - store->hdr.name, store->address, store->SDport); - if (!connect_to_storage_daemon(ua->jcr, 10, SDConnectTimeout, 1)) { - bsendmsg(ua, _("Failed to connect to Storage daemon.\n")); - return; - } - sd = ua->jcr->store_bsock; - - bstrncpy(dev_name, store->dev_name, sizeof(dev_name)); - bash_spaces(dev_name); - /* Ask for autochanger list of volumes */ - bnet_fsend(sd, _("autochanger list %s \n"), dev_name); - - /* Read and organize list of Volumes */ - while (bget_msg(sd, 0) >= 0) { - char *p; - int Slot; - strip_trailing_junk(sd->msg); - - /* Check for returned SD messages */ - if (sd->msg[0] == '3' && sd->msg[1] == '9' && - B_ISDIGIT(sd->msg[2]) && B_ISDIGIT(sd->msg[3]) && - sd->msg[4] == ' ') { - bsendmsg(ua, "%s\n", sd->msg); /* pass them on to user */ - continue; - } - - /* Validate Slot:Barcode */ - p = strchr(sd->msg, ':'); - if (p && strlen(p) > 1) { - *p++ = 0; - if (!is_an_integer(sd->msg)) { - continue; - } - } else { - continue; - } - Slot = atoi(sd->msg); - if (Slot <= 0 || !is_legal_volume_name(ua, p)) { - continue; - } + vol_list = get_slot_list_from_SD(ua); - /* Add Slot and VolumeName to list */ - vl = (vol_list_t *)malloc(sizeof(vol_list_t)); - vl->Slot = Slot; - vl->VolName = bstrdup(p); - if (!vol_list) { - vl->next = vol_list; - vol_list = vl; - } else { - /* Add new entry to end of list */ - for (vol_list_t *tvl=vol_list; tvl; tvl=tvl->next) { - if (!tvl->next) { - tvl->next = vl; - vl->next = NULL; - break; - } - } - } - } if (!vol_list) { bsendmsg(ua, _("No Volumes found to label, or no barcodes.\n")); @@ -332,8 +346,8 @@ static void label_from_barcodes(UAContext *ua) } bstrncpy(mr.MediaType, store->media_type, sizeof(mr.MediaType)); if (ua->jcr->store_bsock) { - bnet_sig(sd, BNET_TERMINATE); - bnet_close(sd); + bnet_sig(ua->jcr->store_bsock, BNET_TERMINATE); + bnet_close(ua->jcr->store_bsock); ua->jcr->store_bsock = NULL; } bsendmsg(ua, _("Connecting to Storage daemon %s at %s:%d ...\n"), @@ -342,7 +356,6 @@ static void label_from_barcodes(UAContext *ua) bsendmsg(ua, _("Failed to connect to Storage daemon.\n")); goto bail_out; } - sd = ua->jcr->store_bsock; mr.Slot = vl->Slot; send_label_request(ua, &mr, &omr, &pr, 0); @@ -360,8 +373,8 @@ bail_out: } if (ua->jcr->store_bsock) { - bnet_sig(sd, BNET_TERMINATE); - bnet_close(sd); + bnet_sig(ua->jcr->store_bsock, BNET_TERMINATE); + bnet_close(ua->jcr->store_bsock); ua->jcr->store_bsock = NULL; } @@ -439,3 +452,75 @@ static int send_label_request(UAContext *ua, MEDIA_DBR *mr, MEDIA_DBR *omr, } return ok; } + +static vol_list_t *get_slot_list_from_SD(UAContext *ua) +{ + STORE *store = ua->jcr->store; + char dev_name[MAX_NAME_LENGTH]; + BSOCK *sd; + vol_list_t *vl; + vol_list_t *vol_list = NULL; + + + bsendmsg(ua, _("Connecting to Storage daemon %s at %s:%d ...\n"), + store->hdr.name, store->address, store->SDport); + if (!connect_to_storage_daemon(ua->jcr, 10, SDConnectTimeout, 1)) { + bsendmsg(ua, _("Failed to connect to Storage daemon.\n")); + return NULL; + } + sd = ua->jcr->store_bsock; + + bstrncpy(dev_name, store->dev_name, sizeof(dev_name)); + bash_spaces(dev_name); + /* Ask for autochanger list of volumes */ + bnet_fsend(sd, _("autochanger list %s \n"), dev_name); + + /* Read and organize list of Volumes */ + while (bget_msg(sd, 0) >= 0) { + char *p; + int Slot; + strip_trailing_junk(sd->msg); + + /* Check for returned SD messages */ + if (sd->msg[0] == '3' && sd->msg[1] == '9' && + B_ISDIGIT(sd->msg[2]) && B_ISDIGIT(sd->msg[3]) && + sd->msg[4] == ' ') { + bsendmsg(ua, "%s\n", sd->msg); /* pass them on to user */ + continue; + } + + /* Validate Slot:Barcode */ + p = strchr(sd->msg, ':'); + if (p && strlen(p) > 1) { + *p++ = 0; + if (!is_an_integer(sd->msg)) { + continue; + } + } else { + continue; + } + Slot = atoi(sd->msg); + if (Slot <= 0 || !is_legal_volume_name(ua, p)) { + continue; + } + + /* Add Slot and VolumeName to list */ + vl = (vol_list_t *)malloc(sizeof(vol_list_t)); + vl->Slot = Slot; + vl->VolName = bstrdup(p); + if (!vol_list) { + vl->next = vol_list; + vol_list = vl; + } else { + /* Add new entry to end of list */ + for (vol_list_t *tvl=vol_list; tvl; tvl=tvl->next) { + if (!tvl->next) { + tvl->next = vl; + vl->next = NULL; + break; + } + } + } + } + return vol_list; +} diff --git a/bacula/src/dird/ua_select.c b/bacula/src/dird/ua_select.c index 5c99a18e25..6965095727 100644 --- a/bacula/src/dird/ua_select.c +++ b/bacula/src/dird/ua_select.c @@ -669,7 +669,7 @@ int do_prompt(UAContext *ua, char *msg, char *prompt, int max_prompt) * 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, char *cmd, int use_default) +STORE *get_storage_resource(UAContext *ua, int use_default) { char *store_name = NULL; STORE *store = NULL; diff --git a/bacula/src/dird/ua_status.c b/bacula/src/dird/ua_status.c index 75baaa34db..4cb06736c9 100644 --- a/bacula/src/dird/ua_status.c +++ b/bacula/src/dird/ua_status.c @@ -69,7 +69,7 @@ int statuscmd(UAContext *ua, char *cmd) } return 1; } else { - store = get_storage_resource(ua, cmd, 0); + store = get_storage_resource(ua, 0); if (store) { do_storage_status(ua, store); } diff --git a/bacula/src/stored/btape.c b/bacula/src/stored/btape.c index 983100f2a1..d2ee892822 100644 --- a/bacula/src/stored/btape.c +++ b/bacula/src/stored/btape.c @@ -645,13 +645,7 @@ static int re_read_block_test() } for (int i=0; idata[i] != 3) { - Pmsg0(0, _("Bad data in record. Test failed!\n" - "This is not terribly serious since Bacula only uses\n" - "This function to verify the last block written to the\n" - "tape. Bacula will skip the last block verification\n" - "if you add:\n\n" - "Backward Space Record = No\n\n" - "to your Storage daemon's Device resource definition.\n")); + Pmsg0(0, _("Bad data in record. Test failed!\n")); goto bail_out; } } @@ -663,6 +657,14 @@ static int re_read_block_test() bail_out: free_block(block); free_record(rec); + if (stat == 0) { + Pmsg0(0, _("This is not terribly serious since Bacula only uses\n" + "this function to verify the last block written to the\n" + "tape. Bacula will skip the last block verification\n" + "if you add:\n\n" + "Backward Space Record = No\n\n" + "to your Storage daemon's Device resource definition.\n")); + } return stat; }