From: Kern Sibbald Date: Sun, 11 Nov 2018 09:13:38 +0000 (+0100) Subject: Minor backport from Enterprise + my own changes X-Git-Tag: Release-9.4.0~26 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7ac30b09dee4a8e2d9aec5897546489391ced426;p=thirdparty%2Fbacula.git Minor backport from Enterprise + my own changes --- diff --git a/bacula/src/cats/cats.h b/bacula/src/cats/cats.h index bb102bd60..9801082f3 100644 --- a/bacula/src/cats/cats.h +++ b/bacula/src/cats/cats.h @@ -121,6 +121,7 @@ struct JOB_DBR { JobId_t JobId; char Job[MAX_NAME_LENGTH]; /* Job unique name */ char Name[MAX_NAME_LENGTH]; /* Job base name */ + char PriorJob[MAX_NAME_LENGTH]; /* PriorJob name if any */ int JobType; /* actually char(1) */ int JobLevel; /* actually char(1) */ int JobStatus; /* actually char(1) */ @@ -254,7 +255,14 @@ struct FILE_DBR { }; /* Pool record -- same format as database */ -struct POOL_DBR { +class POOL_DBR { +public: + /* + * Do not turn on constructor until all bmemset on POOL_DBR removed + * + * POOL_DBR() { bmemset(this, 0, sizeof(POOL_DBR)); }; + * ~POOL_DBR() { }; + */ DBId_t PoolId; char Name[MAX_NAME_LENGTH]; /* Pool name */ uint32_t NumVols; /* total number of volumes */ diff --git a/bacula/src/dird/autoprune.c b/bacula/src/dird/autoprune.c index 621cca820..b522da2c1 100644 --- a/bacula/src/dird/autoprune.c +++ b/bacula/src/dird/autoprune.c @@ -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. @@ -92,7 +92,7 @@ void prune_volumes(JCR *jcr, bool InChanger, MEDIA_DBR *mr, return; } - memset(&prune_list, 0, sizeof(prune_list)); + bmemset(&prune_list, 0, sizeof(prune_list)); prune_list.max_ids = 10000; prune_list.JobId = (JobId_t *)malloc(sizeof(JobId_t) * prune_list.max_ids); @@ -104,7 +104,7 @@ void prune_volumes(JCR *jcr, bool InChanger, MEDIA_DBR *mr, /* * Get Pool record for Scratch Pool */ - memset(&spr, 0, sizeof(spr)); + bmemset(&spr, 0, sizeof(spr)); bstrncpy(spr.Name, "Scratch", sizeof(spr.Name)); if (db_get_pool_record(jcr, jcr->db, &spr)) { edit_int64(spr.PoolId, ed2); diff --git a/bacula/src/dird/catreq.c b/bacula/src/dird/catreq.c index 0ef663553..482de9032 100644 --- a/bacula/src/dird/catreq.c +++ b/bacula/src/dird/catreq.c @@ -123,7 +123,6 @@ void catalog_request(JCR *jcr, BSOCK *bs) char pool_name[MAX_NAME_LENGTH]; int index, ok, label, writing; POOLMEM *omsg; - POOL_DBR pr; uint64_t MediaId; utime_t VolFirstWritten; utime_t VolLastWritten; @@ -131,8 +130,8 @@ void catalog_request(JCR *jcr, BSOCK *bs) int Enabled, Recycle; JobId_t JobId = 0; - memset(&sdmr, 0, sizeof(sdmr)); - memset(&jm, 0, sizeof(jm)); + bmemset(&sdmr, 0, sizeof(sdmr)); + bmemset(&jm, 0, sizeof(jm)); Dsm_check(100); /* @@ -152,7 +151,9 @@ void catalog_request(JCR *jcr, BSOCK *bs) */ n = sscanf(bs->msg, Find_media, &JobId, &index, &pool_name, &mr.MediaType, &mr.VolType); if (n == 5) { - memset(&pr, 0, sizeof(pr)); + POOL_MEM errmsg; + POOL_DBR pr; + bmemset(&pr, 0, sizeof(pr)); bstrncpy(pr.Name, pool_name, sizeof(pr.Name)); unbash_spaces(pr.Name); ok = db_get_pool_record(jcr, jcr->db, &pr); @@ -160,7 +161,7 @@ void catalog_request(JCR *jcr, BSOCK *bs) mr.PoolId = pr.PoolId; set_storageid_in_mr(jcr->wstore, &mr); mr.ScratchPoolId = pr.ScratchPoolId; - ok = find_next_volume_for_append(jcr, &mr, index, fnv_create_vol, fnv_prune); + ok = find_next_volume_for_append(jcr, &mr, index, fnv_create_vol, fnv_prune, errmsg); Dmsg3(050, "find_media ok=%d idx=%d vol=%s\n", ok, index, mr.VolumeName); } else { /* Report problem finding pool */ @@ -173,8 +174,8 @@ void catalog_request(JCR *jcr, BSOCK *bs) if (ok) { send_volume_info_to_storage_daemon(jcr, bs, &mr); } else { - bs->fsend(_("1901 No Media.\n")); - Dmsg0(500, "1901 No Media.\n"); + bs->fsend(_("1901 No Media. %s\n"), errmsg.c_str()); + Dmsg1(500, "1901 No Media. %s\n", errmsg.c_str()); } goto ok_out; } @@ -566,7 +567,7 @@ static void update_attribute(JCR *jcr, char *msg, int32_t msglen) } else if (Stream == STREAM_RESTORE_OBJECT) { ROBJECT_DBR ro; - memset(&ro, 0, sizeof(ro)); + bmemset(&ro, 0, sizeof(ro)); ro.Stream = Stream; ro.FileIndex = FileIndex; if (jcr->wjcr) { diff --git a/bacula/src/dird/dir_plugins.c b/bacula/src/dird/dir_plugins.c index c43e0d82b..59f28eabd 100644 --- a/bacula/src/dird/dir_plugins.c +++ b/bacula/src/dird/dir_plugins.c @@ -1,7 +1,7 @@ /* Bacula(R) - The Network Backup Solution - Copyright (C) 2000-2015 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. @@ -297,6 +297,7 @@ void free_plugins(JCR *jcr) static bRC baculaGetValue(bpContext *ctx, brDirVariable var, void *value) { JCR *jcr; + POOL_DBR pr; bRC ret = bRC_OK; if (!ctx) { @@ -335,8 +336,7 @@ static bRC baculaGetValue(bpContext *ctx, brDirVariable var, void *value) Dmsg1(dbglvl, "Bacula: return bDirVarClient=%s\n", jcr->client->hdr.name); break; case bDirVarNumVols: - POOL_DBR pr; - memset(&pr, 0, sizeof(pr)); + bmemset(&pr, 0, sizeof(pr)); bstrncpy(pr.Name, jcr->pool->hdr.name, sizeof(pr.Name)); if (!db_get_pool_numvols(jcr, jcr->db, &pr)) { ret=bRC_Error; diff --git a/bacula/src/dird/dird_conf.c b/bacula/src/dird/dird_conf.c index a16d13e0c..23fa07ac1 100644 --- a/bacula/src/dird/dird_conf.c +++ b/bacula/src/dird/dird_conf.c @@ -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. @@ -708,21 +708,21 @@ extern RES_ITEM msgs_items[]; * name items rcode */ RES_TABLE resources[] = { - {"Director", dir_items, R_DIRECTOR}, - {"Client", cli_items, R_CLIENT}, - {"Job", job_items, R_JOB}, - {"Storage", store_items, R_STORAGE}, - {"Catalog", cat_items, R_CATALOG}, - {"Schedule", sch_items, R_SCHEDULE}, - {"Fileset", fs_items, R_FILESET}, - {"Pool", pool_items, R_POOL}, - {"Messages", msgs_items, R_MSGS}, - {"Counter", counter_items, R_COUNTER}, - {"Console", con_items, R_CONSOLE}, - {"JobDefs", job_items, R_JOBDEFS}, - {"Device", NULL, R_DEVICE}, /* info obtained from SD */ - {"Autochanger", store_items, R_AUTOCHANGER}, /* alias for R_STORAGE */ - {NULL, NULL, 0} + {"Director", dir_items, R_DIRECTOR}, + {"Client", cli_items, R_CLIENT}, + {"Job", job_items, R_JOB}, + {"Storage", store_items, R_STORAGE}, + {"Catalog", cat_items, R_CATALOG}, + {"Schedule", sch_items, R_SCHEDULE}, + {"Fileset", fs_items, R_FILESET}, + {"Pool", pool_items, R_POOL}, + {"Messages", msgs_items, R_MSGS}, + {"Counter", counter_items, R_COUNTER}, + {"Console", con_items, R_CONSOLE}, + {"JobDefs", job_items, R_JOBDEFS}, + {"Device", NULL, R_DEVICE}, /* info obtained from SD */ + {"Autochanger", store_items, R_AUTOCHANGER}, /* alias for R_STORAGE */ + {NULL, NULL, 0} }; @@ -963,7 +963,8 @@ void dump_resource(int type, RES *ares, void sendit(void *sock, const char *fmt, sendit(sock, _("%s: name=%s JobType=%d level=%s Priority=%d Enabled=%d\n"), type == R_JOB ? _("Job") : _("JobDefs"), res->res_job.hdr.name, res->res_job.JobType, - level_to_str(edl, sizeof(edl), res->res_job.JobLevel), res->res_job.Priority, + level_to_str(edl, sizeof(edl), res->res_job.JobLevel), + res->res_job.Priority, res->res_job.is_enabled()); sendit(sock, _(" MaxJobs=%u NumJobs=%u Resched=%d Times=%d Interval=%s Spool=%d WritePartAfterJob=%d\n"), res->res_job.MaxConcurrentJobs, @@ -1202,7 +1203,8 @@ void dump_resource(int type, RES *ares, void sendit(void *sock, const char *fmt, break; } next_run: - sendit(sock, _(" --> Run Level=%s\n"), level_to_str(edl, sizeof(edl), run->level)); + sendit(sock, _(" --> Run Level=%s\n"), + level_to_str(edl, sizeof(edl), run->level)); if (run->MaxRunSchedTime) { sendit(sock, _(" MaxRunSchedTime=%u\n"), run->MaxRunSchedTime); } diff --git a/bacula/src/dird/inc_conf.c b/bacula/src/dird/inc_conf.c index 3f4fbf55e..b8d424159 100644 --- a/bacula/src/dird/inc_conf.c +++ b/bacula/src/dird/inc_conf.c @@ -1,7 +1,7 @@ /* Bacula(R) - The Network Backup Solution - Copyright (C) 2000-2015 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. @@ -357,7 +357,7 @@ static void store_newinc(LEX *lc, RES_ITEM *item, int index, int pass) MD5Init(&res_all.res_fs.md5c); res_all.res_fs.have_MD5 = true; } - memset(&res_incexe, 0, sizeof(INCEXE)); + bmemset(&res_incexe, 0, sizeof(INCEXE)); res_all.res_fs.new_include = true; while ((token = lex_get_token(lc, T_SKIP_EOL)) != T_EOF) { if (token == T_EOB) { @@ -388,7 +388,7 @@ static void store_newinc(LEX *lc, RES_ITEM *item, int index, int pass) if (pass == 1) { incexe = (INCEXE *)malloc(sizeof(INCEXE)); memcpy(incexe, &res_incexe, sizeof(INCEXE)); - memset(&res_incexe, 0, sizeof(INCEXE)); + bmemset(&res_incexe, 0, sizeof(INCEXE)); if (item->code == 0) { /* include */ if (res_all.res_fs.num_includes == 0) { res_all.res_fs.include_items = (INCEXE **)malloc(sizeof(INCEXE *)); @@ -776,7 +776,7 @@ void store_opts(LEX *lc, RES_ITEM *item, int index, int pass) static void setup_current_opts(void) { FOPTS *fo = (FOPTS *)malloc(sizeof(FOPTS)); - memset(fo, 0, sizeof(FOPTS)); + bmemset(fo, 0, sizeof(FOPTS)); fo->regex.init(1, true); fo->regexdir.init(1, true); fo->regexfile.init(1, true); diff --git a/bacula/src/dird/mac.c b/bacula/src/dird/mac.c index ffecd697c..c052640db 100644 --- a/bacula/src/dird/mac.c +++ b/bacula/src/dird/mac.c @@ -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. @@ -246,7 +246,7 @@ static bool set_mac_next_pool(JCR *jcr, POOL **retpool) * Get the PoolId used with the original job. Then * find the pool name from the database record. */ - memset(&pr, 0, sizeof(pr)); + bmemset(&pr, 0, sizeof(pr)); pr.PoolId = jcr->jr.PoolId; if (!db_get_pool_record(jcr, jcr->db, &pr)) { Jmsg(jcr, M_FATAL, 0, _("Pool for JobId %s not in database. ERR=%s\n"), @@ -654,6 +654,11 @@ void mac_cleanup(JCR *jcr, int TermCode, int writeTermCode) wjcr->JobBytes = jcr->JobBytes = wjcr->SDJobBytes; wjcr->jr.RealEndTime = 0; wjcr->jr.PriorJobId = jcr->previous_jr.JobId; + if (jcr->previous_jr.PriorJob[0]) { + bstrncpy(wjcr->jr.PriorJob, jcr->previous_jr.PriorJob, sizeof(wjcr->jr.PriorJob)); + } else { + bstrncpy(wjcr->jr.PriorJob, jcr->previous_jr.Job, sizeof(wjcr->jr.PriorJob)); + } wjcr->JobErrors += wjcr->SDErrors; update_job_end(wjcr, TermCode); diff --git a/bacula/src/dird/newvol.c b/bacula/src/dird/newvol.c index 207b1650f..a047584ff 100644 --- a/bacula/src/dird/newvol.c +++ b/bacula/src/dird/newvol.c @@ -1,18 +1,20 @@ /* - Bacula® - The Network Backup Solution + Bacula(R) - The Network Backup Solution - Copyright (C) 2000-2014 Bacula Systems SA - All rights reserved. + Copyright (C) 2000-2018 Kern Sibbald - The main author of Bacula is Kern Sibbald, with contributions from many - others, a complete list can be found in the file AUTHORS. + The original author of Bacula is Kern Sibbald, with contributions + from many others, a complete list can be found in the file AUTHORS. - Licensees holding a valid Bacula Systems SA license may use this file - and others of this release in accordance with the proprietary license - agreement provided in the LICENSE file. Redistribution of any part of - this release is not permitted. + You may use this file and others of this release according to the + license defined in the LICENSE file, which includes the Affero General + Public License, v3.0 ("AGPLv3") and some additional permissions and + terms pursuant to its AGPLv3 Section 7. - Bacula® is a registered trademark of Kern Sibbald. + This notice must be preserved when any source code is + conveyed and/or propagated. + + Bacula(R) is a registered trademark of Kern Sibbald. */ /* * @@ -51,7 +53,6 @@ bool newVolume(JCR *jcr, MEDIA_DBR *mr, STORE *store, POOL_MEM &errmsg) /* See if we can create a new Volume */ db_lock(jcr->db); pr.PoolId = mr->PoolId; - pr.PoolBytes = 1; /* Get the size of the pool */ if (!db_get_pool_numvols(jcr, jcr->db, &pr)) { goto bail_out; @@ -63,12 +64,6 @@ bool newVolume(JCR *jcr, MEDIA_DBR *mr, STORE *store, POOL_MEM &errmsg) goto bail_out; } - if (check_max_pool_bytes(&pr)) { - Mmsg(errmsg, "Maximum Pool Bytes exceeded for Pool %s", pr.Name); - Dmsg1(90, "Too much bytes for Pool %s\n", pr.Name); - goto bail_out; - } - mr->clear(); set_pool_dbr_defaults_in_media_dbr(mr, &pr); jcr->VolumeName[0] = 0; diff --git a/bacula/src/dird/next_vol.c b/bacula/src/dird/next_vol.c index f960000bb..c4aa7b287 100644 --- a/bacula/src/dird/next_vol.c +++ b/bacula/src/dird/next_vol.c @@ -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. @@ -98,7 +98,7 @@ static void set_volume_to_exclude_list(JCR *jcr, int index, MEDIA_DBR *mr) * create -- whether or not to create a new volume */ int find_next_volume_for_append(JCR *jcr, MEDIA_DBR *mr, int index, - bool create, bool prune) + bool create, bool prune, POOL_MEM &errmsg) { int retry = 0; bool ok; @@ -123,6 +123,7 @@ int find_next_volume_for_append(JCR *jcr, MEDIA_DBR *mr, int index, */ db_lock(jcr->db); for ( ;; ) { + pm_strcpy(errmsg, ""); bstrncpy(mr->VolStatus, "Append", sizeof(mr->VolStatus)); /* want only appendable volumes */ /* * 1. Look for volume with "Append" status. @@ -185,7 +186,7 @@ int find_next_volume_for_append(JCR *jcr, MEDIA_DBR *mr, int index, /* * 6. Try "creating" a new Volume */ - ok = newVolume(jcr, mr, store); + ok = newVolume(jcr, mr, store, errmsg); } /* * Look at more drastic ways to find an Appendable Volume @@ -233,6 +234,7 @@ int find_next_volume_for_append(JCR *jcr, MEDIA_DBR *mr, int index, } else { Jmsg(jcr, M_ERROR, 0, _( "We seem to be looping trying to find the next volume. I give up.\n")); + ok = false; } } } @@ -420,7 +422,7 @@ bool get_scratch_volume(JCR *jcr, bool InChanger, MEDIA_DBR *mr, STORE *store) { MEDIA_DBR smr; /* for searching scratch pool */ - POOL_DBR spr, pr; + POOL_DBR spr; bool ok = false; bool found = false; @@ -432,7 +434,7 @@ bool get_scratch_volume(JCR *jcr, bool InChanger, MEDIA_DBR *mr, * db_get_pool_numvols will first try ScratchPoolId, * and then try the pool named Scratch */ - memset(&spr, 0, sizeof(spr)); + bmemset(&spr, 0, sizeof(spr)); bstrncpy(spr.Name, "Scratch", sizeof(spr.Name)); spr.PoolId = mr->ScratchPoolId; if (db_get_pool_record(jcr, jcr->db, &spr)) { @@ -457,13 +459,14 @@ bool get_scratch_volume(JCR *jcr, bool InChanger, MEDIA_DBR *mr, } if (found) { + POOL_DBR pr; POOL_MEM query(PM_MESSAGE); /* * Get pool record where the Scratch Volume will go to ensure * that we can add a Volume. */ - memset(&pr, 0, sizeof(pr)); + bmemset(&pr, 0, sizeof(pr)); bstrncpy(pr.Name, jcr->pool->name(), sizeof(pr.Name)); if (!db_get_pool_numvols(jcr, jcr->db, &pr)) { diff --git a/bacula/src/dird/protos.h b/bacula/src/dird/protos.h index 05217c683..414004615 100644 --- a/bacula/src/dird/protos.h +++ b/bacula/src/dird/protos.h @@ -181,16 +181,16 @@ extern void wait_for_storage_daemon_termination(JCR *jcr); extern bool send_bootstrap_file(JCR *jcr, BSOCK *sd); /* next_vol.c */ -void set_storageid_in_mr(STORE *store, MEDIA_DBR *mr); int find_next_volume_for_append(JCR *jcr, MEDIA_DBR *mr, int index, - bool create, bool purge); + bool create, bool purge, POOL_MEM &errmsg); +void set_storageid_in_mr(STORE *store, MEDIA_DBR *mr); bool has_volume_expired(JCR *jcr, MEDIA_DBR *mr); void check_if_volume_valid_or_recyclable(JCR *jcr, MEDIA_DBR *mr, const char **reason); bool get_scratch_volume(JCR *jcr, bool InChanger, MEDIA_DBR *mr, STORE *store); /* newvol.c */ -bool newVolume(JCR *jcr, MEDIA_DBR *mr, STORE *store); +bool newVolume(JCR *jcr, MEDIA_DBR *mr, STORE *store, POOL_MEM &errmsg); /* restore.c */ extern bool do_restore(JCR *jcr); diff --git a/bacula/src/dird/ua_output.c b/bacula/src/dird/ua_output.c index 8425d99e0..5afb543a0 100644 --- a/bacula/src/dird/ua_output.c +++ b/bacula/src/dird/ua_output.c @@ -759,6 +759,7 @@ static bool list_nextvol(UAContext *ua, int ndays) bool found = false; MEDIA_DBR mr; POOL_DBR pr; + POOL_MEM errmsg; char edl[50]; int i = find_arg_with_value(ua, "job"); @@ -786,7 +787,7 @@ static bool list_nextvol(UAContext *ua, int ndays) ua->error_msg(_("Could not find Pool for Job %s\n"), job->name()); continue; } - memset(&pr, 0, sizeof(pr)); + bmemset(&pr, 0, sizeof(pr)); pr.PoolId = jcr->jr.PoolId; if (!db_get_pool_record(jcr, jcr->db, &pr)) { bstrncpy(pr.Name, "*UnknownPool*", sizeof(pr.Name)); @@ -795,9 +796,9 @@ static bool list_nextvol(UAContext *ua, int ndays) get_job_storage(&store, job, run); set_storageid_in_mr(store.store, &mr); /* no need to set ScratchPoolId, since we use fnv_no_create_vol */ - if (!find_next_volume_for_append(jcr, &mr, 1, fnv_no_create_vol, fnv_prune)) { - ua->error_msg(_("Could not find next Volume for Job %s (Pool=%s, Level=%s).\n"), - job->name(), pr.Name, level_to_str(edl, sizeof(edl), run->level)); + if (!find_next_volume_for_append(jcr, &mr, 1, fnv_no_create_vol, fnv_prune, errmsg)) { + ua->error_msg(_("Could not find next Volume for Job %s (Pool=%s, Level=%s). %s\n"), + job->name(), pr.Name, level_to_str(edl, sizeof(edl), run->level), errmsg.c_str()); } else { ua->send_msg( _("The next Volume to be used by Job \"%s\" (Pool=%s, Level=%s) will be %s\n"), @@ -925,7 +926,7 @@ bool complete_jcr_for_job(JCR *jcr, JOB *job, POOL *pool) { POOL_DBR pr; - memset(&pr, 0, sizeof(POOL_DBR)); + bmemset(&pr, 0, sizeof(POOL_DBR)); set_jcr_defaults(jcr, job); if (pool) { jcr->pool = pool; /* override */ diff --git a/bacula/src/dird/ua_status.c b/bacula/src/dird/ua_status.c index 5507f3756..b11461e28 100644 --- a/bacula/src/dird/ua_status.c +++ b/bacula/src/dird/ua_status.c @@ -674,6 +674,7 @@ static void prt_runtime(UAContext *ua, sched_pkt *sp, OutputWriter *ow) bool close_db = false; JCR *jcr = ua->jcr; MEDIA_DBR mr; + POOL_MEM errmsg; int orig_jobtype; orig_jobtype = jcr->getJobType(); @@ -690,7 +691,7 @@ static void prt_runtime(UAContext *ua, sched_pkt *sp, OutputWriter *ow) set_storageid_in_mr(jcr->wstore, &mr); Dmsg0(250, "call find_next_volume_for_append\n"); /* no need to set ScratchPoolId, since we use fnv_no_create_vol */ - ok = find_next_volume_for_append(jcr, &mr, 1, fnv_no_create_vol, fnv_no_prune); + ok = find_next_volume_for_append(jcr, &mr, 1, fnv_no_create_vol, fnv_no_prune, errmsg); } if (!ok) { bstrncpy(mr.VolumeName, "*unknown*", sizeof(mr.VolumeName));