2 Bacula(R) - The Network Backup Solution
4 Copyright (C) 2000-2017 Kern Sibbald
6 The original author of Bacula is Kern Sibbald, with contributions
7 from many others, a complete list can be found in the file AUTHORS.
9 You may use this file and others of this release according to the
10 license defined in the LICENSE file, which includes the Affero General
11 Public License, v3.0 ("AGPLv3") and some additional permissions and
12 terms pursuant to its AGPLv3 Section 7.
14 This notice must be preserved when any source code is
15 conveyed and/or propagated.
17 Bacula(R) is a registered trademark of Kern Sibbald.
21 * Bacula Director -- Update command processing
22 * Split from ua_cmds.c March 2005
24 * Kern Sibbald, September MM
31 /* Forward referenced functions */
32 static int update_volume(UAContext *ua);
33 static bool update_pool(UAContext *ua);
34 static bool update_job(UAContext *ua);
35 static bool update_stats(UAContext *ua);
38 * Update a Pool Record in the database.
39 * It is always updated from the Resource record.
41 * update pool=<pool-name>
42 * updates pool from Pool resource
43 * update media pool=<pool-name> volume=<volume-name>
44 * changes pool info for volume
45 * update slots [scan=...]
46 * updates autochanger slots
47 * update stats [days=...]
48 * updates long term statistics
50 int update_cmd(UAContext *ua, const char *cmd)
52 static const char *kw[] = {
54 NT_("volume"), /* 1 */
61 NT_("snapshot"),/* 8 */
64 if (!open_client_db(ua)) {
68 switch (find_arg_keyword(ua, kw)) {
94 start_prompt(ua, _("Update choice:\n"));
95 add_prompt(ua, _("Volume parameters"));
96 add_prompt(ua, _("Pool from resource"));
97 add_prompt(ua, _("Slots from autochanger"));
98 add_prompt(ua, _("Long term statistics"));
99 add_prompt(ua, _("Snapshot parameters"));
100 switch (do_prompt(ua, _("item"), _("Choose catalog item to update"), NULL, 0)) {
122 static void update_volstatus(UAContext *ua, const char *val, MEDIA_DBR *mr)
124 POOL_MEM query(PM_MESSAGE);
139 for (i=0; kw[i]; i++) {
140 if (strcasecmp(val, kw[i]) == 0) {
146 ua->error_msg(_("Invalid VolStatus specified: %s\n"), val);
149 bstrncpy(mr->VolStatus, kw[i], sizeof(mr->VolStatus));
150 Mmsg(query, "UPDATE Media SET VolStatus='%s' WHERE MediaId=%s",
151 mr->VolStatus, edit_int64(mr->MediaId,ed1));
152 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
153 ua->error_msg("%s", db_strerror(ua->db));
155 ua->info_msg(_("New Volume status is: %s\n"), mr->VolStatus);
160 static void update_volretention(UAContext *ua, char *val, MEDIA_DBR *mr)
162 char ed1[150], ed2[50];
163 POOL_MEM query(PM_MESSAGE);
164 if (!duration_to_utime(val, &mr->VolRetention)) {
165 ua->error_msg(_("Invalid retention period specified: %s\n"), val);
168 Mmsg(query, "UPDATE Media SET VolRetention=%s WHERE MediaId=%s",
169 edit_uint64(mr->VolRetention, ed1), edit_int64(mr->MediaId,ed2));
170 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
171 ua->error_msg("%s", db_strerror(ua->db));
173 ua->info_msg(_("New retention period is: %s\n"),
174 edit_utime(mr->VolRetention, ed1, sizeof(ed1)));
178 static void update_vol_cacheretention(UAContext *ua, char *val, MEDIA_DBR *mr)
180 char ed1[150], ed2[50];
181 POOL_MEM query(PM_MESSAGE);
182 if (!duration_to_utime(val, &mr->CacheRetention)) {
183 ua->error_msg(_("Invalid cache retention period specified: %s\n"), val);
186 Mmsg(query, "UPDATE Media SET CacheRetention=%s WHERE MediaId=%s",
187 edit_uint64(mr->CacheRetention, 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 Cache Retention period is: %s\n"),
192 edit_utime(mr->CacheRetention, ed1, sizeof(ed1)));
196 static void update_voluseduration(UAContext *ua, char *val, MEDIA_DBR *mr)
198 char ed1[150], ed2[50];
199 POOL_MEM query(PM_MESSAGE);
201 if (!duration_to_utime(val, &mr->VolUseDuration)) {
202 ua->error_msg(_("Invalid use duration specified: %s\n"), val);
205 Mmsg(query, "UPDATE Media SET VolUseDuration=%s WHERE MediaId=%s",
206 edit_uint64(mr->VolUseDuration, ed1), edit_int64(mr->MediaId,ed2));
207 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
208 ua->error_msg("%s", db_strerror(ua->db));
210 ua->info_msg(_("New use duration is: %s\n"),
211 edit_utime(mr->VolUseDuration, ed1, sizeof(ed1)));
215 static void update_volmaxjobs(UAContext *ua, char *val, MEDIA_DBR *mr)
217 POOL_MEM query(PM_MESSAGE);
219 Mmsg(query, "UPDATE Media SET MaxVolJobs=%s WHERE MediaId=%s",
220 val, edit_int64(mr->MediaId,ed1));
221 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
222 ua->error_msg("%s", db_strerror(ua->db));
224 ua->info_msg(_("New max jobs is: %s\n"), val);
228 static void update_volmaxfiles(UAContext *ua, char *val, MEDIA_DBR *mr)
230 POOL_MEM query(PM_MESSAGE);
232 Mmsg(query, "UPDATE Media SET MaxVolFiles=%s WHERE MediaId=%s",
233 val, edit_int64(mr->MediaId, ed1));
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 files is: %s\n"), val);
241 static void update_volmaxbytes(UAContext *ua, char *val, MEDIA_DBR *mr)
244 char ed1[50], ed2[50];
245 POOL_MEM query(PM_MESSAGE);
247 if (!size_to_uint64(val, strlen(val), &maxbytes)) {
248 ua->error_msg(_("Invalid max. bytes specification: %s\n"), val);
251 Mmsg(query, "UPDATE Media SET MaxVolBytes=%s WHERE MediaId=%s",
252 edit_uint64(maxbytes, ed1), edit_int64(mr->MediaId, ed2));
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 Max bytes is: %s\n"), edit_uint64(maxbytes, ed1));
260 static void update_volrecycle(UAContext *ua, char *val, MEDIA_DBR *mr)
265 POOL_MEM query(PM_MESSAGE);
266 if (!is_yesno(val, &recycle)) {
267 ua->error_msg(_("Invalid value. It must be yes or no.\n"));
270 Mmsg(query, "UPDATE Media SET Recycle=%d WHERE MediaId=%s",
271 recycle, edit_int64(mr->MediaId, ed1));
272 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
273 ua->error_msg("%s", db_strerror(ua->db));
275 ua->info_msg(_("New Recycle flag is: %s\n"),
276 recycle==1?_("yes"):_("no"));
280 static void update_volinchanger(UAContext *ua, char *val, MEDIA_DBR *mr)
285 POOL_MEM query(PM_MESSAGE);
286 if (!is_yesno(val, &InChanger)) {
287 ua->error_msg(_("Invalid value. It must be yes or no.\n"));
290 Mmsg(query, "UPDATE Media SET InChanger=%d WHERE MediaId=%s",
291 InChanger, edit_int64(mr->MediaId, ed1));
292 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
293 ua->error_msg("%s", db_strerror(ua->db));
295 ua->info_msg(_("New InChanger flag is: %s\n"),
296 InChanger==1?_("yes"):_("no"));
301 static void update_volslot(UAContext *ua, char *val, MEDIA_DBR *mr)
305 memset(&pr, 0, sizeof(POOL_DBR));
306 pr.PoolId = mr->PoolId;
307 if (!db_get_pool_numvols(ua->jcr, ua->db, &pr)) {
308 ua->error_msg("%s", db_strerror(ua->db));
311 mr->Slot = atoi(val);
312 if (pr.MaxVols > 0 && mr->Slot > (int)pr.MaxVols) {
313 ua->error_msg(_("Invalid slot, it must be between 0 and MaxVols=%d\n"),
318 * Make sure to use db_update... rather than doing this directly,
319 * so that any Slot is handled correctly.
321 set_storageid_in_mr(NULL, mr);
322 if (!db_update_media_record(ua->jcr, ua->db, mr)) {
323 ua->error_msg(_("Error updating media record Slot: ERR=%s"), db_strerror(ua->db));
325 ua->info_msg(_("New Slot is: %d\n"), mr->Slot);
329 /* Modify the Pool in which this Volume is located */
330 void update_vol_pool(UAContext *ua, char *val, MEDIA_DBR *mr, POOL_DBR *opr)
333 POOL_MEM query(PM_MESSAGE);
334 char ed1[50], ed2[50];
336 memset(&pr, 0, sizeof(pr));
337 bstrncpy(pr.Name, val, sizeof(pr.Name));
338 if (!get_pool_dbr(ua, &pr)) {
341 mr->PoolId = pr.PoolId; /* set new PoolId */
345 Mmsg(query, "UPDATE Media SET PoolId=%s WHERE MediaId=%s",
346 edit_int64(mr->PoolId, ed1), edit_int64(mr->MediaId, ed2));
347 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
348 ua->error_msg("%s", db_strerror(ua->db));
350 ua->info_msg(_("New Pool is: %s\n"), pr.Name);
352 if (!db_update_pool_record(ua->jcr, ua->db, opr)) {
353 ua->error_msg("%s", db_strerror(ua->db));
356 if (!db_update_pool_record(ua->jcr, ua->db, &pr)) {
357 ua->error_msg("%s", db_strerror(ua->db));
363 /* Modify the RecyclePool of a Volume */
364 void update_vol_recyclepool(UAContext *ua, char *val, MEDIA_DBR *mr)
367 POOL_MEM query(PM_MESSAGE);
368 char ed1[50], ed2[50], *poolname;
370 if(val && *val) { /* update volume recyclepool="Scratch" */
371 /* If a pool name is given, look up the PoolId */
372 memset(&pr, 0, sizeof(pr));
373 bstrncpy(pr.Name, val, sizeof(pr.Name));
374 if (!get_pool_dbr(ua, &pr, NT_("recyclepool"))) {
377 /* pool = select_pool_resource(ua); */
378 mr->RecyclePoolId = pr.PoolId; /* get the PoolId */
381 } else { /* update volume recyclepool="" */
382 /* If no pool name is given, set the PoolId to 0 (the default) */
383 mr->RecyclePoolId = 0;
384 poolname = _("*None*");
388 Mmsg(query, "UPDATE Media SET RecyclePoolId=%s WHERE MediaId=%s",
389 edit_int64(mr->RecyclePoolId, ed1), edit_int64(mr->MediaId, ed2));
390 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
391 ua->error_msg("%s", db_strerror(ua->db));
393 ua->info_msg(_("New RecyclePool is: %s\n"), poolname);
399 * Refresh the Volume information from the Pool record
401 static void update_vol_from_pool(UAContext *ua, MEDIA_DBR *mr)
405 memset(&pr, 0, sizeof(pr));
406 pr.PoolId = mr->PoolId;
407 if (!db_get_pool_numvols(ua->jcr, ua->db, &pr) ||
408 !acl_access_ok(ua, Pool_ACL, pr.Name)) {
411 set_pool_dbr_defaults_in_media_dbr(mr, &pr);
412 if (!db_update_media_defaults(ua->jcr, ua->db, mr)) {
413 ua->error_msg(_("Error updating Volume record: ERR=%s"), db_strerror(ua->db));
415 ua->info_msg(_("Volume defaults updated from \"%s\" Pool record.\n"),
421 * Refresh the Volume information from the Pool record
424 static void update_all_vols_from_pool(UAContext *ua, const char *pool_name)
429 memset(&pr, 0, sizeof(pr));
431 bstrncpy(pr.Name, pool_name, sizeof(pr.Name));
432 if (!get_pool_dbr(ua, &pr)) {
435 set_pool_dbr_defaults_in_media_dbr(&mr, &pr);
436 mr.PoolId = pr.PoolId;
437 if (!db_update_media_defaults(ua->jcr, ua->db, &mr)) {
438 ua->error_msg(_("Error updating Volume records: ERR=%s"), db_strerror(ua->db));
440 ua->info_msg(_("All Volume defaults updated from \"%s\" Pool record.\n"),
445 static void update_all_vols(UAContext *ua)
452 memset(&pr, 0, sizeof(pr));
454 if (!db_get_pool_ids(ua->jcr, ua->db, &num_pools, &ids)) {
455 ua->error_msg(_("Error obtaining pool ids. ERR=%s\n"), db_strerror(ua->db));
459 for (i=0; i<num_pools; i++) {
461 if (!db_get_pool_numvols(ua->jcr, ua->db, &pr)) { /* ***FIXME*** use acl? */
462 ua->warning_msg(_("Updating all pools, but skipped PoolId=%d. ERR=%s\n"), db_strerror(ua->db));
466 set_pool_dbr_defaults_in_media_dbr(&mr, &pr);
467 mr.PoolId = pr.PoolId;
469 if (!db_update_media_defaults(ua->jcr, ua->db, &mr)) {
470 ua->error_msg(_("Error updating Volume records: ERR=%s"), db_strerror(ua->db));
472 ua->info_msg(_("All Volume defaults updated from \"%s\" Pool record.\n"),
480 static void update_volenabled(UAContext *ua, char *val, MEDIA_DBR *mr)
482 mr->Enabled = get_enabled(ua, val);
483 if (mr->Enabled < 0) {
486 set_storageid_in_mr(NULL, mr);
487 if (!db_update_media_record(ua->jcr, ua->db, mr)) {
488 ua->error_msg(_("Error updating media record Enabled: ERR=%s"),
489 db_strerror(ua->db));
491 ua->info_msg(_("New Enabled is: %d\n"), mr->Enabled);
495 static void update_vol_actiononpurge(UAContext *ua, char *val, MEDIA_DBR *mr)
498 if (strcasecmp(val, "truncate") == 0) {
499 mr->ActionOnPurge = ON_PURGE_TRUNCATE;
501 mr->ActionOnPurge = 0;
504 set_storageid_in_mr(NULL, mr);
505 if (!db_update_media_record(ua->jcr, ua->db, mr)) {
506 ua->error_msg(_("Error updating media record ActionOnPurge: ERR=%s"),
507 db_strerror(ua->db));
509 ua->info_msg(_("New ActionOnPurge is: %s\n"),
510 action_on_purge_to_string(mr->ActionOnPurge, ret));
515 * Update a media record -- allows you to change the
516 * Volume status. E.g. if you want Bacula to stop
517 * writing on the volume, set it to anything other
520 static int update_volume(UAContext *ua)
532 NT_("VolStatus"), /* 0 */
533 NT_("VolRetention"), /* 1 */
534 NT_("VolUse"), /* 2 */
535 NT_("MaxVolJobs"), /* 3 */
536 NT_("MaxVolFiles"), /* 4 */
537 NT_("MaxVolBytes"), /* 5 */
538 NT_("Recycle"), /* 6 */
539 NT_("InChanger"), /* 7 */
542 NT_("FromPool"), /* 10 !!! see below !!! */
543 NT_("AllFromPool"), /* 11 !!! see below !!! */
544 NT_("Enabled"), /* 12 */
545 NT_("RecyclePool"), /* 13 */
546 NT_("ActionOnPurge"), /* 14 */
547 NT_("FromAllPools"), /* 15 !!! see bellow !!! */
548 NT_("CacheRetention"), /* 16 */
551 #define FromPool 10 /* keep this updated */
552 #define AllFromPool 11 /* keep this updated with above */
553 #define FromAllPools 15 /* keep this updated */
555 for (i=0; kw[i]; i++) {
558 /* No argv with these parameters */
559 if (i == FromPool || i == FromAllPools) {
560 j = find_arg(ua, kw[i]);
563 j = find_arg_with_value(ua, kw[i]);
566 /* If all from pool/from all pools don't select a media record */
567 if (i != AllFromPool && i != FromAllPools && !select_media_dbr(ua, &mr)) {
572 update_volstatus(ua, ua->argv[j], &mr);
575 update_volretention(ua, ua->argv[j], &mr);
578 update_voluseduration(ua, ua->argv[j], &mr);
581 update_volmaxjobs(ua, ua->argv[j], &mr);
584 update_volmaxfiles(ua, ua->argv[j], &mr);
587 update_volmaxbytes(ua, ua->argv[j], &mr);
590 update_volrecycle(ua, ua->argv[j], &mr);
593 update_volinchanger(ua, ua->argv[j], &mr);
596 update_volslot(ua, ua->argv[j], &mr);
599 memset(&pr, 0, sizeof(POOL_DBR));
600 pr.PoolId = mr.PoolId;
601 if (!db_get_pool_numvols(ua->jcr, ua->db, &pr)) {
602 ua->error_msg("%s", db_strerror(ua->db));
605 update_vol_pool(ua, ua->argv[j], &mr, &pr);
608 update_vol_from_pool(ua, &mr);
611 update_all_vols_from_pool(ua, ua->argv[j]);
614 update_volenabled(ua, ua->argv[j], &mr);
617 update_vol_recyclepool(ua, ua->argv[j], &mr);
620 update_vol_actiononpurge(ua, ua->argv[j], &mr);
626 update_vol_cacheretention(ua, ua->argv[j], &mr);
634 start_prompt(ua, _("Parameters to modify:\n"));
635 add_prompt(ua, _("Volume Status")); /* 0 */
636 add_prompt(ua, _("Volume Retention Period")); /* 1 */
637 add_prompt(ua, _("Volume Use Duration")); /* 2 */
638 add_prompt(ua, _("Maximum Volume Jobs")); /* 3 */
639 add_prompt(ua, _("Maximum Volume Files")); /* 4 */
640 add_prompt(ua, _("Maximum Volume Bytes")); /* 5 */
641 add_prompt(ua, _("Recycle Flag")); /* 6 */
642 add_prompt(ua, _("Slot")); /* 7 */
643 add_prompt(ua, _("InChanger Flag")); /* 8 */
644 add_prompt(ua, _("Volume Files")); /* 9 */
645 add_prompt(ua, _("Pool")); /* 10 */
646 add_prompt(ua, _("Volume from Pool")); /* 11 */
647 add_prompt(ua, _("All Volumes from Pool")); /* 12 */
648 add_prompt(ua, _("All Volumes from all Pools")); /* 13 */
649 add_prompt(ua, _("Enabled")), /* 14 */
650 add_prompt(ua, _("RecyclePool")), /* 15 */
651 add_prompt(ua, _("Action On Purge")), /* 16 */
652 add_prompt(ua, _("Cache Retention")), /* 17 */
653 add_prompt(ua, _("Done")); /* 18 */
654 i = do_prompt(ua, "", _("Select parameter to modify"), NULL, 0);
656 /* For All Volumes, All Volumes from Pool, and Done, we don't need
658 if ( i != 12 && i != 13 && i != 18) {
659 if (!select_media_dbr(ua, &mr)) { /* Get Volume record */
662 ua->info_msg(_("Updating Volume \"%s\"\n"), mr.VolumeName);
665 case 0: /* Volume Status */
666 /* Modify Volume Status */
667 ua->info_msg(_("Current Volume status is: %s\n"), mr.VolStatus);
668 start_prompt(ua, _("Possible Values are:\n"));
669 add_prompt(ua, NT_("Append"));
670 add_prompt(ua, NT_("Archive"));
671 add_prompt(ua, NT_("Disabled"));
672 add_prompt(ua, NT_("Full"));
673 add_prompt(ua, NT_("Used"));
674 add_prompt(ua, NT_("Cleaning"));
675 if (strcmp(mr.VolStatus, NT_("Purged")) == 0) {
676 add_prompt(ua, NT_("Recycle"));
678 add_prompt(ua, NT_("Read-Only"));
679 if (do_prompt(ua, "", _("Choose new Volume Status"), ua->cmd, sizeof(mr.VolStatus)) < 0) {
682 update_volstatus(ua, ua->cmd, &mr);
684 case 1: /* Retention */
685 ua->info_msg(_("Current retention period is: %s\n"),
686 edit_utime(mr.VolRetention, ed1, sizeof(ed1)));
687 if (!get_cmd(ua, _("Enter Volume Retention period: "))) {
690 update_volretention(ua, ua->cmd, &mr);
693 case 2: /* Use Duration */
694 ua->info_msg(_("Current use duration is: %s\n"),
695 edit_utime(mr.VolUseDuration, ed1, sizeof(ed1)));
696 if (!get_cmd(ua, _("Enter Volume Use Duration: "))) {
699 update_voluseduration(ua, ua->cmd, &mr);
702 case 3: /* Max Jobs */
703 ua->info_msg(_("Current max jobs is: %u\n"), mr.MaxVolJobs);
704 if (!get_pint(ua, _("Enter new Maximum Jobs: "))) {
707 update_volmaxjobs(ua, ua->cmd, &mr);
710 case 4: /* Max Files */
711 ua->info_msg(_("Current max files is: %u\n"), mr.MaxVolFiles);
712 if (!get_pint(ua, _("Enter new Maximum Files: "))) {
715 update_volmaxfiles(ua, ua->cmd, &mr);
718 case 5: /* Max Bytes */
719 ua->info_msg(_("Current value is: %s\n"), edit_uint64(mr.MaxVolBytes, ed1));
720 if (!get_cmd(ua, _("Enter new Maximum Bytes: "))) {
723 update_volmaxbytes(ua, ua->cmd, &mr);
727 case 6: /* Recycle */
728 ua->info_msg(_("Current recycle flag is: %s\n"),
729 mr.Recycle==1?_("yes"):_("no"));
730 if (!get_yesno(ua, _("Enter new Recycle status: "))) {
733 update_volrecycle(ua, ua->cmd, &mr);
737 ua->info_msg(_("Current Slot is: %d\n"), mr.Slot);
738 if (!get_pint(ua, _("Enter new Slot: "))) {
741 update_volslot(ua, ua->cmd, &mr);
744 case 8: /* InChanger */
745 ua->info_msg(_("Current InChanger flag is: %d\n"), mr.InChanger);
746 bsnprintf(buf, sizeof(buf), _("Set InChanger flag for Volume \"%s\": yes/no: "),
748 if (!get_yesno(ua, buf)) {
751 mr.InChanger = ua->pint32_val;
753 * Make sure to use db_update... rather than doing this directly,
754 * so that any Slot is handled correctly.
756 set_storageid_in_mr(NULL, &mr);
757 if (!db_update_media_record(ua->jcr, ua->db, &mr)) {
758 ua->error_msg(_("Error updating media record Slot: ERR=%s"), db_strerror(ua->db));
760 ua->info_msg(_("New InChanger flag is: %d\n"), mr.InChanger);
765 case 9: /* Volume Files */
767 ua->warning_msg(_("Warning changing Volume Files can result\n"
768 "in loss of data on your Volume\n\n"));
769 ua->info_msg(_("Current Volume Files is: %u\n"), mr.VolFiles);
770 if (!get_pint(ua, _("Enter new number of Files for Volume: "))) {
773 VolFiles = ua->pint32_val;
774 if (VolFiles != (int)(mr.VolFiles + 1)) {
775 ua->warning_msg(_("Normally, you should only increase Volume Files by one!\n"));
776 if (!get_yesno(ua, _("Increase Volume Files? (yes/no): ")) || ua->pint32_val == 0) {
780 query = get_pool_memory(PM_MESSAGE);
781 Mmsg(query, "UPDATE Media SET VolFiles=%u WHERE MediaId=%s",
782 VolFiles, edit_int64(mr.MediaId, ed1));
783 if (!db_sql_query(ua->db, query, NULL, NULL)) {
784 ua->error_msg("%s", db_strerror(ua->db));
786 ua->info_msg(_("New Volume Files is: %u\n"), VolFiles);
788 free_pool_memory(query);
791 case 10: /* Volume's Pool */
792 memset(&pr, 0, sizeof(POOL_DBR));
793 pr.PoolId = mr.PoolId;
794 if (!db_get_pool_numvols(ua->jcr, ua->db, &pr)) {
795 ua->error_msg("%s", db_strerror(ua->db));
798 ua->info_msg(_("Current Pool is: %s\n"), pr.Name);
799 if (!get_cmd(ua, _("Enter new Pool name: "))) {
802 update_vol_pool(ua, ua->cmd, &mr, &pr);
806 update_vol_from_pool(ua, &mr);
809 pool = select_pool_resource(ua);
811 update_all_vols_from_pool(ua, pool->name());
820 ua->info_msg(_("Current Enabled is: %d\n"), mr.Enabled);
821 if (!get_cmd(ua, _("Enter new Enabled: "))) {
824 update_volenabled(ua, ua->cmd, &mr);
828 memset(&pr, 0, sizeof(POOL_DBR));
829 pr.PoolId = mr.RecyclePoolId;
830 if (db_get_pool_numvols(ua->jcr, ua->db, &pr)) {
831 ua->info_msg(_("Current RecyclePool is: %s\n"), pr.Name);
833 ua->info_msg(_("No current RecyclePool\n"));
835 if (!select_pool_dbr(ua, &pr, NT_("recyclepool"))) {
838 update_vol_recyclepool(ua, pr.Name, &mr);
843 ua->info_msg(_("Current ActionOnPurge is: %s\n"),
844 action_on_purge_to_string(mr.ActionOnPurge, ret));
845 if (!get_cmd(ua, _("Enter new ActionOnPurge (one of: Truncate, None): "))) {
849 update_vol_actiononpurge(ua, ua->cmd, &mr);
854 ua->info_msg(_("Current Cache Retention period is: %s\n"),
855 edit_utime(mr.CacheRetention, ed1, sizeof(ed1)));
856 if (!get_cmd(ua, _("Enter Cache Retention period: "))) {
859 update_vol_cacheretention(ua, ua->cmd, &mr);
862 default: /* Done or error */
863 ua->info_msg(_("Selection terminated.\n"));
871 * Update long term statistics
873 static bool update_stats(UAContext *ua)
875 int i = find_arg_with_value(ua, NT_("days"));
879 since = atoi(ua->argv[i]) * 24*60*60;
882 int nb = db_update_stats(ua->jcr, ua->db, since);
883 ua->info_msg(_("Updating %i job(s).\n"), nb);
889 * Update pool record -- pull info from current POOL resource
891 static bool update_pool(UAContext *ua)
899 pool = get_pool_resource(ua);
904 memset(&pr, 0, sizeof(pr));
905 bstrncpy(pr.Name, pool->name(), sizeof(pr.Name));
906 if (!get_pool_dbr(ua, &pr)) {
910 set_pooldbr_from_poolres(&pr, pool, POOL_OP_UPDATE); /* update */
911 set_pooldbr_references(ua->jcr, ua->db, &pr, pool);
913 id = db_update_pool_record(ua->jcr, ua->db, &pr);
915 ua->error_msg(_("db_update_pool_record returned %d. ERR=%s\n"),
916 id, db_strerror(ua->db));
918 query = get_pool_memory(PM_MESSAGE);
919 Mmsg(query, list_pool, edit_int64(pr.PoolId, ed1));
920 db_list_sql_query(ua->jcr, ua->db, query, prtit, ua, 1, HORZ_LIST);
921 free_pool_memory(query);
922 ua->info_msg(_("Pool DB record updated from resource.\n"));
927 * Update a Job record -- allows you to change the
928 * date fields in a Job record. This helps when
929 * providing migration from other vendors.
931 static bool update_job(UAContext *ua)
934 char ed1[50], ed2[50], ed3[50];
935 POOL_MEM cmd(PM_MESSAGE);
940 char *client_name = NULL;
941 char *start_time = NULL;
943 NT_("starttime"), /* 0 */
944 NT_("client"), /* 1 */
945 NT_("priority"), /* 2 */
948 Dmsg1(200, "cmd=%s\n", ua->cmd);
949 i = find_arg_with_value(ua, NT_("jobid"));
951 ua->error_msg(_("Expect JobId keyword, not found.\n"));
954 memset(&jr, 0, sizeof(jr));
955 memset(&cr, 0, sizeof(cr));
956 jr.JobId = str_to_int64(ua->argv[i]);
958 ua->error_msg("Bad jobid\n");
961 if (!db_get_job_record(ua->jcr, ua->db, &jr)) {
962 ua->error_msg("%s", db_strerror(ua->db));
965 if (!acl_access_ok(ua, Job_ACL, jr.Name)) {
966 ua->error_msg(_("Update failed. Job not authorized on this console\n"));
969 for (i=0; kw[i]; i++) {
971 if ((j=find_arg_with_value(ua, kw[i])) >= 0) {
973 case 0: /* start time */
974 start_time = ua->argv[j];
976 case 1: /* Client name */
977 client_name = ua->argv[j];
980 priority = str_to_int64(ua->argv[j]);
985 if (!client_name && !start_time && !priority) {
986 ua->error_msg(_("Neither Client, StartTime or Priority specified.\n"));
991 if (jcr->JobId == jr.JobId) {
992 int old = jcr->JobPriority;
993 jcr->JobPriority = priority;
995 ua->send_msg(_("Priority updated for running job \"%s\" from %d to %d\n"), jr.Job, old, priority);
1000 ua->error_msg(_("Job not found.\n"));
1004 if (!get_client_dbr(ua, &cr, JT_BACKUP_RESTORE)) {
1007 jr.ClientId = cr.ClientId;
1010 utime_t delta_start;
1012 StartTime = str_to_utime(start_time);
1013 if (StartTime == 0) {
1014 ua->error_msg(_("Improper date format: %s\n"), ua->argv[i]);
1017 delta_start = StartTime - jr.StartTime;
1018 Dmsg3(200, "ST=%lld jr.ST=%lld delta=%lld\n", StartTime,
1019 (utime_t)jr.StartTime, delta_start);
1020 jr.StartTime = (time_t)StartTime;
1021 jr.SchedTime += (time_t)delta_start;
1022 jr.EndTime += (time_t)delta_start;
1023 jr.JobTDate += delta_start;
1024 /* Convert to DB times */
1025 bstrutime(jr.cStartTime, sizeof(jr.cStartTime), jr.StartTime);
1026 bstrutime(jr.cSchedTime, sizeof(jr.cSchedTime), jr.SchedTime);
1027 bstrutime(jr.cEndTime, sizeof(jr.cEndTime), jr.EndTime);
1029 Mmsg(cmd, "UPDATE Job SET ClientId=%s,StartTime='%s',SchedTime='%s',"
1030 "EndTime='%s',JobTDate=%s WHERE JobId=%s",
1031 edit_int64(jr.ClientId, ed1),
1035 edit_uint64(jr.JobTDate, ed2),
1036 edit_int64(jr.JobId, ed3));
1037 if (!db_sql_query(ua->db, cmd.c_str(), NULL, NULL)) {
1038 ua->error_msg("%s", db_strerror(ua->db));