2 Bacula® - The Network Backup Solution
4 Copyright (C) 2000-2008 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 John Walker.
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);
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
57 int update_cmd(UAContext *ua, const char *cmd)
59 static const char *kw[] = {
61 NT_("volume"), /* 1 */
67 if (!open_client_db(ua)) {
71 switch (find_arg_keyword(ua, kw)) {
89 start_prompt(ua, _("Update choice:\n"));
90 add_prompt(ua, _("Volume parameters"));
91 add_prompt(ua, _("Pool from resource"));
92 add_prompt(ua, _("Slots from autochanger"));
93 switch (do_prompt(ua, _("item"), _("Choose catalog item to update"), NULL, 0)) {
109 static void update_volstatus(UAContext *ua, const char *val, MEDIA_DBR *mr)
111 POOL_MEM query(PM_MESSAGE);
126 for (i=0; kw[i]; i++) {
127 if (strcasecmp(val, kw[i]) == 0) {
133 ua->error_msg(_("Invalid VolStatus specified: %s\n"), val);
136 bstrncpy(mr->VolStatus, kw[i], sizeof(mr->VolStatus));
137 Mmsg(query, "UPDATE Media SET VolStatus='%s' WHERE MediaId=%s",
138 mr->VolStatus, edit_int64(mr->MediaId,ed1));
139 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
140 ua->error_msg("%s", db_strerror(ua->db));
142 ua->info_msg(_("New Volume status is: %s\n"), mr->VolStatus);
147 static void update_volretention(UAContext *ua, char *val, MEDIA_DBR *mr)
149 char ed1[150], ed2[50];
150 POOL_MEM query(PM_MESSAGE);
151 if (!duration_to_utime(val, &mr->VolRetention)) {
152 ua->error_msg(_("Invalid retention period specified: %s\n"), val);
155 Mmsg(query, "UPDATE Media SET VolRetention=%s WHERE MediaId=%s",
156 edit_uint64(mr->VolRetention, ed1), edit_int64(mr->MediaId,ed2));
157 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
158 ua->error_msg("%s", db_strerror(ua->db));
160 ua->info_msg(_("New retention period is: %s\n"),
161 edit_utime(mr->VolRetention, ed1, sizeof(ed1)));
165 static void update_voluseduration(UAContext *ua, char *val, MEDIA_DBR *mr)
167 char ed1[150], ed2[50];
168 POOL_MEM query(PM_MESSAGE);
170 if (!duration_to_utime(val, &mr->VolUseDuration)) {
171 ua->error_msg(_("Invalid use duration specified: %s\n"), val);
174 Mmsg(query, "UPDATE Media SET VolUseDuration=%s WHERE MediaId=%s",
175 edit_uint64(mr->VolUseDuration, ed1), edit_int64(mr->MediaId,ed2));
176 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
177 ua->error_msg("%s", db_strerror(ua->db));
179 ua->info_msg(_("New use duration is: %s\n"),
180 edit_utime(mr->VolUseDuration, ed1, sizeof(ed1)));
184 static void update_volmaxjobs(UAContext *ua, char *val, MEDIA_DBR *mr)
186 POOL_MEM query(PM_MESSAGE);
188 Mmsg(query, "UPDATE Media SET MaxVolJobs=%s WHERE MediaId=%s",
189 val, edit_int64(mr->MediaId,ed1));
190 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
191 ua->error_msg("%s", db_strerror(ua->db));
193 ua->info_msg(_("New max jobs is: %s\n"), val);
197 static void update_volmaxfiles(UAContext *ua, char *val, MEDIA_DBR *mr)
199 POOL_MEM query(PM_MESSAGE);
201 Mmsg(query, "UPDATE Media SET MaxVolFiles=%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 files is: %s\n"), val);
210 static void update_volmaxbytes(UAContext *ua, char *val, MEDIA_DBR *mr)
213 char ed1[50], ed2[50];
214 POOL_MEM query(PM_MESSAGE);
216 if (!size_to_uint64(val, strlen(val), &maxbytes)) {
217 ua->error_msg(_("Invalid max. bytes specification: %s\n"), val);
220 Mmsg(query, "UPDATE Media SET MaxVolBytes=%s WHERE MediaId=%s",
221 edit_uint64(maxbytes, ed1), edit_int64(mr->MediaId, ed2));
222 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
223 ua->error_msg("%s", db_strerror(ua->db));
225 ua->info_msg(_("New Max bytes is: %s\n"), edit_uint64(maxbytes, ed1));
229 static void update_volrecycle(UAContext *ua, char *val, MEDIA_DBR *mr)
234 POOL_MEM query(PM_MESSAGE);
235 if (!is_yesno(val, &recycle)) {
236 ua->error_msg(_("Invalid value. It must be yes or no.\n"));
239 Mmsg(query, "UPDATE Media SET Recycle=%d WHERE MediaId=%s",
240 recycle, edit_int64(mr->MediaId, ed1));
241 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
242 ua->error_msg("%s", db_strerror(ua->db));
244 ua->info_msg(_("New Recycle flag is: %s\n"),
245 recycle==1?_("yes"):_("no"));
249 static void update_volinchanger(UAContext *ua, char *val, MEDIA_DBR *mr)
254 POOL_MEM query(PM_MESSAGE);
255 if (!is_yesno(val, &InChanger)) {
256 ua->error_msg(_("Invalid value. It must be yes or no.\n"));
259 Mmsg(query, "UPDATE Media SET InChanger=%d WHERE MediaId=%s",
260 InChanger, edit_int64(mr->MediaId, ed1));
261 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
262 ua->error_msg("%s", db_strerror(ua->db));
264 ua->info_msg(_("New InChanger flag is: %s\n"),
265 InChanger==1?_("yes"):_("no"));
270 static void update_volslot(UAContext *ua, char *val, MEDIA_DBR *mr)
274 memset(&pr, 0, sizeof(POOL_DBR));
275 pr.PoolId = mr->PoolId;
276 if (!db_get_pool_record(ua->jcr, ua->db, &pr)) {
277 ua->error_msg("%s", db_strerror(ua->db));
280 mr->Slot = atoi(val);
281 if (pr.MaxVols > 0 && mr->Slot > (int)pr.MaxVols) {
282 ua->error_msg(_("Invalid slot, it must be between 0 and MaxVols=%d\n"),
287 * Make sure to use db_update... rather than doing this directly,
288 * so that any Slot is handled correctly.
290 if (!db_update_media_record(ua->jcr, ua->db, mr)) {
291 ua->error_msg(_("Error updating media record Slot: ERR=%s"), db_strerror(ua->db));
293 ua->info_msg(_("New Slot is: %d\n"), mr->Slot);
297 /* Modify the Pool in which this Volume is located */
298 void update_vol_pool(UAContext *ua, char *val, MEDIA_DBR *mr, POOL_DBR *opr)
301 POOL_MEM query(PM_MESSAGE);
302 char ed1[50], ed2[50];
304 memset(&pr, 0, sizeof(pr));
305 bstrncpy(pr.Name, val, sizeof(pr.Name));
306 if (!get_pool_dbr(ua, &pr)) {
309 mr->PoolId = pr.PoolId; /* set new PoolId */
313 Mmsg(query, "UPDATE Media SET PoolId=%s WHERE MediaId=%s",
314 edit_int64(mr->PoolId, ed1), edit_int64(mr->MediaId, ed2));
315 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
316 ua->error_msg("%s", db_strerror(ua->db));
318 ua->info_msg(_("New Pool is: %s\n"), pr.Name);
320 if (!db_update_pool_record(ua->jcr, ua->db, opr)) {
321 ua->error_msg("%s", db_strerror(ua->db));
324 if (!db_update_pool_record(ua->jcr, ua->db, &pr)) {
325 ua->error_msg("%s", db_strerror(ua->db));
331 /* Modify the RecyclePool of a Volume */
332 void update_vol_recyclepool(UAContext *ua, char *val, MEDIA_DBR *mr)
335 POOL_MEM query(PM_MESSAGE);
336 char ed1[50], ed2[50], *poolname;
338 if(val && *val) { /* update volume recyclepool="Scratch" */
339 /* If a pool name is given, look up the PoolId */
340 memset(&pr, 0, sizeof(pr));
341 bstrncpy(pr.Name, val, sizeof(pr.Name));
342 if (!get_pool_dbr(ua, &pr, NT_("recyclepool"))) {
345 /* pool = select_pool_resource(ua); */
346 mr->RecyclePoolId = pr.PoolId; /* get the PoolId */
349 } else { /* update volume recyclepool="" */
350 /* If no pool name is given, set the PoolId to 0 (the default) */
351 mr->RecyclePoolId = 0;
352 poolname = _("*None*");
356 Mmsg(query, "UPDATE Media SET RecyclePoolId=%s WHERE MediaId=%s",
357 edit_int64(mr->RecyclePoolId, ed1), edit_int64(mr->MediaId, ed2));
358 if (!db_sql_query(ua->db, query.c_str(), NULL, NULL)) {
359 ua->error_msg("%s", db_strerror(ua->db));
361 ua->info_msg(_("New RecyclePool is: %s\n"), poolname);
367 * Refresh the Volume information from the Pool record
369 static void update_vol_from_pool(UAContext *ua, MEDIA_DBR *mr)
373 memset(&pr, 0, sizeof(pr));
374 pr.PoolId = mr->PoolId;
375 if (!db_get_pool_record(ua->jcr, ua->db, &pr) ||
376 !acl_access_ok(ua, Pool_ACL, pr.Name)) {
379 set_pool_dbr_defaults_in_media_dbr(mr, &pr);
380 if (!db_update_media_defaults(ua->jcr, ua->db, mr)) {
381 ua->error_msg(_("Error updating Volume record: ERR=%s"), db_strerror(ua->db));
383 ua->info_msg(_("Volume defaults updated from \"%s\" Pool record.\n"),
389 * Refresh the Volume information from the Pool record
392 static void update_all_vols_from_pool(UAContext *ua, const char *pool_name)
397 memset(&pr, 0, sizeof(pr));
398 memset(&mr, 0, sizeof(mr));
400 bstrncpy(pr.Name, pool_name, sizeof(pr.Name));
401 if (!get_pool_dbr(ua, &pr)) {
404 set_pool_dbr_defaults_in_media_dbr(&mr, &pr);
405 mr.PoolId = pr.PoolId;
406 if (!db_update_media_defaults(ua->jcr, ua->db, &mr)) {
407 ua->error_msg(_("Error updating Volume records: ERR=%s"), db_strerror(ua->db));
409 ua->info_msg(_("All Volume defaults updated from \"%s\" Pool record.\n"),
414 static void update_all_vols(UAContext *ua)
421 memset(&pr, 0, sizeof(pr));
422 memset(&mr, 0, sizeof(mr));
424 if (!db_get_pool_ids(ua->jcr, ua->db, &num_pools, &ids)) {
425 ua->error_msg(_("Error obtaining pool ids. ERR=%s\n"), db_strerror(ua->db));
429 for (i=0; i<num_pools; i++) {
431 if (!db_get_pool_record(ua->jcr, ua->db, &pr)) { /* ***FIXME*** use acl? */
432 ua->warning_msg(_("Updating all pools, but skipped PoolId=%d. ERR=%s\n"), db_strerror(ua->db));
436 set_pool_dbr_defaults_in_media_dbr(&mr, &pr);
437 mr.PoolId = pr.PoolId;
439 if (!db_update_media_defaults(ua->jcr, ua->db, &mr)) {
440 ua->error_msg(_("Error updating Volume records: ERR=%s"), db_strerror(ua->db));
442 ua->info_msg(_("All Volume defaults updated from \"%s\" Pool record.\n"),
450 static void update_volenabled(UAContext *ua, char *val, MEDIA_DBR *mr)
452 mr->Enabled = get_enabled(ua, val);
453 if (mr->Enabled < 0) {
456 if (!db_update_media_record(ua->jcr, ua->db, mr)) {
457 ua->error_msg(_("Error updating media record Enabled: ERR=%s"), db_strerror(ua->db));
459 ua->info_msg(_("New Enabled is: %d\n"), mr->Enabled);
466 * Update a media record -- allows you to change the
467 * Volume status. E.g. if you want Bacula to stop
468 * writing on the volume, set it to anything other
471 static int update_volume(UAContext *ua)
482 NT_("VolStatus"), /* 0 */
483 NT_("VolRetention"), /* 1 */
484 NT_("VolUse"), /* 2 */
485 NT_("MaxVolJobs"), /* 3 */
486 NT_("MaxVolFiles"), /* 4 */
487 NT_("MaxVolBytes"), /* 5 */
488 NT_("Recycle"), /* 6 */
489 NT_("InChanger"), /* 7 */
492 NT_("FromPool"), /* 10 */
493 NT_("AllFromPool"), /* 11 !!! see below !!! */
494 NT_("Enabled"), /* 12 */
495 NT_("RecyclePool"), /* 13 */
498 #define AllFromPool 11 /* keep this updated with above */
500 for (i=0; kw[i]; i++) {
504 if ((j=find_arg_with_value(ua, kw[i])) > 0) {
505 /* If all from pool don't select a media record */
506 if (i != AllFromPool && !select_media_dbr(ua, &mr)) {
511 update_volstatus(ua, ua->argv[j], &mr);
514 update_volretention(ua, ua->argv[j], &mr);
517 update_voluseduration(ua, ua->argv[j], &mr);
520 update_volmaxjobs(ua, ua->argv[j], &mr);
523 update_volmaxfiles(ua, ua->argv[j], &mr);
526 update_volmaxbytes(ua, ua->argv[j], &mr);
529 update_volrecycle(ua, ua->argv[j], &mr);
532 update_volinchanger(ua, ua->argv[j], &mr);
535 update_volslot(ua, ua->argv[j], &mr);
538 memset(&pr, 0, sizeof(POOL_DBR));
539 pr.PoolId = mr.PoolId;
540 if (!db_get_pool_record(ua->jcr, ua->db, &pr)) {
541 ua->error_msg("%s", db_strerror(ua->db));
544 update_vol_pool(ua, ua->argv[j], &mr, &pr);
547 update_vol_from_pool(ua, &mr);
550 update_all_vols_from_pool(ua, ua->argv[j]);
553 update_volenabled(ua, ua->argv[j], &mr);
556 update_vol_recyclepool(ua, ua->argv[j], &mr);
563 /* Allow user to simply update all volumes */
564 if (find_arg(ua, NT_("fromallpools")) > 0) {
570 start_prompt(ua, _("Parameters to modify:\n"));
571 add_prompt(ua, _("Volume Status")); /* 0 */
572 add_prompt(ua, _("Volume Retention Period")); /* 1 */
573 add_prompt(ua, _("Volume Use Duration")); /* 2 */
574 add_prompt(ua, _("Maximum Volume Jobs")); /* 3 */
575 add_prompt(ua, _("Maximum Volume Files")); /* 4 */
576 add_prompt(ua, _("Maximum Volume Bytes")); /* 5 */
577 add_prompt(ua, _("Recycle Flag")); /* 6 */
578 add_prompt(ua, _("Slot")); /* 7 */
579 add_prompt(ua, _("InChanger Flag")); /* 8 */
580 add_prompt(ua, _("Volume Files")); /* 9 */
581 add_prompt(ua, _("Pool")); /* 10 */
582 add_prompt(ua, _("Volume from Pool")); /* 11 */
583 add_prompt(ua, _("All Volumes from Pool")); /* 12 */
584 add_prompt(ua, _("All Volumes from all Pools")); /* 13 */
585 add_prompt(ua, _("Enabled")), /* 14 */
586 add_prompt(ua, _("RecyclePool")), /* 15 */
587 add_prompt(ua, _("Done")); /* 16 */
588 i = do_prompt(ua, "", _("Select parameter to modify"), NULL, 0);
590 /* For All Volumes, All Volumes from Pool, and Done, we don't need
592 if ( i != 12 && i != 13 && i != 16) {
593 if (!select_media_dbr(ua, &mr)) { /* Get Volume record */
596 ua->info_msg(_("Updating Volume \"%s\"\n"), mr.VolumeName);
599 case 0: /* Volume Status */
600 /* Modify Volume Status */
601 ua->info_msg(_("Current Volume status is: %s\n"), mr.VolStatus);
602 start_prompt(ua, _("Possible Values are:\n"));
603 add_prompt(ua, NT_("Append"));
604 add_prompt(ua, NT_("Archive"));
605 add_prompt(ua, NT_("Disabled"));
606 add_prompt(ua, NT_("Full"));
607 add_prompt(ua, NT_("Used"));
608 add_prompt(ua, NT_("Cleaning"));
609 if (strcmp(mr.VolStatus, NT_("Purged")) == 0) {
610 add_prompt(ua, NT_("Recycle"));
612 add_prompt(ua, NT_("Read-Only"));
613 if (do_prompt(ua, "", _("Choose new Volume Status"), ua->cmd, sizeof(mr.VolStatus)) < 0) {
616 update_volstatus(ua, ua->cmd, &mr);
618 case 1: /* Retention */
619 ua->info_msg(_("Current retention period is: %s\n"),
620 edit_utime(mr.VolRetention, ed1, sizeof(ed1)));
621 if (!get_cmd(ua, _("Enter Volume Retention period: "))) {
624 update_volretention(ua, ua->cmd, &mr);
627 case 2: /* Use Duration */
628 ua->info_msg(_("Current use duration is: %s\n"),
629 edit_utime(mr.VolUseDuration, ed1, sizeof(ed1)));
630 if (!get_cmd(ua, _("Enter Volume Use Duration: "))) {
633 update_voluseduration(ua, ua->cmd, &mr);
636 case 3: /* Max Jobs */
637 ua->info_msg(_("Current max jobs is: %u\n"), mr.MaxVolJobs);
638 if (!get_pint(ua, _("Enter new Maximum Jobs: "))) {
641 update_volmaxjobs(ua, ua->cmd, &mr);
644 case 4: /* Max Files */
645 ua->info_msg(_("Current max files is: %u\n"), mr.MaxVolFiles);
646 if (!get_pint(ua, _("Enter new Maximum Files: "))) {
649 update_volmaxfiles(ua, ua->cmd, &mr);
652 case 5: /* Max Bytes */
653 ua->info_msg(_("Current value is: %s\n"), edit_uint64(mr.MaxVolBytes, ed1));
654 if (!get_cmd(ua, _("Enter new Maximum Bytes: "))) {
657 update_volmaxbytes(ua, ua->cmd, &mr);
661 case 6: /* Recycle */
662 ua->info_msg(_("Current recycle flag is: %s\n"),
663 mr.Recycle==1?_("yes"):_("no"));
664 if (!get_yesno(ua, _("Enter new Recycle status: "))) {
667 update_volrecycle(ua, ua->cmd, &mr);
671 ua->info_msg(_("Current Slot is: %d\n"), mr.Slot);
672 if (!get_pint(ua, _("Enter new Slot: "))) {
675 update_volslot(ua, ua->cmd, &mr);
678 case 8: /* InChanger */
679 ua->info_msg(_("Current InChanger flag is: %d\n"), mr.InChanger);
680 bsnprintf(buf, sizeof(buf), _("Set InChanger flag for Volume \"%s\": yes/no: "),
682 if (!get_yesno(ua, buf)) {
685 mr.InChanger = ua->pint32_val;
687 * Make sure to use db_update... rather than doing this directly,
688 * so that any Slot is handled correctly.
690 if (!db_update_media_record(ua->jcr, ua->db, &mr)) {
691 ua->error_msg(_("Error updating media record Slot: ERR=%s"), db_strerror(ua->db));
693 ua->info_msg(_("New InChanger flag is: %d\n"), mr.InChanger);
698 case 9: /* Volume Files */
700 ua->warning_msg(_("Warning changing Volume Files can result\n"
701 "in loss of data on your Volume\n\n"));
702 ua->info_msg(_("Current Volume Files is: %u\n"), mr.VolFiles);
703 if (!get_pint(ua, _("Enter new number of Files for Volume: "))) {
706 VolFiles = ua->pint32_val;
707 if (VolFiles != (int)(mr.VolFiles + 1)) {
708 ua->warning_msg(_("Normally, you should only increase Volume Files by one!\n"));
709 if (!get_yesno(ua, _("Increase Volume Files? (yes/no): ")) || ua->pint32_val == 0) {
713 query = get_pool_memory(PM_MESSAGE);
714 Mmsg(query, "UPDATE Media SET VolFiles=%u WHERE MediaId=%s",
715 VolFiles, edit_int64(mr.MediaId, ed1));
716 if (!db_sql_query(ua->db, query, NULL, NULL)) {
717 ua->error_msg("%s", db_strerror(ua->db));
719 ua->info_msg(_("New Volume Files is: %u\n"), VolFiles);
721 free_pool_memory(query);
724 case 10: /* Volume's Pool */
725 memset(&pr, 0, sizeof(POOL_DBR));
726 pr.PoolId = mr.PoolId;
727 if (!db_get_pool_record(ua->jcr, ua->db, &pr)) {
728 ua->error_msg("%s", db_strerror(ua->db));
731 ua->info_msg(_("Current Pool is: %s\n"), pr.Name);
732 if (!get_cmd(ua, _("Enter new Pool name: "))) {
735 update_vol_pool(ua, ua->cmd, &mr, &pr);
739 update_vol_from_pool(ua, &mr);
742 pool = select_pool_resource(ua);
744 update_all_vols_from_pool(ua, pool->name());
753 ua->info_msg(_("Current Enabled is: %d\n"), mr.Enabled);
754 if (!get_cmd(ua, _("Enter new Enabled: "))) {
757 if (strcasecmp(ua->cmd, "yes") == 0 || strcasecmp(ua->cmd, "true") == 0) {
759 } else if (strcasecmp(ua->cmd, "no") == 0 || strcasecmp(ua->cmd, "false") == 0) {
761 } else if (strcasecmp(ua->cmd, "archived") == 0) {
764 mr.Enabled = atoi(ua->cmd);
766 update_volenabled(ua, ua->cmd, &mr);
770 memset(&pr, 0, sizeof(POOL_DBR));
771 pr.PoolId = mr.RecyclePoolId;
772 if (db_get_pool_record(ua->jcr, ua->db, &pr)) {
773 ua->info_msg(_("Current RecyclePool is: %s\n"), pr.Name);
775 ua->info_msg(_("No current RecyclePool\n"));
777 if (!select_pool_dbr(ua, &pr, NT_("recyclepool"))) {
780 update_vol_recyclepool(ua, pr.Name, &mr);
783 default: /* Done or error */
784 ua->info_msg(_("Selection terminated.\n"));
792 * Update pool record -- pull info from current POOL resource
794 static bool update_pool(UAContext *ua)
802 pool = get_pool_resource(ua);
807 memset(&pr, 0, sizeof(pr));
808 bstrncpy(pr.Name, pool->name(), sizeof(pr.Name));
809 if (!get_pool_dbr(ua, &pr)) {
813 set_pooldbr_from_poolres(&pr, pool, POOL_OP_UPDATE); /* update */
814 set_pooldbr_recyclepoolid(ua->jcr, ua->db, &pr, pool);
816 id = db_update_pool_record(ua->jcr, ua->db, &pr);
818 ua->error_msg(_("db_update_pool_record returned %d. ERR=%s\n"),
819 id, db_strerror(ua->db));
821 query = get_pool_memory(PM_MESSAGE);
822 Mmsg(query, list_pool, edit_int64(pr.PoolId, ed1));
823 db_list_sql_query(ua->jcr, ua->db, query, prtit, ua, 1, HORZ_LIST);
824 free_pool_memory(query);
825 ua->info_msg(_("Pool DB record updated from resource.\n"));
830 * Update a Job record -- allows you to change the
831 * date fields in a Job record. This helps when
832 * providing migration from other vendors.
834 static bool update_job(UAContext *ua)
837 char ed1[50], ed2[50];
838 POOL_MEM cmd(PM_MESSAGE);
842 char *client_name = NULL;
843 char *start_time = NULL;
845 NT_("starttime"), /* 0 */
846 NT_("client"), /* 1 */
849 Dmsg1(200, "cmd=%s\n", ua->cmd);
850 i = find_arg_with_value(ua, NT_("jobid"));
852 ua->error_msg(_("Expect JobId keyword, not found.\n"));
855 memset(&jr, 0, sizeof(jr));
856 memset(&cr, 0, sizeof(cr));
857 jr.JobId = str_to_int64(ua->argv[i]);
858 if (!db_get_job_record(ua->jcr, ua->db, &jr)) {
859 ua->error_msg("%s", db_strerror(ua->db));
863 for (i=0; kw[i]; i++) {
865 if ((j=find_arg_with_value(ua, kw[i])) >= 0) {
867 case 0: /* start time */
868 start_time = ua->argv[j];
870 case 1: /* Client name */
871 client_name = ua->argv[j];
876 if (!client_name && !start_time) {
877 ua->error_msg(_("Neither Client nor StartTime specified.\n"));
881 if (!get_client_dbr(ua, &cr)) {
884 jr.ClientId = cr.ClientId;
889 StartTime = str_to_utime(start_time);
890 if (StartTime == 0) {
891 ua->error_msg(_("Improper date format: %s\n"), ua->argv[i]);
894 delta_start = StartTime - jr.StartTime;
895 Dmsg3(200, "ST=%d jr.ST=%d delta=%d\n", (time_t)StartTime,
896 (time_t)jr.StartTime, (time_t)delta_start);
897 jr.StartTime = (time_t)StartTime;
898 jr.SchedTime += (time_t)delta_start;
899 jr.EndTime += (time_t)delta_start;
900 jr.JobTDate += delta_start;
901 /* Convert to DB times */
902 bstrutime(jr.cStartTime, sizeof(jr.cStartTime), jr.StartTime);
903 bstrutime(jr.cSchedTime, sizeof(jr.cSchedTime), jr.SchedTime);
904 bstrutime(jr.cEndTime, sizeof(jr.cEndTime), jr.EndTime);
906 Mmsg(cmd, "UPDATE Job SET ClientId=%s,StartTime='%s',SchedTime='%s',"
907 "EndTime='%s',JobTDate=%s WHERE JobId=%s",
908 edit_int64(jr.ClientId, ed1),
912 edit_uint64(jr.JobTDate, ed1),
913 edit_int64(jr.JobId, ed2));
914 if (!db_sql_query(ua->db, cmd.c_str(), NULL, NULL)) {
915 ua->error_msg("%s", db_strerror(ua->db));