2 Bacula® - The Network Backup Solution
4 Copyright (C) 2000-2012 Free Software Foundation Europe e.V.
6 The main author of Bacula is Kern Sibbald, with contributions from
7 many others, a complete list can be found in the file AUTHORS.
8 This program is Free Software; you can redistribute it and/or
9 modify it under the terms of version three of the GNU Affero General Public
10 License as published by the Free Software Foundation and included
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU Affero General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 Bacula® is a registered trademark of Kern Sibbald.
24 The licensor of Bacula is the Free Software Foundation Europe
25 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26 Switzerland, email:ftf@fsfeurope.org.
30 * Bacula Director -- Update command processing
31 * Split from ua_cmds.c March 2005
33 * Kern Sibbald, September MM
40 /* Forward referenced functions */
41 static int update_volume(UAContext *ua);
42 static bool update_pool(UAContext *ua);
43 static bool update_job(UAContext *ua);
44 static bool update_stats(UAContext *ua);
47 * Update a Pool Record in the database.
48 * It is always updated from the Resource record.
50 * update pool=<pool-name>
51 * updates pool from Pool resource
52 * update media pool=<pool-name> volume=<volume-name>
53 * changes pool info for volume
54 * update slots [scan=...]
55 * updates autochanger slots
56 * update stats [days=...]
57 * updates long term statistics
59 int update_cmd(UAContext *ua, const char *cmd)
61 static const char *kw[] = {
63 NT_("volume"), /* 1 */
71 if (!open_client_db(ua)) {
75 switch (find_arg_keyword(ua, kw)) {
97 start_prompt(ua, _("Update choice:\n"));
98 add_prompt(ua, _("Volume parameters"));
99 add_prompt(ua, _("Pool from resource"));
100 add_prompt(ua, _("Slots from autochanger"));
101 add_prompt(ua, _("Long term statistics"));
102 switch (do_prompt(ua, _("item"), _("Choose catalog item to update"), NULL, 0)) {
121 static void update_volstatus(UAContext *ua, const char *val, MEDIA_DBR *mr)
123 POOL_MEM query(PM_MESSAGE);
138 for (i=0; kw[i]; i++) {
139 if (strcasecmp(val, kw[i]) == 0) {
145 ua->error_msg(_("Invalid VolStatus specified: %s\n"), val);
148 bstrncpy(mr->VolStatus, kw[i], sizeof(mr->VolStatus));
149 Mmsg(query, "UPDATE Media SET VolStatus='%s' WHERE MediaId=%s",
150 mr->VolStatus, edit_int64(mr->MediaId,ed1));
151 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
152 ua->error_msg("%s", db_strerror(ua->db));
154 ua->info_msg(_("New Volume status is: %s\n"), mr->VolStatus);
159 static void update_volretention(UAContext *ua, char *val, MEDIA_DBR *mr)
161 char ed1[150], ed2[50];
162 POOL_MEM query(PM_MESSAGE);
163 if (!duration_to_utime(val, &mr->VolRetention)) {
164 ua->error_msg(_("Invalid retention period specified: %s\n"), val);
167 Mmsg(query, "UPDATE Media SET VolRetention=%s WHERE MediaId=%s",
168 edit_uint64(mr->VolRetention, ed1), edit_int64(mr->MediaId,ed2));
169 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
170 ua->error_msg("%s", db_strerror(ua->db));
172 ua->info_msg(_("New retention period is: %s\n"),
173 edit_utime(mr->VolRetention, ed1, sizeof(ed1)));
177 static void update_voluseduration(UAContext *ua, char *val, MEDIA_DBR *mr)
179 char ed1[150], ed2[50];
180 POOL_MEM query(PM_MESSAGE);
182 if (!duration_to_utime(val, &mr->VolUseDuration)) {
183 ua->error_msg(_("Invalid use duration specified: %s\n"), val);
186 Mmsg(query, "UPDATE Media SET VolUseDuration=%s WHERE MediaId=%s",
187 edit_uint64(mr->VolUseDuration, ed1), edit_int64(mr->MediaId,ed2));
188 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
189 ua->error_msg("%s", db_strerror(ua->db));
191 ua->info_msg(_("New use duration is: %s\n"),
192 edit_utime(mr->VolUseDuration, ed1, sizeof(ed1)));
196 static void update_volmaxjobs(UAContext *ua, char *val, MEDIA_DBR *mr)
198 POOL_MEM query(PM_MESSAGE);
200 Mmsg(query, "UPDATE Media SET MaxVolJobs=%s WHERE MediaId=%s",
201 val, edit_int64(mr->MediaId,ed1));
202 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
203 ua->error_msg("%s", db_strerror(ua->db));
205 ua->info_msg(_("New max jobs is: %s\n"), val);
209 static void update_volmaxfiles(UAContext *ua, char *val, MEDIA_DBR *mr)
211 POOL_MEM query(PM_MESSAGE);
213 Mmsg(query, "UPDATE Media SET MaxVolFiles=%s WHERE MediaId=%s",
214 val, edit_int64(mr->MediaId, ed1));
215 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
216 ua->error_msg("%s", db_strerror(ua->db));
218 ua->info_msg(_("New max files is: %s\n"), val);
222 static void update_volmaxbytes(UAContext *ua, char *val, MEDIA_DBR *mr)
225 char ed1[50], ed2[50];
226 POOL_MEM query(PM_MESSAGE);
228 if (!size_to_uint64(val, strlen(val), &maxbytes)) {
229 ua->error_msg(_("Invalid max. bytes specification: %s\n"), val);
232 Mmsg(query, "UPDATE Media SET MaxVolBytes=%s WHERE MediaId=%s",
233 edit_uint64(maxbytes, ed1), edit_int64(mr->MediaId, ed2));
234 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
235 ua->error_msg("%s", db_strerror(ua->db));
237 ua->info_msg(_("New Max bytes is: %s\n"), edit_uint64(maxbytes, ed1));
241 static void update_volrecycle(UAContext *ua, char *val, MEDIA_DBR *mr)
246 POOL_MEM query(PM_MESSAGE);
247 if (!is_yesno(val, &recycle)) {
248 ua->error_msg(_("Invalid value. It must be yes or no.\n"));
251 Mmsg(query, "UPDATE Media SET Recycle=%d WHERE MediaId=%s",
252 recycle, edit_int64(mr->MediaId, ed1));
253 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
254 ua->error_msg("%s", db_strerror(ua->db));
256 ua->info_msg(_("New Recycle flag is: %s\n"),
257 recycle==1?_("yes"):_("no"));
261 static void update_volinchanger(UAContext *ua, char *val, MEDIA_DBR *mr)
266 POOL_MEM query(PM_MESSAGE);
267 if (!is_yesno(val, &InChanger)) {
268 ua->error_msg(_("Invalid value. It must be yes or no.\n"));
271 Mmsg(query, "UPDATE Media SET InChanger=%d WHERE MediaId=%s",
272 InChanger, edit_int64(mr->MediaId, ed1));
273 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
274 ua->error_msg("%s", db_strerror(ua->db));
276 ua->info_msg(_("New InChanger flag is: %s\n"),
277 InChanger==1?_("yes"):_("no"));
282 static void update_volslot(UAContext *ua, char *val, MEDIA_DBR *mr)
286 memset(&pr, 0, sizeof(POOL_DBR));
287 pr.PoolId = mr->PoolId;
288 if (!db_get_pool_record(ua->jcr, ua->db, &pr)) {
289 ua->error_msg("%s", db_strerror(ua->db));
292 mr->Slot = atoi(val);
293 if (pr.MaxVols > 0 && mr->Slot > (int)pr.MaxVols) {
294 ua->error_msg(_("Invalid slot, it must be between 0 and MaxVols=%d\n"),
299 * Make sure to use db_update... rather than doing this directly,
300 * so that any Slot is handled correctly.
302 set_storageid_in_mr(NULL, mr);
303 if (!db_update_media_record(ua->jcr, ua->db, mr)) {
304 ua->error_msg(_("Error updating media record Slot: ERR=%s"), db_strerror(ua->db));
306 ua->info_msg(_("New Slot is: %d\n"), mr->Slot);
310 /* Modify the Pool in which this Volume is located */
311 void update_vol_pool(UAContext *ua, char *val, MEDIA_DBR *mr, POOL_DBR *opr)
314 POOL_MEM query(PM_MESSAGE);
315 char ed1[50], ed2[50];
317 memset(&pr, 0, sizeof(pr));
318 bstrncpy(pr.Name, val, sizeof(pr.Name));
319 if (!get_pool_dbr(ua, &pr)) {
322 mr->PoolId = pr.PoolId; /* set new PoolId */
326 Mmsg(query, "UPDATE Media SET PoolId=%s WHERE MediaId=%s",
327 edit_int64(mr->PoolId, ed1), edit_int64(mr->MediaId, ed2));
328 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
329 ua->error_msg("%s", db_strerror(ua->db));
331 ua->info_msg(_("New Pool is: %s\n"), pr.Name);
333 if (!db_update_pool_record(ua->jcr, ua->db, opr)) {
334 ua->error_msg("%s", db_strerror(ua->db));
337 if (!db_update_pool_record(ua->jcr, ua->db, &pr)) {
338 ua->error_msg("%s", db_strerror(ua->db));
344 /* Modify the RecyclePool of a Volume */
345 void update_vol_recyclepool(UAContext *ua, char *val, MEDIA_DBR *mr)
348 POOL_MEM query(PM_MESSAGE);
349 char ed1[50], ed2[50], *poolname;
351 if(val && *val) { /* update volume recyclepool="Scratch" */
352 /* If a pool name is given, look up the PoolId */
353 memset(&pr, 0, sizeof(pr));
354 bstrncpy(pr.Name, val, sizeof(pr.Name));
355 if (!get_pool_dbr(ua, &pr, NT_("recyclepool"))) {
358 /* pool = select_pool_resource(ua); */
359 mr->RecyclePoolId = pr.PoolId; /* get the PoolId */
362 } else { /* update volume recyclepool="" */
363 /* If no pool name is given, set the PoolId to 0 (the default) */
364 mr->RecyclePoolId = 0;
365 poolname = _("*None*");
369 Mmsg(query, "UPDATE Media SET RecyclePoolId=%s WHERE MediaId=%s",
370 edit_int64(mr->RecyclePoolId, ed1), edit_int64(mr->MediaId, ed2));
371 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
372 ua->error_msg("%s", db_strerror(ua->db));
374 ua->info_msg(_("New RecyclePool is: %s\n"), poolname);
380 * Refresh the Volume information from the Pool record
382 static void update_vol_from_pool(UAContext *ua, MEDIA_DBR *mr)
386 memset(&pr, 0, sizeof(pr));
387 pr.PoolId = mr->PoolId;
388 if (!db_get_pool_record(ua->jcr, ua->db, &pr) ||
389 !acl_access_ok(ua, Pool_ACL, pr.Name)) {
392 set_pool_dbr_defaults_in_media_dbr(mr, &pr);
393 if (!db_update_media_defaults(ua->jcr, ua->db, mr)) {
394 ua->error_msg(_("Error updating Volume record: ERR=%s"), db_strerror(ua->db));
396 ua->info_msg(_("Volume defaults updated from \"%s\" Pool record.\n"),
402 * Refresh the Volume information from the Pool record
405 static void update_all_vols_from_pool(UAContext *ua, const char *pool_name)
410 memset(&pr, 0, sizeof(pr));
412 bstrncpy(pr.Name, pool_name, sizeof(pr.Name));
413 if (!get_pool_dbr(ua, &pr)) {
416 set_pool_dbr_defaults_in_media_dbr(&mr, &pr);
417 mr.PoolId = pr.PoolId;
418 if (!db_update_media_defaults(ua->jcr, ua->db, &mr)) {
419 ua->error_msg(_("Error updating Volume records: ERR=%s"), db_strerror(ua->db));
421 ua->info_msg(_("All Volume defaults updated from \"%s\" Pool record.\n"),
426 static void update_all_vols(UAContext *ua)
433 memset(&pr, 0, sizeof(pr));
435 if (!db_get_pool_ids(ua->jcr, ua->db, &num_pools, &ids)) {
436 ua->error_msg(_("Error obtaining pool ids. ERR=%s\n"), db_strerror(ua->db));
440 for (i=0; i<num_pools; i++) {
442 if (!db_get_pool_record(ua->jcr, ua->db, &pr)) { /* ***FIXME*** use acl? */
443 ua->warning_msg(_("Updating all pools, but skipped PoolId=%d. ERR=%s\n"), db_strerror(ua->db));
447 set_pool_dbr_defaults_in_media_dbr(&mr, &pr);
448 mr.PoolId = pr.PoolId;
450 if (!db_update_media_defaults(ua->jcr, ua->db, &mr)) {
451 ua->error_msg(_("Error updating Volume records: ERR=%s"), db_strerror(ua->db));
453 ua->info_msg(_("All Volume defaults updated from \"%s\" Pool record.\n"),
461 static void update_volenabled(UAContext *ua, char *val, MEDIA_DBR *mr)
463 mr->Enabled = get_enabled(ua, val);
464 if (mr->Enabled < 0) {
467 set_storageid_in_mr(NULL, mr);
468 if (!db_update_media_record(ua->jcr, ua->db, mr)) {
469 ua->error_msg(_("Error updating media record Enabled: ERR=%s"),
470 db_strerror(ua->db));
472 ua->info_msg(_("New Enabled is: %d\n"), mr->Enabled);
476 static void update_vol_actiononpurge(UAContext *ua, char *val, MEDIA_DBR *mr)
479 if (strcasecmp(val, "truncate") == 0) {
480 mr->ActionOnPurge = ON_PURGE_TRUNCATE;
482 mr->ActionOnPurge = 0;
485 set_storageid_in_mr(NULL, mr);
486 if (!db_update_media_record(ua->jcr, ua->db, mr)) {
487 ua->error_msg(_("Error updating media record ActionOnPurge: ERR=%s"),
488 db_strerror(ua->db));
490 ua->info_msg(_("New ActionOnPurge is: %s\n"),
491 action_on_purge_to_string(mr->ActionOnPurge, ret));
496 * Update a media record -- allows you to change the
497 * Volume status. E.g. if you want Bacula to stop
498 * writing on the volume, set it to anything other
501 static int update_volume(UAContext *ua)
513 NT_("VolStatus"), /* 0 */
514 NT_("VolRetention"), /* 1 */
515 NT_("VolUse"), /* 2 */
516 NT_("MaxVolJobs"), /* 3 */
517 NT_("MaxVolFiles"), /* 4 */
518 NT_("MaxVolBytes"), /* 5 */
519 NT_("Recycle"), /* 6 */
520 NT_("InChanger"), /* 7 */
523 NT_("FromPool"), /* 10 */
524 NT_("AllFromPool"), /* 11 !!! see below !!! */
525 NT_("Enabled"), /* 12 */
526 NT_("RecyclePool"), /* 13 */
527 NT_("ActionOnPurge"), /* 14 */
530 #define AllFromPool 11 /* keep this updated with above */
532 for (i=0; kw[i]; i++) {
536 if ((j=find_arg_with_value(ua, kw[i])) > 0) {
537 /* If all from pool don't select a media record */
538 if (i != AllFromPool && !select_media_dbr(ua, &mr)) {
543 update_volstatus(ua, ua->argv[j], &mr);
546 update_volretention(ua, ua->argv[j], &mr);
549 update_voluseduration(ua, ua->argv[j], &mr);
552 update_volmaxjobs(ua, ua->argv[j], &mr);
555 update_volmaxfiles(ua, ua->argv[j], &mr);
558 update_volmaxbytes(ua, ua->argv[j], &mr);
561 update_volrecycle(ua, ua->argv[j], &mr);
564 update_volinchanger(ua, ua->argv[j], &mr);
567 update_volslot(ua, ua->argv[j], &mr);
570 memset(&pr, 0, sizeof(POOL_DBR));
571 pr.PoolId = mr.PoolId;
572 if (!db_get_pool_record(ua->jcr, ua->db, &pr)) {
573 ua->error_msg("%s", db_strerror(ua->db));
576 update_vol_pool(ua, ua->argv[j], &mr, &pr);
579 update_vol_from_pool(ua, &mr);
582 update_all_vols_from_pool(ua, ua->argv[j]);
585 update_volenabled(ua, ua->argv[j], &mr);
588 update_vol_recyclepool(ua, ua->argv[j], &mr);
591 update_vol_actiononpurge(ua, ua->argv[j], &mr);
598 /* Allow user to simply update all volumes */
599 if (find_arg(ua, NT_("fromallpools")) > 0) {
605 start_prompt(ua, _("Parameters to modify:\n"));
606 add_prompt(ua, _("Volume Status")); /* 0 */
607 add_prompt(ua, _("Volume Retention Period")); /* 1 */
608 add_prompt(ua, _("Volume Use Duration")); /* 2 */
609 add_prompt(ua, _("Maximum Volume Jobs")); /* 3 */
610 add_prompt(ua, _("Maximum Volume Files")); /* 4 */
611 add_prompt(ua, _("Maximum Volume Bytes")); /* 5 */
612 add_prompt(ua, _("Recycle Flag")); /* 6 */
613 add_prompt(ua, _("Slot")); /* 7 */
614 add_prompt(ua, _("InChanger Flag")); /* 8 */
615 add_prompt(ua, _("Volume Files")); /* 9 */
616 add_prompt(ua, _("Pool")); /* 10 */
617 add_prompt(ua, _("Volume from Pool")); /* 11 */
618 add_prompt(ua, _("All Volumes from Pool")); /* 12 */
619 add_prompt(ua, _("All Volumes from all Pools")); /* 13 */
620 add_prompt(ua, _("Enabled")), /* 14 */
621 add_prompt(ua, _("RecyclePool")), /* 15 */
622 add_prompt(ua, _("Action On Purge")), /* 16 */
623 add_prompt(ua, _("Done")); /* 17 */
624 i = do_prompt(ua, "", _("Select parameter to modify"), NULL, 0);
626 /* For All Volumes, All Volumes from Pool, and Done, we don't need
628 if ( i != 12 && i != 13 && i != 17) {
629 if (!select_media_dbr(ua, &mr)) { /* Get Volume record */
632 ua->info_msg(_("Updating Volume \"%s\"\n"), mr.VolumeName);
635 case 0: /* Volume Status */
636 /* Modify Volume Status */
637 ua->info_msg(_("Current Volume status is: %s\n"), mr.VolStatus);
638 start_prompt(ua, _("Possible Values are:\n"));
639 add_prompt(ua, NT_("Append"));
640 add_prompt(ua, NT_("Archive"));
641 add_prompt(ua, NT_("Disabled"));
642 add_prompt(ua, NT_("Full"));
643 add_prompt(ua, NT_("Used"));
644 add_prompt(ua, NT_("Cleaning"));
645 if (strcmp(mr.VolStatus, NT_("Purged")) == 0) {
646 add_prompt(ua, NT_("Recycle"));
648 add_prompt(ua, NT_("Read-Only"));
649 if (do_prompt(ua, "", _("Choose new Volume Status"), ua->cmd, sizeof(mr.VolStatus)) < 0) {
652 update_volstatus(ua, ua->cmd, &mr);
654 case 1: /* Retention */
655 ua->info_msg(_("Current retention period is: %s\n"),
656 edit_utime(mr.VolRetention, ed1, sizeof(ed1)));
657 if (!get_cmd(ua, _("Enter Volume Retention period: "))) {
660 update_volretention(ua, ua->cmd, &mr);
663 case 2: /* Use Duration */
664 ua->info_msg(_("Current use duration is: %s\n"),
665 edit_utime(mr.VolUseDuration, ed1, sizeof(ed1)));
666 if (!get_cmd(ua, _("Enter Volume Use Duration: "))) {
669 update_voluseduration(ua, ua->cmd, &mr);
672 case 3: /* Max Jobs */
673 ua->info_msg(_("Current max jobs is: %u\n"), mr.MaxVolJobs);
674 if (!get_pint(ua, _("Enter new Maximum Jobs: "))) {
677 update_volmaxjobs(ua, ua->cmd, &mr);
680 case 4: /* Max Files */
681 ua->info_msg(_("Current max files is: %u\n"), mr.MaxVolFiles);
682 if (!get_pint(ua, _("Enter new Maximum Files: "))) {
685 update_volmaxfiles(ua, ua->cmd, &mr);
688 case 5: /* Max Bytes */
689 ua->info_msg(_("Current value is: %s\n"), edit_uint64(mr.MaxVolBytes, ed1));
690 if (!get_cmd(ua, _("Enter new Maximum Bytes: "))) {
693 update_volmaxbytes(ua, ua->cmd, &mr);
697 case 6: /* Recycle */
698 ua->info_msg(_("Current recycle flag is: %s\n"),
699 mr.Recycle==1?_("yes"):_("no"));
700 if (!get_yesno(ua, _("Enter new Recycle status: "))) {
703 update_volrecycle(ua, ua->cmd, &mr);
707 ua->info_msg(_("Current Slot is: %d\n"), mr.Slot);
708 if (!get_pint(ua, _("Enter new Slot: "))) {
711 update_volslot(ua, ua->cmd, &mr);
714 case 8: /* InChanger */
715 ua->info_msg(_("Current InChanger flag is: %d\n"), mr.InChanger);
716 bsnprintf(buf, sizeof(buf), _("Set InChanger flag for Volume \"%s\": yes/no: "),
718 if (!get_yesno(ua, buf)) {
721 mr.InChanger = ua->pint32_val;
723 * Make sure to use db_update... rather than doing this directly,
724 * so that any Slot is handled correctly.
726 set_storageid_in_mr(NULL, &mr);
727 if (!db_update_media_record(ua->jcr, ua->db, &mr)) {
728 ua->error_msg(_("Error updating media record Slot: ERR=%s"), db_strerror(ua->db));
730 ua->info_msg(_("New InChanger flag is: %d\n"), mr.InChanger);
735 case 9: /* Volume Files */
737 ua->warning_msg(_("Warning changing Volume Files can result\n"
738 "in loss of data on your Volume\n\n"));
739 ua->info_msg(_("Current Volume Files is: %u\n"), mr.VolFiles);
740 if (!get_pint(ua, _("Enter new number of Files for Volume: "))) {
743 VolFiles = ua->pint32_val;
744 if (VolFiles != (int)(mr.VolFiles + 1)) {
745 ua->warning_msg(_("Normally, you should only increase Volume Files by one!\n"));
746 if (!get_yesno(ua, _("Increase Volume Files? (yes/no): ")) || ua->pint32_val == 0) {
750 query = get_pool_memory(PM_MESSAGE);
751 Mmsg(query, "UPDATE Media SET VolFiles=%u WHERE MediaId=%s",
752 VolFiles, edit_int64(mr.MediaId, ed1));
753 if (!db_sql_query(ua->db, query, NULL, NULL)) {
754 ua->error_msg("%s", db_strerror(ua->db));
756 ua->info_msg(_("New Volume Files is: %u\n"), VolFiles);
758 free_pool_memory(query);
761 case 10: /* Volume's Pool */
762 memset(&pr, 0, sizeof(POOL_DBR));
763 pr.PoolId = mr.PoolId;
764 if (!db_get_pool_record(ua->jcr, ua->db, &pr)) {
765 ua->error_msg("%s", db_strerror(ua->db));
768 ua->info_msg(_("Current Pool is: %s\n"), pr.Name);
769 if (!get_cmd(ua, _("Enter new Pool name: "))) {
772 update_vol_pool(ua, ua->cmd, &mr, &pr);
776 update_vol_from_pool(ua, &mr);
779 pool = select_pool_resource(ua);
781 update_all_vols_from_pool(ua, pool->name());
790 ua->info_msg(_("Current Enabled is: %d\n"), mr.Enabled);
791 if (!get_cmd(ua, _("Enter new Enabled: "))) {
794 if (strcasecmp(ua->cmd, "yes") == 0 || strcasecmp(ua->cmd, "true") == 0) {
796 } else if (strcasecmp(ua->cmd, "no") == 0 || strcasecmp(ua->cmd, "false") == 0) {
798 } else if (strcasecmp(ua->cmd, "archived") == 0) {
801 mr.Enabled = atoi(ua->cmd);
803 update_volenabled(ua, ua->cmd, &mr);
807 memset(&pr, 0, sizeof(POOL_DBR));
808 pr.PoolId = mr.RecyclePoolId;
809 if (db_get_pool_record(ua->jcr, ua->db, &pr)) {
810 ua->info_msg(_("Current RecyclePool is: %s\n"), pr.Name);
812 ua->info_msg(_("No current RecyclePool\n"));
814 if (!select_pool_dbr(ua, &pr, NT_("recyclepool"))) {
817 update_vol_recyclepool(ua, pr.Name, &mr);
822 ua->info_msg(_("Current ActionOnPurge is: %s\n"),
823 action_on_purge_to_string(mr.ActionOnPurge, ret));
824 if (!get_cmd(ua, _("Enter new ActionOnPurge (one of: Truncate, None): "))) {
828 update_vol_actiononpurge(ua, ua->cmd, &mr);
831 default: /* Done or error */
832 ua->info_msg(_("Selection terminated.\n"));
840 * Update long term statistics
842 static bool update_stats(UAContext *ua)
844 int i = find_arg_with_value(ua, NT_("days"));
848 since = atoi(ua->argv[i]) * 24*60*60;
851 int nb = db_update_stats(ua->jcr, ua->db, since);
852 ua->info_msg(_("Updating %i job(s).\n"), nb);
858 * Update pool record -- pull info from current POOL resource
860 static bool update_pool(UAContext *ua)
868 pool = get_pool_resource(ua);
873 memset(&pr, 0, sizeof(pr));
874 bstrncpy(pr.Name, pool->name(), sizeof(pr.Name));
875 if (!get_pool_dbr(ua, &pr)) {
879 set_pooldbr_from_poolres(&pr, pool, POOL_OP_UPDATE); /* update */
880 set_pooldbr_references(ua->jcr, ua->db, &pr, pool);
882 id = db_update_pool_record(ua->jcr, ua->db, &pr);
884 ua->error_msg(_("db_update_pool_record returned %d. ERR=%s\n"),
885 id, db_strerror(ua->db));
887 query = get_pool_memory(PM_MESSAGE);
888 Mmsg(query, list_pool, edit_int64(pr.PoolId, ed1));
889 db_list_sql_query(ua->jcr, ua->db, query, prtit, ua, 1, HORZ_LIST);
890 free_pool_memory(query);
891 ua->info_msg(_("Pool DB record updated from resource.\n"));
896 * Update a Job record -- allows you to change the
897 * date fields in a Job record. This helps when
898 * providing migration from other vendors.
900 static bool update_job(UAContext *ua)
903 char ed1[50], ed2[50];
904 POOL_MEM cmd(PM_MESSAGE);
908 char *client_name = NULL;
909 char *start_time = NULL;
911 NT_("starttime"), /* 0 */
912 NT_("client"), /* 1 */
915 Dmsg1(200, "cmd=%s\n", ua->cmd);
916 i = find_arg_with_value(ua, NT_("jobid"));
918 ua->error_msg(_("Expect JobId keyword, not found.\n"));
921 memset(&jr, 0, sizeof(jr));
922 memset(&cr, 0, sizeof(cr));
923 jr.JobId = str_to_int64(ua->argv[i]);
924 if (!db_get_job_record(ua->jcr, ua->db, &jr)) {
925 ua->error_msg("%s", db_strerror(ua->db));
929 for (i=0; kw[i]; i++) {
931 if ((j=find_arg_with_value(ua, kw[i])) >= 0) {
933 case 0: /* start time */
934 start_time = ua->argv[j];
936 case 1: /* Client name */
937 client_name = ua->argv[j];
942 if (!client_name && !start_time) {
943 ua->error_msg(_("Neither Client nor StartTime specified.\n"));
947 if (!get_client_dbr(ua, &cr)) {
950 jr.ClientId = cr.ClientId;
955 StartTime = str_to_utime(start_time);
956 if (StartTime == 0) {
957 ua->error_msg(_("Improper date format: %s\n"), ua->argv[i]);
960 delta_start = StartTime - jr.StartTime;
961 Dmsg3(200, "ST=%lld jr.ST=%lld delta=%lld\n", StartTime,
962 (utime_t)jr.StartTime, delta_start);
963 jr.StartTime = (time_t)StartTime;
964 jr.SchedTime += (time_t)delta_start;
965 jr.EndTime += (time_t)delta_start;
966 jr.JobTDate += delta_start;
967 /* Convert to DB times */
968 bstrutime(jr.cStartTime, sizeof(jr.cStartTime), jr.StartTime);
969 bstrutime(jr.cSchedTime, sizeof(jr.cSchedTime), jr.SchedTime);
970 bstrutime(jr.cEndTime, sizeof(jr.cEndTime), jr.EndTime);
972 Mmsg(cmd, "UPDATE Job SET ClientId=%s,StartTime='%s',SchedTime='%s',"
973 "EndTime='%s',JobTDate=%s WHERE JobId=%s",
974 edit_int64(jr.ClientId, ed1),
978 edit_uint64(jr.JobTDate, ed1),
979 edit_int64(jr.JobId, ed2));
980 if (!db_sql_query(ua->db, cmd.c_str(), NULL, NULL)) {
981 ua->error_msg("%s", db_strerror(ua->db));