2 Bacula® - The Network Backup Solution
4 Copyright (C) 2000-2009 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 two of the GNU 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 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
41 /* Forward referenced functions */
42 static int update_volume(UAContext *ua);
43 static bool update_pool(UAContext *ua);
44 static bool update_job(UAContext *ua);
45 static bool update_stats(UAContext *ua);
48 * Update a Pool Record in the database.
49 * It is always updated from the Resource record.
51 * update pool=<pool-name>
52 * updates pool from Pool resource
53 * update media pool=<pool-name> volume=<volume-name>
54 * changes pool info for volume
55 * update slots [scan=...]
56 * updates autochanger slots
57 * update stats [days=...]
58 * updates long term statistics
60 int update_cmd(UAContext *ua, const char *cmd)
62 static const char *kw[] = {
64 NT_("volume"), /* 1 */
72 if (!open_client_db(ua)) {
76 switch (find_arg_keyword(ua, kw)) {
98 start_prompt(ua, _("Update choice:\n"));
99 add_prompt(ua, _("Volume parameters"));
100 add_prompt(ua, _("Pool from resource"));
101 add_prompt(ua, _("Slots from autochanger"));
102 add_prompt(ua, _("Long term statistics"));
103 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_voluseduration(UAContext *ua, char *val, MEDIA_DBR *mr)
180 char ed1[150], ed2[50];
181 POOL_MEM query(PM_MESSAGE);
183 if (!duration_to_utime(val, &mr->VolUseDuration)) {
184 ua->error_msg(_("Invalid use duration specified: %s\n"), val);
187 Mmsg(query, "UPDATE Media SET VolUseDuration=%s WHERE MediaId=%s",
188 edit_uint64(mr->VolUseDuration, ed1), edit_int64(mr->MediaId,ed2));
189 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
190 ua->error_msg("%s", db_strerror(ua->db));
192 ua->info_msg(_("New use duration is: %s\n"),
193 edit_utime(mr->VolUseDuration, ed1, sizeof(ed1)));
197 static void update_volmaxjobs(UAContext *ua, char *val, MEDIA_DBR *mr)
199 POOL_MEM query(PM_MESSAGE);
201 Mmsg(query, "UPDATE Media SET MaxVolJobs=%s WHERE MediaId=%s",
202 val, edit_int64(mr->MediaId,ed1));
203 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
204 ua->error_msg("%s", db_strerror(ua->db));
206 ua->info_msg(_("New max jobs is: %s\n"), val);
210 static void update_volmaxfiles(UAContext *ua, char *val, MEDIA_DBR *mr)
212 POOL_MEM query(PM_MESSAGE);
214 Mmsg(query, "UPDATE Media SET MaxVolFiles=%s WHERE MediaId=%s",
215 val, edit_int64(mr->MediaId, ed1));
216 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
217 ua->error_msg("%s", db_strerror(ua->db));
219 ua->info_msg(_("New max files is: %s\n"), val);
223 static void update_volmaxbytes(UAContext *ua, char *val, MEDIA_DBR *mr)
226 char ed1[50], ed2[50];
227 POOL_MEM query(PM_MESSAGE);
229 if (!size_to_uint64(val, strlen(val), &maxbytes)) {
230 ua->error_msg(_("Invalid max. bytes specification: %s\n"), val);
233 Mmsg(query, "UPDATE Media SET MaxVolBytes=%s WHERE MediaId=%s",
234 edit_uint64(maxbytes, ed1), edit_int64(mr->MediaId, ed2));
235 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
236 ua->error_msg("%s", db_strerror(ua->db));
238 ua->info_msg(_("New Max bytes is: %s\n"), edit_uint64(maxbytes, ed1));
242 static void update_volrecycle(UAContext *ua, char *val, MEDIA_DBR *mr)
247 POOL_MEM query(PM_MESSAGE);
248 if (!is_yesno(val, &recycle)) {
249 ua->error_msg(_("Invalid value. It must be yes or no.\n"));
252 Mmsg(query, "UPDATE Media SET Recycle=%d WHERE MediaId=%s",
253 recycle, edit_int64(mr->MediaId, ed1));
254 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
255 ua->error_msg("%s", db_strerror(ua->db));
257 ua->info_msg(_("New Recycle flag is: %s\n"),
258 recycle==1?_("yes"):_("no"));
262 static void update_volinchanger(UAContext *ua, char *val, MEDIA_DBR *mr)
267 POOL_MEM query(PM_MESSAGE);
268 if (!is_yesno(val, &InChanger)) {
269 ua->error_msg(_("Invalid value. It must be yes or no.\n"));
272 Mmsg(query, "UPDATE Media SET InChanger=%d WHERE MediaId=%s",
273 InChanger, edit_int64(mr->MediaId, ed1));
274 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
275 ua->error_msg("%s", db_strerror(ua->db));
277 ua->info_msg(_("New InChanger flag is: %s\n"),
278 InChanger==1?_("yes"):_("no"));
283 static void update_volslot(UAContext *ua, char *val, MEDIA_DBR *mr)
287 memset(&pr, 0, sizeof(POOL_DBR));
288 pr.PoolId = mr->PoolId;
289 if (!db_get_pool_record(ua->jcr, ua->db, &pr)) {
290 ua->error_msg("%s", db_strerror(ua->db));
293 mr->Slot = atoi(val);
294 if (pr.MaxVols > 0 && mr->Slot > (int)pr.MaxVols) {
295 ua->error_msg(_("Invalid slot, it must be between 0 and MaxVols=%d\n"),
300 * Make sure to use db_update... rather than doing this directly,
301 * so that any Slot is handled correctly.
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));
411 memset(&mr, 0, sizeof(mr));
413 bstrncpy(pr.Name, pool_name, sizeof(pr.Name));
414 if (!get_pool_dbr(ua, &pr)) {
417 set_pool_dbr_defaults_in_media_dbr(&mr, &pr);
418 mr.PoolId = pr.PoolId;
419 if (!db_update_media_defaults(ua->jcr, ua->db, &mr)) {
420 ua->error_msg(_("Error updating Volume records: ERR=%s"), db_strerror(ua->db));
422 ua->info_msg(_("All Volume defaults updated from \"%s\" Pool record.\n"),
427 static void update_all_vols(UAContext *ua)
434 memset(&pr, 0, sizeof(pr));
435 memset(&mr, 0, sizeof(mr));
437 if (!db_get_pool_ids(ua->jcr, ua->db, &num_pools, &ids)) {
438 ua->error_msg(_("Error obtaining pool ids. ERR=%s\n"), db_strerror(ua->db));
442 for (i=0; i<num_pools; i++) {
444 if (!db_get_pool_record(ua->jcr, ua->db, &pr)) { /* ***FIXME*** use acl? */
445 ua->warning_msg(_("Updating all pools, but skipped PoolId=%d. ERR=%s\n"), db_strerror(ua->db));
449 set_pool_dbr_defaults_in_media_dbr(&mr, &pr);
450 mr.PoolId = pr.PoolId;
452 if (!db_update_media_defaults(ua->jcr, ua->db, &mr)) {
453 ua->error_msg(_("Error updating Volume records: ERR=%s"), db_strerror(ua->db));
455 ua->info_msg(_("All Volume defaults updated from \"%s\" Pool record.\n"),
463 static void update_volenabled(UAContext *ua, char *val, MEDIA_DBR *mr)
465 mr->Enabled = get_enabled(ua, val);
466 if (mr->Enabled < 0) {
469 if (!db_update_media_record(ua->jcr, ua->db, mr)) {
470 ua->error_msg(_("Error updating media record Enabled: ERR=%s"),
471 db_strerror(ua->db));
473 ua->info_msg(_("New Enabled is: %d\n"), mr->Enabled);
477 static void update_vol_actiononpurge(UAContext *ua, char *val, MEDIA_DBR *mr)
480 if (strcasecmp(val, "truncate") == 0) {
481 mr->ActionOnPurge = AOP_TRUNCATE;
483 mr->ActionOnPurge = 0;
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 aop_to_str(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 if (!db_update_media_record(ua->jcr, ua->db, &mr)) {
727 ua->error_msg(_("Error updating media record Slot: ERR=%s"), db_strerror(ua->db));
729 ua->info_msg(_("New InChanger flag is: %d\n"), mr.InChanger);
734 case 9: /* Volume Files */
736 ua->warning_msg(_("Warning changing Volume Files can result\n"
737 "in loss of data on your Volume\n\n"));
738 ua->info_msg(_("Current Volume Files is: %u\n"), mr.VolFiles);
739 if (!get_pint(ua, _("Enter new number of Files for Volume: "))) {
742 VolFiles = ua->pint32_val;
743 if (VolFiles != (int)(mr.VolFiles + 1)) {
744 ua->warning_msg(_("Normally, you should only increase Volume Files by one!\n"));
745 if (!get_yesno(ua, _("Increase Volume Files? (yes/no): ")) || ua->pint32_val == 0) {
749 query = get_pool_memory(PM_MESSAGE);
750 Mmsg(query, "UPDATE Media SET VolFiles=%u WHERE MediaId=%s",
751 VolFiles, edit_int64(mr.MediaId, ed1));
752 if (!db_sql_query(ua->db, query, NULL, NULL)) {
753 ua->error_msg("%s", db_strerror(ua->db));
755 ua->info_msg(_("New Volume Files is: %u\n"), VolFiles);
757 free_pool_memory(query);
760 case 10: /* Volume's Pool */
761 memset(&pr, 0, sizeof(POOL_DBR));
762 pr.PoolId = mr.PoolId;
763 if (!db_get_pool_record(ua->jcr, ua->db, &pr)) {
764 ua->error_msg("%s", db_strerror(ua->db));
767 ua->info_msg(_("Current Pool is: %s\n"), pr.Name);
768 if (!get_cmd(ua, _("Enter new Pool name: "))) {
771 update_vol_pool(ua, ua->cmd, &mr, &pr);
775 update_vol_from_pool(ua, &mr);
778 pool = select_pool_resource(ua);
780 update_all_vols_from_pool(ua, pool->name());
789 ua->info_msg(_("Current Enabled is: %d\n"), mr.Enabled);
790 if (!get_cmd(ua, _("Enter new Enabled: "))) {
793 if (strcasecmp(ua->cmd, "yes") == 0 || strcasecmp(ua->cmd, "true") == 0) {
795 } else if (strcasecmp(ua->cmd, "no") == 0 || strcasecmp(ua->cmd, "false") == 0) {
797 } else if (strcasecmp(ua->cmd, "archived") == 0) {
800 mr.Enabled = atoi(ua->cmd);
802 update_volenabled(ua, ua->cmd, &mr);
806 memset(&pr, 0, sizeof(POOL_DBR));
807 pr.PoolId = mr.RecyclePoolId;
808 if (db_get_pool_record(ua->jcr, ua->db, &pr)) {
809 ua->info_msg(_("Current RecyclePool is: %s\n"), pr.Name);
811 ua->info_msg(_("No current RecyclePool\n"));
813 if (!select_pool_dbr(ua, &pr, NT_("recyclepool"))) {
816 update_vol_recyclepool(ua, pr.Name, &mr);
821 ua->info_msg(_("Current ActionOnPurge is: %s\n"),
822 aop_to_str(mr.ActionOnPurge, ret));
823 if (!get_cmd(ua, _("Enter new ActionOnPurge (one of: Truncate, None): "))) {
827 update_vol_actiononpurge(ua, ua->cmd, &mr);
830 default: /* Done or error */
831 ua->info_msg(_("Selection terminated.\n"));
839 * Update long term statistics
841 static bool update_stats(UAContext *ua)
843 int i = find_arg_with_value(ua, NT_("days"));
847 since = atoi(ua->argv[i]) * 24*60*60;
850 int nb = db_update_stats(ua->jcr, ua->db, since);
851 ua->info_msg(_("Updating %i job(s).\n"), nb);
857 * Update pool record -- pull info from current POOL resource
859 static bool update_pool(UAContext *ua)
867 pool = get_pool_resource(ua);
872 memset(&pr, 0, sizeof(pr));
873 bstrncpy(pr.Name, pool->name(), sizeof(pr.Name));
874 if (!get_pool_dbr(ua, &pr)) {
878 set_pooldbr_from_poolres(&pr, pool, POOL_OP_UPDATE); /* update */
879 set_pooldbr_references(ua->jcr, ua->db, &pr, pool);
881 id = db_update_pool_record(ua->jcr, ua->db, &pr);
883 ua->error_msg(_("db_update_pool_record returned %d. ERR=%s\n"),
884 id, db_strerror(ua->db));
886 query = get_pool_memory(PM_MESSAGE);
887 Mmsg(query, list_pool, edit_int64(pr.PoolId, ed1));
888 db_list_sql_query(ua->jcr, ua->db, query, prtit, ua, 1, HORZ_LIST);
889 free_pool_memory(query);
890 ua->info_msg(_("Pool DB record updated from resource.\n"));
895 * Update a Job record -- allows you to change the
896 * date fields in a Job record. This helps when
897 * providing migration from other vendors.
899 static bool update_job(UAContext *ua)
902 char ed1[50], ed2[50];
903 POOL_MEM cmd(PM_MESSAGE);
907 char *client_name = NULL;
908 char *start_time = NULL;
910 NT_("starttime"), /* 0 */
911 NT_("client"), /* 1 */
914 Dmsg1(200, "cmd=%s\n", ua->cmd);
915 i = find_arg_with_value(ua, NT_("jobid"));
917 ua->error_msg(_("Expect JobId keyword, not found.\n"));
920 memset(&jr, 0, sizeof(jr));
921 memset(&cr, 0, sizeof(cr));
922 jr.JobId = str_to_int64(ua->argv[i]);
923 if (!db_get_job_record(ua->jcr, ua->db, &jr)) {
924 ua->error_msg("%s", db_strerror(ua->db));
928 for (i=0; kw[i]; i++) {
930 if ((j=find_arg_with_value(ua, kw[i])) >= 0) {
932 case 0: /* start time */
933 start_time = ua->argv[j];
935 case 1: /* Client name */
936 client_name = ua->argv[j];
941 if (!client_name && !start_time) {
942 ua->error_msg(_("Neither Client nor StartTime specified.\n"));
946 if (!get_client_dbr(ua, &cr)) {
949 jr.ClientId = cr.ClientId;
954 StartTime = str_to_utime(start_time);
955 if (StartTime == 0) {
956 ua->error_msg(_("Improper date format: %s\n"), ua->argv[i]);
959 delta_start = StartTime - jr.StartTime;
960 Dmsg3(200, "ST=%lld jr.ST=%lld delta=%lld\n", StartTime,
961 (utime_t)jr.StartTime, delta_start);
962 jr.StartTime = (time_t)StartTime;
963 jr.SchedTime += (time_t)delta_start;
964 jr.EndTime += (time_t)delta_start;
965 jr.JobTDate += delta_start;
966 /* Convert to DB times */
967 bstrutime(jr.cStartTime, sizeof(jr.cStartTime), jr.StartTime);
968 bstrutime(jr.cSchedTime, sizeof(jr.cSchedTime), jr.SchedTime);
969 bstrutime(jr.cEndTime, sizeof(jr.cEndTime), jr.EndTime);
971 Mmsg(cmd, "UPDATE Job SET ClientId=%s,StartTime='%s',SchedTime='%s',"
972 "EndTime='%s',JobTDate=%s WHERE JobId=%s",
973 edit_int64(jr.ClientId, ed1),
977 edit_uint64(jr.JobTDate, ed1),
978 edit_int64(jr.JobId, ed2));
979 if (!db_sql_query(ua->db, cmd.c_str(), NULL, NULL)) {
980 ua->error_msg("%s", db_strerror(ua->db));