From: Kern Sibbald Date: Sun, 1 Jul 2018 19:36:15 +0000 (+0200) Subject: Backport parts of src/dird to community X-Git-Tag: Release-9.2.0~37 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=c03320ae302b1c28819976002874a342d72d0eed;p=thirdparty%2Fbacula.git Backport parts of src/dird to community --- diff --git a/bacula/src/cats/protos.h b/bacula/src/cats/protos.h index 39242564dc..678d8a16e9 100644 --- a/bacula/src/cats/protos.h +++ b/bacula/src/cats/protos.h @@ -161,6 +161,8 @@ void bdb_free_restoreobject_record(JCR *jcr, ROBJECT_DBR *rr); mdb->bdb_purge_media_record(jcr, mr) #define db_delete_snapshot_record(jcr, mdb, sr) \ mdb->bdb_delete_snapshot_record(jcr, sr) +#define db_delete_client_record(jcr, mdb, cr) \ + mdb->bdb_delete_client_record(jcr, cr) /* sql_find.c */ @@ -180,6 +182,8 @@ void bdb_free_restoreobject_record(JCR *jcr, ROBJECT_DBR *rr); /* sql_get.c */ #define db_get_volume_jobids(jcr, mdb, mr, lst) \ mdb->bdb_get_volume_jobids(jcr, mr, lst) +#define db_get_client_jobids(jcr, mdb, cr, lst) \ + mdb->bdb_get_client_jobids(jcr, cr, lst) #define db_get_base_file_list(jcr, mdb, use_md5, result_handler, ctx) \ mdb->bdb_get_base_file_list(jcr, use_md5, result_handler, ctx) #define db_get_path_record(jcr, mdb) \ diff --git a/bacula/src/cats/sql_delete.c b/bacula/src/cats/sql_delete.c index a46a3114a4..c93690fe44 100644 --- a/bacula/src/cats/sql_delete.c +++ b/bacula/src/cats/sql_delete.c @@ -236,4 +236,19 @@ int BDB::bdb_delete_snapshot_record(JCR *jcr, SNAPSHOT_DBR *sr) return 1; } +/* Delete Client record */ +int BDB::bdb_delete_client_record(JCR *jcr, CLIENT_DBR *cr) +{ + bdb_lock(); + if (cr->ClientId == 0 && !bdb_get_client_record(jcr, cr)) { + bdb_unlock(); + return 0; + } + + Mmsg(cmd, "DELETE FROM Client WHERE ClientId=%d", cr->ClientId); + bdb_sql_query(cmd, NULL, (void *)NULL); + bdb_unlock(); + return 1; +} + #endif /* HAVE_SQLITE3 || HAVE_MYSQL || HAVE_POSTGRESQL */ diff --git a/bacula/src/cats/sql_get.c b/bacula/src/cats/sql_get.c index d2f26273c8..da6938f406 100644 --- a/bacula/src/cats/sql_get.c +++ b/bacula/src/cats/sql_get.c @@ -1491,6 +1491,21 @@ bool BDB::bdb_get_volume_jobids(JCR *jcr, return ret; } +/* Get JobIds associated with a client */ +bool BDB::bdb_get_client_jobids(JCR *jcr, + CLIENT_DBR *cr, db_list_ctx *lst) +{ + char ed1[50]; + bool ret = false; + + bdb_lock(); + Mmsg(cmd, "SELECT JobId FROM Job WHERE ClientId=%s", + edit_int64(cr->ClientId, ed1)); + ret = bdb_sql_query(cmd, db_list_handler, lst); + bdb_unlock(); + return ret; +} + /** * Get Snapshot Record * diff --git a/bacula/src/dird/dird_conf.h b/bacula/src/dird/dird_conf.h index 40a69bb1ae..15bfb374b3 100644 --- a/bacula/src/dird/dird_conf.h +++ b/bacula/src/dird/dird_conf.h @@ -1,7 +1,7 @@ /* Bacula(R) - The Network Backup Solution - Copyright (C) 2000-2017 Kern Sibbald + Copyright (C) 2000-2018 Kern Sibbald The original author of Bacula is Kern Sibbald, with contributions from many others, a complete list can be found in the file AUTHORS. @@ -669,6 +669,7 @@ public: uint32_t MaxVolJobs; /* Maximum jobs on the Volume */ uint32_t MaxVolFiles; /* Maximum files on the Volume */ uint64_t MaxVolBytes; /* Maximum bytes on the Volume */ + uint64_t MaxPoolBytes; /* Maximum bytes on the pool to create new vol */ utime_t MigrationTime; /* Time to migrate to next pool */ uint64_t MigrationHighBytes; /* When migration starts */ uint64_t MigrationLowBytes; /* When migration stops */ diff --git a/bacula/src/dird/ua_cmds.c b/bacula/src/dird/ua_cmds.c index 2c69f58020..b9fd55c51d 100644 --- a/bacula/src/dird/ua_cmds.c +++ b/bacula/src/dird/ua_cmds.c @@ -80,6 +80,7 @@ static void do_job_delete(UAContext *ua, JobId_t JobId); static int delete_volume(UAContext *ua); static int delete_pool(UAContext *ua); static void delete_job(UAContext *ua); +static int delete_client(UAContext *ua); static void do_storage_cmd(UAContext *ua, const char *command); int qhelp_cmd(UAContext *ua, const char *cmd); @@ -103,7 +104,7 @@ static struct cmdstruct commands[] = { /* C NT_("[storage=] [volume=] [pool=] [allpools] [allfrompool] [mediatype=] [drive=] [slots="), false}, - { NT_("delete"), delete_cmd, _("Delete volume, pool or job"), NT_("volume= | pool= | jobid= | snapshot"), true}, + { NT_("delete"), delete_cmd, _("Delete volume, pool, client or job"), NT_("volume= | pool= | jobid= | client= | snapshot"), true}, { NT_("disable"), disable_cmd, _("Disable a job, attributes batch process"), NT_("job= | client= | schedule= | storage= | batch"), true}, { NT_("enable"), enable_cmd, _("Enable a job, attributes batch process"), NT_("job= | client= | schedule= | storage= | batch"), true}, { NT_("estimate"), estimate_cmd, _("Performs FileSet estimate, listing gives full listing"), @@ -1564,6 +1565,9 @@ static int delete_cmd(UAContext *ua, const char *cmd) case 3: delete_snapshot(ua); return 1; + case 4: + delete_client(ua); + return 1; default: break; } @@ -1585,6 +1589,9 @@ static int delete_cmd(UAContext *ua, const char *cmd) case 3: delete_snapshot(ua); return 1; + case 4: + delete_client(ua); + return 1; default: ua->warning_msg(_("Nothing done.\n")); break; @@ -1713,6 +1720,59 @@ static int delete_pool(UAContext *ua) return 1; } +/* + * Delete a client record from the database + */ +static int delete_client(UAContext *ua) +{ + CLIENT *client; + CLIENT_DBR cr; + char buf[200]; + db_list_ctx lst; + + memset(&cr, 0, sizeof(cr)); + + if (!get_client_dbr(ua, &cr, 0)) { + return 1; + } + + client = (CLIENT*) GetResWithName(R_CLIENT, cr.Name); + + if (client) { + ua->error_msg(_("Unable to delete Client \"%s\", the resource is still defined in the configuration.\n"), cr.Name); + return 1; + } + + if (!db_get_client_jobids(ua->jcr, ua->db, &cr, &lst)) { + ua->error_msg(_("Can't list jobs on this client\n")); + return 1; + } + + if (find_arg(ua, "yes") > 0) { + ua->pint32_val = 1; + + } else { + if (lst.count == 0) { + bsnprintf(buf, sizeof(buf), _("Are you sure you want to delete Client \"%s\? (yes/no): "), cr.Name); + } else { + bsnprintf(buf, sizeof(buf), _("Are you sure you want to delete Client \"%s\" and purge %d job(s)? (yes/no): "), cr.Name, lst.count); + } + if (!get_yesno(ua, buf)) { + return 1; + } + } + + if (ua->pint32_val) { + if (lst.count) { + ua->send_msg(_("Purging %d job(s).\n"), lst.count); + purge_jobs_from_catalog(ua, lst.list); + } + ua->send_msg(_("Deleting client \"%s\".\n"), cr.Name); + db_delete_client_record(ua->jcr, ua->db, &cr); + } + return 1; +} + int memory_cmd(UAContext *ua, const char *cmd) { garbage_collect_memory(); diff --git a/bacula/src/dird/ua_dotcmds.c b/bacula/src/dird/ua_dotcmds.c index 223735ca32..a165625470 100644 --- a/bacula/src/dird/ua_dotcmds.c +++ b/bacula/src/dird/ua_dotcmds.c @@ -180,7 +180,9 @@ bool do_a_dot_command(UAContext *ua) ok = (*commands[i].func)(ua, ua->cmd); /* go execute command */ if (ua->api) ua->signal(ok?BNET_CMD_OK:BNET_CMD_FAILED); ua->gui = gui; - found = ua->UA_sock->is_stop() ? false : true; + if (ua->UA_sock) { + found = ua->UA_sock->is_stop() ? false : true; + } break; } }