/*
Bacula® - The Network Backup Solution
- Copyright (C) 2000-2009 Free Software Foundation Europe e.V.
+ Copyright (C) 2000-2011 Free Software Foundation Europe e.V.
The main author of Bacula is Kern Sibbald, with contributions from
many others, a complete list can be found in the file AUTHORS.
This program is Free Software; you can redistribute it and/or
- modify it under the terms of version two of the GNU General Public
+ modify it under the terms of version three of the GNU Affero General Public
License as published by the Free Software Foundation and included
in the file LICENSE.
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
General Public License for more details.
- You should have received a copy of the GNU General Public License
+ You should have received a copy of the GNU Affero General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
02110-1301, USA.
*
* Kern Sibbald, September MM
*
- * Version $Id$
*/
#include "bacula.h"
{ NT_("disable"), disable_cmd, _("Disable a job"), NT_("job=<name>"), true},
{ NT_("enable"), enable_cmd, _("Enable a job"), NT_("job=<name>"), true},
{ NT_("estimate"), estimate_cmd, _("Performs FileSet estimate, listing gives full listing"),
- NT_("fileset=<fs> client=<cli> accurate=<yes/no> job=<job> listing"), true},
+ NT_("fileset=<fs> client=<cli> level=<level> accurate=<yes/no> job=<job> listing"), true},
{ NT_("exit"), quit_cmd, _("Terminate Bconsole session"), NT_(""), false},
{ NT_("gui"), gui_cmd, _("Non-interactive gui mode"), NT_("on | off"), false},
{ NT_("help"), help_cmd, _("Print help on specific command"),
NT_("add autodisplay automount cancel create delete disable\n\tenable estimate exit gui label list llist"
"\n\tmessages memory mount prune purge python quit query\n\trestore relabel release reload run status"
- "\n\tsetdebug setip show sqlquery time trace unmount umount\n\tupdate use var version wait"), false},
+ "\n\tsetdebug setip show sqlquery time trace unmount\n\tumount update use var version wait"), false},
- { NT_("label"), label_cmd, _("Label a tape"), NT_("storage=<storage> volume=<vol> pool=<pool>"), false},
+ { NT_("label"), label_cmd, _("Label a tape"), NT_("storage=<storage> volume=<vol> pool=<pool> slot=<slot> barcodes"), false},
{ NT_("list"), list_cmd, _("List objects from catalog"),
- NT_("pools | jobs | jobtotals | media <pool=pool-name> | files jobid=<nn> | copies jobid=<nn>"), true},
+ NT_("pools | jobs | jobtotals | volume | media <pool=pool-name> | files jobid=<nn> | copies jobid=<nn>"), true},
{ NT_("llist"), llist_cmd, _("Full or long list like list command"),
NT_("pools | jobs | jobtotals | media <pool=pool-name> | files jobid=<nn> | copies jobid=<nn>"), true},
{ NT_("quit"), quit_cmd, _("Terminate Bconsole session"), NT_(""), false},
{ NT_("query"), querycmd, _("Query catalog"), NT_(""), false},
{ NT_("restore"), restore_cmd, _("Restore files"),
- NT_("where=</path> client=<client> storage=<storage> bootstrap=<file>"
+ NT_("where=</path> client=<client> storage=<storage> bootstrap=<file> "
+ "restore_job=<job>"
"\n\tcomment=<text> jobid=<jobid> done select all"), false},
{ NT_("relabel"), relabel_cmd, _("Relabel a tape"),
NT_("storage=<storage-name> oldvolume=<old-volume-name>\n\tvolume=<newvolume-name> pool=<pool>"), false},
- { NT_("release"), release_cmd, _("Release storage"), NT_("storage-name"), false},
+ { NT_("release"), release_cmd, _("Release storage"), NT_("storage=<storage-name>"), false},
{ NT_("reload"), reload_cmd, _("Reload conf file"), NT_(""), true},
{ NT_("run"), run_cmd, _("Run a job"),
NT_("job=<job-name> client=<client-name>\n\tfileset=<FileSet-name> level=<level-keyword>\n\tstorage=<storage-name>"
"\n\t pool=<pool> recycle=<yes/no> slot=<number>\n\t inchanger=<yes/no>"
"\n\t maxvolbytes=<size> maxvolfiles=<nb> maxvoljobs=<nb>"
"\n\t enable=<yes/no> recyclepool=<pool> actiononpurge=<action>"),true},
- { NT_("use"), use_cmd, _("Use catalog xxx"), NT_(""), false},
+ { NT_("use"), use_cmd, _("Use catalog xxx"), NT_("catalog=<catalog>"), false},
{ NT_("var"), var_cmd, _("Does variable expansion"), NT_(""), false},
{ NT_("version"), version_cmd, _("Print Director version"), NT_(""), true},
{ NT_("wait"), wait_cmd, _("Wait until no jobs are running"),
for (i=1; i<ua->argc; i++) {
if (strcasecmp(ua->argk[i], NT_("jobid")) == 0) {
uint32_t JobId;
- if (!ua->argv[i]) {
+ JobId = str_to_int64(ua->argv[i]);
+ if (!JobId) {
break;
}
- JobId = str_to_int64(ua->argv[i]);
if (!(jcr=get_jcr_by_id(JobId))) {
ua->error_msg(_("JobId %s is not running. Use Job name to cancel inactive jobs.\n"), ua->argv[i]);
return 1;
return 1;
}
-
/*
* Set a new address in a Client resource. We do this only
* if the Console name is the same as the Client name
return 1;
}
-
static void do_storage_setdebug(UAContext *ua, STORE *store, int level, int trace_flag)
{
BSOCK *sd;
return;
}
-static void do_client_setdebug(UAContext *ua, CLIENT *client, int level, int trace_flag)
+/*
+ * For the client, we have the following values that can be set
+ * level = debug level
+ * trace = send debug output to a file
+ * hangup = how many records to send to SD before hanging up
+ * obviously this is most useful for testing restarting
+ * failed jobs.
+ */
+static void do_client_setdebug(UAContext *ua, CLIENT *client,
+ int level, int trace, int hangup)
{
BSOCK *fd;
}
Dmsg0(120, "Connected to file daemon\n");
fd = ua->jcr->file_bsock;
- fd->fsend("setdebug=%d trace=%d\n", level, trace_flag);
+ fd->fsend("setdebug=%d trace=%d hangup=%d\n", level, trace, hangup);
if (fd->recv() >= 0) {
ua->send_msg("%s", fd->msg);
}
}
-static void do_all_setdebug(UAContext *ua, int level, int trace_flag)
+static void do_all_setdebug(UAContext *ua, int level, int trace_flag, int hangup)
{
STORE *store, **unique_store;
CLIENT *client, **unique_client;
/* Call each unique File daemon */
for (j=0; j<i; j++) {
- do_client_setdebug(ua, unique_client[j], level, trace_flag);
+ do_client_setdebug(ua, unique_client[j], level, trace_flag, hangup);
}
free(unique_client);
}
CLIENT *client;
int level;
int trace_flag = -1;
+ int hangup = -1;
int i;
Dmsg1(120, "setdebug:%s:\n", cmd);
}
}
+ /* Look for hangup (debug only)flag. -1 => not change */
+ i = find_arg_with_value(ua, "hangup");
+ if (i >= 0) {
+ hangup = atoi(ua->argv[i]);
+ }
+
+
/* General debug? */
for (i=1; i<ua->argc; i++) {
if (strcasecmp(ua->argk[i], "all") == 0) {
- do_all_setdebug(ua, level, trace_flag);
+ do_all_setdebug(ua, level, trace_flag, hangup);
return 1;
}
if (strcasecmp(ua->argk[i], "dir") == 0 ||
if (ua->argv[i]) {
client = GetClientResWithName(ua->argv[i]);
if (client) {
- do_client_setdebug(ua, client, level, trace_flag);
+ do_client_setdebug(ua, client, level, trace_flag, hangup);
return 1;
}
}
client = select_client_resource(ua);
if (client) {
- do_client_setdebug(ua, client, level, trace_flag);
+ do_client_setdebug(ua, client, level, trace_flag, hangup);
return 1;
}
}
case 2:
client = select_client_resource(ua);
if (client) {
- do_client_setdebug(ua, client, level, trace_flag);
+ do_client_setdebug(ua, client, level, trace_flag, hangup);
}
break;
case 3:
- do_all_setdebug(ua, level, trace_flag);
+ do_all_setdebug(ua, level, trace_flag, hangup);
break;
default:
break;
JCR *jcr = ua->jcr;
int accurate=-1;
- jcr->set_JobLevel(L_FULL);
+ jcr->setJobLevel(L_FULL);
for (int i=1; i<ua->argc; i++) {
if (strcasecmp(ua->argk[i], NT_("client")) == 0 ||
strcasecmp(ua->argk[i], NT_("fd")) == 0) {
}
jcr->job = job;
- jcr->set_JobType(JT_BACKUP);
+ jcr->setJobType(JT_BACKUP);
init_jcr_job_record(jcr);
if (!get_or_create_client_record(jcr)) {
goto bail_out;
}
- bnet_fsend(jcr->file_bsock, "estimate listing=%d\n", listing);
- while (bnet_recv(jcr->file_bsock) >= 0) {
+ jcr->file_bsock->fsend("estimate listing=%d\n", listing);
+ while (jcr->file_bsock->recv() >= 0) {
ua->send_msg("%s", jcr->file_bsock->msg);
}
bail_out:
if (jcr->file_bsock) {
- bnet_sig(jcr->file_bsock, BNET_TERMINATE);
- bnet_close(jcr->file_bsock);
+ jcr->file_bsock->signal(BNET_TERMINATE);
+ jcr->file_bsock->close();
jcr->file_bsock = NULL;
}
return 1;
{
MEDIA_DBR mr;
char buf[1000];
+ db_list_ctx lst;
if (!select_media_dbr(ua, &mr)) {
return 1;
return 1;
}
}
- if (ua->pint32_val) {
- db_delete_media_record(ua->jcr, ua->db, &mr);
+ if (!ua->pint32_val) {
+ return 1;
+ }
+
+ /* If not purged, do it */
+ if (strcmp(mr.VolStatus, "Purged") != 0) {
+ if (!db_get_volume_jobids(ua->jcr, ua->db, &mr, &lst)) {
+ ua->error_msg(_("Can't list jobs on this volume\n"));
+ return 1;
+ }
+ if (lst.count) {
+ purge_jobs_from_catalog(ua, lst.list);
+ }
}
+
+ db_delete_media_record(ua->jcr, ua->db, &mr);
return 1;
}
int memory_cmd(UAContext *ua, const char *cmd)
{
+ garbage_collect_memory();
list_dir_status_header(ua);
sm_dump(false, true);
return 1;
bstrncpy(dev_name, store.store->dev_name(), sizeof(dev_name));
bash_spaces(dev_name);
if (slot > 0) {
- bnet_fsend(sd, "%s %s drive=%d slot=%d", command, dev_name, drive, slot);
+ sd->fsend("%s %s drive=%d slot=%d", command, dev_name, drive, slot);
} else {
- bnet_fsend(sd, "%s %s drive=%d", command, dev_name, drive);
+ sd->fsend("%s %s drive=%d", command, dev_name, drive);
}
- while (bnet_recv(sd) >= 0) {
+ while (sd->recv() >= 0) {
ua->send_msg("%s", sd->msg);
}
- bnet_sig(sd, BNET_TERMINATE);
- bnet_close(sd);
+ sd->signal(BNET_TERMINATE);
+ sd->close();
jcr->store_bsock = NULL;
}
}
#endif
+/*
+ * This call uses open_client_db() and force a
+ * new dedicated connection to the catalog
+ */
+bool open_new_client_db(UAContext *ua)
+{
+ bool ret;
+
+ /* Force a new dedicated connection */
+ close_db(ua);
+ ua->force_mult_db_connections = true;
+ ret = open_client_db(ua);
+ ua->force_mult_db_connections = false;
+ return ret;
+}
+
/*
* This call explicitly checks for a catalog=xxx and
* if given, opens that catalog. It also checks for
*/
bool open_db(UAContext *ua)
{
+ bool mult_db_conn;
+
if (ua->db) {
return true;
}
}
}
+ /* Some modules like bvfs need their own catalog connection */
+ mult_db_conn = ua->catalog->mult_db_connections;
+ if (ua->force_mult_db_connections) {
+ mult_db_conn = true;
+ }
+
ua->jcr->catalog = ua->catalog;
Dmsg0(100, "UA Open database\n");
- ua->db = db_init(ua->jcr, ua->catalog->db_driver, ua->catalog->db_name,
+ ua->db = db_init_database(ua->jcr, ua->catalog->db_driver, ua->catalog->db_name,
ua->catalog->db_user,
ua->catalog->db_password, ua->catalog->db_address,
ua->catalog->db_port, ua->catalog->db_socket,
- ua->catalog->mult_db_connections);
+ mult_db_conn, ua->catalog->disable_batch_insert);
if (!ua->db || !db_open_database(ua->jcr, ua->db)) {
ua->error_msg(_("Could not open catalog database \"%s\".\n"),
ua->catalog->db_name);