From: Kern Sibbald Date: Sat, 15 Mar 2003 10:36:22 +0000 (+0000) Subject: Corrections to Recycle Oldest code X-Git-Tag: Release-1.30~86 X-Git-Url: https://git.sur5r.net/?a=commitdiff_plain;h=6b793db11b9e78ebcab8eaa3b781f671b2ea8d2a;p=bacula%2Fbacula Corrections to Recycle Oldest code git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@381 91ce42f0-d328-0410-95d8-f526ca767f89 --- diff --git a/bacula/kernstodo b/bacula/kernstodo index a694d532c9..0a4d5ab4f7 100644 --- a/bacula/kernstodo +++ b/bacula/kernstodo @@ -21,7 +21,17 @@ Testing to do: (painful) - ***test GetFileAttributexEx, and remove MessageBox at 335 of winservice.cpp **** For 1.30 release: -- Ability to backup to a file then later transfer to a tape. +- Cancelling of a queued job does NOT work!!!!!! +- Bevan Anderson suggests having a run queue for each device + so that multiple simultaneous jobs can run but each writing + to a different Volume. +- Get two +rufus-dir: Volume used once. Marking Volume "File0003" as Used. +rufus-sd: Recycled volume File0003 on device /home/kern/bacula/working, all previous data lost. +rufus-dir: Volume used once. Marking Volume "File0003" as Used. +- Ability to backup to a file then later transfer to a tape -- Migration. + Migration based on MaxJobs(MinJobs),MaxVols(MinVols),AgeJobs,MaxBytes(MinBytes) + (i.e. HighwaterMark, LowwaterMark). - Eugeny Fisher wants to cycle through a set of volumes recycling the oldest volume when it is needed. - Fix "access not allowed" for backup of files on WinXP. diff --git a/bacula/src/dird/catreq.c b/bacula/src/dird/catreq.c index 571fbaac8f..0eec8efbaf 100644 --- a/bacula/src/dird/catreq.c +++ b/bacula/src/dird/catreq.c @@ -80,7 +80,7 @@ void catalog_request(JCR *jcr, BSOCK *bs, char *msg) /* * Request to find next appendable Volume for this Job */ - Dmsg1(120, "catreq %s", bs->msg); + Dmsg1(200, "catreq %s", bs->msg); if (sscanf(bs->msg, Find_media, &Job, &index) == 2) { mr.PoolId = jcr->PoolId; strcpy(mr.MediaType, jcr->store->media_type); @@ -94,15 +94,24 @@ next_volume: ok = db_find_next_volume(jcr, jcr->db, index, &mr); Dmsg2(100, "catreq after find_next_vol ok=%d FW=%d\n", ok, mr.FirstWritten); if (!ok) { + Dmsg1(200, "No next volume found. RecycleOldest=%d\n", + jcr->pool->recycle_oldest_volume); if (jcr->pool->recycle_oldest_volume) { + Dmsg0(200, "Request to find oldest volume.\n"); /* Find oldest volume to recycle */ ok = db_find_next_volume(jcr, jcr->db, -1, &mr); + Dmsg1(400, "Find oldest=%d\n", ok); if (ok) { UAContext ua; + Dmsg0(400, "Try purge.\n"); /* Try to purge oldest volume */ create_ua_context(jcr, &ua); ok = purge_jobs_from_volume(&ua, &mr); free_ua_context(&ua); + if (ok) { + ok = recycle_oldest_purged_volume(jcr, &mr); + Dmsg1(400, "Recycle after recycle oldest=%d\n", ok); + } } } if (!ok) { @@ -111,7 +120,7 @@ next_volume: Dmsg2(100, "find_recycled_volume1 %d FW=%d\n", ok, mr.FirstWritten); if (!ok) { prune_volumes(jcr); - ok = recycle_a_volume(jcr, &mr); + ok = recycle_oldest_purged_volume(jcr, &mr); Dmsg2(200, "find_recycled_volume2 %d FW=%d\n", ok, mr.FirstWritten); if (!ok) { /* See if we can create a new Volume */ @@ -123,7 +132,7 @@ next_volume: /* Check if use duration has expired */ Dmsg2(100, "VolJobs=%d FirstWritten=%d\n", mr.VolJobs, mr.FirstWritten); if (ok && mr.VolJobs > 0 && mr.VolUseDuration > 0 && - strcmp(mr.VolStatus, "Recycle") != 0) { + strcmp(mr.VolStatus, "Append") == 0) { utime_t now = time(NULL); if (mr.VolUseDuration <= (now - mr.FirstWritten)) { Dmsg4(100, "Duration=%d now=%d start=%d now-start=%d\n", @@ -168,7 +177,7 @@ next_volume: * Request to find specific Volume information */ } else if (sscanf(bs->msg, Get_Vol_Info, &Job, &mr.VolumeName, &writing) == 3) { - Dmsg1(120, "CatReq GetVolInfo Vol=%s\n", mr.VolumeName); + Dmsg1(400, "CatReq GetVolInfo Vol=%s\n", mr.VolumeName); /* * Find the Volume */ @@ -227,6 +236,8 @@ next_volume: &sdmr.VolWrites, &sdmr.MaxVolBytes, &sdmr.LastWritten, &sdmr.VolStatus, &sdmr.Slot, &relabel) == 14) { + Dmsg3(400, "Update media %s oldStat=%s newStat=%s\n", sdmr.VolumeName, + mr.VolStatus, sdmr.VolStatus); bstrncpy(mr.VolumeName, sdmr.VolumeName, sizeof(mr.VolumeName)); /* copy Volume name */ if (!db_get_media_record(jcr, jcr->db, &mr)) { Jmsg(jcr, M_ERROR, 0, _("Unable to get Media record for Volume %s: ERR=%s\n"), @@ -255,41 +266,43 @@ next_volume: * Update Media Record */ - /* First handle Max Volume Bytes */ - if ((mr.MaxVolBytes > 0 && mr.VolBytes >= mr.MaxVolBytes)) { - Jmsg(jcr, M_INFO, 0, _("Max Volume bytes exceeded. " - "Marking Volume \"%s\" as Full.\n"), mr.VolumeName); - strcpy(mr.VolStatus, "Full"); - - /* Now see if Volume should only be used once */ - } else if (mr.VolBytes > 0 && jcr->pool->use_volume_once) { - Jmsg(jcr, M_INFO, 0, _("Volume used once. " - "Marking Volume \"%s\" as Used.\n"), mr.VolumeName); - strcpy(mr.VolStatus, "Used"); - - /* Now see if Max Jobs written to volume */ - } else if (mr.MaxVolJobs > 0 && mr.MaxVolJobs <= mr.VolJobs) { - Jmsg(jcr, M_INFO, 0, _("Max Volume jobs exceeded. " - "Marking Volume \"%s\" as Used.\n"), mr.VolumeName); - strcpy(mr.VolStatus, "Used"); - - /* Now see if Max Files written to volume */ - } else if (mr.MaxVolFiles > 0 && mr.MaxVolFiles <= mr.VolFiles) { - Jmsg(jcr, M_INFO, 0, _("Max Volume files exceeded. " - "Marking Volume \"%s\" as Used.\n"), mr.VolumeName); - strcpy(mr.VolStatus, "Used"); - - /* Finally, check Use duration expiration */ - } else if (mr.VolUseDuration > 0) { - utime_t now = time(NULL); - /* See if Vol Use has expired */ - if (mr.VolUseDuration <= (now - mr.FirstWritten)) { - Jmsg(jcr, M_INFO, 0, _("Max configured use duration exceeded. " - "Marking Volume \"%s\"as Used.\n"), mr.VolumeName); - strcpy(mr.VolStatus, "Used"); /* yes, mark as used */ + /* Check limits and expirations if "Append" and not a relable request */ + if (strcmp(mr.VolStatus, "Append") == 0 && !relabel) { + /* First handle Max Volume Bytes */ + if ((mr.MaxVolBytes > 0 && mr.VolBytes >= mr.MaxVolBytes)) { + Jmsg(jcr, M_INFO, 0, _("Max Volume bytes exceeded. " + "Marking Volume \"%s\" as Full.\n"), mr.VolumeName); + strcpy(mr.VolStatus, "Full"); + + /* Now see if Volume should only be used once */ + } else if (mr.VolBytes > 0 && jcr->pool->use_volume_once) { + Jmsg(jcr, M_INFO, 0, _("Volume used once. " + "Marking Volume \"%s\" as Used.\n"), mr.VolumeName); + strcpy(mr.VolStatus, "Used"); + + /* Now see if Max Jobs written to volume */ + } else if (mr.MaxVolJobs > 0 && mr.MaxVolJobs <= mr.VolJobs) { + Jmsg(jcr, M_INFO, 0, _("Max Volume jobs exceeded. " + "Marking Volume \"%s\" as Used.\n"), mr.VolumeName); + strcpy(mr.VolStatus, "Used"); + + /* Now see if Max Files written to volume */ + } else if (mr.MaxVolFiles > 0 && mr.MaxVolFiles <= mr.VolFiles) { + Jmsg(jcr, M_INFO, 0, _("Max Volume files exceeded. " + "Marking Volume \"%s\" as Used.\n"), mr.VolumeName); + strcpy(mr.VolStatus, "Used"); + + /* Finally, check Use duration expiration */ + } else if (mr.VolUseDuration > 0) { + utime_t now = time(NULL); + /* See if Vol Use has expired */ + if (mr.VolUseDuration <= (now - mr.FirstWritten)) { + Jmsg(jcr, M_INFO, 0, _("Max configured use duration exceeded. " + "Marking Volume \"%s\"as Used.\n"), mr.VolumeName); + strcpy(mr.VolStatus, "Used"); /* yes, mark as used */ + } } } - Dmsg2(200, "db_update_media_record. Stat=%s Vol=%s\n", mr.VolStatus, mr.VolumeName); if (db_update_media_record(jcr, jcr->db, &mr)) { bnet_fsend(bs, OK_update); diff --git a/bacula/src/dird/dird_conf.c b/bacula/src/dird/dird_conf.c index 04e21d4f9e..6bb7211b9b 100644 --- a/bacula/src/dird/dird_conf.c +++ b/bacula/src/dird/dird_conf.c @@ -8,14 +8,14 @@ * 1. The generic lexical scanner in lib/lex.c and lib/lex.h * * 2. The generic config scanner in lib/parse_config.c and - * lib/parse_config.h. - * These files contain the parser code, some utility - * routines, and the common store routines (name, int, - * string). + * lib/parse_config.h. + * These files contain the parser code, some utility + * routines, and the common store routines (name, int, + * string). * * 3. The daemon specific file, which contains the Resource - * definitions as well as any specific store routines - * for the resource records. + * definitions as well as any specific store routines + * for the resource records. * * Kern Sibbald, January MM * @@ -83,7 +83,7 @@ int res_all_size = sizeof(res_all); /* * Director Resource * - * name handler value code flags default_value + * name handler value code flags default_value */ static struct res_items dir_items[] = { {"name", store_name, ITEM(res_dir.hdr.name), 0, ITEM_REQUIRED, 0}, @@ -105,7 +105,7 @@ static struct res_items dir_items[] = { /* * Client or File daemon resource * - * name handler value code flags default_value + * name handler value code flags default_value */ static struct res_items cli_items[] = { @@ -123,7 +123,7 @@ static struct res_items cli_items[] = { /* Storage daemon resource * - * name handler value code flags default_value + * name handler value code flags default_value */ static struct res_items store_items[] = { {"name", store_name, ITEM(res_store.hdr.name), 0, ITEM_REQUIRED, 0}, @@ -141,7 +141,7 @@ static struct res_items store_items[] = { /* * Catalog Resource Directives * - * name handler value code flags default_value + * name handler value code flags default_value */ static struct res_items cat_items[] = { {"name", store_name, ITEM(res_cat.hdr.name), 0, ITEM_REQUIRED, 0}, @@ -160,7 +160,7 @@ static struct res_items cat_items[] = { /* * Job Resource Directives * - * name handler value code flags default_value + * name handler value code flags default_value */ static struct res_items job_items[] = { {"name", store_name, ITEM(res_job.hdr.name), 0, ITEM_REQUIRED, 0}, @@ -194,7 +194,7 @@ static struct res_items job_items[] = { /* FileSet resource * - * name handler value code flags default_value + * name handler value code flags default_value */ static struct res_items fs_items[] = { {"name", store_name, ITEM(res_fs.hdr.name), 0, ITEM_REQUIRED, 0}, @@ -203,13 +203,13 @@ static struct res_items fs_items[] = { {"finclude", store_finc, NULL, 0, ITEM_NO_EQUALS, 0}, {"exclude", store_inc, NULL, 1, 0, 0}, {"fexclude", store_finc, NULL, 1, ITEM_NO_EQUALS, 0}, - {NULL, NULL, NULL, 0, 0, 0} + {NULL, NULL, NULL, 0, 0, 0} }; /* Schedule -- see run_conf.c */ /* Schedule * - * name handler value code flags default_value + * name handler value code flags default_value */ static struct res_items sch_items[] = { {"name", store_name, ITEM(res_sch.hdr.name), 0, ITEM_REQUIRED, 0}, @@ -220,7 +220,7 @@ static struct res_items sch_items[] = { /* Group resource -- not implemented * - * name handler value code flags default_value + * name handler value code flags default_value */ static struct res_items group_items[] = { {"name", store_name, ITEM(res_group.hdr.name), 0, ITEM_REQUIRED, 0}, @@ -230,7 +230,7 @@ static struct res_items group_items[] = { /* Pool resource * - * name handler value code flags default_value + * name handler value code flags default_value */ static struct res_items pool_items[] = { {"name", store_name, ITEM(res_pool.hdr.name), 0, ITEM_REQUIRED, 0}, @@ -239,7 +239,7 @@ static struct res_items pool_items[] = { {"labelformat", store_strname, ITEM(res_pool.label_format), 0, 0, 0}, {"usecatalog", store_yesno, ITEM(res_pool.use_catalog), 1, ITEM_DEFAULT, 1}, {"usevolumeonce", store_yesno, ITEM(res_pool.use_volume_once), 1, 0, 0}, - {"recycleoldestvolume", store_yesno, ITEM(res_pool.recycle_oldest_volume), 0, 0, 0}, + {"recycleoldestvolume", store_yesno, ITEM(res_pool.recycle_oldest_volume), 1, 0, 0}, {"maximumvolumes", store_pint, ITEM(res_pool.max_volumes), 0, 0, 0}, {"maximumvolumejobs", store_pint, ITEM(res_pool.MaxVolJobs), 0, 0, 0}, {"maximumvolumefiles", store_pint, ITEM(res_pool.MaxVolFiles), 0, 0, 0}, @@ -255,7 +255,7 @@ static struct res_items pool_items[] = { /* * Counter Resource - * name handler value code flags default_value + * name handler value code flags default_value */ static struct res_items counter_items[] = { {"name", store_name, ITEM(res_counter.hdr.name), 0, ITEM_REQUIRED, 0}, @@ -275,7 +275,7 @@ extern struct res_items msgs_items[]; * This is the master resource definition. * It must have one item for each of the resources. * - * name items rcode res_head + * name items rcode res_head */ struct s_res resources[] = { {"director", dir_items, R_DIRECTOR, NULL}, @@ -289,13 +289,13 @@ struct s_res resources[] = { {"pool", pool_items, R_POOL, NULL}, {"messages", msgs_items, R_MSGS, NULL}, {"counter", counter_items, R_COUNTER, NULL}, - {NULL, NULL, 0, NULL} + {NULL, NULL, 0, NULL} }; /* Keywords (RHS) permitted in Job Level records * - * level_name level job_type + * level_name level job_type */ struct s_jl joblevels[] = { {"Full", L_FULL, JT_BACKUP}, @@ -306,19 +306,19 @@ struct s_jl joblevels[] = { {"Initcatalog", L_VERIFY_INIT, JT_VERIFY}, {"VolumeToCatalog", L_VERIFY_VOLUME_TO_CATALOG, JT_VERIFY}, {"Data", L_VERIFY_DATA, JT_VERIFY}, - {NULL, 0} + {NULL, 0} }; /* Keywords (RHS) permitted in Job type records * - * type_name job_type + * type_name job_type */ struct s_jt jobtypes[] = { {"backup", JT_BACKUP}, {"admin", JT_ADMIN}, {"verify", JT_VERIFY}, {"restore", JT_RESTORE}, - {NULL, 0} + {NULL, 0} }; @@ -327,7 +327,7 @@ static struct s_kw BakVerFields[] = { {"client", 'C'}, {"fileset", 'F'}, {"level", 'L'}, - {NULL, 0} + {NULL, 0} }; /* Keywords (RHS) permitted in Restore records */ @@ -338,7 +338,7 @@ static struct s_kw RestoreFields[] = { {"where", 'W'}, /* root of restore */ {"replace", 'R'}, /* replacement options */ {"bootstrap", 'B'}, /* bootstrap file */ - {NULL, 0} + {NULL, 0} }; /* Options permitted in Restore replace= */ @@ -347,7 +347,7 @@ struct s_kw ReplaceOptions[] = { {"ifnewer", REPLACE_IFNEWER}, {"ifolder", REPLACE_IFOLDER}, {"never", REPLACE_NEVER}, - {NULL, 0} + {NULL, 0} }; char *level_to_str(int level) @@ -359,8 +359,8 @@ char *level_to_str(int level) sprintf(level_no, "%d", level); /* default if not found */ for (i=0; joblevels[i].level_name; i++) { if (level == joblevels[i].level) { - str = joblevels[i].level_name; - break; + str = joblevels[i].level_name; + break; } } return str; @@ -376,211 +376,214 @@ void dump_resource(int type, RES *reshdr, void sendit(void *sock, char *fmt, ... sendit(sock, "No %s resource defined\n", res_to_str(type)); return; } - if (type < 0) { /* no recursion */ + if (type < 0) { /* no recursion */ type = - type; recurse = 0; } switch (type) { case R_DIRECTOR: - char ed1[30], ed2[30]; + char ed1[30], ed2[30]; sendit(sock, "Director: name=%s maxjobs=%d FDtimeout=%s SDtimeout=%s\n", - reshdr->name, res->res_dir.MaxConcurrentJobs, - edit_uint64(res->res_dir.FDConnectTimeout, ed1), - edit_uint64(res->res_dir.SDConnectTimeout, ed2)); - if (res->res_dir.query_file) { + reshdr->name, res->res_dir.MaxConcurrentJobs, + edit_uint64(res->res_dir.FDConnectTimeout, ed1), + edit_uint64(res->res_dir.SDConnectTimeout, ed2)); + if (res->res_dir.query_file) { sendit(sock, " query_file=%s\n", res->res_dir.query_file); - } - if (res->res_dir.messages) { + } + if (res->res_dir.messages) { sendit(sock, " --> "); - dump_resource(-R_MSGS, (RES *)res->res_dir.messages, sendit, sock); - } - break; + dump_resource(-R_MSGS, (RES *)res->res_dir.messages, sendit, sock); + } + break; case R_CLIENT: sendit(sock, "Client: name=%s address=%s FDport=%d\n", - res->res_client.hdr.name, res->res_client.address, res->res_client.FDport); + res->res_client.hdr.name, res->res_client.address, res->res_client.FDport); sendit(sock, " JobRetention=%" lld " FileRetention=%" lld " AutoPrune=%d\n", - res->res_client.JobRetention, res->res_client.FileRetention, - res->res_client.AutoPrune); - if (res->res_client.catalog) { + res->res_client.JobRetention, res->res_client.FileRetention, + res->res_client.AutoPrune); + if (res->res_client.catalog) { sendit(sock, " --> "); - dump_resource(-R_CATALOG, (RES *)res->res_client.catalog, sendit, sock); - } - break; + dump_resource(-R_CATALOG, (RES *)res->res_client.catalog, sendit, sock); + } + break; case R_STORAGE: sendit(sock, "Storage: name=%s address=%s SDport=%d\n\ DeviceName=%s MediaType=%s\n", - res->res_store.hdr.name, res->res_store.address, res->res_store.SDport, - res->res_store.dev_name, res->res_store.media_type); - break; + res->res_store.hdr.name, res->res_store.address, res->res_store.SDport, + res->res_store.dev_name, res->res_store.media_type); + break; case R_CATALOG: sendit(sock, "Catalog: name=%s address=%s DBport=%d db_name=%s\n\ db_user=%s\n", - res->res_cat.hdr.name, NPRT(res->res_cat.db_address), - res->res_cat.db_port, res->res_cat.db_name, NPRT(res->res_cat.db_user)); - break; + res->res_cat.hdr.name, NPRT(res->res_cat.db_address), + res->res_cat.db_port, res->res_cat.db_name, NPRT(res->res_cat.db_user)); + break; case R_JOB: sendit(sock, "Job: name=%s JobType=%d level=%s\n", res->res_job.hdr.name, - res->res_job.JobType, level_to_str(res->res_job.level)); - if (res->res_job.client) { + res->res_job.JobType, level_to_str(res->res_job.level)); + if (res->res_job.client) { sendit(sock, " --> "); - dump_resource(-R_CLIENT, (RES *)res->res_job.client, sendit, sock); - } - if (res->res_job.fileset) { + dump_resource(-R_CLIENT, (RES *)res->res_job.client, sendit, sock); + } + if (res->res_job.fileset) { sendit(sock, " --> "); - dump_resource(-R_FILESET, (RES *)res->res_job.fileset, sendit, sock); - } - if (res->res_job.schedule) { + dump_resource(-R_FILESET, (RES *)res->res_job.fileset, sendit, sock); + } + if (res->res_job.schedule) { sendit(sock, " --> "); - dump_resource(-R_SCHEDULE, (RES *)res->res_job.schedule, sendit, sock); - } - if (res->res_job.RestoreWhere) { + dump_resource(-R_SCHEDULE, (RES *)res->res_job.schedule, sendit, sock); + } + if (res->res_job.RestoreWhere) { sendit(sock, " --> Where=%s\n", NPRT(res->res_job.RestoreWhere)); - } - if (res->res_job.RestoreBootstrap) { + } + if (res->res_job.RestoreBootstrap) { sendit(sock, " --> Bootstrap=%s\n", NPRT(res->res_job.RestoreBootstrap)); - } - if (res->res_job.RunBeforeJob) { + } + if (res->res_job.RunBeforeJob) { sendit(sock, " --> RunBefore=%s\n", NPRT(res->res_job.RunBeforeJob)); - } - if (res->res_job.RunAfterJob) { + } + if (res->res_job.RunAfterJob) { sendit(sock, " --> RunAfter=%s\n", NPRT(res->res_job.RunAfterJob)); - } - if (res->res_job.WriteBootstrap) { + } + if (res->res_job.WriteBootstrap) { sendit(sock, " --> WriteBootstrap=%s\n", NPRT(res->res_job.WriteBootstrap)); - } - if (res->res_job.storage) { + } + if (res->res_job.storage) { sendit(sock, " --> "); - dump_resource(-R_STORAGE, (RES *)res->res_job.storage, sendit, sock); - } - if (res->res_job.pool) { + dump_resource(-R_STORAGE, (RES *)res->res_job.storage, sendit, sock); + } + if (res->res_job.pool) { sendit(sock, " --> "); - dump_resource(-R_POOL, (RES *)res->res_job.pool, sendit, sock); - } else { + dump_resource(-R_POOL, (RES *)res->res_job.pool, sendit, sock); + } else { sendit(sock, "!!! No Pool resource\n"); - } - if (res->res_job.messages) { + } + if (res->res_job.messages) { sendit(sock, " --> "); - dump_resource(-R_MSGS, (RES *)res->res_job.messages, sendit, sock); - } - break; + dump_resource(-R_MSGS, (RES *)res->res_job.messages, sendit, sock); + } + break; case R_FILESET: sendit(sock, "FileSet: name=%s\n", res->res_fs.hdr.name); - for (int i=0; ires_fs.num_includes; i++) { - INCEXE *incexe = res->res_fs.include_items[i]; - for (int j=0; jnum_names; j++) { + for (int i=0; ires_fs.num_includes; i++) { + INCEXE *incexe = res->res_fs.include_items[i]; + for (int j=0; jnum_names; j++) { sendit(sock, " Inc: %s\n", incexe->name_list[j]); - } - } - for (int i=0; ires_fs.num_excludes; i++) { - INCEXE *incexe = res->res_fs.exclude_items[i]; - for (int j=0; jnum_names; j++) { + } + } + for (int i=0; ires_fs.num_excludes; i++) { + INCEXE *incexe = res->res_fs.exclude_items[i]; + for (int j=0; jnum_names; j++) { sendit(sock, " Exc: %s\n", incexe->name_list[j]); - } - } - break; + } + } + break; case R_SCHEDULE: - if (res->res_sch.run) { - int i; - RUN *run = res->res_sch.run; - char buf[1000], num[10]; + if (res->res_sch.run) { + int i; + RUN *run = res->res_sch.run; + char buf[1000], num[10]; sendit(sock, "Schedule: name=%s\n", res->res_sch.hdr.name); - if (!run) { - break; - } + if (!run) { + break; + } next_run: sendit(sock, " --> Run Level=%s\n", level_to_str(run->level)); strcpy(buf, " hour="); - for (i=0; i<24; i++) { - if (bit_is_set(i, run->hour)) { + for (i=0; i<24; i++) { + if (bit_is_set(i, run->hour)) { sprintf(num, "%d ", i); - strcat(buf, num); - } - } + strcat(buf, num); + } + } strcat(buf, "\n"); - sendit(sock, buf); + sendit(sock, buf); strcpy(buf, " mday="); - for (i=0; i<31; i++) { - if (bit_is_set(i, run->mday)) { + for (i=0; i<31; i++) { + if (bit_is_set(i, run->mday)) { sprintf(num, "%d ", i+1); - strcat(buf, num); - } - } + strcat(buf, num); + } + } strcat(buf, "\n"); - sendit(sock, buf); + sendit(sock, buf); strcpy(buf, " month="); - for (i=0; i<12; i++) { - if (bit_is_set(i, run->month)) { + for (i=0; i<12; i++) { + if (bit_is_set(i, run->month)) { sprintf(num, "%d ", i+1); - strcat(buf, num); - } - } + strcat(buf, num); + } + } strcat(buf, "\n"); - sendit(sock, buf); + sendit(sock, buf); strcpy(buf, " wday="); - for (i=0; i<7; i++) { - if (bit_is_set(i, run->wday)) { + for (i=0; i<7; i++) { + if (bit_is_set(i, run->wday)) { sprintf(num, "%d ", i+1); - strcat(buf, num); - } - } + strcat(buf, num); + } + } strcat(buf, "\n"); - sendit(sock, buf); + sendit(sock, buf); strcpy(buf, " wpos="); - for (i=0; i<5; i++) { - if (bit_is_set(i, run->wpos)) { + for (i=0; i<5; i++) { + if (bit_is_set(i, run->wpos)) { sprintf(num, "%d ", i+1); - strcat(buf, num); - } - } + strcat(buf, num); + } + } strcat(buf, "\n"); - sendit(sock, buf); + sendit(sock, buf); sendit(sock, " mins=%d\n", run->minute); - if (run->pool) { + if (run->pool) { sendit(sock, " --> "); - dump_resource(-R_POOL, (RES *)run->pool, sendit, sock); - } - if (run->storage) { + dump_resource(-R_POOL, (RES *)run->pool, sendit, sock); + } + if (run->storage) { sendit(sock, " --> "); - dump_resource(-R_STORAGE, (RES *)run->storage, sendit, sock); - } - if (run->msgs) { + dump_resource(-R_STORAGE, (RES *)run->storage, sendit, sock); + } + if (run->msgs) { sendit(sock, " --> "); - dump_resource(-R_MSGS, (RES *)run->msgs, sendit, sock); - } - /* If another Run record is chained in, go print it */ - if (run->next) { - run = run->next; - goto next_run; - } - } else { + dump_resource(-R_MSGS, (RES *)run->msgs, sendit, sock); + } + /* If another Run record is chained in, go print it */ + if (run->next) { + run = run->next; + goto next_run; + } + } else { sendit(sock, "Schedule: name=%s\n", res->res_sch.hdr.name); - } - break; + } + break; case R_GROUP: sendit(sock, "Group: name=%s\n", res->res_group.hdr.name); - break; + break; case R_POOL: sendit(sock, "Pool: name=%s PoolType=%s\n", res->res_pool.hdr.name, - res->res_pool.pool_type); + res->res_pool.pool_type); sendit(sock, " use_cat=%d use_once=%d acpt_any=%d cat_files=%d\n", - res->res_pool.use_catalog, res->res_pool.use_volume_once, - res->res_pool.accept_any_volume, res->res_pool.catalog_files); + res->res_pool.use_catalog, res->res_pool.use_volume_once, + res->res_pool.accept_any_volume, res->res_pool.catalog_files); sendit(sock, " max_vols=%d auto_prune=%d VolRetention=%" lld "\n", - res->res_pool.max_volumes, res->res_pool.AutoPrune, - res->res_pool.VolRetention); + res->res_pool.max_volumes, res->res_pool.AutoPrune, + res->res_pool.VolRetention); sendit(sock, " recycle=%d LabelFormat=%s\n", res->res_pool.Recycle, - NPRT(res->res_pool.label_format)); - break; + NPRT(res->res_pool.label_format)); + sendit(sock, " recyleOldest=%d MaxVolJobs=%d MaxVolFiles=%d\n", + res->res_pool.recycle_oldest_volume, + res->res_pool.MaxVolJobs, res->res_pool.MaxVolFiles); + break; case R_MSGS: sendit(sock, "Messages: name=%s\n", res->res_msgs.hdr.name); - if (res->res_msgs.mail_cmd) + if (res->res_msgs.mail_cmd) sendit(sock, " mailcmd=%s\n", res->res_msgs.mail_cmd); - if (res->res_msgs.operator_cmd) + if (res->res_msgs.operator_cmd) sendit(sock, " opcmd=%s\n", res->res_msgs.operator_cmd); - break; + break; default: sendit(sock, "Unknown resource type %d in dump_resource.\n", type); - break; + break; } if (recurse && res->res_dir.hdr.next) { dump_resource(type, res->res_dir.hdr.next, sendit, sock); @@ -601,13 +604,13 @@ static void free_incexe(INCEXE *incexe) for (int i=0; inum_opts; i++) { FOPTS *fopt = incexe->opts_list[i]; if (fopt->match) { - free(fopt->match); + free(fopt->match); } for (int j=0; jnum_base; j++) { - free(fopt->base_list[j]); + free(fopt->base_list[j]); } if (fopt->base_list) { - free(fopt->base_list); + free(fopt->base_list); } free(fopt); } @@ -647,126 +650,126 @@ void free_resource(int type) switch (type) { case R_DIRECTOR: - if (res->res_dir.working_directory) { - free(res->res_dir.working_directory); - } - if (res->res_dir.pid_directory) { - free(res->res_dir.pid_directory); - } - if (res->res_dir.subsys_directory) { - free(res->res_dir.subsys_directory); - } - if (res->res_dir.password) { - free(res->res_dir.password); - } - if (res->res_dir.query_file) { - free(res->res_dir.query_file); - } - if (res->res_dir.DIRaddr) { - free(res->res_dir.DIRaddr); - } - break; + if (res->res_dir.working_directory) { + free(res->res_dir.working_directory); + } + if (res->res_dir.pid_directory) { + free(res->res_dir.pid_directory); + } + if (res->res_dir.subsys_directory) { + free(res->res_dir.subsys_directory); + } + if (res->res_dir.password) { + free(res->res_dir.password); + } + if (res->res_dir.query_file) { + free(res->res_dir.query_file); + } + if (res->res_dir.DIRaddr) { + free(res->res_dir.DIRaddr); + } + break; case R_CLIENT: - if (res->res_client.address) { - free(res->res_client.address); - } - if (res->res_client.password) { - free(res->res_client.password); - } - break; + if (res->res_client.address) { + free(res->res_client.address); + } + if (res->res_client.password) { + free(res->res_client.password); + } + break; case R_STORAGE: - if (res->res_store.address) { - free(res->res_store.address); - } - if (res->res_store.password) { - free(res->res_store.password); - } - if (res->res_store.media_type) { - free(res->res_store.media_type); - } - if (res->res_store.dev_name) { - free(res->res_store.dev_name); - } - break; + if (res->res_store.address) { + free(res->res_store.address); + } + if (res->res_store.password) { + free(res->res_store.password); + } + if (res->res_store.media_type) { + free(res->res_store.media_type); + } + if (res->res_store.dev_name) { + free(res->res_store.dev_name); + } + break; case R_CATALOG: - if (res->res_cat.db_address) { - free(res->res_cat.db_address); - } - if (res->res_cat.db_socket) { - free(res->res_cat.db_socket); - } - if (res->res_cat.db_user) { - free(res->res_cat.db_user); - } - if (res->res_cat.db_name) { - free(res->res_cat.db_name); - } - if (res->res_cat.db_password) { - free(res->res_cat.db_password); - } - break; + if (res->res_cat.db_address) { + free(res->res_cat.db_address); + } + if (res->res_cat.db_socket) { + free(res->res_cat.db_socket); + } + if (res->res_cat.db_user) { + free(res->res_cat.db_user); + } + if (res->res_cat.db_name) { + free(res->res_cat.db_name); + } + if (res->res_cat.db_password) { + free(res->res_cat.db_password); + } + break; case R_FILESET: - if ((num=res->res_fs.num_includes)) { - while (--num >= 0) { - free_incexe(res->res_fs.include_items[num]); - } - free(res->res_fs.include_items); - } - res->res_fs.num_includes = 0; - if ((num=res->res_fs.num_excludes)) { - while (--num >= 0) { - free_incexe(res->res_fs.exclude_items[num]); - } - free(res->res_fs.exclude_items); - } - res->res_fs.num_excludes = 0; - break; + if ((num=res->res_fs.num_includes)) { + while (--num >= 0) { + free_incexe(res->res_fs.include_items[num]); + } + free(res->res_fs.include_items); + } + res->res_fs.num_includes = 0; + if ((num=res->res_fs.num_excludes)) { + while (--num >= 0) { + free_incexe(res->res_fs.exclude_items[num]); + } + free(res->res_fs.exclude_items); + } + res->res_fs.num_excludes = 0; + break; case R_POOL: - if (res->res_pool.pool_type) { - free(res->res_pool.pool_type); - } - if (res->res_pool.label_format) { - free(res->res_pool.label_format); - } - break; + if (res->res_pool.pool_type) { + free(res->res_pool.pool_type); + } + if (res->res_pool.label_format) { + free(res->res_pool.label_format); + } + break; case R_SCHEDULE: - if (res->res_sch.run) { - RUN *nrun, *next; - nrun = res->res_sch.run; - while (nrun) { - next = nrun->next; - free(nrun); - nrun = next; - } - } - break; + if (res->res_sch.run) { + RUN *nrun, *next; + nrun = res->res_sch.run; + while (nrun) { + next = nrun->next; + free(nrun); + nrun = next; + } + } + break; case R_JOB: - if (res->res_job.RestoreWhere) { - free(res->res_job.RestoreWhere); - } - if (res->res_job.RestoreBootstrap) { - free(res->res_job.RestoreBootstrap); - } - if (res->res_job.WriteBootstrap) { - free(res->res_job.WriteBootstrap); - } - if (res->res_job.RunBeforeJob) { - free(res->res_job.RunBeforeJob); - } - if (res->res_job.RunAfterJob) { - free(res->res_job.RunAfterJob); - } - break; + if (res->res_job.RestoreWhere) { + free(res->res_job.RestoreWhere); + } + if (res->res_job.RestoreBootstrap) { + free(res->res_job.RestoreBootstrap); + } + if (res->res_job.WriteBootstrap) { + free(res->res_job.WriteBootstrap); + } + if (res->res_job.RunBeforeJob) { + free(res->res_job.RunBeforeJob); + } + if (res->res_job.RunAfterJob) { + free(res->res_job.RunAfterJob); + } + break; case R_MSGS: - if (res->res_msgs.mail_cmd) - free(res->res_msgs.mail_cmd); - if (res->res_msgs.operator_cmd) - free(res->res_msgs.operator_cmd); - free_msgs_res((MSGS *)res); /* free message resource */ - res = NULL; - break; + if (res->res_msgs.mail_cmd) + free(res->res_msgs.mail_cmd); + if (res->res_msgs.operator_cmd) + free(res->res_msgs.operator_cmd); + free_msgs_res((MSGS *)res); /* free message resource */ + res = NULL; + break; case R_GROUP: - break; + break; default: printf("Unknown resource type %d in free_resource.\n", type); } @@ -798,10 +801,10 @@ void save_resource(int type, struct res_items *items, int pass) */ for (i=0; items[i].name; i++) { if (items[i].flags & ITEM_REQUIRED) { - if (!bit_is_set(i, res_all.res_dir.hdr.item_present)) { + if (!bit_is_set(i, res_all.res_dir.hdr.item_present)) { Emsg2(M_ERROR_TERM, 0, "%s item is required in %s resource, but not found.\n", - items[i].name, resources[rindex]); - } + items[i].name, resources[rindex]); + } } /* If this triggers, take a look at lib/parse_conf.h */ if (i >= MAX_RES_ITEMS) { @@ -816,82 +819,82 @@ void save_resource(int type, struct res_items *items, int pass) */ if (pass == 2) { switch (type) { - /* Resources not containing a resource */ - case R_CATALOG: - case R_STORAGE: - case R_GROUP: - case R_POOL: - case R_MSGS: - case R_FILESET: - break; + /* Resources not containing a resource */ + case R_CATALOG: + case R_STORAGE: + case R_GROUP: + case R_POOL: + case R_MSGS: + case R_FILESET: + break; - /* Resources containing another resource */ - case R_DIRECTOR: - if ((res = (URES *)GetResWithName(R_DIRECTOR, res_all.res_dir.hdr.name)) == NULL) { + /* Resources containing another resource */ + case R_DIRECTOR: + if ((res = (URES *)GetResWithName(R_DIRECTOR, res_all.res_dir.hdr.name)) == NULL) { Emsg1(M_ERROR_TERM, 0, "Cannot find Director resource %s\n", res_all.res_dir.hdr.name); - } - res->res_dir.messages = res_all.res_dir.messages; - break; - case R_JOB: - if ((res = (URES *)GetResWithName(R_JOB, res_all.res_dir.hdr.name)) == NULL) { + } + res->res_dir.messages = res_all.res_dir.messages; + break; + case R_JOB: + if ((res = (URES *)GetResWithName(R_JOB, res_all.res_dir.hdr.name)) == NULL) { Emsg1(M_ERROR_TERM, 0, "Cannot find Job resource %s\n", res_all.res_dir.hdr.name); - } - res->res_job.messages = res_all.res_job.messages; - res->res_job.schedule = res_all.res_job.schedule; - res->res_job.client = res_all.res_job.client; - res->res_job.fileset = res_all.res_job.fileset; - res->res_job.storage = res_all.res_job.storage; - res->res_job.pool = res_all.res_job.pool; - if (res->res_job.JobType == 0) { + } + res->res_job.messages = res_all.res_job.messages; + res->res_job.schedule = res_all.res_job.schedule; + res->res_job.client = res_all.res_job.client; + res->res_job.fileset = res_all.res_job.fileset; + res->res_job.storage = res_all.res_job.storage; + res->res_job.pool = res_all.res_job.pool; + if (res->res_job.JobType == 0) { Emsg1(M_ERROR_TERM, 0, "Job Type not defined for Job resource %s\n", res_all.res_dir.hdr.name); - } - if (res->res_job.level != 0) { - int i; - for (i=0; joblevels[i].level_name; i++) { - if (joblevels[i].level == res->res_job.level && - joblevels[i].job_type == res->res_job.JobType) { - i = 0; - break; - } - } - if (i != 0) { + } + if (res->res_job.level != 0) { + int i; + for (i=0; joblevels[i].level_name; i++) { + if (joblevels[i].level == res->res_job.level && + joblevels[i].job_type == res->res_job.JobType) { + i = 0; + break; + } + } + if (i != 0) { Emsg1(M_ERROR_TERM, 0, "Inappropriate level specified in Job resource %s\n", - res_all.res_dir.hdr.name); - } - } - break; - case R_CLIENT: - if ((res = (URES *)GetResWithName(R_CLIENT, res_all.res_client.hdr.name)) == NULL) { + res_all.res_dir.hdr.name); + } + } + break; + case R_CLIENT: + if ((res = (URES *)GetResWithName(R_CLIENT, res_all.res_client.hdr.name)) == NULL) { Emsg1(M_ERROR_TERM, 0, "Cannot find Client resource %s\n", res_all.res_client.hdr.name); - } - res->res_client.catalog = res_all.res_client.catalog; - break; - case R_SCHEDULE: - /* Schedule is a bit different in that it contains a RUN record + } + res->res_client.catalog = res_all.res_client.catalog; + break; + case R_SCHEDULE: + /* Schedule is a bit different in that it contains a RUN record * chain which isn't a "named" resource. This chain was linked - * in by run_conf.c during pass 2, so here we jam the pointer - * into the Schedule resource. - */ - if ((res = (URES *)GetResWithName(R_SCHEDULE, res_all.res_client.hdr.name)) == NULL) { + * in by run_conf.c during pass 2, so here we jam the pointer + * into the Schedule resource. + */ + if ((res = (URES *)GetResWithName(R_SCHEDULE, res_all.res_client.hdr.name)) == NULL) { Emsg1(M_ERROR_TERM, 0, "Cannot find Schedule resource %s\n", res_all.res_client.hdr.name); - } - res->res_sch.run = res_all.res_sch.run; - break; - default: + } + res->res_sch.run = res_all.res_sch.run; + break; + default: Emsg1(M_ERROR, 0, "Unknown resource type %d in save_resource.\n", type); - error = 1; - break; + error = 1; + break; } /* Note, the resource name was already saved during pass 1, * so here, we can just release it. */ if (res_all.res_dir.hdr.name) { - free(res_all.res_dir.hdr.name); - res_all.res_dir.hdr.name = NULL; + free(res_all.res_dir.hdr.name); + res_all.res_dir.hdr.name = NULL; } if (res_all.res_dir.hdr.desc) { - free(res_all.res_dir.hdr.desc); - res_all.res_dir.hdr.desc = NULL; + free(res_all.res_dir.hdr.desc); + res_all.res_dir.hdr.desc = NULL; } return; } @@ -899,60 +902,60 @@ void save_resource(int type, struct res_items *items, int pass) /* The following code is only executed for pass 1 */ switch (type) { case R_DIRECTOR: - size = sizeof(DIRRES); - break; + size = sizeof(DIRRES); + break; case R_CLIENT: - size =sizeof(CLIENT); - break; + size =sizeof(CLIENT); + break; case R_STORAGE: - size = sizeof(STORE); - break; + size = sizeof(STORE); + break; case R_CATALOG: - size = sizeof(CAT); - break; + size = sizeof(CAT); + break; case R_JOB: - size = sizeof(JOB); - break; + size = sizeof(JOB); + break; case R_FILESET: - size = sizeof(FILESET); - break; + size = sizeof(FILESET); + break; case R_SCHEDULE: - size = sizeof(SCHED); - break; + size = sizeof(SCHED); + break; case R_GROUP: - size = sizeof(GROUP); - break; + size = sizeof(GROUP); + break; case R_POOL: - size = sizeof(POOL); - break; + size = sizeof(POOL); + break; case R_MSGS: - size = sizeof(MSGS); - break; + size = sizeof(MSGS); + break; case R_COUNTER: - size = sizeof(COUNTER); - break; + size = sizeof(COUNTER); + break; default: printf("Unknown resource type %d in save_resrouce.\n", type); - error = 1; - size = 1; - break; + error = 1; + size = 1; + break; } /* Common */ if (!error) { res = (URES *)malloc(size); memcpy(res, &res_all, size); if (!resources[rindex].res_head) { - resources[rindex].res_head = (RES *)res; /* store first entry */ + resources[rindex].res_head = (RES *)res; /* store first entry */ Dmsg3(200, "Inserting first %s res: %s index=%d\n", res_to_str(type), - res->res_dir.hdr.name, rindex); + res->res_dir.hdr.name, rindex); } else { - RES *next; - /* Add new res to end of chain */ - for (next=resources[rindex].res_head; next->next; next=next->next) - { } - next->next = (RES *)res; + RES *next; + /* Add new res to end of chain */ + for (next=resources[rindex].res_head; next->next; next=next->next) + { } + next->next = (RES *)res; Dmsg3(200, "Inserting %s res: %s index=%d\n", res_to_str(type), - res->res_dir.hdr.name, rindex); + res->res_dir.hdr.name, rindex); } } } @@ -969,9 +972,9 @@ static void store_jobtype(LEX *lc, struct res_items *item, int index, int pass) /* Store the type both pass 1 and pass 2 */ for (i=0; jobtypes[i].type_name; i++) { if (strcasecmp(lc->str, jobtypes[i].type_name) == 0) { - ((JOB *)(item->value))->JobType = jobtypes[i].job_type; - i = 0; - break; + ((JOB *)(item->value))->JobType = jobtypes[i].job_type; + i = 0; + break; } } if (i != 0) { @@ -993,9 +996,9 @@ static void store_level(LEX *lc, struct res_items *item, int index, int pass) /* Store the level pass 2 so that type is defined */ for (i=0; joblevels[i].level_name; i++) { if (strcasecmp(lc->str, joblevels[i].level_name) == 0) { - ((JOB *)(item->value))->level = joblevels[i].level; - i = 0; - break; + ((JOB *)(item->value))->level = joblevels[i].level; + i = 0; + break; } } if (i != 0) { @@ -1012,9 +1015,9 @@ static void store_replace(LEX *lc, struct res_items *item, int index, int pass) /* Scan Replacement options */ for (i=0; ReplaceOptions[i].name; i++) { if (strcasecmp(lc->str, ReplaceOptions[i].name) == 0) { - *(int *)(item->value) = ReplaceOptions[i].token; - i = 0; - break; + *(int *)(item->value) = ReplaceOptions[i].token; + i = 0; + break; } } if (i != 0) { @@ -1052,59 +1055,59 @@ static void store_backup(LEX *lc, struct res_items *item, int index, int pass) Dmsg1(190, "Got keyword: %s\n", lc->str); found = FALSE; for (i=0; BakVerFields[i].name; i++) { - if (strcasecmp(lc->str, BakVerFields[i].name) == 0) { - found = TRUE; - if (lex_get_token(lc, T_ALL) != T_EQUALS) { + if (strcasecmp(lc->str, BakVerFields[i].name) == 0) { + found = TRUE; + if (lex_get_token(lc, T_ALL) != T_EQUALS) { scan_err1(lc, "Expected an equals, got: %s", lc->str); - } - token = lex_get_token(lc, T_NAME); + } + token = lex_get_token(lc, T_NAME); Dmsg1(190, "Got value: %s\n", lc->str); - switch (BakVerFields[i].token) { + switch (BakVerFields[i].token) { case 'C': - /* Find Client Resource */ - if (pass == 2) { - res = GetResWithName(R_CLIENT, lc->str); - if (res == NULL) { + /* Find Client Resource */ + if (pass == 2) { + res = GetResWithName(R_CLIENT, lc->str); + if (res == NULL) { scan_err1(lc, "Could not find specified Client Resource: %s", - lc->str); - } - res_all.res_job.client = (CLIENT *)res; - } - break; + lc->str); + } + res_all.res_job.client = (CLIENT *)res; + } + break; case 'F': - /* Find FileSet Resource */ - if (pass == 2) { - res = GetResWithName(R_FILESET, lc->str); - if (res == NULL) { + /* Find FileSet Resource */ + if (pass == 2) { + res = GetResWithName(R_FILESET, lc->str); + if (res == NULL) { scan_err1(lc, "Could not find specified FileSet Resource: %s\n", - lc->str); - } - res_all.res_job.fileset = (FILESET *)res; - } - break; + lc->str); + } + res_all.res_job.fileset = (FILESET *)res; + } + break; case 'L': - /* Get level */ - for (i=0; joblevels[i].level_name; i++) { - if (joblevels[i].job_type == item->code && - strcasecmp(lc->str, joblevels[i].level_name) == 0) { - ((JOB *)(item->value))->level = joblevels[i].level; - i = 0; - break; - } - } - if (i != 0) { + /* Get level */ + for (i=0; joblevels[i].level_name; i++) { + if (joblevels[i].job_type == item->code && + strcasecmp(lc->str, joblevels[i].level_name) == 0) { + ((JOB *)(item->value))->level = joblevels[i].level; + i = 0; + break; + } + } + if (i != 0) { scan_err1(lc, "Expected a Job Level keyword, got: %s", lc->str); - } - break; - } /* end switch */ - break; - } /* end if strcmp() */ + } + break; + } /* end switch */ + break; + } /* end if strcmp() */ } /* end for */ if (!found) { scan_err1(lc, "%s not a valid Backup/verify keyword", lc->str); } } /* end while */ - lc->options = options; /* reset original options */ + lc->options = options; /* reset original options */ set_bit(index, res_all.hdr.item_present); } @@ -1134,91 +1137,91 @@ static void store_restore(LEX *lc, struct res_items *item, int index, int pass) found = FALSE; for (i=0; RestoreFields[i].name; i++) { Dmsg1(190, "Restore kw=%s\n", lc->str); - if (strcasecmp(lc->str, RestoreFields[i].name) == 0) { - found = TRUE; - if (lex_get_token(lc, T_ALL) != T_EQUALS) { + if (strcasecmp(lc->str, RestoreFields[i].name) == 0) { + found = TRUE; + if (lex_get_token(lc, T_ALL) != T_EQUALS) { scan_err1(lc, "Expected an equals, got: %s", lc->str); - } - token = lex_get_token(lc, T_ALL); + } + token = lex_get_token(lc, T_ALL); Dmsg1(190, "Restore value=%s\n", lc->str); - switch (RestoreFields[i].token) { + switch (RestoreFields[i].token) { case 'B': - /* Bootstrap */ - if (token != T_IDENTIFIER && token != T_UNQUOTED_STRING && token != T_QUOTED_STRING) { + /* Bootstrap */ + if (token != T_IDENTIFIER && token != T_UNQUOTED_STRING && token != T_QUOTED_STRING) { scan_err1(lc, "Expected a Restore bootstrap file, got: %s", lc->str); - } - if (pass == 1) { - res_all.res_job.RestoreBootstrap = bstrdup(lc->str); - } - break; + } + if (pass == 1) { + res_all.res_job.RestoreBootstrap = bstrdup(lc->str); + } + break; case 'C': - /* Find Client Resource */ - if (pass == 2) { - res = GetResWithName(R_CLIENT, lc->str); - if (res == NULL) { + /* Find Client Resource */ + if (pass == 2) { + res = GetResWithName(R_CLIENT, lc->str); + if (res == NULL) { scan_err1(lc, "Could not find specified Client Resource: %s", - lc->str); - } - res_all.res_job.client = (CLIENT *)res; - } - break; + lc->str); + } + res_all.res_job.client = (CLIENT *)res; + } + break; case 'F': - /* Find FileSet Resource */ - if (pass == 2) { - res = GetResWithName(R_FILESET, lc->str); - if (res == NULL) { + /* Find FileSet Resource */ + if (pass == 2) { + res = GetResWithName(R_FILESET, lc->str); + if (res == NULL) { scan_err1(lc, "Could not find specified FileSet Resource: %s\n", - lc->str); - } - res_all.res_job.fileset = (FILESET *)res; - } - break; + lc->str); + } + res_all.res_job.fileset = (FILESET *)res; + } + break; case 'J': - /* JobId */ - if (token != T_NUMBER) { + /* JobId */ + if (token != T_NUMBER) { scan_err1(lc, "expected an integer number, got: %s", lc->str); - } - errno = 0; - res_all.res_job.RestoreJobId = strtol(lc->str, NULL, 0); + } + errno = 0; + res_all.res_job.RestoreJobId = strtol(lc->str, NULL, 0); Dmsg1(190, "RestorJobId=%d\n", res_all.res_job.RestoreJobId); - if (errno != 0) { + if (errno != 0) { scan_err1(lc, "expected an integer number, got: %s", lc->str); - } - break; + } + break; case 'W': - /* Where */ - if (token != T_IDENTIFIER && token != T_UNQUOTED_STRING && token != T_QUOTED_STRING) { + /* Where */ + if (token != T_IDENTIFIER && token != T_UNQUOTED_STRING && token != T_QUOTED_STRING) { scan_err1(lc, "Expected a Restore root directory, got: %s", lc->str); - } - if (pass == 1) { - res_all.res_job.RestoreWhere = bstrdup(lc->str); - } - break; + } + if (pass == 1) { + res_all.res_job.RestoreWhere = bstrdup(lc->str); + } + break; case 'R': - /* Replacement options */ - if (token != T_IDENTIFIER && token != T_UNQUOTED_STRING && token != T_QUOTED_STRING) { + /* Replacement options */ + if (token != T_IDENTIFIER && token != T_UNQUOTED_STRING && token != T_QUOTED_STRING) { scan_err1(lc, "Expected a keyword name, got: %s", lc->str); - } - /* Fix to scan Replacement options */ - for (i=0; ReplaceOptions[i].name; i++) { - if (strcasecmp(lc->str, ReplaceOptions[i].name) == 0) { - ((JOB *)(item->value))->replace = ReplaceOptions[i].token; - i = 0; - break; - } - } - if (i != 0) { + } + /* Fix to scan Replacement options */ + for (i=0; ReplaceOptions[i].name; i++) { + if (strcasecmp(lc->str, ReplaceOptions[i].name) == 0) { + ((JOB *)(item->value))->replace = ReplaceOptions[i].token; + i = 0; + break; + } + } + if (i != 0) { scan_err1(lc, "Expected a Restore replacement option, got: %s", lc->str); - } - break; - } /* end switch */ - break; - } /* end if strcmp() */ + } + break; + } /* end switch */ + break; + } /* end if strcmp() */ } /* end for */ if (!found) { scan_err1(lc, "%s not a valid Restore keyword", lc->str); } } /* end while */ - lc->options = options; /* reset original options */ + lc->options = options; /* reset original options */ set_bit(index, res_all.hdr.item_present); } diff --git a/bacula/src/dird/protos.h b/bacula/src/dird/protos.h index ffd8354876..ef70fcbe18 100644 --- a/bacula/src/dird/protos.h +++ b/bacula/src/dird/protos.h @@ -35,7 +35,7 @@ void create_ua_context(JCR *jcr, UAContext *ua); void free_ua_context(UAContext *ua); /* autorecycle.c */ -extern int recycle_a_volume(JCR *jcr, MEDIA_DBR *mr); +extern int recycle_oldest_purged_volume(JCR *jcr, MEDIA_DBR *mr); extern int find_recycled_volume(JCR *jcr, MEDIA_DBR *mr); @@ -48,13 +48,13 @@ extern char *level_to_str(int level); /* fd_cmds.c */ extern int connect_to_file_daemon(JCR *jcr, int retry_interval, - int max_retry_time, int verbose); + int max_retry_time, int verbose); extern int send_include_list(JCR *jcr); extern int send_exclude_list(JCR *jcr); extern int get_attributes_and_put_in_catalog(JCR *jcr); extern int get_attributes_and_compare_to_catalog(JCR *jcr, JobId_t JobId); extern int put_file_into_catalog(JCR *jcr, long file_index, char *fname, - char *link, char *attr, int stream); + char *link, char *attr, int stream); /* job.c */ extern void set_jcr_defaults(JCR *jcr, JOB *job); @@ -67,7 +67,7 @@ extern void mount_request(JCR *jcr, BSOCK *bs, char *buf); /* msgchan.c */ extern int connect_to_storage_daemon(JCR *jcr, int retry_interval, - int max_retry_time, int verbose); + int max_retry_time, int verbose); extern int start_storage_daemon_job(JCR *jcr); extern int start_storage_daemon_message_thread(JCR *jcr); extern int32_t bget_msg(BSOCK *bs, int type); @@ -98,27 +98,27 @@ void prtit(void *ctx, char *msg); void bsendmsg(void *sock, char *fmt, ...); /* ua_select.c */ -STORE *select_storage_resource(UAContext *ua); -JOB *select_job_resource(UAContext *ua); -JOB *select_restore_job_resource(UAContext *ua); -CLIENT *select_client_resource(UAContext *ua); +STORE *select_storage_resource(UAContext *ua); +JOB *select_job_resource(UAContext *ua); +JOB *select_restore_job_resource(UAContext *ua); +CLIENT *select_client_resource(UAContext *ua); FILESET *select_fileset_resource(UAContext *ua); -int select_pool_and_media_dbr(UAContext *ua, POOL_DBR *pr, MEDIA_DBR *mr); -int select_pool_dbr(UAContext *ua, POOL_DBR *pr); -int select_client_dbr(UAContext *ua, CLIENT_DBR *cr); - -void start_prompt(UAContext *ua, char *msg); -void add_prompt(UAContext *ua, char *prompt); -int do_prompt(UAContext *ua, char *msg, char *prompt, int max_prompt); -CAT *get_catalog_resource(UAContext *ua); +int select_pool_and_media_dbr(UAContext *ua, POOL_DBR *pr, MEDIA_DBR *mr); +int select_pool_dbr(UAContext *ua, POOL_DBR *pr); +int select_client_dbr(UAContext *ua, CLIENT_DBR *cr); + +void start_prompt(UAContext *ua, char *msg); +void add_prompt(UAContext *ua, char *prompt); +int do_prompt(UAContext *ua, char *msg, char *prompt, int max_prompt); +CAT *get_catalog_resource(UAContext *ua); STORE *get_storage_resource(UAContext *ua, char *cmd); -int get_media_type(UAContext *ua, char *MediaType, int max_media); -int get_pool_dbr(UAContext *ua, POOL_DBR *pr); -int get_client_dbr(UAContext *ua, CLIENT_DBR *cr); +int get_media_type(UAContext *ua, char *MediaType, int max_media); +int get_pool_dbr(UAContext *ua, POOL_DBR *pr); +int get_client_dbr(UAContext *ua, CLIENT_DBR *cr); POOL *get_pool_resource(UAContext *ua); POOL *select_pool_resource(UAContext *ua); CLIENT *get_client_resource(UAContext *ua); -int get_job_dbr(UAContext *ua, JOB_DBR *jr); +int get_job_dbr(UAContext *ua, JOB_DBR *jr); int find_arg_keyword(UAContext *ua, char **list); int do_keyword_prompt(UAContext *ua, char *msg, char **list); diff --git a/bacula/src/dird/recycle.c b/bacula/src/dird/recycle.c index 0093eeaf68..066051eb74 100644 --- a/bacula/src/dird/recycle.c +++ b/bacula/src/dird/recycle.c @@ -71,7 +71,7 @@ int find_recycled_volume(JCR *jcr, MEDIA_DBR *mr) /* * Look for oldest Purged volume */ -int recycle_a_volume(JCR *jcr, MEDIA_DBR *mr) +int recycle_oldest_purged_volume(JCR *jcr, MEDIA_DBR *mr) { struct s_oldest_ctx oldest; POOLMEM *query = get_pool_memory(PM_EMSG); @@ -80,13 +80,13 @@ int recycle_a_volume(JCR *jcr, MEDIA_DBR *mr) "WHERE PoolId=%d AND Recycle=1 AND VolStatus=\"Purged\" " "AND MediaType=\"%s\""; - Dmsg0(100, "Enter recycle_a_volume\n"); + Dmsg0(100, "Enter recycle_oldest_purged_volume\n"); oldest.MediaId = 0; strcpy(oldest.LastWritten, "9999-99-99 99:99:99"); Mmsg(&query, select, mr->PoolId, mr->MediaType); if (!db_sql_query(jcr->db, query, oldest_handler, (void *)&oldest)) { Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db)); - Dmsg0(100, "Exit 0 recycle_a_volume query\n"); + Dmsg0(100, "Exit 0 recycle_oldest_purged_volume query\n"); free_pool_memory(query); return 0; } @@ -96,14 +96,17 @@ int recycle_a_volume(JCR *jcr, MEDIA_DBR *mr) mr->MediaId = oldest.MediaId; if (db_get_media_record(jcr, jcr->db, mr)) { strcpy(mr->VolStatus, "Recycle"); + mr->VolJobs = mr->VolFiles = mr->VolBlocks = mr->VolErrors = 0; + mr->VolBytes = 0; + mr->FirstWritten = mr->LastWritten = 0; if (db_update_media_record(jcr, jcr->db, mr)) { Jmsg(jcr, M_INFO, 0, "Recycled volume %s\n", mr->VolumeName); - Dmsg1(100, "Exit 1 recycle_a_volume Vol=%s\n", mr->VolumeName); + Dmsg1(100, "Exit 1 recycle_oldest_purged_volume Vol=%s\n", mr->VolumeName); return 1; } } Jmsg(jcr, M_ERROR, 0, "%s", db_strerror(jcr->db)); } - Dmsg0(100, "Exit 0 recycle_a_volume end\n"); + Dmsg0(100, "Exit 0 recycle_oldest_purged_volume end\n"); return 0; } diff --git a/bacula/src/dird/ua_purge.c b/bacula/src/dird/ua_purge.c index 91ed47c122..b41a095b02 100644 --- a/bacula/src/dird/ua_purge.c +++ b/bacula/src/dird/ua_purge.c @@ -500,8 +500,8 @@ int purge_jobs_from_volume(UAContext *ua, MEDIA_DBR *mr) if (del.JobId) { free(del.JobId); } - bsendmsg(ua, _("%d Files for Volume %s purged from catalog.\n"), del.num_del, - mr->VolumeName); + bsendmsg(ua, _("%d File%s on Volume %s purged from catalog.\n"), del.num_del, + del.num_del==1?"":"s", mr->VolumeName); /* If purged, mark it so */ if (del.num_ids == del.num_del) {