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 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
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];
350 const char *poolname;
352 if(val && *val) { /* update volume recyclepool="Scratch" */
353 /* If a pool name is given, look up the PoolId */
354 memset(&pr, 0, sizeof(pr));
355 bstrncpy(pr.Name, val, sizeof(pr.Name));
356 if (!get_pool_dbr(ua, &pr, NT_("recyclepool"))) {
359 /* pool = select_pool_resource(ua); */
360 mr->RecyclePoolId = pr.PoolId; /* get the PoolId */
363 } else { /* update volume recyclepool="" */
364 /* If no pool name is given, set the PoolId to 0 (the default) */
365 mr->RecyclePoolId = 0;
366 poolname = _("*None*");
370 Mmsg(query, "UPDATE Media SET RecyclePoolId=%s WHERE MediaId=%s",
371 edit_int64(mr->RecyclePoolId, ed1), edit_int64(mr->MediaId, ed2));
372 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
373 ua->error_msg("%s", db_strerror(ua->db));
375 ua->info_msg(_("New RecyclePool is: %s\n"), poolname);
381 * Refresh the Volume information from the Pool record
383 static void update_vol_from_pool(UAContext *ua, MEDIA_DBR *mr)
387 memset(&pr, 0, sizeof(pr));
388 pr.PoolId = mr->PoolId;
389 if (!db_get_pool_record(ua->jcr, ua->db, &pr) ||
390 !acl_access_ok(ua, Pool_ACL, pr.Name)) {
393 set_pool_dbr_defaults_in_media_dbr(mr, &pr);
394 if (!db_update_media_defaults(ua->jcr, ua->db, mr)) {
395 ua->error_msg(_("Error updating Volume record: ERR=%s"), db_strerror(ua->db));
397 ua->info_msg(_("Volume defaults updated from \"%s\" Pool record.\n"),
403 * Refresh the Volume information from the Pool record
406 static void update_all_vols_from_pool(UAContext *ua, const char *pool_name)
411 memset(&pr, 0, sizeof(pr));
412 memset(&mr, 0, sizeof(mr));
414 bstrncpy(pr.Name, pool_name, sizeof(pr.Name));
415 if (!get_pool_dbr(ua, &pr)) {
418 set_pool_dbr_defaults_in_media_dbr(&mr, &pr);
419 mr.PoolId = pr.PoolId;
420 if (!db_update_media_defaults(ua->jcr, ua->db, &mr)) {
421 ua->error_msg(_("Error updating Volume records: ERR=%s"), db_strerror(ua->db));
423 ua->info_msg(_("All Volume defaults updated from \"%s\" Pool record.\n"),
428 static void update_all_vols(UAContext *ua)
435 memset(&pr, 0, sizeof(pr));
436 memset(&mr, 0, sizeof(mr));
438 if (!db_get_pool_ids(ua->jcr, ua->db, &num_pools, &ids)) {
439 ua->error_msg(_("Error obtaining pool ids. ERR=%s\n"), db_strerror(ua->db));
443 for (i=0; i<num_pools; i++) {
445 if (!db_get_pool_record(ua->jcr, ua->db, &pr)) { /* ***FIXME*** use acl? */
446 ua->warning_msg(_("Updating all pools, but skipped PoolId=%d. ERR=%s\n"), db_strerror(ua->db));
450 set_pool_dbr_defaults_in_media_dbr(&mr, &pr);
451 mr.PoolId = pr.PoolId;
453 if (!db_update_media_defaults(ua->jcr, ua->db, &mr)) {
454 ua->error_msg(_("Error updating Volume records: ERR=%s"), db_strerror(ua->db));
456 ua->info_msg(_("All Volume defaults updated from \"%s\" Pool record.\n"),
464 static void update_volenabled(UAContext *ua, char *val, MEDIA_DBR *mr)
466 mr->Enabled = get_enabled(ua, val);
467 if (mr->Enabled < 0) {
470 if (!db_update_media_record(ua->jcr, ua->db, mr)) {
471 ua->error_msg(_("Error updating media record Enabled: ERR=%s"),
472 db_strerror(ua->db));
474 ua->info_msg(_("New Enabled is: %d\n"), mr->Enabled);
478 static void update_vol_actiononpurge(UAContext *ua, char *val, MEDIA_DBR *mr)
481 if (strcasecmp(val, "truncate") == 0) {
482 mr->ActionOnPurge = AOP_TRUNCATE;
484 mr->ActionOnPurge = 0;
487 if (!db_update_media_record(ua->jcr, ua->db, mr)) {
488 ua->error_msg(_("Error updating media record ActionOnPurge: ERR=%s"),
489 db_strerror(ua->db));
491 ua->info_msg(_("New ActionOnPurge is: %s\n"),
492 aop_to_str(mr->ActionOnPurge, ret));
497 * Update a media record -- allows you to change the
498 * Volume status. E.g. if you want Bacula to stop
499 * writing on the volume, set it to anything other
502 static int update_volume(UAContext *ua)
514 NT_("VolStatus"), /* 0 */
515 NT_("VolRetention"), /* 1 */
516 NT_("VolUse"), /* 2 */
517 NT_("MaxVolJobs"), /* 3 */
518 NT_("MaxVolFiles"), /* 4 */
519 NT_("MaxVolBytes"), /* 5 */
520 NT_("Recycle"), /* 6 */
521 NT_("InChanger"), /* 7 */
524 NT_("FromPool"), /* 10 */
525 NT_("AllFromPool"), /* 11 !!! see below !!! */
526 NT_("Enabled"), /* 12 */
527 NT_("RecyclePool"), /* 13 */
528 NT_("ActionOnPurge"), /* 14 */
531 #define AllFromPool 11 /* keep this updated with above */
533 for (i=0; kw[i]; i++) {
537 if ((j=find_arg_with_value(ua, kw[i])) > 0) {
538 /* If all from pool don't select a media record */
539 if (i != AllFromPool && !select_media_dbr(ua, &mr)) {
544 update_volstatus(ua, ua->argv[j], &mr);
547 update_volretention(ua, ua->argv[j], &mr);
550 update_voluseduration(ua, ua->argv[j], &mr);
553 update_volmaxjobs(ua, ua->argv[j], &mr);
556 update_volmaxfiles(ua, ua->argv[j], &mr);
559 update_volmaxbytes(ua, ua->argv[j], &mr);
562 update_volrecycle(ua, ua->argv[j], &mr);
565 update_volinchanger(ua, ua->argv[j], &mr);
568 update_volslot(ua, ua->argv[j], &mr);
571 memset(&pr, 0, sizeof(POOL_DBR));
572 pr.PoolId = mr.PoolId;
573 if (!db_get_pool_record(ua->jcr, ua->db, &pr)) {
574 ua->error_msg("%s", db_strerror(ua->db));
577 update_vol_pool(ua, ua->argv[j], &mr, &pr);
580 update_vol_from_pool(ua, &mr);
583 update_all_vols_from_pool(ua, ua->argv[j]);
586 update_volenabled(ua, ua->argv[j], &mr);
589 update_vol_recyclepool(ua, ua->argv[j], &mr);
592 update_vol_actiononpurge(ua, ua->argv[j], &mr);
599 /* Allow user to simply update all volumes */
600 if (find_arg(ua, NT_("fromallpools")) > 0) {
606 start_prompt(ua, _("Parameters to modify:\n"));
607 add_prompt(ua, _("Volume Status")); /* 0 */
608 add_prompt(ua, _("Volume Retention Period")); /* 1 */
609 add_prompt(ua, _("Volume Use Duration")); /* 2 */
610 add_prompt(ua, _("Maximum Volume Jobs")); /* 3 */
611 add_prompt(ua, _("Maximum Volume Files")); /* 4 */
612 add_prompt(ua, _("Maximum Volume Bytes")); /* 5 */
613 add_prompt(ua, _("Recycle Flag")); /* 6 */
614 add_prompt(ua, _("Slot")); /* 7 */
615 add_prompt(ua, _("InChanger Flag")); /* 8 */
616 add_prompt(ua, _("Volume Files")); /* 9 */
617 add_prompt(ua, _("Pool")); /* 10 */
618 add_prompt(ua, _("Volume from Pool")); /* 11 */
619 add_prompt(ua, _("All Volumes from Pool")); /* 12 */
620 add_prompt(ua, _("All Volumes from all Pools")); /* 13 */
621 add_prompt(ua, _("Enabled")), /* 14 */
622 add_prompt(ua, _("RecyclePool")), /* 15 */
623 add_prompt(ua, _("Action On Purge")), /* 16 */
624 add_prompt(ua, _("Done")); /* 17 */
625 i = do_prompt(ua, "", _("Select parameter to modify"), NULL, 0);
627 /* For All Volumes, All Volumes from Pool, and Done, we don't need
629 if ( i != 12 && i != 13 && i != 17) {
630 if (!select_media_dbr(ua, &mr)) { /* Get Volume record */
633 ua->info_msg(_("Updating Volume \"%s\"\n"), mr.VolumeName);
636 case 0: /* Volume Status */
637 /* Modify Volume Status */
638 ua->info_msg(_("Current Volume status is: %s\n"), mr.VolStatus);
639 start_prompt(ua, _("Possible Values are:\n"));
640 add_prompt(ua, NT_("Append"));
641 add_prompt(ua, NT_("Archive"));
642 add_prompt(ua, NT_("Disabled"));
643 add_prompt(ua, NT_("Full"));
644 add_prompt(ua, NT_("Used"));
645 add_prompt(ua, NT_("Cleaning"));
646 if (strcmp(mr.VolStatus, NT_("Purged")) == 0) {
647 add_prompt(ua, NT_("Recycle"));
649 add_prompt(ua, NT_("Read-Only"));
650 if (do_prompt(ua, "", _("Choose new Volume Status"), ua->cmd, sizeof(mr.VolStatus)) < 0) {
653 update_volstatus(ua, ua->cmd, &mr);
655 case 1: /* Retention */
656 ua->info_msg(_("Current retention period is: %s\n"),
657 edit_utime(mr.VolRetention, ed1, sizeof(ed1)));
658 if (!get_cmd(ua, _("Enter Volume Retention period: "))) {
661 update_volretention(ua, ua->cmd, &mr);
664 case 2: /* Use Duration */
665 ua->info_msg(_("Current use duration is: %s\n"),
666 edit_utime(mr.VolUseDuration, ed1, sizeof(ed1)));
667 if (!get_cmd(ua, _("Enter Volume Use Duration: "))) {
670 update_voluseduration(ua, ua->cmd, &mr);
673 case 3: /* Max Jobs */
674 ua->info_msg(_("Current max jobs is: %u\n"), mr.MaxVolJobs);
675 if (!get_pint(ua, _("Enter new Maximum Jobs: "))) {
678 update_volmaxjobs(ua, ua->cmd, &mr);
681 case 4: /* Max Files */
682 ua->info_msg(_("Current max files is: %u\n"), mr.MaxVolFiles);
683 if (!get_pint(ua, _("Enter new Maximum Files: "))) {
686 update_volmaxfiles(ua, ua->cmd, &mr);
689 case 5: /* Max Bytes */
690 ua->info_msg(_("Current value is: %s\n"), edit_uint64(mr.MaxVolBytes, ed1));
691 if (!get_cmd(ua, _("Enter new Maximum Bytes: "))) {
694 update_volmaxbytes(ua, ua->cmd, &mr);
698 case 6: /* Recycle */
699 ua->info_msg(_("Current recycle flag is: %s\n"),
700 mr.Recycle==1?_("yes"):_("no"));
701 if (!get_yesno(ua, _("Enter new Recycle status: "))) {
704 update_volrecycle(ua, ua->cmd, &mr);
708 ua->info_msg(_("Current Slot is: %d\n"), mr.Slot);
709 if (!get_pint(ua, _("Enter new Slot: "))) {
712 update_volslot(ua, ua->cmd, &mr);
715 case 8: /* InChanger */
716 ua->info_msg(_("Current InChanger flag is: %d\n"), mr.InChanger);
717 bsnprintf(buf, sizeof(buf), _("Set InChanger flag for Volume \"%s\": yes/no: "),
719 if (!get_yesno(ua, buf)) {
722 mr.InChanger = ua->pint32_val;
724 * Make sure to use db_update... rather than doing this directly,
725 * so that any Slot is handled correctly.
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 aop_to_str(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));