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];
369 const char *poolname;
371 if(val && *val) { /* update volume recyclepool="Scratch" */
372 /* If a pool name is given, look up the PoolId */
373 memset(&pr, 0, sizeof(pr));
374 bstrncpy(pr.Name, val, sizeof(pr.Name));
375 if (!get_pool_dbr(ua, &pr, NT_("recyclepool"))) {
378 /* pool = select_pool_resource(ua); */
379 mr->RecyclePoolId = pr.PoolId; /* get the PoolId */
382 } else { /* update volume recyclepool="" */
383 /* If no pool name is given, set the PoolId to 0 (the default) */
384 mr->RecyclePoolId = 0;
385 poolname = _("*None*");
389 Mmsg(query, "UPDATE Media SET RecyclePoolId=%s WHERE MediaId=%s",
390 edit_int64(mr->RecyclePoolId, ed1), edit_int64(mr->MediaId, ed2));
391 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
392 ua->error_msg("%s", db_strerror(ua->db));
394 ua->info_msg(_("New RecyclePool is: %s\n"), poolname);
400 * Refresh the Volume information from the Pool record
402 static void update_vol_from_pool(UAContext *ua, MEDIA_DBR *mr)
406 memset(&pr, 0, sizeof(pr));
407 pr.PoolId = mr->PoolId;
408 if (!db_get_pool_numvols(ua->jcr, ua->db, &pr) ||
409 !acl_access_ok(ua, Pool_ACL, pr.Name)) {
412 set_pool_dbr_defaults_in_media_dbr(mr, &pr);
413 if (!db_update_media_defaults(ua->jcr, ua->db, mr)) {
414 ua->error_msg(_("Error updating Volume record: ERR=%s"), db_strerror(ua->db));
416 ua->info_msg(_("Volume defaults updated from \"%s\" Pool record.\n"),
422 * Refresh the Volume information from the Pool record
425 static void update_all_vols_from_pool(UAContext *ua, const char *pool_name)
430 memset(&pr, 0, sizeof(pr));
432 bstrncpy(pr.Name, pool_name, sizeof(pr.Name));
433 if (!get_pool_dbr(ua, &pr)) {
436 set_pool_dbr_defaults_in_media_dbr(&mr, &pr);
437 mr.PoolId = pr.PoolId;
438 if (!db_update_media_defaults(ua->jcr, ua->db, &mr)) {
439 ua->error_msg(_("Error updating Volume records: ERR=%s"), db_strerror(ua->db));
441 ua->info_msg(_("All Volume defaults updated from \"%s\" Pool record.\n"),
446 static void update_all_vols(UAContext *ua)
453 memset(&pr, 0, sizeof(pr));
455 if (!db_get_pool_ids(ua->jcr, ua->db, &num_pools, &ids)) {
456 ua->error_msg(_("Error obtaining pool ids. ERR=%s\n"), db_strerror(ua->db));
460 for (i=0; i<num_pools; i++) {
462 if (!db_get_pool_numvols(ua->jcr, ua->db, &pr)) { /* ***FIXME*** use acl? */
463 ua->warning_msg(_("Updating all pools, but skipped PoolId=%d. ERR=%s\n"), db_strerror(ua->db));
467 set_pool_dbr_defaults_in_media_dbr(&mr, &pr);
468 mr.PoolId = pr.PoolId;
470 if (!db_update_media_defaults(ua->jcr, ua->db, &mr)) {
471 ua->error_msg(_("Error updating Volume records: ERR=%s"), db_strerror(ua->db));
473 ua->info_msg(_("All Volume defaults updated from \"%s\" Pool record.\n"),
481 static void update_volenabled(UAContext *ua, char *val, MEDIA_DBR *mr)
483 mr->Enabled = get_enabled(ua, val);
484 if (mr->Enabled < 0) {
487 set_storageid_in_mr(NULL, mr);
488 if (!db_update_media_record(ua->jcr, ua->db, mr)) {
489 ua->error_msg(_("Error updating media record Enabled: ERR=%s"),
490 db_strerror(ua->db));
492 ua->info_msg(_("New Enabled is: %d\n"), mr->Enabled);
496 static void update_vol_actiononpurge(UAContext *ua, char *val, MEDIA_DBR *mr)
499 if (strcasecmp(val, "truncate") == 0) {
500 mr->ActionOnPurge = ON_PURGE_TRUNCATE;
502 mr->ActionOnPurge = 0;
505 set_storageid_in_mr(NULL, mr);
506 if (!db_update_media_record(ua->jcr, ua->db, mr)) {
507 ua->error_msg(_("Error updating media record ActionOnPurge: ERR=%s"),
508 db_strerror(ua->db));
510 ua->info_msg(_("New ActionOnPurge is: %s\n"),
511 action_on_purge_to_string(mr->ActionOnPurge, ret));
516 * Update a media record -- allows you to change the
517 * Volume status. E.g. if you want Bacula to stop
518 * writing on the volume, set it to anything other
521 static int update_volume(UAContext *ua)
533 NT_("VolStatus"), /* 0 */
534 NT_("VolRetention"), /* 1 */
535 NT_("VolUse"), /* 2 */
536 NT_("MaxVolJobs"), /* 3 */
537 NT_("MaxVolFiles"), /* 4 */
538 NT_("MaxVolBytes"), /* 5 */
539 NT_("Recycle"), /* 6 */
540 NT_("InChanger"), /* 7 */
543 NT_("FromPool"), /* 10 !!! see below !!! */
544 NT_("AllFromPool"), /* 11 !!! see below !!! */
545 NT_("Enabled"), /* 12 */
546 NT_("RecyclePool"), /* 13 */
547 NT_("ActionOnPurge"), /* 14 */
548 NT_("FromAllPools"), /* 15 !!! see bellow !!! */
549 NT_("CacheRetention"), /* 16 */
552 #define FromPool 10 /* keep this updated */
553 #define AllFromPool 11 /* keep this updated with above */
554 #define FromAllPools 15 /* keep this updated */
556 for (i=0; kw[i]; i++) {
559 /* No argv with these parameters */
560 if (i == FromPool || i == FromAllPools) {
561 j = find_arg(ua, kw[i]);
564 j = find_arg_with_value(ua, kw[i]);
567 /* If all from pool/from all pools don't select a media record */
568 if (i != AllFromPool && i != FromAllPools && !select_media_dbr(ua, &mr)) {
573 update_volstatus(ua, ua->argv[j], &mr);
576 update_volretention(ua, ua->argv[j], &mr);
579 update_voluseduration(ua, ua->argv[j], &mr);
582 update_volmaxjobs(ua, ua->argv[j], &mr);
585 update_volmaxfiles(ua, ua->argv[j], &mr);
588 update_volmaxbytes(ua, ua->argv[j], &mr);
591 update_volrecycle(ua, ua->argv[j], &mr);
594 update_volinchanger(ua, ua->argv[j], &mr);
597 update_volslot(ua, ua->argv[j], &mr);
600 memset(&pr, 0, sizeof(POOL_DBR));
601 pr.PoolId = mr.PoolId;
602 if (!db_get_pool_numvols(ua->jcr, ua->db, &pr)) {
603 ua->error_msg("%s", db_strerror(ua->db));
606 update_vol_pool(ua, ua->argv[j], &mr, &pr);
609 update_vol_from_pool(ua, &mr);
612 update_all_vols_from_pool(ua, ua->argv[j]);
615 update_volenabled(ua, ua->argv[j], &mr);
618 update_vol_recyclepool(ua, ua->argv[j], &mr);
621 update_vol_actiononpurge(ua, ua->argv[j], &mr);
627 update_vol_cacheretention(ua, ua->argv[j], &mr);
635 start_prompt(ua, _("Parameters to modify:\n"));
636 add_prompt(ua, _("Volume Status")); /* 0 */
637 add_prompt(ua, _("Volume Retention Period")); /* 1 */
638 add_prompt(ua, _("Volume Use Duration")); /* 2 */
639 add_prompt(ua, _("Maximum Volume Jobs")); /* 3 */
640 add_prompt(ua, _("Maximum Volume Files")); /* 4 */
641 add_prompt(ua, _("Maximum Volume Bytes")); /* 5 */
642 add_prompt(ua, _("Recycle Flag")); /* 6 */
643 add_prompt(ua, _("Slot")); /* 7 */
644 add_prompt(ua, _("InChanger Flag")); /* 8 */
645 add_prompt(ua, _("Volume Files")); /* 9 */
646 add_prompt(ua, _("Pool")); /* 10 */
647 add_prompt(ua, _("Volume from Pool")); /* 11 */
648 add_prompt(ua, _("All Volumes from Pool")); /* 12 */
649 add_prompt(ua, _("All Volumes from all Pools")); /* 13 */
650 add_prompt(ua, _("Enabled")), /* 14 */
651 add_prompt(ua, _("RecyclePool")), /* 15 */
652 add_prompt(ua, _("Action On Purge")), /* 16 */
653 add_prompt(ua, _("Cache Retention")), /* 17 */
654 add_prompt(ua, _("Done")); /* 18 */
655 i = do_prompt(ua, "", _("Select parameter to modify"), NULL, 0);
657 /* For All Volumes, All Volumes from Pool, and Done, we don't need
659 if ( i != 12 && i != 13 && i != 18) {
660 if (!select_media_dbr(ua, &mr)) { /* Get Volume record */
663 ua->info_msg(_("Updating Volume \"%s\"\n"), mr.VolumeName);
666 case 0: /* Volume Status */
667 /* Modify Volume Status */
668 ua->info_msg(_("Current Volume status is: %s\n"), mr.VolStatus);
669 start_prompt(ua, _("Possible Values are:\n"));
670 add_prompt(ua, NT_("Append"));
671 add_prompt(ua, NT_("Archive"));
672 add_prompt(ua, NT_("Disabled"));
673 add_prompt(ua, NT_("Full"));
674 add_prompt(ua, NT_("Used"));
675 add_prompt(ua, NT_("Cleaning"));
676 if (strcmp(mr.VolStatus, NT_("Purged")) == 0) {
677 add_prompt(ua, NT_("Recycle"));
679 add_prompt(ua, NT_("Read-Only"));
680 if (do_prompt(ua, "", _("Choose new Volume Status"), ua->cmd, sizeof(mr.VolStatus)) < 0) {
683 update_volstatus(ua, ua->cmd, &mr);
685 case 1: /* Retention */
686 ua->info_msg(_("Current retention period is: %s\n"),
687 edit_utime(mr.VolRetention, ed1, sizeof(ed1)));
688 if (!get_cmd(ua, _("Enter Volume Retention period: "))) {
691 update_volretention(ua, ua->cmd, &mr);
694 case 2: /* Use Duration */
695 ua->info_msg(_("Current use duration is: %s\n"),
696 edit_utime(mr.VolUseDuration, ed1, sizeof(ed1)));
697 if (!get_cmd(ua, _("Enter Volume Use Duration: "))) {
700 update_voluseduration(ua, ua->cmd, &mr);
703 case 3: /* Max Jobs */
704 ua->info_msg(_("Current max jobs is: %u\n"), mr.MaxVolJobs);
705 if (!get_pint(ua, _("Enter new Maximum Jobs: "))) {
708 update_volmaxjobs(ua, ua->cmd, &mr);
711 case 4: /* Max Files */
712 ua->info_msg(_("Current max files is: %u\n"), mr.MaxVolFiles);
713 if (!get_pint(ua, _("Enter new Maximum Files: "))) {
716 update_volmaxfiles(ua, ua->cmd, &mr);
719 case 5: /* Max Bytes */
720 ua->info_msg(_("Current value is: %s\n"), edit_uint64(mr.MaxVolBytes, ed1));
721 if (!get_cmd(ua, _("Enter new Maximum Bytes: "))) {
724 update_volmaxbytes(ua, ua->cmd, &mr);
728 case 6: /* Recycle */
729 ua->info_msg(_("Current recycle flag is: %s\n"),
730 mr.Recycle==1?_("yes"):_("no"));
731 if (!get_yesno(ua, _("Enter new Recycle status: "))) {
734 update_volrecycle(ua, ua->cmd, &mr);
738 ua->info_msg(_("Current Slot is: %d\n"), mr.Slot);
739 if (!get_pint(ua, _("Enter new Slot: "))) {
742 update_volslot(ua, ua->cmd, &mr);
745 case 8: /* InChanger */
746 ua->info_msg(_("Current InChanger flag is: %d\n"), mr.InChanger);
747 bsnprintf(buf, sizeof(buf), _("Set InChanger flag for Volume \"%s\": yes/no: "),
749 if (!get_yesno(ua, buf)) {
752 mr.InChanger = ua->pint32_val;
754 * Make sure to use db_update... rather than doing this directly,
755 * so that any Slot is handled correctly.
757 set_storageid_in_mr(NULL, &mr);
758 if (!db_update_media_record(ua->jcr, ua->db, &mr)) {
759 ua->error_msg(_("Error updating media record Slot: ERR=%s"), db_strerror(ua->db));
761 ua->info_msg(_("New InChanger flag is: %d\n"), mr.InChanger);
766 case 9: /* Volume Files */
768 ua->warning_msg(_("Warning changing Volume Files can result\n"
769 "in loss of data on your Volume\n\n"));
770 ua->info_msg(_("Current Volume Files is: %u\n"), mr.VolFiles);
771 if (!get_pint(ua, _("Enter new number of Files for Volume: "))) {
774 VolFiles = ua->pint32_val;
775 if (VolFiles != (int)(mr.VolFiles + 1)) {
776 ua->warning_msg(_("Normally, you should only increase Volume Files by one!\n"));
777 if (!get_yesno(ua, _("Increase Volume Files? (yes/no): ")) || ua->pint32_val == 0) {
781 query = get_pool_memory(PM_MESSAGE);
782 Mmsg(query, "UPDATE Media SET VolFiles=%u WHERE MediaId=%s",
783 VolFiles, edit_int64(mr.MediaId, ed1));
784 if (!db_sql_query(ua->db, query, NULL, NULL)) {
785 ua->error_msg("%s", db_strerror(ua->db));
787 ua->info_msg(_("New Volume Files is: %u\n"), VolFiles);
789 free_pool_memory(query);
792 case 10: /* Volume's Pool */
793 memset(&pr, 0, sizeof(POOL_DBR));
794 pr.PoolId = mr.PoolId;
795 if (!db_get_pool_numvols(ua->jcr, ua->db, &pr)) {
796 ua->error_msg("%s", db_strerror(ua->db));
799 ua->info_msg(_("Current Pool is: %s\n"), pr.Name);
800 if (!get_cmd(ua, _("Enter new Pool name: "))) {
803 update_vol_pool(ua, ua->cmd, &mr, &pr);
807 update_vol_from_pool(ua, &mr);
810 pool = select_pool_resource(ua);
812 update_all_vols_from_pool(ua, pool->name());
821 ua->info_msg(_("Current Enabled is: %d\n"), mr.Enabled);
822 if (!get_cmd(ua, _("Enter new Enabled: "))) {
825 update_volenabled(ua, ua->cmd, &mr);
829 memset(&pr, 0, sizeof(POOL_DBR));
830 pr.PoolId = mr.RecyclePoolId;
831 if (db_get_pool_numvols(ua->jcr, ua->db, &pr)) {
832 ua->info_msg(_("Current RecyclePool is: %s\n"), pr.Name);
834 ua->info_msg(_("No current RecyclePool\n"));
836 if (!select_pool_dbr(ua, &pr, NT_("recyclepool"))) {
839 update_vol_recyclepool(ua, pr.Name, &mr);
844 ua->info_msg(_("Current ActionOnPurge is: %s\n"),
845 action_on_purge_to_string(mr.ActionOnPurge, ret));
846 if (!get_cmd(ua, _("Enter new ActionOnPurge (one of: Truncate, None): "))) {
850 update_vol_actiononpurge(ua, ua->cmd, &mr);
855 ua->info_msg(_("Current Cache Retention period is: %s\n"),
856 edit_utime(mr.CacheRetention, ed1, sizeof(ed1)));
857 if (!get_cmd(ua, _("Enter Cache Retention period: "))) {
860 update_vol_cacheretention(ua, ua->cmd, &mr);
863 default: /* Done or error */
864 ua->info_msg(_("Selection terminated.\n"));
872 * Update long term statistics
874 static bool update_stats(UAContext *ua)
876 int i = find_arg_with_value(ua, NT_("days"));
880 since = atoi(ua->argv[i]) * 24*60*60;
883 int nb = db_update_stats(ua->jcr, ua->db, since);
884 ua->info_msg(_("Updating %i job(s).\n"), nb);
890 * Update pool record -- pull info from current POOL resource
892 static bool update_pool(UAContext *ua)
900 pool = get_pool_resource(ua);
905 memset(&pr, 0, sizeof(pr));
906 bstrncpy(pr.Name, pool->name(), sizeof(pr.Name));
907 if (!get_pool_dbr(ua, &pr)) {
911 set_pooldbr_from_poolres(&pr, pool, POOL_OP_UPDATE); /* update */
912 set_pooldbr_references(ua->jcr, ua->db, &pr, pool);
914 id = db_update_pool_record(ua->jcr, ua->db, &pr);
916 ua->error_msg(_("db_update_pool_record returned %d. ERR=%s\n"),
917 id, db_strerror(ua->db));
919 query = get_pool_memory(PM_MESSAGE);
920 Mmsg(query, list_pool, edit_int64(pr.PoolId, ed1));
921 db_list_sql_query(ua->jcr, ua->db, query, prtit, ua, 1, HORZ_LIST);
922 free_pool_memory(query);
923 ua->info_msg(_("Pool DB record updated from resource.\n"));
928 * Update a Job record -- allows you to change the
929 * date fields in a Job record. This helps when
930 * providing migration from other vendors.
932 static bool update_job(UAContext *ua)
935 char ed1[50], ed2[50], ed3[50];
936 POOL_MEM cmd(PM_MESSAGE);
941 char *client_name = NULL;
942 char *start_time = NULL;
944 NT_("starttime"), /* 0 */
945 NT_("client"), /* 1 */
946 NT_("priority"), /* 2 */
949 Dmsg1(200, "cmd=%s\n", ua->cmd);
950 i = find_arg_with_value(ua, NT_("jobid"));
952 ua->error_msg(_("Expect JobId keyword, not found.\n"));
955 memset(&jr, 0, sizeof(jr));
956 memset(&cr, 0, sizeof(cr));
957 jr.JobId = str_to_int64(ua->argv[i]);
959 ua->error_msg("Bad jobid\n");
962 if (!db_get_job_record(ua->jcr, ua->db, &jr)) {
963 ua->error_msg("%s", db_strerror(ua->db));
966 if (!acl_access_ok(ua, Job_ACL, jr.Name)) {
967 ua->error_msg(_("Update failed. Job not authorized on this console\n"));
970 for (i=0; kw[i]; i++) {
972 if ((j=find_arg_with_value(ua, kw[i])) >= 0) {
974 case 0: /* start time */
975 start_time = ua->argv[j];
977 case 1: /* Client name */
978 client_name = ua->argv[j];
981 priority = str_to_int64(ua->argv[j]);
986 if (!client_name && !start_time && !priority) {
987 ua->error_msg(_("Neither Client, StartTime or Priority specified.\n"));
992 if (jcr->JobId == jr.JobId) {
993 int old = jcr->JobPriority;
994 jcr->JobPriority = priority;
996 ua->send_msg(_("Priority updated for running job \"%s\" from %d to %d\n"), jr.Job, old, priority);
1001 ua->error_msg(_("Job not found.\n"));
1005 if (!get_client_dbr(ua, &cr, JT_BACKUP_RESTORE)) {
1008 jr.ClientId = cr.ClientId;
1011 utime_t delta_start;
1013 StartTime = str_to_utime(start_time);
1014 if (StartTime == 0) {
1015 ua->error_msg(_("Improper date format: %s\n"), ua->argv[i]);
1018 delta_start = StartTime - jr.StartTime;
1019 Dmsg3(200, "ST=%lld jr.ST=%lld delta=%lld\n", StartTime,
1020 (utime_t)jr.StartTime, delta_start);
1021 jr.StartTime = (time_t)StartTime;
1022 jr.SchedTime += (time_t)delta_start;
1023 jr.EndTime += (time_t)delta_start;
1024 jr.JobTDate += delta_start;
1025 /* Convert to DB times */
1026 bstrutime(jr.cStartTime, sizeof(jr.cStartTime), jr.StartTime);
1027 bstrutime(jr.cSchedTime, sizeof(jr.cSchedTime), jr.SchedTime);
1028 bstrutime(jr.cEndTime, sizeof(jr.cEndTime), jr.EndTime);
1030 Mmsg(cmd, "UPDATE Job SET ClientId=%s,StartTime='%s',SchedTime='%s',"
1031 "EndTime='%s',JobTDate=%s WHERE JobId=%s",
1032 edit_int64(jr.ClientId, ed1),
1036 edit_uint64(jr.JobTDate, ed2),
1037 edit_int64(jr.JobId, ed3));
1038 if (!db_sql_query(ua->db, cmd.c_str(), NULL, NULL)) {
1039 ua->error_msg("%s", db_strerror(ua->db));