2 Bacula® - The Network Backup Solution
4 Copyright (C) 2000-2010 Free Software Foundation Europe e.V.
6 The main author of Bacula is Kern Sibbald, with contributions from
7 many others, a complete list can be found in the file AUTHORS.
8 This program is Free Software; you can redistribute it and/or
9 modify it under the terms of version three of the GNU Affero General Public
10 License as published by the Free Software Foundation and included
13 This program is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU Affero General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
23 Bacula® is a registered trademark of Kern Sibbald.
24 The licensor of Bacula is the Free Software Foundation Europe
25 (FSFE), Fiduciary Program, Sumatrastrasse 25, 8006 Zürich,
26 Switzerland, email:ftf@fsfeurope.org.
30 * Bacula Director -- Update command processing
31 * Split from ua_cmds.c March 2005
33 * Kern Sibbald, September MM
40 /* Forward referenced functions */
41 static int update_volume(UAContext *ua);
42 static bool update_pool(UAContext *ua);
43 static bool update_job(UAContext *ua);
44 static bool update_stats(UAContext *ua);
47 * Update a Pool Record in the database.
48 * It is always updated from the Resource record.
50 * update pool=<pool-name>
51 * updates pool from Pool resource
52 * update media pool=<pool-name> volume=<volume-name>
53 * changes pool info for volume
54 * update slots [scan=...]
55 * updates autochanger slots
56 * update stats [days=...]
57 * updates long term statistics
59 int update_cmd(UAContext *ua, const char *cmd)
61 static const char *kw[] = {
63 NT_("volume"), /* 1 */
71 if (!open_client_db(ua)) {
75 switch (find_arg_keyword(ua, kw)) {
97 start_prompt(ua, _("Update choice:\n"));
98 add_prompt(ua, _("Volume parameters"));
99 add_prompt(ua, _("Pool from resource"));
100 add_prompt(ua, _("Slots from autochanger"));
101 add_prompt(ua, _("Long term statistics"));
102 switch (do_prompt(ua, _("item"), _("Choose catalog item to update"), NULL, 0)) {
121 static void update_volstatus(UAContext *ua, const char *val, MEDIA_DBR *mr)
123 POOL_MEM query(PM_MESSAGE);
138 for (i=0; kw[i]; i++) {
139 if (strcasecmp(val, kw[i]) == 0) {
145 ua->error_msg(_("Invalid VolStatus specified: %s\n"), val);
148 bstrncpy(mr->VolStatus, kw[i], sizeof(mr->VolStatus));
149 Mmsg(query, "UPDATE Media SET VolStatus='%s' WHERE MediaId=%s",
150 mr->VolStatus, edit_int64(mr->MediaId,ed1));
151 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
152 ua->error_msg("%s", db_strerror(ua->db));
154 ua->info_msg(_("New Volume status is: %s\n"), mr->VolStatus);
159 static void update_volretention(UAContext *ua, char *val, MEDIA_DBR *mr)
161 char ed1[150], ed2[50];
162 POOL_MEM query(PM_MESSAGE);
163 if (!duration_to_utime(val, &mr->VolRetention)) {
164 ua->error_msg(_("Invalid retention period specified: %s\n"), val);
167 Mmsg(query, "UPDATE Media SET VolRetention=%s WHERE MediaId=%s",
168 edit_uint64(mr->VolRetention, ed1), edit_int64(mr->MediaId,ed2));
169 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
170 ua->error_msg("%s", db_strerror(ua->db));
172 ua->info_msg(_("New retention period is: %s\n"),
173 edit_utime(mr->VolRetention, ed1, sizeof(ed1)));
177 static void update_voluseduration(UAContext *ua, char *val, MEDIA_DBR *mr)
179 char ed1[150], ed2[50];
180 POOL_MEM query(PM_MESSAGE);
182 if (!duration_to_utime(val, &mr->VolUseDuration)) {
183 ua->error_msg(_("Invalid use duration specified: %s\n"), val);
186 Mmsg(query, "UPDATE Media SET VolUseDuration=%s WHERE MediaId=%s",
187 edit_uint64(mr->VolUseDuration, ed1), edit_int64(mr->MediaId,ed2));
188 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
189 ua->error_msg("%s", db_strerror(ua->db));
191 ua->info_msg(_("New use duration is: %s\n"),
192 edit_utime(mr->VolUseDuration, ed1, sizeof(ed1)));
196 static void update_volmaxjobs(UAContext *ua, char *val, MEDIA_DBR *mr)
198 POOL_MEM query(PM_MESSAGE);
200 Mmsg(query, "UPDATE Media SET MaxVolJobs=%s WHERE MediaId=%s",
201 val, edit_int64(mr->MediaId,ed1));
202 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
203 ua->error_msg("%s", db_strerror(ua->db));
205 ua->info_msg(_("New max jobs is: %s\n"), val);
209 static void update_volmaxfiles(UAContext *ua, char *val, MEDIA_DBR *mr)
211 POOL_MEM query(PM_MESSAGE);
213 Mmsg(query, "UPDATE Media SET MaxVolFiles=%s WHERE MediaId=%s",
214 val, edit_int64(mr->MediaId, ed1));
215 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
216 ua->error_msg("%s", db_strerror(ua->db));
218 ua->info_msg(_("New max files is: %s\n"), val);
222 static void update_volmaxbytes(UAContext *ua, char *val, MEDIA_DBR *mr)
225 char ed1[50], ed2[50];
226 POOL_MEM query(PM_MESSAGE);
228 if (!size_to_uint64(val, strlen(val), &maxbytes)) {
229 ua->error_msg(_("Invalid max. bytes specification: %s\n"), val);
232 Mmsg(query, "UPDATE Media SET MaxVolBytes=%s WHERE MediaId=%s",
233 edit_uint64(maxbytes, ed1), edit_int64(mr->MediaId, ed2));
234 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
235 ua->error_msg("%s", db_strerror(ua->db));
237 ua->info_msg(_("New Max bytes is: %s\n"), edit_uint64(maxbytes, ed1));
241 static void update_volrecycle(UAContext *ua, char *val, MEDIA_DBR *mr)
246 POOL_MEM query(PM_MESSAGE);
247 if (!is_yesno(val, &recycle)) {
248 ua->error_msg(_("Invalid value. It must be yes or no.\n"));
251 Mmsg(query, "UPDATE Media SET Recycle=%d WHERE MediaId=%s",
252 recycle, edit_int64(mr->MediaId, ed1));
253 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
254 ua->error_msg("%s", db_strerror(ua->db));
256 ua->info_msg(_("New Recycle flag is: %s\n"),
257 recycle==1?_("yes"):_("no"));
261 static void update_volinchanger(UAContext *ua, char *val, MEDIA_DBR *mr)
266 POOL_MEM query(PM_MESSAGE);
267 if (!is_yesno(val, &InChanger)) {
268 ua->error_msg(_("Invalid value. It must be yes or no.\n"));
271 Mmsg(query, "UPDATE Media SET InChanger=%d WHERE MediaId=%s",
272 InChanger, edit_int64(mr->MediaId, ed1));
273 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
274 ua->error_msg("%s", db_strerror(ua->db));
276 ua->info_msg(_("New InChanger flag is: %s\n"),
277 InChanger==1?_("yes"):_("no"));
282 static void update_volslot(UAContext *ua, char *val, MEDIA_DBR *mr)
286 memset(&pr, 0, sizeof(POOL_DBR));
287 pr.PoolId = mr->PoolId;
288 if (!db_get_pool_record(ua->jcr, ua->db, &pr)) {
289 ua->error_msg("%s", db_strerror(ua->db));
292 mr->Slot = atoi(val);
293 if (pr.MaxVols > 0 && mr->Slot > (int)pr.MaxVols) {
294 ua->error_msg(_("Invalid slot, it must be between 0 and MaxVols=%d\n"),
299 * Make sure to use db_update... rather than doing this directly,
300 * so that any Slot is handled correctly.
302 if (!db_update_media_record(ua->jcr, ua->db, mr)) {
303 ua->error_msg(_("Error updating media record Slot: ERR=%s"), db_strerror(ua->db));
305 ua->info_msg(_("New Slot is: %d\n"), mr->Slot);
309 /* Modify the Pool in which this Volume is located */
310 void update_vol_pool(UAContext *ua, char *val, MEDIA_DBR *mr, POOL_DBR *opr)
313 POOL_MEM query(PM_MESSAGE);
314 char ed1[50], ed2[50];
316 memset(&pr, 0, sizeof(pr));
317 bstrncpy(pr.Name, val, sizeof(pr.Name));
318 if (!get_pool_dbr(ua, &pr)) {
321 mr->PoolId = pr.PoolId; /* set new PoolId */
325 Mmsg(query, "UPDATE Media SET PoolId=%s WHERE MediaId=%s",
326 edit_int64(mr->PoolId, ed1), edit_int64(mr->MediaId, ed2));
327 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
328 ua->error_msg("%s", db_strerror(ua->db));
330 ua->info_msg(_("New Pool is: %s\n"), pr.Name);
332 if (!db_update_pool_record(ua->jcr, ua->db, opr)) {
333 ua->error_msg("%s", db_strerror(ua->db));
336 if (!db_update_pool_record(ua->jcr, ua->db, &pr)) {
337 ua->error_msg("%s", db_strerror(ua->db));
343 /* Modify the RecyclePool of a Volume */
344 void update_vol_recyclepool(UAContext *ua, char *val, MEDIA_DBR *mr)
347 POOL_MEM query(PM_MESSAGE);
348 char ed1[50], ed2[50], *poolname;
350 if(val && *val) { /* update volume recyclepool="Scratch" */
351 /* If a pool name is given, look up the PoolId */
352 memset(&pr, 0, sizeof(pr));
353 bstrncpy(pr.Name, val, sizeof(pr.Name));
354 if (!get_pool_dbr(ua, &pr, NT_("recyclepool"))) {
357 /* pool = select_pool_resource(ua); */
358 mr->RecyclePoolId = pr.PoolId; /* get the PoolId */
361 } else { /* update volume recyclepool="" */
362 /* If no pool name is given, set the PoolId to 0 (the default) */
363 mr->RecyclePoolId = 0;
364 poolname = _("*None*");
368 Mmsg(query, "UPDATE Media SET RecyclePoolId=%s WHERE MediaId=%s",
369 edit_int64(mr->RecyclePoolId, ed1), edit_int64(mr->MediaId, ed2));
370 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
371 ua->error_msg("%s", db_strerror(ua->db));
373 ua->info_msg(_("New RecyclePool is: %s\n"), poolname);
379 * Refresh the Volume information from the Pool record
381 static void update_vol_from_pool(UAContext *ua, MEDIA_DBR *mr)
385 memset(&pr, 0, sizeof(pr));
386 pr.PoolId = mr->PoolId;
387 if (!db_get_pool_record(ua->jcr, ua->db, &pr) ||
388 !acl_access_ok(ua, Pool_ACL, pr.Name)) {
391 set_pool_dbr_defaults_in_media_dbr(mr, &pr);
392 if (!db_update_media_defaults(ua->jcr, ua->db, mr)) {
393 ua->error_msg(_("Error updating Volume record: ERR=%s"), db_strerror(ua->db));
395 ua->info_msg(_("Volume defaults updated from \"%s\" Pool record.\n"),
401 * Refresh the Volume information from the Pool record
404 static void update_all_vols_from_pool(UAContext *ua, const char *pool_name)
409 memset(&pr, 0, sizeof(pr));
410 memset(&mr, 0, sizeof(mr));
412 bstrncpy(pr.Name, pool_name, sizeof(pr.Name));
413 if (!get_pool_dbr(ua, &pr)) {
416 set_pool_dbr_defaults_in_media_dbr(&mr, &pr);
417 mr.PoolId = pr.PoolId;
418 if (!db_update_media_defaults(ua->jcr, ua->db, &mr)) {
419 ua->error_msg(_("Error updating Volume records: ERR=%s"), db_strerror(ua->db));
421 ua->info_msg(_("All Volume defaults updated from \"%s\" Pool record.\n"),
426 static void update_all_vols(UAContext *ua)
433 memset(&pr, 0, sizeof(pr));
434 memset(&mr, 0, sizeof(mr));
436 if (!db_get_pool_ids(ua->jcr, ua->db, &num_pools, &ids)) {
437 ua->error_msg(_("Error obtaining pool ids. ERR=%s\n"), db_strerror(ua->db));
441 for (i=0; i<num_pools; i++) {
443 if (!db_get_pool_record(ua->jcr, ua->db, &pr)) { /* ***FIXME*** use acl? */
444 ua->warning_msg(_("Updating all pools, but skipped PoolId=%d. ERR=%s\n"), db_strerror(ua->db));
448 set_pool_dbr_defaults_in_media_dbr(&mr, &pr);
449 mr.PoolId = pr.PoolId;
451 if (!db_update_media_defaults(ua->jcr, ua->db, &mr)) {
452 ua->error_msg(_("Error updating Volume records: ERR=%s"), db_strerror(ua->db));
454 ua->info_msg(_("All Volume defaults updated from \"%s\" Pool record.\n"),
462 static void update_volenabled(UAContext *ua, char *val, MEDIA_DBR *mr)
464 mr->Enabled = get_enabled(ua, val);
465 if (mr->Enabled < 0) {
468 if (!db_update_media_record(ua->jcr, ua->db, mr)) {
469 ua->error_msg(_("Error updating media record Enabled: ERR=%s"),
470 db_strerror(ua->db));
472 ua->info_msg(_("New Enabled is: %d\n"), mr->Enabled);
476 static void update_vol_actiononpurge(UAContext *ua, char *val, MEDIA_DBR *mr)
479 if (strcasecmp(val, "truncate") == 0) {
480 mr->ActionOnPurge = ON_PURGE_TRUNCATE;
482 mr->ActionOnPurge = 0;
485 if (!db_update_media_record(ua->jcr, ua->db, mr)) {
486 ua->error_msg(_("Error updating media record ActionOnPurge: ERR=%s"),
487 db_strerror(ua->db));
489 ua->info_msg(_("New ActionOnPurge is: %s\n"),
490 action_on_purge_to_string(mr->ActionOnPurge, ret));
495 * Update a media record -- allows you to change the
496 * Volume status. E.g. if you want Bacula to stop
497 * writing on the volume, set it to anything other
500 static int update_volume(UAContext *ua)
512 NT_("VolStatus"), /* 0 */
513 NT_("VolRetention"), /* 1 */
514 NT_("VolUse"), /* 2 */
515 NT_("MaxVolJobs"), /* 3 */
516 NT_("MaxVolFiles"), /* 4 */
517 NT_("MaxVolBytes"), /* 5 */
518 NT_("Recycle"), /* 6 */
519 NT_("InChanger"), /* 7 */
522 NT_("FromPool"), /* 10 */
523 NT_("AllFromPool"), /* 11 !!! see below !!! */
524 NT_("Enabled"), /* 12 */
525 NT_("RecyclePool"), /* 13 */
526 NT_("ActionOnPurge"), /* 14 */
529 #define AllFromPool 11 /* keep this updated with above */
531 for (i=0; kw[i]; i++) {
535 if ((j=find_arg_with_value(ua, kw[i])) > 0) {
536 /* If all from pool don't select a media record */
537 if (i != AllFromPool && !select_media_dbr(ua, &mr)) {
542 update_volstatus(ua, ua->argv[j], &mr);
545 update_volretention(ua, ua->argv[j], &mr);
548 update_voluseduration(ua, ua->argv[j], &mr);
551 update_volmaxjobs(ua, ua->argv[j], &mr);
554 update_volmaxfiles(ua, ua->argv[j], &mr);
557 update_volmaxbytes(ua, ua->argv[j], &mr);
560 update_volrecycle(ua, ua->argv[j], &mr);
563 update_volinchanger(ua, ua->argv[j], &mr);
566 update_volslot(ua, ua->argv[j], &mr);
569 memset(&pr, 0, sizeof(POOL_DBR));
570 pr.PoolId = mr.PoolId;
571 if (!db_get_pool_record(ua->jcr, ua->db, &pr)) {
572 ua->error_msg("%s", db_strerror(ua->db));
575 update_vol_pool(ua, ua->argv[j], &mr, &pr);
578 update_vol_from_pool(ua, &mr);
581 update_all_vols_from_pool(ua, ua->argv[j]);
584 update_volenabled(ua, ua->argv[j], &mr);
587 update_vol_recyclepool(ua, ua->argv[j], &mr);
590 update_vol_actiononpurge(ua, ua->argv[j], &mr);
597 /* Allow user to simply update all volumes */
598 if (find_arg(ua, NT_("fromallpools")) > 0) {
604 start_prompt(ua, _("Parameters to modify:\n"));
605 add_prompt(ua, _("Volume Status")); /* 0 */
606 add_prompt(ua, _("Volume Retention Period")); /* 1 */
607 add_prompt(ua, _("Volume Use Duration")); /* 2 */
608 add_prompt(ua, _("Maximum Volume Jobs")); /* 3 */
609 add_prompt(ua, _("Maximum Volume Files")); /* 4 */
610 add_prompt(ua, _("Maximum Volume Bytes")); /* 5 */
611 add_prompt(ua, _("Recycle Flag")); /* 6 */
612 add_prompt(ua, _("Slot")); /* 7 */
613 add_prompt(ua, _("InChanger Flag")); /* 8 */
614 add_prompt(ua, _("Volume Files")); /* 9 */
615 add_prompt(ua, _("Pool")); /* 10 */
616 add_prompt(ua, _("Volume from Pool")); /* 11 */
617 add_prompt(ua, _("All Volumes from Pool")); /* 12 */
618 add_prompt(ua, _("All Volumes from all Pools")); /* 13 */
619 add_prompt(ua, _("Enabled")), /* 14 */
620 add_prompt(ua, _("RecyclePool")), /* 15 */
621 add_prompt(ua, _("Action On Purge")), /* 16 */
622 add_prompt(ua, _("Done")); /* 17 */
623 i = do_prompt(ua, "", _("Select parameter to modify"), NULL, 0);
625 /* For All Volumes, All Volumes from Pool, and Done, we don't need
627 if ( i != 12 && i != 13 && i != 17) {
628 if (!select_media_dbr(ua, &mr)) { /* Get Volume record */
631 ua->info_msg(_("Updating Volume \"%s\"\n"), mr.VolumeName);
634 case 0: /* Volume Status */
635 /* Modify Volume Status */
636 ua->info_msg(_("Current Volume status is: %s\n"), mr.VolStatus);
637 start_prompt(ua, _("Possible Values are:\n"));
638 add_prompt(ua, NT_("Append"));
639 add_prompt(ua, NT_("Archive"));
640 add_prompt(ua, NT_("Disabled"));
641 add_prompt(ua, NT_("Full"));
642 add_prompt(ua, NT_("Used"));
643 add_prompt(ua, NT_("Cleaning"));
644 if (strcmp(mr.VolStatus, NT_("Purged")) == 0) {
645 add_prompt(ua, NT_("Recycle"));
647 add_prompt(ua, NT_("Read-Only"));
648 if (do_prompt(ua, "", _("Choose new Volume Status"), ua->cmd, sizeof(mr.VolStatus)) < 0) {
651 update_volstatus(ua, ua->cmd, &mr);
653 case 1: /* Retention */
654 ua->info_msg(_("Current retention period is: %s\n"),
655 edit_utime(mr.VolRetention, ed1, sizeof(ed1)));
656 if (!get_cmd(ua, _("Enter Volume Retention period: "))) {
659 update_volretention(ua, ua->cmd, &mr);
662 case 2: /* Use Duration */
663 ua->info_msg(_("Current use duration is: %s\n"),
664 edit_utime(mr.VolUseDuration, ed1, sizeof(ed1)));
665 if (!get_cmd(ua, _("Enter Volume Use Duration: "))) {
668 update_voluseduration(ua, ua->cmd, &mr);
671 case 3: /* Max Jobs */
672 ua->info_msg(_("Current max jobs is: %u\n"), mr.MaxVolJobs);
673 if (!get_pint(ua, _("Enter new Maximum Jobs: "))) {
676 update_volmaxjobs(ua, ua->cmd, &mr);
679 case 4: /* Max Files */
680 ua->info_msg(_("Current max files is: %u\n"), mr.MaxVolFiles);
681 if (!get_pint(ua, _("Enter new Maximum Files: "))) {
684 update_volmaxfiles(ua, ua->cmd, &mr);
687 case 5: /* Max Bytes */
688 ua->info_msg(_("Current value is: %s\n"), edit_uint64(mr.MaxVolBytes, ed1));
689 if (!get_cmd(ua, _("Enter new Maximum Bytes: "))) {
692 update_volmaxbytes(ua, ua->cmd, &mr);
696 case 6: /* Recycle */
697 ua->info_msg(_("Current recycle flag is: %s\n"),
698 mr.Recycle==1?_("yes"):_("no"));
699 if (!get_yesno(ua, _("Enter new Recycle status: "))) {
702 update_volrecycle(ua, ua->cmd, &mr);
706 ua->info_msg(_("Current Slot is: %d\n"), mr.Slot);
707 if (!get_pint(ua, _("Enter new Slot: "))) {
710 update_volslot(ua, ua->cmd, &mr);
713 case 8: /* InChanger */
714 ua->info_msg(_("Current InChanger flag is: %d\n"), mr.InChanger);
715 bsnprintf(buf, sizeof(buf), _("Set InChanger flag for Volume \"%s\": yes/no: "),
717 if (!get_yesno(ua, buf)) {
720 mr.InChanger = ua->pint32_val;
722 * Make sure to use db_update... rather than doing this directly,
723 * so that any Slot is handled correctly.
725 if (!db_update_media_record(ua->jcr, ua->db, &mr)) {
726 ua->error_msg(_("Error updating media record Slot: ERR=%s"), db_strerror(ua->db));
728 ua->info_msg(_("New InChanger flag is: %d\n"), mr.InChanger);
733 case 9: /* Volume Files */
735 ua->warning_msg(_("Warning changing Volume Files can result\n"
736 "in loss of data on your Volume\n\n"));
737 ua->info_msg(_("Current Volume Files is: %u\n"), mr.VolFiles);
738 if (!get_pint(ua, _("Enter new number of Files for Volume: "))) {
741 VolFiles = ua->pint32_val;
742 if (VolFiles != (int)(mr.VolFiles + 1)) {
743 ua->warning_msg(_("Normally, you should only increase Volume Files by one!\n"));
744 if (!get_yesno(ua, _("Increase Volume Files? (yes/no): ")) || ua->pint32_val == 0) {
748 query = get_pool_memory(PM_MESSAGE);
749 Mmsg(query, "UPDATE Media SET VolFiles=%u WHERE MediaId=%s",
750 VolFiles, edit_int64(mr.MediaId, ed1));
751 if (!db_sql_query(ua->db, query, NULL, NULL)) {
752 ua->error_msg("%s", db_strerror(ua->db));
754 ua->info_msg(_("New Volume Files is: %u\n"), VolFiles);
756 free_pool_memory(query);
759 case 10: /* Volume's Pool */
760 memset(&pr, 0, sizeof(POOL_DBR));
761 pr.PoolId = mr.PoolId;
762 if (!db_get_pool_record(ua->jcr, ua->db, &pr)) {
763 ua->error_msg("%s", db_strerror(ua->db));
766 ua->info_msg(_("Current Pool is: %s\n"), pr.Name);
767 if (!get_cmd(ua, _("Enter new Pool name: "))) {
770 update_vol_pool(ua, ua->cmd, &mr, &pr);
774 update_vol_from_pool(ua, &mr);
777 pool = select_pool_resource(ua);
779 update_all_vols_from_pool(ua, pool->name());
788 ua->info_msg(_("Current Enabled is: %d\n"), mr.Enabled);
789 if (!get_cmd(ua, _("Enter new Enabled: "))) {
792 if (strcasecmp(ua->cmd, "yes") == 0 || strcasecmp(ua->cmd, "true") == 0) {
794 } else if (strcasecmp(ua->cmd, "no") == 0 || strcasecmp(ua->cmd, "false") == 0) {
796 } else if (strcasecmp(ua->cmd, "archived") == 0) {
799 mr.Enabled = atoi(ua->cmd);
801 update_volenabled(ua, ua->cmd, &mr);
805 memset(&pr, 0, sizeof(POOL_DBR));
806 pr.PoolId = mr.RecyclePoolId;
807 if (db_get_pool_record(ua->jcr, ua->db, &pr)) {
808 ua->info_msg(_("Current RecyclePool is: %s\n"), pr.Name);
810 ua->info_msg(_("No current RecyclePool\n"));
812 if (!select_pool_dbr(ua, &pr, NT_("recyclepool"))) {
815 update_vol_recyclepool(ua, pr.Name, &mr);
820 ua->info_msg(_("Current ActionOnPurge is: %s\n"),
821 action_on_purge_to_string(mr.ActionOnPurge, ret));
822 if (!get_cmd(ua, _("Enter new ActionOnPurge (one of: Truncate, None): "))) {
826 update_vol_actiononpurge(ua, ua->cmd, &mr);
829 default: /* Done or error */
830 ua->info_msg(_("Selection terminated.\n"));
838 * Update long term statistics
840 static bool update_stats(UAContext *ua)
842 int i = find_arg_with_value(ua, NT_("days"));
846 since = atoi(ua->argv[i]) * 24*60*60;
849 int nb = db_update_stats(ua->jcr, ua->db, since);
850 ua->info_msg(_("Updating %i job(s).\n"), nb);
856 * Update pool record -- pull info from current POOL resource
858 static bool update_pool(UAContext *ua)
866 pool = get_pool_resource(ua);
871 memset(&pr, 0, sizeof(pr));
872 bstrncpy(pr.Name, pool->name(), sizeof(pr.Name));
873 if (!get_pool_dbr(ua, &pr)) {
877 set_pooldbr_from_poolres(&pr, pool, POOL_OP_UPDATE); /* update */
878 set_pooldbr_references(ua->jcr, ua->db, &pr, pool);
880 id = db_update_pool_record(ua->jcr, ua->db, &pr);
882 ua->error_msg(_("db_update_pool_record returned %d. ERR=%s\n"),
883 id, db_strerror(ua->db));
885 query = get_pool_memory(PM_MESSAGE);
886 Mmsg(query, list_pool, edit_int64(pr.PoolId, ed1));
887 db_list_sql_query(ua->jcr, ua->db, query, prtit, ua, 1, HORZ_LIST);
888 free_pool_memory(query);
889 ua->info_msg(_("Pool DB record updated from resource.\n"));
894 * Update a Job record -- allows you to change the
895 * date fields in a Job record. This helps when
896 * providing migration from other vendors.
898 static bool update_job(UAContext *ua)
901 char ed1[50], ed2[50];
902 POOL_MEM cmd(PM_MESSAGE);
906 char *client_name = NULL;
907 char *start_time = NULL;
909 NT_("starttime"), /* 0 */
910 NT_("client"), /* 1 */
913 Dmsg1(200, "cmd=%s\n", ua->cmd);
914 i = find_arg_with_value(ua, NT_("jobid"));
916 ua->error_msg(_("Expect JobId keyword, not found.\n"));
919 memset(&jr, 0, sizeof(jr));
920 memset(&cr, 0, sizeof(cr));
921 jr.JobId = str_to_int64(ua->argv[i]);
922 if (!db_get_job_record(ua->jcr, ua->db, &jr)) {
923 ua->error_msg("%s", db_strerror(ua->db));
927 for (i=0; kw[i]; i++) {
929 if ((j=find_arg_with_value(ua, kw[i])) >= 0) {
931 case 0: /* start time */
932 start_time = ua->argv[j];
934 case 1: /* Client name */
935 client_name = ua->argv[j];
940 if (!client_name && !start_time) {
941 ua->error_msg(_("Neither Client nor StartTime specified.\n"));
945 if (!get_client_dbr(ua, &cr)) {
948 jr.ClientId = cr.ClientId;
953 StartTime = str_to_utime(start_time);
954 if (StartTime == 0) {
955 ua->error_msg(_("Improper date format: %s\n"), ua->argv[i]);
958 delta_start = StartTime - jr.StartTime;
959 Dmsg3(200, "ST=%lld jr.ST=%lld delta=%lld\n", StartTime,
960 (utime_t)jr.StartTime, delta_start);
961 jr.StartTime = (time_t)StartTime;
962 jr.SchedTime += (time_t)delta_start;
963 jr.EndTime += (time_t)delta_start;
964 jr.JobTDate += delta_start;
965 /* Convert to DB times */
966 bstrutime(jr.cStartTime, sizeof(jr.cStartTime), jr.StartTime);
967 bstrutime(jr.cSchedTime, sizeof(jr.cSchedTime), jr.SchedTime);
968 bstrutime(jr.cEndTime, sizeof(jr.cEndTime), jr.EndTime);
970 Mmsg(cmd, "UPDATE Job SET ClientId=%s,StartTime='%s',SchedTime='%s',"
971 "EndTime='%s',JobTDate=%s WHERE JobId=%s",
972 edit_int64(jr.ClientId, ed1),
976 edit_uint64(jr.JobTDate, ed1),
977 edit_int64(jr.JobId, ed2));
978 if (!db_sql_query(ua->db, cmd.c_str(), NULL, NULL)) {
979 ua->error_msg("%s", db_strerror(ua->db));