From 94210b670dbff54b7588cca047dcd8033820f01d Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Thu, 29 Aug 2002 11:52:56 +0000 Subject: [PATCH] Autochanger fixes git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@127 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/kernstodo | 1 + bacula/src/cats/sql.c | 21 +- bacula/src/cats/sql_create.c | 7 +- bacula/src/cats/sql_list.c | 2 +- bacula/src/dird/dird.c | 6 + bacula/src/dird/dird_conf.c | 1007 +++++++++++++++++----------------- bacula/src/dird/dird_conf.h | 205 +++---- bacula/src/dird/ua_cmds.c | 39 +- bacula/src/stored/acquire.c | 18 - bacula/src/stored/block.c | 2 - bacula/src/stored/bls.c | 12 +- bacula/src/stored/dev.h | 13 +- bacula/src/stored/device.c | 67 +-- bacula/src/stored/dircmd.c | 27 +- bacula/src/stored/mount.c | 21 +- bacula/src/stored/protos.h | 166 +++--- 16 files changed, 812 insertions(+), 802 deletions(-) diff --git a/bacula/kernstodo b/bacula/kernstodo index fb6c5c066c..3e76f18b85 100644 --- a/bacula/kernstodo +++ b/bacula/kernstodo @@ -28,6 +28,7 @@ From Chuck: --sd.conf password does not match dir.conf storage password ======= +- Create all pools when Director starts - Implement autochanger for restore. ARRRGGG! I forgot! - Make BSR accept count (total files to be restored). - Make BSR return next_block when it knows record is not diff --git a/bacula/src/cats/sql.c b/bacula/src/cats/sql.c index 84a848d058..2948c77d73 100644 --- a/bacula/src/cats/sql.c +++ b/bacula/src/cats/sql.c @@ -75,6 +75,7 @@ int check_tables_version(B_DB *mdb) if (version != BDB_VERSION) { Mmsg(&mdb->errmsg, "Database version mismatch. Wanted %d, got %d\n", BDB_VERSION, version); + Jmsg(mdb->jcr, M_FATAL, 0, mdb->errmsg); return 0; } return 1; @@ -86,7 +87,7 @@ QueryDB(char *file, int line, B_DB *mdb, char *cmd) { if (sql_query(mdb, cmd)) { m_msg(file, line, &mdb->errmsg, _("query %s failed:\n%s\n"), cmd, sql_strerror(mdb)); - e_msg(file, line, M_FATAL, 0, mdb->errmsg); + j_msg(file, line, mdb->jcr, M_FATAL, 0, mdb->errmsg); return 0; } mdb->result = sql_store_result(mdb); @@ -104,7 +105,7 @@ InsertDB(char *file, int line, B_DB *mdb, char *cmd) { if (sql_query(mdb, cmd)) { m_msg(file, line, &mdb->errmsg, _("insert %s failed:\n%s\n"), cmd, sql_strerror(mdb)); - e_msg(file, line, M_FATAL, 0, mdb->errmsg); + j_msg(file, line, mdb->jcr, M_FATAL, 0, mdb->errmsg); return 0; } if (mdb->have_insert_id) { @@ -116,7 +117,7 @@ InsertDB(char *file, int line, B_DB *mdb, char *cmd) char ed1[30]; m_msg(file, line, &mdb->errmsg, _("Insertion problem: affect_rows=%s\n"), edit_uint64(mdb->num_rows, ed1)); - e_msg(file, line, M_FATAL, 0, mdb->errmsg); /* ***FIXME*** remove me */ + j_msg(file, line, mdb->jcr, M_FATAL, 0, mdb->errmsg); /* ***FIXME*** remove me */ return 0; } mdb->changes++; @@ -133,8 +134,8 @@ UpdateDB(char *file, int line, B_DB *mdb, char *cmd) if (sql_query(mdb, cmd)) { m_msg(file, line, &mdb->errmsg, _("update %s failed:\n%s\n"), cmd, sql_strerror(mdb)); - e_msg(file, line, M_ERROR, 0, mdb->errmsg); - e_msg(file, line, M_ERROR, 0, "%s\n", cmd); + j_msg(file, line, mdb->jcr, M_ERROR, 0, mdb->errmsg); + j_msg(file, line, mdb->jcr, M_ERROR, 0, "%s\n", cmd); return 0; } mdb->num_rows = sql_affected_rows(mdb); @@ -142,8 +143,8 @@ UpdateDB(char *file, int line, B_DB *mdb, char *cmd) char ed1[30]; m_msg(file, line, &mdb->errmsg, _("Update problem: affect_rows=%s\n"), edit_uint64(mdb->num_rows, ed1)); - e_msg(file, line, M_ERROR, 0, mdb->errmsg); - e_msg(file, line, M_ERROR, 0, "%s\n", cmd); + j_msg(file, line, mdb->jcr, M_ERROR, 0, mdb->errmsg); + j_msg(file, line, mdb->jcr, M_ERROR, 0, "%s\n", cmd); return 0; } mdb->changes++; @@ -161,7 +162,7 @@ DeleteDB(char *file, int line, B_DB *mdb, char *cmd) if (sql_query(mdb, cmd)) { m_msg(file, line, &mdb->errmsg, _("delete %s failed:\n%s\n"), cmd, sql_strerror(mdb)); - e_msg(file, line, M_ERROR, 0, mdb->errmsg); + j_msg(file, line, mdb->jcr, M_ERROR, 0, mdb->errmsg); return -1; } mdb->changes++; @@ -205,7 +206,7 @@ void _db_lock(char *file, int line, B_DB *mdb) { int errstat; if ((errstat=rwl_writelock(&mdb->lock)) != 0) { - e_msg(file, line, M_ABORT, 0, "rwl_writelock failure. ERR=%s\n", + j_msg(file, line, mdb->jcr, M_ABORT, 0, "rwl_writelock failure. ERR=%s\n", strerror(errstat)); } } @@ -214,7 +215,7 @@ void _db_unlock(char *file, int line, B_DB *mdb) { int errstat; if ((errstat=rwl_writeunlock(&mdb->lock)) != 0) { - e_msg(file, line, M_ABORT, 0, "rwl_writeunlock failure. ERR=%s\n", + j_msg(file, line, mdb->jcr, M_ABORT, 0, "rwl_writeunlock failure. ERR=%s\n", strerror(errstat)); } } diff --git a/bacula/src/cats/sql_create.c b/bacula/src/cats/sql_create.c index 033d5451f0..6db2e8e962 100644 --- a/bacula/src/cats/sql_create.c +++ b/bacula/src/cats/sql_create.c @@ -238,15 +238,16 @@ db_create_media_record(B_DB *mdb, MEDIA_DBR *mr) /* Must create it */ Mmsg(&mdb->cmd, -"INSERT INTO Media (VolumeName, MediaType, PoolId, VolMaxBytes, VolCapacityBytes, \ -Recycle, VolRetention, VolStatus) VALUES ('%s', '%s', %d, %s, %s, %d, %s, '%s')", +"INSERT INTO Media (VolumeName,MediaType,PoolId,VolMaxBytes,VolCapacityBytes, \ +Recycle,VolRetention,VolStatus,Slot) VALUES ('%s', '%s', %d, %s, %s, %d, %s, '%s', %d)", mr->VolumeName, mr->MediaType, mr->PoolId, edit_uint64(mr->VolMaxBytes,ed1), edit_uint64(mr->VolCapacityBytes, ed2), mr->Recycle, edit_uint64(mr->VolRetention, ed3), - mr->VolStatus); + mr->VolStatus, + mr->Slot); Dmsg1(500, "Create Volume: %s\n", mdb->cmd); if (!INSERT_DB(mdb, mdb->cmd)) { diff --git a/bacula/src/cats/sql_list.c b/bacula/src/cats/sql_list.c index 1336f08d09..72507d3e81 100644 --- a/bacula/src/cats/sql_list.c +++ b/bacula/src/cats/sql_list.c @@ -97,7 +97,7 @@ db_list_media_records(B_DB *mdb, MEDIA_DBR *mdbr, DB_LIST_HANDLER *sendit, void { Mmsg(&mdb->cmd, "SELECT MediaId,VolumeName,MediaType,VolStatus,\ -VolBytes,LastWritten,VolRetention,Recycle \ +VolBytes,LastWritten,VolRetention,Recycle,Slot \ FROM Media WHERE Media.PoolId=%d ORDER BY MediaId", mdbr->PoolId); db_lock(mdb); diff --git a/bacula/src/dird/dird.c b/bacula/src/dird/dird.c index 09a6080fad..5099207b4c 100644 --- a/bacula/src/dird/dird.c +++ b/bacula/src/dird/dird.c @@ -356,6 +356,12 @@ Without that I don't know who I am :-(\n"), configfile); if (!db_open_database(db)) { Jmsg(NULL, M_FATAL, 0, "%s", db_strerror(db)); } + /* If a pool is defined for this job, create the pool DB + * record if it is not already created. + */ + if (job->pool) { + create_pool(db, job->pool); + } db_close_database(db); } else { if (job->client) { diff --git a/bacula/src/dird/dird_conf.c b/bacula/src/dird/dird_conf.c index 79b910fd70..f52970fbd5 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 * @@ -81,7 +81,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}, @@ -102,7 +102,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[] = { @@ -120,7 +120,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}, @@ -131,13 +131,14 @@ static struct res_items store_items[] = { {"password", store_password, ITEM(res_store.password), 0, ITEM_REQUIRED, 0}, {"device", store_strname, ITEM(res_store.dev_name), 0, ITEM_REQUIRED, 0}, {"mediatype", store_strname, ITEM(res_store.media_type), 0, ITEM_REQUIRED, 0}, + {"autochanger", store_yesno, ITEM(res_store.autochanger), 1, ITEM_DEFAULT, 0}, {NULL, NULL, NULL, 0, 0, 0} }; /* * 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}, @@ -154,7 +155,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}, @@ -185,20 +186,20 @@ 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}, {"description", store_str, ITEM(res_fs.hdr.desc), 0, 0, 0}, {"include", store_inc, NULL, 0, 0, 0}, {"exclude", store_inc, NULL, 1, 0, 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}, @@ -209,7 +210,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}, @@ -219,7 +220,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 +240,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}, @@ -259,7 +260,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}, @@ -273,13 +274,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}, @@ -291,19 +292,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} }; @@ -312,7 +313,7 @@ static struct s_kw BakVerFields[] = { {"client", 'C'}, {"fileset", 'F'}, {"level", 'L'}, - {NULL, 0} + {NULL, 0} }; /* Keywords (RHS) permitted in Restore records */ @@ -323,7 +324,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= */ @@ -331,20 +332,20 @@ static struct s_kw ReplaceOptions[] = { {"always", 'A'}, /* always */ {"ifnewer", 'W'}, {"never", 'N'}, - {NULL, 0} + {NULL, 0} }; /* Define FileSet KeyWord values */ -#define FS_KW_NONE 0 +#define FS_KW_NONE 0 #define FS_KW_COMPRESSION 1 #define FS_KW_SIGNATURE 2 #define FS_KW_ENCRYPTION 3 -#define FS_KW_VERIFY 4 -#define FS_KW_ONEFS 5 -#define FS_KW_RECURSE 6 +#define FS_KW_VERIFY 4 +#define FS_KW_ONEFS 5 +#define FS_KW_RECURSE 6 /* FileSet keywords */ static struct s_kw FS_option_kw[] = { @@ -354,7 +355,7 @@ static struct s_kw FS_option_kw[] = { {"verify", FS_KW_VERIFY}, {"onefs", FS_KW_ONEFS}, {"recurse", FS_KW_RECURSE}, - {NULL, 0} + {NULL, 0} }; /* Options for FileSet keywords */ @@ -384,7 +385,7 @@ static struct s_fs_opt FS_options[] = { {"no", FS_KW_ONEFS, "f"}, {"yes", FS_KW_RECURSE, "0"}, {"no", FS_KW_RECURSE, "h"}, - {NULL, 0, 0} + {NULL, 0, 0} }; char *level_to_str(int level) @@ -396,8 +397,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; @@ -416,191 +417,191 @@ 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.address), - res->res_cat.DBport, res->res_cat.db_name, NPRT(res->res_cat.db_user)); - break; + res->res_cat.hdr.name, NPRT(res->res_cat.address), + res->res_cat.DBport, 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.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 (i=0; ires_fs.num_includes; i++) + for (i=0; ires_fs.num_includes; i++) sendit(sock, " Inc: %s\n", res->res_fs.include_array[i]); - for (i=0; ires_fs.num_excludes; i++) + for (i=0; ires_fs.num_excludes; i++) sendit(sock, " Exc: %s\n", res->res_fs.exclude_array[i]); - 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+1); - 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); 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)); + 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\n", type); - break; + break; } if (recurse && res->res_dir.hdr.next) { dump_resource(type, res->res_dir.hdr.next, sendit, sock); @@ -637,98 +638,98 @@ 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); - 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); + 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.address) - free(res->res_cat.address); - 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.address) + free(res->res_cat.address); + 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(res->res_fs.include_array[num]); - free(res->res_fs.include_array); - } - if ((num=res->res_fs.num_excludes)) { - while (--num >= 0) - free(res->res_fs.exclude_array[num]); - free(res->res_fs.exclude_array); - } - break; + if ((num=res->res_fs.num_includes)) { + while (--num >= 0) + free(res->res_fs.include_array[num]); + free(res->res_fs.include_array); + } + if ((num=res->res_fs.num_excludes)) { + while (--num >= 0) + free(res->res_fs.exclude_array[num]); + free(res->res_fs.exclude_array); + } + 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.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.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\n", type); } @@ -760,10 +761,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) { @@ -778,82 +779,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_FILESET: - case R_GROUP: - case R_POOL: - case R_MSGS: - break; - - /* Resources containing another resource */ - case R_DIRECTOR: - if ((res = (URES *)GetResWithName(R_DIRECTOR, res_all.res_dir.hdr.name)) == NULL) { + /* Resources not containing a resource */ + case R_CATALOG: + case R_STORAGE: + case R_FILESET: + case R_GROUP: + case R_POOL: + case R_MSGS: + break; + + /* 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\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; } @@ -861,55 +862,55 @@ 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; default: printf("Unknown resource type %d\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 */ } 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; Dmsg2(90, "Inserting %s res: %s\n", res_to_str(type), - res->res_dir.hdr.name); + res->res_dir.hdr.name); } } } @@ -926,9 +927,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) { @@ -950,9 +951,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) { @@ -992,59 +993,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); } @@ -1074,92 +1075,92 @@ 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))->RestoreOptions = 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))->RestoreOptions = 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); } @@ -1175,33 +1176,33 @@ static char *scan_fs_options(LEX *lc, int keyword) static char opts[100]; char option[3]; - option[0] = 0; /* default option = none */ - opts[0] = option[2] = 0; /* terminate options */ + option[0] = 0; /* default option = none */ + opts[0] = option[2] = 0; /* terminate options */ for (;;) { - token = lex_get_token(lc, T_NAME); /* expect at least one option */ + token = lex_get_token(lc, T_NAME); /* expect at least one option */ if (keyword == FS_KW_VERIFY) { /* special case */ - /* ***FIXME**** ensure these are in permitted set */ + /* ***FIXME**** ensure these are in permitted set */ strcpy(option, "V"); /* indicate Verify */ - strcat(option, lc->str); + strcat(option, lc->str); strcat(option, ":"); /* terminate it */ } else { - for (i=0; FS_options[i].name; i++) { - if (strcasecmp(lc->str, FS_options[i].name) == 0 && FS_options[i].keyword == keyword) { - option[0] = FS_options[i].option[0]; - option[1] = FS_options[i].option[1]; - i = 0; - break; - } - } - if (i != 0) { + for (i=0; FS_options[i].name; i++) { + if (strcasecmp(lc->str, FS_options[i].name) == 0 && FS_options[i].keyword == keyword) { + option[0] = FS_options[i].option[0]; + option[1] = FS_options[i].option[1]; + i = 0; + break; + } + } + if (i != 0) { scan_err1(lc, "Expected a FileSet option keyword, got: %s", lc->str); - } + } } strcat(opts, option); /* check if more options are specified */ if (lc->ch != ',') { - break; /* no, get out */ + break; /* no, get out */ } token = lex_get_token(lc, T_ALL); /* yes, eat comma */ } @@ -1227,10 +1228,10 @@ static void store_inc(LEX *lc, struct res_items *item, int index, int pass) while ((token=lex_get_token(lc, T_ALL)) != T_BOB) { keyword = FS_KW_NONE; for (i=0; FS_option_kw[i].name; i++) { - if (strcasecmp(lc->str, FS_option_kw[i].name) == 0) { - keyword = FS_option_kw[i].token; - break; - } + if (strcasecmp(lc->str, FS_option_kw[i].name) == 0) { + keyword = FS_option_kw[i].token; + break; + } } if (keyword == FS_KW_NONE) { scan_err1(lc, "Expected a FileSet keyword, got: %s", lc->str); @@ -1241,7 +1242,7 @@ static void store_inc(LEX *lc, struct res_items *item, int index, int pass) } strcat(inc_opts, scan_fs_options(lc, keyword)); if (token == T_BOB) { - break; + break; } } strcat(inc_opts, " "); /* add field separator */ @@ -1250,8 +1251,8 @@ static void store_inc(LEX *lc, struct res_items *item, int index, int pass) if (pass == 1) { if (!res_all.res_fs.have_MD5) { - MD5Init(&res_all.res_fs.md5c); - res_all.res_fs.have_MD5 = TRUE; + MD5Init(&res_all.res_fs.md5c); + res_all.res_fs.have_MD5 = TRUE; } /* Pickup include/exclude names. Note, they are stored as * XYZ fname @@ -1260,53 +1261,53 @@ static void store_inc(LEX *lc, struct res_items *item, int index, int pass) * and fname is the file/directory name given */ while ((token = lex_get_token(lc, T_ALL)) != T_EOB) { - switch (token) { - case T_COMMA: - case T_EOL: - continue; - - case T_IDENTIFIER: - case T_UNQUOTED_STRING: - case T_QUOTED_STRING: - fname = (char *) malloc(lc->str_len + inc_opts_len + 1); - strcpy(fname, inc_opts); - strcat(fname, lc->str); - if (res_all.res_fs.have_MD5) { - MD5Update(&res_all.res_fs.md5c, (unsigned char *) fname, inc_opts_len + lc->str_len); - } - if (item->code == 0) { /* include */ - if (res_all.res_fs.num_includes == res_all.res_fs.include_size) { - res_all.res_fs.include_size += 10; - if (res_all.res_fs.include_array == NULL) { - res_all.res_fs.include_array = (char **) malloc(sizeof(char *) * res_all.res_fs.include_size); - } else { - res_all.res_fs.include_array = (char **) realloc(res_all.res_fs.include_array, - sizeof(char *) * res_all.res_fs.include_size); - } - } - res_all.res_fs.include_array[res_all.res_fs.num_includes++] = - fname; - } else { /* exclude */ - if (res_all.res_fs.num_excludes == res_all.res_fs.exclude_size) { - res_all.res_fs.exclude_size += 10; - if (res_all.res_fs.exclude_array == NULL) { - res_all.res_fs.exclude_array = (char **) malloc(sizeof(char *) * res_all.res_fs.exclude_size); - } else { - res_all.res_fs.exclude_array = (char **) realloc(res_all.res_fs.exclude_array, - sizeof(char *) * res_all.res_fs.exclude_size); - } - } - res_all.res_fs.exclude_array[res_all.res_fs.num_excludes++] = - fname; - } - break; - default: + switch (token) { + case T_COMMA: + case T_EOL: + continue; + + case T_IDENTIFIER: + case T_UNQUOTED_STRING: + case T_QUOTED_STRING: + fname = (char *) malloc(lc->str_len + inc_opts_len + 1); + strcpy(fname, inc_opts); + strcat(fname, lc->str); + if (res_all.res_fs.have_MD5) { + MD5Update(&res_all.res_fs.md5c, (unsigned char *) fname, inc_opts_len + lc->str_len); + } + if (item->code == 0) { /* include */ + if (res_all.res_fs.num_includes == res_all.res_fs.include_size) { + res_all.res_fs.include_size += 10; + if (res_all.res_fs.include_array == NULL) { + res_all.res_fs.include_array = (char **) malloc(sizeof(char *) * res_all.res_fs.include_size); + } else { + res_all.res_fs.include_array = (char **) realloc(res_all.res_fs.include_array, + sizeof(char *) * res_all.res_fs.include_size); + } + } + res_all.res_fs.include_array[res_all.res_fs.num_includes++] = + fname; + } else { /* exclude */ + if (res_all.res_fs.num_excludes == res_all.res_fs.exclude_size) { + res_all.res_fs.exclude_size += 10; + if (res_all.res_fs.exclude_array == NULL) { + res_all.res_fs.exclude_array = (char **) malloc(sizeof(char *) * res_all.res_fs.exclude_size); + } else { + res_all.res_fs.exclude_array = (char **) realloc(res_all.res_fs.exclude_array, + sizeof(char *) * res_all.res_fs.exclude_size); + } + } + res_all.res_fs.exclude_array[res_all.res_fs.num_excludes++] = + fname; + } + break; + default: scan_err1(lc, "Expected a filename, got: %s", lc->str); - } + } } } else { /* pass 2 */ while (lex_get_token(lc, T_ALL) != T_EOB) - {} + {} } scan_to_eol(lc); lc->options = options; diff --git a/bacula/src/dird/dird_conf.h b/bacula/src/dird/dird_conf.h index 2689d89b0e..3f5f98e769 100644 --- a/bacula/src/dird/dird_conf.h +++ b/bacula/src/dird/dird_conf.h @@ -30,43 +30,43 @@ /* * Resource codes -- they must be sequential for indexing */ -#define R_FIRST 1001 - -#define R_DIRECTOR 1001 -#define R_CLIENT 1002 -#define R_JOB 1003 -#define R_STORAGE 1004 -#define R_CATALOG 1005 -#define R_SCHEDULE 1006 -#define R_FILESET 1007 -#define R_GROUP 1008 -#define R_POOL 1009 -#define R_MSGS 1010 -#define R_COUNTER 1011 - -#define R_LAST R_COUNTER +#define R_FIRST 1001 + +#define R_DIRECTOR 1001 +#define R_CLIENT 1002 +#define R_JOB 1003 +#define R_STORAGE 1004 +#define R_CATALOG 1005 +#define R_SCHEDULE 1006 +#define R_FILESET 1007 +#define R_GROUP 1008 +#define R_POOL 1009 +#define R_MSGS 1010 +#define R_COUNTER 1011 + +#define R_LAST R_COUNTER /* * Some resource attributes */ -#define R_NAME 1020 -#define R_ADDRESS 1021 -#define R_PASSWORD 1022 -#define R_TYPE 1023 -#define R_BACKUP 1024 +#define R_NAME 1020 +#define R_ADDRESS 1021 +#define R_PASSWORD 1022 +#define R_TYPE 1023 +#define R_BACKUP 1024 /* Used for certain KeyWord tables */ -struct s_kw { +struct s_kw { char *name; - int token; + int token; }; /* Job Level keyword structure */ struct s_jl { - char *level_name; /* level keyword */ - int level; /* level */ - int job_type; /* JobType permitting this level */ + char *level_name; /* level keyword */ + int level; /* level */ + int job_type; /* JobType permitting this level */ }; /* Job Type keyword structure */ @@ -78,21 +78,21 @@ struct s_jt { /* Definition of the contents of each Resource */ /* - * Director Resource + * Director Resource * */ struct s_res_dir { - RES hdr; - int DIRport; /* where we listen -- UA port server port */ - char *password; /* Password for UA access */ - char *query_file; /* SQL query file */ - char *working_directory; /* WorkingDirectory */ - char *pid_directory; /* PidDirectory */ - char *subsys_directory; /* SubsysDirectory */ + RES hdr; + int DIRport; /* where we listen -- UA port server port */ + char *password; /* Password for UA access */ + char *query_file; /* SQL query file */ + char *working_directory; /* WorkingDirectory */ + char *pid_directory; /* PidDirectory */ + char *subsys_directory; /* SubsysDirectory */ struct s_res_msgs *messages; /* Daemon message handler */ - int MaxConcurrentJobs; - btime_t FDConnectTimeout; /* timeout for connect in seconds */ - btime_t SDConnectTimeout; /* timeout in seconds */ + int MaxConcurrentJobs; + btime_t FDConnectTimeout; /* timeout for connect in seconds */ + btime_t SDConnectTimeout; /* timeout in seconds */ }; typedef struct s_res_dir DIRRES; @@ -101,12 +101,12 @@ typedef struct s_res_dir DIRRES; * */ struct s_res_client { - RES hdr; + RES hdr; - int FDport; /* Where File daemon listens */ - int AutoPrune; /* Do automatic pruning? */ - btime_t FileRetention; /* file retention period in seconds */ - btime_t JobRetention; /* job retention period in seconds */ + int FDport; /* Where File daemon listens */ + int AutoPrune; /* Do automatic pruning? */ + btime_t FileRetention; /* file retention period in seconds */ + btime_t JobRetention; /* job retention period in seconds */ char *address; char *password; struct s_res_cat *catalog; /* Catalog resource */ @@ -118,14 +118,15 @@ typedef struct s_res_client CLIENT; * */ struct s_res_store { - RES hdr; + RES hdr; - int SDport; /* port where Directors connect */ - int SDDport; /* data port for File daemon */ + int SDport; /* port where Directors connect */ + int SDDport; /* data port for File daemon */ char *address; char *password; char *media_type; char *dev_name; + int autochanger; /* set if autochanger */ }; typedef struct s_res_store STORE; @@ -134,9 +135,9 @@ typedef struct s_res_store STORE; * */ struct s_res_cat { - RES hdr; + RES hdr; - int DBport; /* Port -- not yet implemented */ + int DBport; /* Port -- not yet implemented */ char *address; char *db_password; char *db_user; @@ -149,29 +150,29 @@ typedef struct s_res_cat CAT; * */ struct s_res_job { - RES hdr; - - int JobType; /* job type (backup, verify, restore */ - int level; /* default backup/verify level */ - int RestoreJobId; /* What -- JobId to restore */ - char *RestoreWhere; /* Where on disk to restore -- directory */ - char *RestoreBootstrap; /* Bootstrap file */ - char *RunBeforeJob; /* Run program before Job */ - char *RunAfterJob; /* Run program after Job */ - int RestoreOptions; /* How (overwrite, ..) */ - btime_t MaxRunTime; /* max run time in seconds */ - btime_t MaxStartDelay; /* max start delay in seconds */ - int PruneJobs; /* Force pruning of Jobs */ - int PruneFiles; /* Force pruning of Files */ - int PruneVolumes; /* Force pruning of Volumes */ - int SpoolAttributes; /* Set to spool attributes in SD */ + RES hdr; + + int JobType; /* job type (backup, verify, restore */ + int level; /* default backup/verify level */ + int RestoreJobId; /* What -- JobId to restore */ + char *RestoreWhere; /* Where on disk to restore -- directory */ + char *RestoreBootstrap; /* Bootstrap file */ + char *RunBeforeJob; /* Run program before Job */ + char *RunAfterJob; /* Run program after Job */ + int RestoreOptions; /* How (overwrite, ..) */ + btime_t MaxRunTime; /* max run time in seconds */ + btime_t MaxStartDelay; /* max start delay in seconds */ + int PruneJobs; /* Force pruning of Jobs */ + int PruneFiles; /* Force pruning of Files */ + int PruneVolumes; /* Force pruning of Volumes */ + int SpoolAttributes; /* Set to spool attributes in SD */ struct s_res_msgs *messages; /* How and where to send messages */ struct s_res_sch *schedule; /* When -- Automatic schedule */ struct s_res_client *client; /* Who to backup */ struct s_res_fs *fileset; /* What to backup -- Fileset */ struct s_res_store *storage; /* Where is device -- Storage daemon */ - struct s_res_pool *pool; /* Where is media -- Media Pool */ + struct s_res_pool *pool; /* Where is media -- Media Pool */ }; typedef struct s_res_job JOB; @@ -180,7 +181,7 @@ typedef struct s_res_job JOB; * */ struct s_res_fs { - RES hdr; + RES hdr; char **include_array; int num_includes; @@ -188,8 +189,8 @@ struct s_res_fs { char **exclude_array; int num_excludes; int exclude_size; - int have_MD5; /* set if MD5 initialized */ - struct MD5Context md5c; /* MD5 of include/exclude */ + int have_MD5; /* set if MD5 initialized */ + struct MD5Context md5c; /* MD5 of include/exclude */ }; typedef struct s_res_fs FILESET; @@ -199,7 +200,7 @@ typedef struct s_res_fs FILESET; * */ struct s_res_sch { - RES hdr; + RES hdr; struct s_run *run; }; @@ -210,7 +211,7 @@ typedef struct s_res_sch SCHED; * */ struct s_res_group { - RES hdr; + RES hdr; }; typedef struct s_res_group GROUP; @@ -218,12 +219,12 @@ typedef struct s_res_group GROUP; * Counter Resource */ struct s_res_counter { - RES hdr; + RES hdr; - int32_t MinValue; /* Minimum value */ - int32_t MaxValue; /* Maximum value */ - int Global; /* global/local */ - char *WrapCounter; /* Wrap counter name */ + int32_t MinValue; /* Minimum value */ + int32_t MaxValue; /* Maximum value */ + int Global; /* global/local */ + char *WrapCounter; /* Wrap counter name */ }; typedef struct s_res_counter COUNTER; @@ -232,19 +233,19 @@ typedef struct s_res_counter COUNTER; * */ struct s_res_pool { - RES hdr; + RES hdr; struct s_res_counter counter; /* Counter resources */ - char *pool_type; /* Pool type */ - char *label_format; /* Label format string */ - int use_catalog; /* maintain catalog for media */ - int catalog_files; /* maintain file entries in catalog */ - int use_volume_once; /* write on volume only once */ - int accept_any_volume; /* accept any volume */ - int max_volumes; /* max number of volumes */ - btime_t VolRetention; /* volume retention period in seconds */ - int AutoPrune; /* default for pool auto prune */ - int Recycle; /* default for media recycle yes/no */ + char *pool_type; /* Pool type */ + char *label_format; /* Label format string */ + int use_catalog; /* maintain catalog for media */ + int catalog_files; /* maintain file entries in catalog */ + int use_volume_once; /* write on volume only once */ + int accept_any_volume; /* accept any volume */ + int max_volumes; /* max number of volumes */ + btime_t VolRetention; /* volume retention period in seconds */ + int AutoPrune; /* default for pool auto prune */ + int Recycle; /* default for media recycle yes/no */ }; typedef struct s_res_pool POOL; @@ -253,16 +254,16 @@ typedef struct s_res_pool POOL; * resource structure definitions. */ union u_res { - struct s_res_dir res_dir; - struct s_res_client res_client; - struct s_res_store res_store; - struct s_res_cat res_cat; - struct s_res_job res_job; - struct s_res_fs res_fs; - struct s_res_sch res_sch; - struct s_res_group res_group; - struct s_res_pool res_pool; - struct s_res_msgs res_msgs; + struct s_res_dir res_dir; + struct s_res_client res_client; + struct s_res_store res_store; + struct s_res_cat res_cat; + struct s_res_job res_job; + struct s_res_fs res_fs; + struct s_res_sch res_sch; + struct s_res_group res_group; + struct s_res_pool res_pool; + struct s_res_msgs res_msgs; struct s_res_counter res_counter; RES hdr; }; @@ -272,17 +273,17 @@ typedef union u_res URES; /* Run structure contained in Schedule Resource */ struct s_run { - struct s_run *next; /* points to next run record */ - int level; /* level override */ + struct s_run *next; /* points to next run record */ + int level; /* level override */ int job_type; - POOL *pool; /* Pool override */ - STORE *storage; /* Storage override */ - MSGS *msgs; /* Messages override */ + POOL *pool; /* Pool override */ + STORE *storage; /* Storage override */ + MSGS *msgs; /* Messages override */ char *since; int level_no; - int minute; /* minute to run job */ - time_t last_run; /* last time run */ - time_t next_run; /* next time to run */ + int minute; /* minute to run job */ + time_t last_run; /* last time run */ + time_t next_run; /* next time to run */ char hour[nbytes_for_bits(24)]; /* bit set for each hour */ char mday[nbytes_for_bits(31)]; /* bit set for each day of month */ char month[nbytes_for_bits(12)]; /* bit set for each month */ diff --git a/bacula/src/dird/ua_cmds.c b/bacula/src/dird/ua_cmds.c index bbfcc73a6f..cfdc8de407 100644 --- a/bacula/src/dird/ua_cmds.c +++ b/bacula/src/dird/ua_cmds.c @@ -145,11 +145,13 @@ static int addcmd(UAContext *ua, char *cmd) int num, i, max, startnum; int first_id = 0; char name[MAX_NAME_LENGTH]; + STORE *store; + int slot = 0; bsendmsg(ua, _( "You probably don't want to be using this command since it\n" "creates database records without labeling the Volumes.\n" -"You probably want to use the label command.\n\n")); +"You probably want to use the \"label\" command.\n\n")); if (!open_db(ua)) { return 1; @@ -180,10 +182,15 @@ static int addcmd(UAContext *ua, char *cmd) } } - if (!get_media_type(ua, mr.MediaType)) { - return 1; + /* Get media type */ + if ((store = get_storage_resource(ua, cmd)) != NULL) { + strcpy(mr.MediaType, store->media_type); + } else { + if (!get_media_type(ua, mr.MediaType)) { + return 1; + } } - + if (pr.MaxVols == 0) { max = 1000; } else { @@ -212,6 +219,7 @@ getVolName: return 1; } } + /* Don't allow | in Volume name because it is the volume separator character */ if (strchr(ua->cmd, '|')) { bsendmsg(ua, _("Illegal character | in a volume name.\n")); goto getVolName; @@ -244,6 +252,13 @@ getVolName: startnum = 1; num = 1; } + + if (store && store->autochanger) { + if (!get_cmd(ua, _("Enter slot (0 for none): "))) { + return 1; + } + slot = atoi(ua->cmd); + } mr.PoolId = pr.PoolId; strcpy(mr.VolStatus, "Append"); @@ -251,6 +266,7 @@ getVolName: mr.VolRetention = pr.VolRetention; for (i=startnum; i < num+startnum; i++) { sprintf(mr.VolumeName, name, i); + mr.Slot = slot++; Dmsg1(200, "Create Volume %s\n", mr.VolumeName); if (!db_create_media_record(ua->db, &mr)) { bsendmsg(ua, db_strerror(ua->db)); @@ -1075,6 +1091,7 @@ static int labelcmd(UAContext *ua, char *cmd) int ok = FALSE; int mounted = FALSE; int i; + int slot = 0; static char *keyword[] = { "volume", NULL}; @@ -1111,6 +1128,7 @@ gotVol: goto getVol; } + memset(&mr, 0, sizeof(mr)); strcpy(mr.VolumeName, ua->cmd); if (db_get_media_record(ua->db, &mr)) { @@ -1118,7 +1136,16 @@ gotVol: mr.VolumeName); return 1; } + + /* Do some more checking on slot ****FIXME**** */ + if (store->autochanger) { + if (!get_cmd(ua, _("Enter slot (0 for none): "))) { + return 1; + } + slot = atoi(ua->cmd); + } strcpy(mr.MediaType, store->media_type); + mr.Slot = slot; memset(&pr, 0, sizeof(pr)); if (!select_pool_dbr(ua, &pr)) { @@ -1142,8 +1169,8 @@ gotVol: bash_spaces(mr.VolumeName); bash_spaces(mr.MediaType); bash_spaces(pr.Name); - bnet_fsend(sd, _("label %s VolumeName=%s PoolName=%s MediaType=%s"), - dev_name, mr.VolumeName, pr.Name, mr.MediaType); + bnet_fsend(sd, _("label %s VolumeName=%s PoolName=%s MediaType=%s Slot=%d"), + dev_name, mr.VolumeName, pr.Name, mr.MediaType, mr.Slot); bsendmsg(ua, "Sending label command ...\n"); while (bget_msg(sd, 0) > 0) { bsendmsg(ua, "%s", sd->msg); diff --git a/bacula/src/stored/acquire.c b/bacula/src/stored/acquire.c index fd1b8b68c5..cea55c1cde 100644 --- a/bacula/src/stored/acquire.c +++ b/bacula/src/stored/acquire.c @@ -41,7 +41,6 @@ int acquire_device_for_read(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) { int stat; - new_lock_device_state(dev, BST_DOING_ACQUIRE); lock_device(dev); if (dev->state & ST_READ || dev->num_writers > 0) { Jmsg(jcr, M_FATAL, 0, _("Device %s is busy.\n"), dev_name(dev)); @@ -53,12 +52,9 @@ int acquire_device_for_read(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) block_device(dev, BST_DOING_ACQUIRE); unlock_device(dev); stat = ready_dev_for_read(jcr, dev, block); -#ifndef NEW_LOCK P(dev->mutex); unblock_device(dev); V(dev->mutex); -#endif - new_unlock_device(dev); return stat; } @@ -74,7 +70,6 @@ int acquire_device_for_append(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) int release = 0; int do_mount = 0; - new_lock_device_state(dev, BST_DOING_ACQUIRE); lock_device(dev); Dmsg1(190, "acquire_append device is %s\n", dev_is_tape(dev)?"tape":"disk"); @@ -97,7 +92,6 @@ int acquire_device_for_append(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) if (dev->num_writers != 0) { Jmsg(jcr, M_FATAL, 0, _("Device %s is busy writing with another Volume.\n"), dev_name(dev)); unlock_device(dev); - new_unlock_device(dev); return 0; } /* Wrong tape mounted, release it, then fall through to get correct one */ @@ -109,7 +103,6 @@ int acquire_device_for_append(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) if (dev->state & ST_READ) { Jmsg(jcr, M_FATAL, 0, _("Device %s is busy reading.\n"), dev_name(dev)); unlock_device(dev); - new_unlock_device(dev); return 0; } ASSERT(dev->num_writers == 0); @@ -122,18 +115,13 @@ int acquire_device_for_append(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) if (!mount_next_write_volume(jcr, dev, block, release)) { Jmsg(jcr, M_FATAL, 0, _("Could not ready device %s for append.\n"), dev_name(dev)); -#ifndef NEW_LOCK P(dev->mutex); unblock_device(dev); unlock_device(dev); -#endif - new_unlock_device(dev); return 0; } -#ifndef NEW_LOCK P(dev->mutex); unblock_device(dev); -#endif } dev->num_writers++; @@ -146,7 +134,6 @@ int acquire_device_for_append(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) } attach_jcr_to_device(dev, jcr); /* attach jcr to device */ unlock_device(dev); - new_unlock_device(dev); return 1; /* got it */ } @@ -157,10 +144,7 @@ int acquire_device_for_append(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) */ int release_device(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) { -#ifndef NEW_LOCK P(dev->mutex); -#endif - new_lock_device(dev); Dmsg1(100, "release_device device is %s\n", dev_is_tape(dev)?"tape":"disk"); if (dev->state & ST_READ) { dev->state &= ~ST_READ; /* clear read bit */ @@ -200,9 +184,7 @@ int release_device(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) Jmsg1(jcr, M_ERROR, 0, _("BAD ERROR: release_device %s not in use.\n"), dev_name(dev)); } detach_jcr_from_device(dev, jcr); -#ifndef NEW_LOCK V(dev->mutex); -#endif new_unlock_device(dev); return 1; } diff --git a/bacula/src/stored/block.c b/bacula/src/stored/block.c index 312c3ab65b..ea1335509c 100644 --- a/bacula/src/stored/block.c +++ b/bacula/src/stored/block.c @@ -240,12 +240,10 @@ static int unser_block_header(DEVICE *dev, DEV_BLOCK *block) int write_block_to_device(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) { int stat = 1; - new_lock_device(dev); lock_device(dev); if (!write_block_to_dev(dev, block)) { stat = fixup_device_block_write_error(jcr, dev, block); } - new_unlock_device(dev); unlock_device(dev); return stat; } diff --git a/bacula/src/stored/bls.c b/bacula/src/stored/bls.c index 9c4c20f106..b0acef5125 100644 --- a/bacula/src/stored/bls.c +++ b/bacula/src/stored/bls.c @@ -134,7 +134,7 @@ int main (int argc, char *argv[]) } while (fgets(line, sizeof(line), fd) != NULL) { strip_trailing_junk(line); - Dmsg1(000, "add_exclude %s\n", line); + Dmsg1(100, "add_exclude %s\n", line); add_fname_to_exclude_list(&ff, line); } fclose(fd); @@ -148,7 +148,7 @@ int main (int argc, char *argv[]) } while (fgets(line, sizeof(line), fd) != NULL) { strip_trailing_junk(line); - Dmsg1(000, "add_include %s\n", line); + Dmsg1(100, "add_include %s\n", line); add_fname_to_include_list(&ff, 0, line); } fclose(fd); @@ -245,7 +245,7 @@ static void do_setup(char *infname) *p = 0; } } - Dmsg2(000, "Device=%s, Vol=%s.\n", infname, VolName); + Dmsg2(100, "Device=%s, Vol=%s.\n", infname, VolName); dev = init_dev(NULL, infname); if (!dev) { Emsg1(M_FATAL, 0, "Cannot open %s\n", infname); @@ -490,14 +490,14 @@ Warning, this Volume is a continuation of Volume %s\n", Dmsg0(20, "!read_record()\n"); if (dev->state & ST_EOT) { DEV_RECORD *record; - Dmsg3(000, "EOT. stat=%s blk=%d rem=%d\n", rec_state_to_str(rec), + Dmsg3(100, "EOT. stat=%s blk=%d rem=%d\n", rec_state_to_str(rec), block->BlockNumber, rec->remainder); if (!mount_next_volume(infname)) { - Dmsg3(000, "After mount next vol. stat=%s blk=%d rem=%d\n", rec_state_to_str(rec), + Dmsg3(100, "After mount next vol. stat=%s blk=%d rem=%d\n", rec_state_to_str(rec), block->BlockNumber, rec->remainder); break; } - Dmsg3(000, "After mount next vol. stat=%s blk=%d rem=%d\n", rec_state_to_str(rec), + Dmsg3(100, "After mount next vol. stat=%s blk=%d rem=%d\n", rec_state_to_str(rec), block->BlockNumber, rec->remainder); record = new_record(); read_block_from_device(dev, block); diff --git a/bacula/src/stored/dev.h b/bacula/src/stored/dev.h index 4173fafe3f..7f9025ae5d 100644 --- a/bacula/src/stored/dev.h +++ b/bacula/src/stored/dev.h @@ -31,9 +31,16 @@ /* #define NEW_LOCK 1 */ -#define new_lock_device(dev) _lock_device(__FILE__, __LINE__, (dev)) -#define new_lock_device_state(dev,state) _lock_device(__FILE__, __LINE__, (dev), (state)) -#define new_unlock_device(dev) _unlock_device(__FILE__, __LINE__, (dev)) +#define new_lock_device(dev) _new_lock_device(__FILE__, __LINE__, (dev)) +#define new_lock_device_state(dev,state) _new_lock_device(__FILE__, __LINE__, (dev), (state)) +#define new_unlock_device(dev) _new_unlock_device(__FILE__, __LINE__, (dev)) + +#define lock_device(d) _lock_device(__FILE__, __LINE__, (d)) +#define unlock_device(d) _unlock_device(__FILE__, __LINE__, (d)) +#define block_device(d, s) _block_device(__FILE__, __LINE__, (d), s) +#define unblock_device(d) _unblock_device(__FILE__, __LINE__, (d)) +#define steal_device_lock(d, p, s) _steal_device_lock(__FILE__, __LINE__, (d), (p), s) +#define return_device_lock(d, p) _return_device_lock(__FILE__, __LINE__, (d), (p)) /* Arguments to open_dev() */ #define READ_WRITE 0 diff --git a/bacula/src/stored/device.c b/bacula/src/stored/device.c index 9af8ce96f1..063fcf7227 100644 --- a/bacula/src/stored/device.c +++ b/bacula/src/stored/device.c @@ -80,10 +80,11 @@ int fixup_device_block_write_error(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) wait_time = time(NULL); status_dev(dev, &stat); if (stat & MT_EOD) { - Dmsg0(190, "======= Got EOD ========\n"); + Dmsg0(100, "======= Got EOD ========\n"); - new_lock_device_state(dev, BST_DOING_ACQUIRE); block_device(dev, BST_DOING_ACQUIRE); + /* Unlock, but leave BLOCKED */ + unlock_device(dev); /* * Walk through all attached jcrs creating a jobmedia_record() @@ -96,6 +97,8 @@ int fixup_device_block_write_error(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) if (!dir_create_jobmedia_record(mjcr)) { Jmsg(mjcr, M_ERROR, 0, _("Could not create JobMedia record for Volume=%s Job=%s\n"), dev->VolCatInfo.VolCatName, mjcr->Job); + P(dev->mutex); + unblock_device(dev); return 0; } } @@ -106,7 +109,8 @@ int fixup_device_block_write_error(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) if (!dir_update_volume_info(jcr, &dev->VolCatInfo, 0)) { /* send Volume info to Director */ Jmsg(jcr, M_ERROR, 0, _("Could not update Volume info Volume=%s Job=%s\n"), dev->VolCatInfo.VolCatName, jcr->Job); - new_unlock_device(dev); + P(dev->mutex); + unblock_device(dev); return 0; /* device locked */ } Dmsg0(190, "Back from update_vol_info\n"); @@ -121,19 +125,12 @@ int fixup_device_block_write_error(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) PrevVolName, edit_uint64_with_commas(dev->VolCatInfo.VolCatBytes, b1), edit_uint64_with_commas(dev->VolCatInfo.VolCatBlocks, b2)); - /* Unlock, but leave BLOCKED */ - unlock_device(dev); if (!mount_next_write_volume(jcr, dev, label_blk, 1)) { - new_unlock_device(dev); -#ifndef NEW_LOCK P(dev->mutex); -#endif unblock_device(dev); return 0; /* device locked */ } -#ifndef NEW_LOCK P(dev->mutex); /* lock again */ -#endif Jmsg(jcr, M_INFO, 0, _("New volume %s mounted on device %s\n"), jcr->VolumeName, dev_name(dev)); @@ -149,7 +146,6 @@ int fixup_device_block_write_error(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) Pmsg1(0, "write_block_to_device Volume label failed. ERR=%s", strerror_dev(dev)); free_block(label_blk); - new_unlock_device(dev); unblock_device(dev); return 0; /* device locked */ } @@ -160,7 +156,6 @@ int fixup_device_block_write_error(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) Pmsg1(0, "write_block_to_device overflow block failed. ERR=%s", strerror_dev(dev)); free_block(label_blk); - new_unlock_device(dev); unblock_device(dev); return 0; /* device locked */ } @@ -175,14 +170,12 @@ int fixup_device_block_write_error(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) mjcr->VolFirstFile = mjcr->JobFiles; mjcr->run_time += time(NULL) - wait_time; /* correct run time */ } - new_unlock_device(dev); unblock_device(dev); return 1; /* device locked */ } if (label_blk) { free_block(label_blk); } - new_unlock_device(dev); return 0; /* device locked */ } @@ -208,13 +201,11 @@ int open_device(DEVICE *dev) return 0; } - new_lock_device(dev); lock_device(dev); /* Defer opening files */ if (!dev_is_tape(dev)) { Dmsg0(129, "Device is file, deferring open.\n"); - new_unlock_device(dev); unlock_device(dev); return 1; } @@ -223,14 +214,12 @@ int open_device(DEVICE *dev) Dmsg0(129, "Opening device.\n"); if (open_dev(dev, NULL, READ_WRITE) < 0) { Emsg1(M_FATAL, 0, _("dev open failed: %s\n"), dev->errmsg); - new_unlock_device(dev); unlock_device(dev); return 0; } } Dmsg1(129, "open_dev %s OK\n", dev_name(dev)); - new_unlock_device(dev); unlock_device(dev); return 1; } @@ -240,11 +229,10 @@ int open_device(DEVICE *dev) * must wait. The no_wait_id thread is out obtaining a new volume * and preparing the label. */ -void lock_device(DEVICE *dev) +void _lock_device(char *file, int line, DEVICE *dev) { -#ifndef NEW_LOCK int stat; - Dmsg1(190, "lock %d\n", dev->dev_blocked); + Dmsg3(100, "lock %d from %s:%d\n", dev->dev_blocked, file, line); P(dev->mutex); if (dev->dev_blocked && !pthread_equal(dev->no_wait_id, pthread_self())) { dev->num_waiting++; /* indicate that I am waiting */ @@ -257,15 +245,12 @@ void lock_device(DEVICE *dev) } dev->num_waiting--; /* no longer waiting */ } -#endif } -void unlock_device(DEVICE *dev) +void _unlock_device(char *file, int line, DEVICE *dev) { -#ifndef NEW_LOCK - Dmsg0(190, "unlock\n"); + Dmsg2(100, "unlock from %s:%d\n", file, line); V(dev->mutex); -#endif } /* @@ -276,49 +261,45 @@ void unlock_device(DEVICE *dev) * the current thread can do slip through the lock_device() * calls without blocking. */ -void block_device(DEVICE *dev, int state) +void _block_device(char *file, int line, DEVICE *dev, int state) { -#ifndef NEW_LOCK - Dmsg1(190, "block set %d\n", state); + Dmsg3(100, "block set %d from %s:%d\n", state, file, line); ASSERT(dev->dev_blocked == BST_NOT_BLOCKED); dev->dev_blocked = state; /* make other threads wait */ dev->no_wait_id = pthread_self(); /* allow us to continue */ -#endif } /* * Unblock the device, and wake up anyone who went to sleep. */ -void unblock_device(DEVICE *dev) +void _unblock_device(char *file, int line, DEVICE *dev) { -#ifndef NEW_LOCK - Dmsg1(190, "unblock %d\n", dev->dev_blocked); + Dmsg3(100, "unblock %d from %s:%d\n", dev->dev_blocked, file, line); ASSERT(dev->dev_blocked); dev->dev_blocked = BST_NOT_BLOCKED; if (dev->num_waiting > 0) { pthread_cond_broadcast(&dev->wait); /* wake them up */ } -#endif } -void steal_device_lock(DEVICE *dev, bsteal_lock_t *hold, int state) +void _steal_device_lock(char *file, int line, DEVICE *dev, bsteal_lock_t *hold, int state) { -#ifndef NEW_LOCK + Dmsg4(100, "steal lock. old=%d new=%d from %s:%d\n", dev->dev_blocked, state, + file, line); hold->dev_blocked = dev->dev_blocked; hold->no_wait_id = dev->no_wait_id; dev->dev_blocked = state; dev->no_wait_id = pthread_self(); V(dev->mutex); -#endif } -void return_device_lock(DEVICE *dev, bsteal_lock_t *hold) +void _return_device_lock(char *file, int line, DEVICE *dev, bsteal_lock_t *hold) { -#ifndef NEW_LOCK + Dmsg4(100, "return lock. old=%d new=%d from %s:%d\n", + dev->dev_blocked, hold->dev_blocked, file, line); P(dev->mutex); dev->dev_blocked = hold->dev_blocked; dev->no_wait_id = hold->no_wait_id; -#endif } @@ -331,7 +312,7 @@ void return_device_lock(DEVICE *dev, bsteal_lock_t *hold) /* * New device locking scheme */ -void _lock_device(char *file, int line, DEVICE *dev) +void _new_lock_device(char *file, int line, DEVICE *dev) { #ifdef NEW_LOCK int errstat; @@ -342,7 +323,7 @@ void _lock_device(char *file, int line, DEVICE *dev) #endif } -void _lock_device(char *file, int line, DEVICE *dev, int state) +void _new_lock_device(char *file, int line, DEVICE *dev, int state) { #ifdef NEW_LOCK int errstat; @@ -354,7 +335,7 @@ void _lock_device(char *file, int line, DEVICE *dev, int state) #endif } -void _unlock_device(char *file, int line, DEVICE *dev) +void _new_unlock_device(char *file, int line, DEVICE *dev) { #ifdef NEW_LOCK int errstat; diff --git a/bacula/src/stored/dircmd.c b/bacula/src/stored/dircmd.c index 45b1a5c4de..482f7f7803 100644 --- a/bacula/src/stored/dircmd.c +++ b/bacula/src/stored/dircmd.c @@ -226,18 +226,19 @@ static int cancel_cmd(JCR *cjcr) */ static int label_cmd(JCR *jcr) { - char *dname, *volname, *poolname, *mtype; + POOLMEM *dname, *volname, *poolname, *mtype; BSOCK *dir = jcr->dir_bsock; DEVRES *device; DEVICE *dev; int found = 0; - - dname = (char *) get_memory(dir->msglen+1); - volname = (char *) get_memory(dir->msglen+1); - poolname = (char *) get_memory(dir->msglen+1); - mtype = (char *) get_memory(dir->msglen+1); - if (sscanf(dir->msg, "label %s VolumeName=%s PoolName=%s MediaType=%s", - dname, volname, poolname, mtype) == 4) { + int slot; + + dname = get_memory(dir->msglen+1); + volname = get_memory(dir->msglen+1); + poolname = get_memory(dir->msglen+1); + mtype = get_memory(dir->msglen+1); + if (sscanf(dir->msg, "label %s VolumeName=%s PoolName=%s MediaType=%s Slot=%d", + dname, volname, poolname, mtype, &slot) == 5) { unbash_spaces(dname); unbash_spaces(volname); unbash_spaces(poolname); @@ -254,14 +255,12 @@ static int label_cmd(JCR *jcr) } UnlockRes(); if (found) { -#ifdef NEW_LOCK - int label_it = FALSE; - brwsteal_t hold; -#endif /******FIXME**** compare MediaTypes */ jcr->device = device; dev = device->dev; +/* *****FIXME***** add autochanger code */ + #ifdef NEW_LOCK P(dev->lock.mutex); if (!(dev->state & ST_OPENED)) { @@ -346,11 +345,9 @@ static void label_volume_if_ok(JCR *jcr, DEVICE *dev, char *vname, char *poolnam { BSOCK *dir = jcr->dir_bsock; DEV_BLOCK *block; -#ifndef NEW_LOCK bsteal_lock_t hold; steal_device_lock(dev, &hold, BST_WRITING_LABEL); -#endif strcpy(jcr->VolumeName, vname); block = new_block(dev); @@ -375,9 +372,7 @@ Unknown status %d from read_volume_label()\n"), jcr->label_status); break; } free_block(block); -#ifndef NEW_LOCK return_device_lock(dev, &hold); -#endif } diff --git a/bacula/src/stored/mount.c b/bacula/src/stored/mount.c index 70879769f2..94f5858149 100644 --- a/bacula/src/stored/mount.c +++ b/bacula/src/stored/mount.c @@ -72,6 +72,7 @@ mount_next_vol: memset(&dev->VolCatInfo, 0, sizeof(dev->VolCatInfo)); memset(&dev->VolHdr, 0, sizeof(dev->VolHdr)); dev->state &= ~ST_LABEL; /* label not yet read */ + jcr->VolumeName[0] = 0; if (!dev_is_tape(dev) || !(dev->capabilities & CAP_ALWAYSOPEN)) { if (dev->capabilities & CAP_OFFLINEUNMOUNT) { @@ -91,14 +92,16 @@ mount_next_vol: } } ask = 1; /* ask operator to mount tape */ - } else { - /* - * Get Director's idea of what tape we should have mounted. - */ - if (!dir_find_next_appendable_volume(jcr)) { - ask = 1; /* we must ask */ - } } + + /* + * Get Director's idea of what tape we should have mounted. + */ + if (!dir_find_next_appendable_volume(jcr)) { + ask = 1; /* we must ask */ + } + Dmsg2(100, "After find_next_append. Vol=%s Slot=%d\n", + jcr->VolCatInfo.VolCatName, jcr->VolCatInfo.Slot); release = 1; /* release if we "recurse" */ /* @@ -161,6 +164,7 @@ mount_next_vol: force_close_dev(dev); if (loaded != 0) { /* must unload drive */ Dmsg0(100, "Doing changer unload.\n"); + Jmsg(jcr, M_INFO, 0, _("Issuing autochanger \"unload\" command.\n")); changer = edit_device_codes(jcr, changer, jcr->device->changer_command, "unload"); status = run_program(changer, timeout, NULL); @@ -170,6 +174,8 @@ mount_next_vol: * Load the desired cassette */ Dmsg1(100, "Doing changer load slot %d\n", slot); + Jmsg(jcr, M_INFO, 0, _("Issuing autochanger \"load slot %d\" command.\n"), + slot); changer = edit_device_codes(jcr, changer, jcr->device->changer_command, "load"); status = run_program(changer, timeout, NULL); @@ -366,6 +372,7 @@ read_volume: return 1; } + int mount_next_read_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *block) { Dmsg2(90, "NumVolumes=%d CurVolume=%d\n", jcr->NumVolumes, jcr->CurVolume); diff --git a/bacula/src/stored/protos.h b/bacula/src/stored/protos.h index 495cdc4cea..efb5a559cb 100644 --- a/bacula/src/stored/protos.h +++ b/bacula/src/stored/protos.h @@ -28,121 +28,123 @@ uint32_t new_VolSessionId(); /* From acquire.c */ -int acquire_device_for_append(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); -int acquire_device_for_read(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); -int ready_dev_for_read(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); -int release_device(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); +int acquire_device_for_append(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); +int acquire_device_for_read(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); +int ready_dev_for_read(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); +int release_device(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); /* From askdir.c */ -int dir_get_volume_info(JCR *jcr); -int dir_find_next_appendable_volume(JCR *jcr); -int dir_update_volume_info(JCR *jcr, VOLUME_CAT_INFO *vol, int relabel); -int dir_ask_sysop_to_mount_next_volume(JCR *jcr, DEVICE *dev); -int dir_ask_sysop_to_mount_volume(JCR *jcr, DEVICE *dev); -int dir_update_file_attributes(JCR *jcr, DEV_RECORD *rec); -int dir_send_job_status(JCR *jcr); -int dir_create_jobmedia_record(JCR *jcr); +int dir_get_volume_info(JCR *jcr); +int dir_find_next_appendable_volume(JCR *jcr); +int dir_update_volume_info(JCR *jcr, VOLUME_CAT_INFO *vol, int relabel); +int dir_ask_sysop_to_mount_next_volume(JCR *jcr, DEVICE *dev); +int dir_ask_sysop_to_mount_volume(JCR *jcr, DEVICE *dev); +int dir_update_file_attributes(JCR *jcr, DEV_RECORD *rec); +int dir_send_job_status(JCR *jcr); +int dir_create_jobmedia_record(JCR *jcr); /* authenticate.c */ -int authenticate_director(JCR *jcr); -int authenticate_filed(JCR *jcr); +int authenticate_director(JCR *jcr); +int authenticate_filed(JCR *jcr); /* From block.c */ -void dump_block(DEV_BLOCK *b, char *msg); +void dump_block(DEV_BLOCK *b, char *msg); DEV_BLOCK *new_block(DEVICE *dev); -void init_block_write(DEV_BLOCK *block); -void empty_block(DEV_BLOCK *block); -void free_block(DEV_BLOCK *block); -int write_block_to_device(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); -int write_block_to_dev(DEVICE *dev, DEV_BLOCK *block); -int read_block_from_device(DEVICE *dev, DEV_BLOCK *block); -int read_block_from_dev(DEVICE *dev, DEV_BLOCK *block); +void init_block_write(DEV_BLOCK *block); +void empty_block(DEV_BLOCK *block); +void free_block(DEV_BLOCK *block); +int write_block_to_device(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); +int write_block_to_dev(DEVICE *dev, DEV_BLOCK *block); +int read_block_from_device(DEVICE *dev, DEV_BLOCK *block); +int read_block_from_dev(DEVICE *dev, DEV_BLOCK *block); /* From dev.c */ -DEVICE *init_dev(DEVICE *dev, char *device); -int open_dev(DEVICE *dev, char *VolName, int mode); -void close_dev(DEVICE *dev); -void force_close_dev(DEVICE *dev); -int truncate_dev(DEVICE *dev); -void term_dev(DEVICE *dev); -char * strerror_dev(DEVICE *dev); -void clrerror_dev(DEVICE *dev, int func); -int update_pos_dev(DEVICE *dev); -int rewind_dev(DEVICE *dev); -int load_dev(DEVICE *dev); -int offline_dev(DEVICE *dev); -int flush_dev(DEVICE *dev); -int weof_dev(DEVICE *dev, int num); -int write_block(DEVICE *dev); -int write_dev(DEVICE *dev, char *buf, size_t len); -int read_dev(DEVICE *dev, char *buf, size_t len); -int status_dev(DEVICE *dev, uint32_t *status); -int eod_dev(DEVICE *dev); -int fsf_dev(DEVICE *dev, int num); -int fsr_dev(DEVICE *dev, int num); -int bsf_dev(DEVICE *dev, int num); -int bsr_dev(DEVICE *dev, int num); -void attach_jcr_to_device(DEVICE *dev, JCR *jcr); -void detach_jcr_from_device(DEVICE *dev, JCR *jcr); -JCR *next_attached_jcr(DEVICE *dev, JCR *jcr); +DEVICE *init_dev(DEVICE *dev, char *device); +int open_dev(DEVICE *dev, char *VolName, int mode); +void close_dev(DEVICE *dev); +void force_close_dev(DEVICE *dev); +int truncate_dev(DEVICE *dev); +void term_dev(DEVICE *dev); +char * strerror_dev(DEVICE *dev); +void clrerror_dev(DEVICE *dev, int func); +int update_pos_dev(DEVICE *dev); +int rewind_dev(DEVICE *dev); +int load_dev(DEVICE *dev); +int offline_dev(DEVICE *dev); +int flush_dev(DEVICE *dev); +int weof_dev(DEVICE *dev, int num); +int write_block(DEVICE *dev); +int write_dev(DEVICE *dev, char *buf, size_t len); +int read_dev(DEVICE *dev, char *buf, size_t len); +int status_dev(DEVICE *dev, uint32_t *status); +int eod_dev(DEVICE *dev); +int fsf_dev(DEVICE *dev, int num); +int fsr_dev(DEVICE *dev, int num); +int bsf_dev(DEVICE *dev, int num); +int bsr_dev(DEVICE *dev, int num); +void attach_jcr_to_device(DEVICE *dev, JCR *jcr); +void detach_jcr_from_device(DEVICE *dev, JCR *jcr); +JCR *next_attached_jcr(DEVICE *dev, JCR *jcr); /* Get info about device */ -char * dev_name(DEVICE *dev); -char * dev_vol_name(DEVICE *dev); +char * dev_name(DEVICE *dev); +char * dev_vol_name(DEVICE *dev); uint32_t dev_block(DEVICE *dev); uint32_t dev_file(DEVICE *dev); -int dev_is_tape(DEVICE *dev); +int dev_is_tape(DEVICE *dev); /* From device.c */ -int open_device(DEVICE *dev); -void block_device(DEVICE *dev, int state); -void unblock_device(DEVICE *dev); -void lock_device(DEVICE *dev); -void unlock_device(DEVICE *dev); -void steal_device_lock(DEVICE *dev, bsteal_lock_t *hold, int state); -void return_device_lock(DEVICE *dev, bsteal_lock_t *hold); -int fixup_device_block_write_error(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); +int open_device(DEVICE *dev); +int fixup_device_block_write_error(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); void _lock_device(char *file, int line, DEVICE *dev); -void _lock_device(char *file, int line, DEVICE *dev, int state); void _unlock_device(char *file, int line, DEVICE *dev); +void _block_device(char *file, int line, DEVICE *dev, int state); +void _unblock_device(char *file, int line, DEVICE *dev); +void _steal_device_lock(char *file, int line, DEVICE *dev, bsteal_lock_t *hold, int state); +void _return_device_lock(char *file, int line, DEVICE *dev, bsteal_lock_t *hold); + +/* don't use */ +void _new_lock_device(char *file, int line, DEVICE *dev); +void _new_lock_device(char *file, int line, DEVICE *dev, int state); +void _new_unlock_device(char *file, int line, DEVICE *dev); void new_steal_device_lock(DEVICE *dev, brwsteal_t *hold, int state); void new_return_device_lock(DEVICE *dev, brwsteal_t *hold); /* From dircmd.c */ -void connection_request(void *arg); +void connection_request(void *arg); /* From fd_cmds.c */ -void run_job(JCR *jcr); +void run_job(JCR *jcr); /* From fdmsg.c */ -int bget_msg(BSOCK *sock); +int bget_msg(BSOCK *sock); /* From job.c */ -void stored_free_jcr(JCR *jcr); -void connection_from_filed(void *arg); -void handle_filed_connection(BSOCK *fd, char *job_name); +void stored_free_jcr(JCR *jcr); +void connection_from_filed(void *arg); +void handle_filed_connection(BSOCK *fd, char *job_name); /* From label.c */ -int read_dev_volume_label(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); -void create_session_label(JCR *jcr, DEV_RECORD *rec, int label); -int write_volume_label_to_dev(JCR *jcr, DEVRES *device, char *VolName, char *PoolName); -int write_session_label(JCR *jcr, DEV_BLOCK *block, int label); -int write_volume_label_to_block(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); -void dump_volume_label(DEVICE *dev); -void dump_label_record(DEVICE *dev, DEV_RECORD *rec, int verbose); -int unser_volume_label(DEVICE *dev, DEV_RECORD *rec); -int unser_session_label(SESSION_LABEL *label, DEV_RECORD *rec); +int read_dev_volume_label(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); +void create_session_label(JCR *jcr, DEV_RECORD *rec, int label); +int write_volume_label_to_dev(JCR *jcr, DEVRES *device, char *VolName, char *PoolName); +int write_session_label(JCR *jcr, DEV_BLOCK *block, int label); +int write_volume_label_to_block(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); +void dump_volume_label(DEVICE *dev); +void dump_label_record(DEVICE *dev, DEV_RECORD *rec, int verbose); +int unser_volume_label(DEVICE *dev, DEV_RECORD *rec); +int unser_session_label(SESSION_LABEL *label, DEV_RECORD *rec); /* From match_bsr.c */ int match_bsr(BSR *bsr, DEV_RECORD *rec, VOLUME_LABEL *volrec, - SESSION_LABEL *sesrec); + SESSION_LABEL *sesrec); /* From mount.c */ -int mount_next_write_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, int release); -int mount_next_read_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); +int mount_next_write_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *block, int release); +int mount_next_read_volume(JCR *jcr, DEVICE *dev, DEV_BLOCK *block); /* From parse_bsr.c */ @@ -157,8 +159,8 @@ extern void create_vol_list(JCR *jcr); /* From record.c */ char *FI_to_ascii(int fi); char *stream_to_ascii(int stream); -int write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec); -int can_write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec); -int read_record_from_block(DEV_BLOCK *block, DEV_RECORD *rec); +int write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec); +int can_write_record_to_block(DEV_BLOCK *block, DEV_RECORD *rec); +int read_record_from_block(DEV_BLOCK *block, DEV_RECORD *rec); DEV_RECORD *new_record(); -void free_record(DEV_RECORD *rec); +void free_record(DEV_RECORD *rec); -- 2.39.5