From 3a8e82c43cf183556c294e86f2912f3eb3a1ebb3 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Sat, 21 Jun 2003 14:40:00 +0000 Subject: [PATCH] Add var command git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@599 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/ChangeLog | 7 +- bacula/src/dird/Makefile.in | 4 +- bacula/src/dird/autoprune.c | 56 ++---- bacula/src/dird/catreq.c | 8 +- bacula/src/dird/newvol.c | 370 +----------------------------------- bacula/src/dird/protos.h | 48 ++--- bacula/src/dird/ua_cmds.c | 23 +++ bacula/src/dird/ua_server.c | 154 ++++++++++----- bacula/src/dird/verify.c | 12 +- bacula/src/version.h | 4 +- 10 files changed, 191 insertions(+), 495 deletions(-) diff --git a/bacula/ChangeLog b/bacula/ChangeLog index 03b17e22c4..fd6021dcc2 100644 --- a/bacula/ChangeLog +++ b/bacula/ChangeLog @@ -1,4 +1,9 @@ -2003-xx-xx Version 1.31 Beta xxJun03 +2003-xx-xx Version 1.31 Beta 20Jun03 +- Change find_next_volume() for oldest to use LastWritten instead of + FirstWritten -- also add Append to volumes slected. +- Do normal recycling before checking for RecycleOldestVolume. +- Implemented block rejection on read. This should make restores run + much faster. Next release will have block positioning -- even faster. - Very preliminary support for Gnome-2.0. Text does not yet work. - Correct buffer corruption in find_one.c with long directory names (Win32). - Make setting owner on directories M_ERROR rather than M_WARNING. diff --git a/bacula/src/dird/Makefile.in b/bacula/src/dird/Makefile.in index 313a192358..2b0cafa68a 100644 --- a/bacula/src/dird/Makefile.in +++ b/bacula/src/dird/Makefile.in @@ -24,7 +24,7 @@ dummy: # SVRSRCS = dird.c admin.c authenticate.c \ autoprune.c backup.c bsr.c \ - catreq.c dird_conf.c \ + catreq.c dird_conf.c expand.c \ fd_cmds.c getmsg.c inc_conf.c job.c \ mountreq.c msgchan.c newvol.c \ recycle.c restore.c run_conf.c \ @@ -37,7 +37,7 @@ SVRSRCS = dird.c admin.c authenticate.c \ ua_status.c ua_tree.c verify.c SVROBJS = dird.o admin.o authenticate.o \ autoprune.o backup.o bsr.o \ - catreq.o dird_conf.o \ + catreq.o dird_conf.o expand.o \ fd_cmds.o getmsg.o inc_conf.o job.o \ mountreq.o msgchan.o newvol.o \ recycle.o restore.o run_conf.o \ diff --git a/bacula/src/dird/autoprune.c b/bacula/src/dird/autoprune.c index e3b8b56867..46107d7426 100644 --- a/bacula/src/dird/autoprune.c +++ b/bacula/src/dird/autoprune.c @@ -34,36 +34,6 @@ /* Forward referenced functions */ -/* - * The pruning code was written to be referenced by the - * User Agent (i.e. the console), so to properly access it and - * to ensure that the Job gets the proper output, we create - * a User Agent context. This is a sort of mini-kludge. - */ -void create_ua_context(JCR *jcr, UAContext *ua) -{ - memset(ua, 0, sizeof(UAContext)); - ua->jcr = jcr; - ua->db = jcr->db; - ua->cmd = get_pool_memory(PM_FNAME); - ua->args = get_pool_memory(PM_FNAME); - ua->verbose = 1; -} - -void free_ua_context(UAContext *ua) -{ - if (ua->cmd) { - free_pool_memory(ua->cmd); - } - if (ua->args) { - free_pool_memory(ua->args); - } - if (ua->prompt) { - free(ua->prompt); - ua->prompt = NULL; - ua->max_prompts = 0; - } -} /* * Auto Prune Jobs and Files. This is called at the end of every @@ -71,36 +41,36 @@ void free_ua_context(UAContext *ua) */ int do_autoprune(JCR *jcr) { - UAContext ua; + UAContext *ua; CLIENT *client; - int pruned; + bool pruned; if (!jcr->client) { /* temp -- remove me */ return 1; } - create_ua_context(jcr, &ua); + ua = new_ua_context(jcr); client = jcr->client; if (jcr->job->PruneJobs || jcr->client->AutoPrune) { Jmsg(jcr, M_INFO, 0, _("Begin pruning Jobs.\n")); - prune_jobs(&ua, client, jcr->JobType); - pruned = TRUE; + prune_jobs(ua, client, jcr->JobType); + pruned = true; } else { - pruned = FALSE; + pruned = false; } if (jcr->job->PruneFiles || jcr->client->AutoPrune) { Jmsg(jcr, M_INFO, 0, _("Begin pruning Files.\n")); - prune_files(&ua, client); - pruned = TRUE; + prune_files(ua, client); + pruned = true; } if (pruned) { Jmsg(jcr, M_INFO, 0, _("End auto prune.\n\n")); } - free_ua_context(&ua); + free_ua_context(ua); return 1; } @@ -120,7 +90,7 @@ int prune_volumes(JCR *jcr) int num_ids = 0; MEDIA_DBR mr; POOL_DBR pr; - UAContext ua; + UAContext *ua; if (!jcr->job->PruneVolumes && !jcr->pool->AutoPrune) { Dmsg0(100, "AutoPrune not set in Pool.\n"); @@ -128,7 +98,7 @@ int prune_volumes(JCR *jcr) } memset(&mr, 0, sizeof(mr)); memset(&pr, 0, sizeof(pr)); - create_ua_context(jcr, &ua); + ua = new_ua_context(jcr); db_lock(jcr->db); @@ -155,14 +125,14 @@ int prune_volumes(JCR *jcr) strcmp(mr.VolStatus, "Append") == 0 || strcmp(mr.VolStatus, "Used") == 0) { Dmsg1(200, "Prune Volume %s\n", mr.VolumeName); - stat += prune_volume(&ua, &pr, &mr); + stat += prune_volume(ua, &pr, &mr); Dmsg1(200, "Num pruned = %d\n", stat); } } bail_out: db_unlock(jcr->db); - free_ua_context(&ua); + free_ua_context(ua); if (ids) { free(ids); } diff --git a/bacula/src/dird/catreq.c b/bacula/src/dird/catreq.c index 391f30a110..a003df9631 100644 --- a/bacula/src/dird/catreq.c +++ b/bacula/src/dird/catreq.c @@ -114,13 +114,13 @@ next_volume: ok = db_find_next_volume(jcr, jcr->db, -1, &mr); Dmsg1(400, "Find oldest=%d\n", ok); if (ok) { - UAContext ua; + UAContext *ua; Dmsg0(400, "Try purge.\n"); /* Try to purge oldest volume */ - create_ua_context(jcr, &ua); + ua = new_ua_context(jcr); Jmsg(jcr, M_INFO, 0, _("Purging oldest volume \"%s\"\n"), mr.VolumeName); - ok = purge_jobs_from_volume(&ua, &mr); - free_ua_context(&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); diff --git a/bacula/src/dird/newvol.c b/bacula/src/dird/newvol.c index 1b96e510d0..380c8c98ba 100644 --- a/bacula/src/dird/newvol.c +++ b/bacula/src/dird/newvol.c @@ -126,374 +126,18 @@ static int create_simple_name(JCR *jcr, MEDIA_DBR *mr, POOL_DBR *pr) return 1; } -static int date_item(JCR *jcr, int code, - const char **val_ptr, int *val_len, int *val_size) -{ - struct tm tm; - time_t now = time(NULL); - localtime_r(&now, &tm); - int val = 0; - char buf[10]; - - switch (code) { - case 1: /* year */ - val = tm.tm_year + 1900; - break; - case 2: /* month */ - val = tm.tm_mon + 1; - break; - case 3: /* day */ - val = tm.tm_mday; - break; - case 4: /* hour */ - val = tm.tm_hour; - break; - case 5: /* minute */ - val = tm.tm_min; - break; - case 6: /* second */ - val = tm.tm_sec; - break; - case 7: /* Week day */ - val = tm.tm_wday; - break; - } - bsnprintf(buf, sizeof(buf), "%d", val); - *val_ptr = bstrdup(buf); - *val_len = strlen(buf); - *val_size = *val_len; - return 1; -} - -static int job_item(JCR *jcr, int code, - const char **val_ptr, int *val_len, int *val_size) -{ - char *str = " "; - char buf[20]; - - switch (code) { - case 1: /* Job */ - str = jcr->Job; - break; - case 2: /* Director's name */ - str = my_name; - break; - case 3: /* level */ - str = job_level_to_str(jcr->JobLevel); - break; - case 4: /* type */ - str = job_type_to_str(jcr->JobType); - break; - case 5: /* JobId */ - bsnprintf(buf, sizeof(buf), "%d", jcr->JobId); - str = buf; - break; - case 6: /* Client */ - str = jcr->client_name; - if (!str) { - str = " "; - } - break; - case 7: /* NumVols */ - bsnprintf(buf, sizeof(buf), "%d", jcr->NumVols); - str = buf; - break; - case 8: /* Pool */ - str = jcr->client->hdr.name; - break; - } - *val_ptr = bstrdup(str); - *val_len = strlen(str); - *val_size = *val_len; - return 1; -} - - -struct s_built_in_vars {char *var_name; int code; int (*func)(JCR *jcr, int code, - const char **val_ptr, int *val_len, int *val_size);}; - -static struct s_built_in_vars built_in_vars[] = { - { N_("Year"), 1, date_item}, - { N_("Month"), 2, date_item}, - { N_("Day"), 3, date_item}, - { N_("Hour"), 4, date_item}, - { N_("Minute"), 5, date_item}, - { N_("Second"), 6, date_item}, - { N_("WeekDay"), 7, date_item}, - - { N_("Job"), 1, job_item}, - { N_("Dir"), 2, job_item}, - { N_("Level"), 3, job_item}, - { N_("Type"), 4, job_item}, - { N_("JobId"), 5, job_item}, - { N_("Client"), 6, job_item}, - { N_("NumVols"), 7, job_item}, - { N_("Pool"), 8, job_item}, - - { NULL, 0, NULL} -}; - - -static var_rc_t lookup_built_in_var(var_t *ctx, void *my_ctx, - const char *var_ptr, int var_len, int var_index, - const char **val_ptr, int *val_len, int *val_size) -{ - JCR *jcr = (JCR *)my_ctx; - int stat; - - for (int i=0; _(built_in_vars[i].var_name); i++) { - if (strncmp(_(built_in_vars[i].var_name), var_ptr, var_len) == 0) { - stat = (*built_in_vars[i].func)(jcr, built_in_vars[i].code, - val_ptr, val_len, val_size); - if (stat) { - return VAR_OK; - } - break; - } - } - return VAR_ERR_UNDEFINED_VARIABLE; -} - - -/* - * Search counter variables - */ -static var_rc_t lookup_counter_var(var_t *ctx, void *my_ctx, - const char *var_ptr, int var_len, int var_inc, int var_index, - const char **val_ptr, int *val_len, int *val_size) -{ - char buf[MAXSTRING]; - var_rc_t stat = VAR_ERR_UNDEFINED_VARIABLE; - - if (var_len > (int)sizeof(buf) - 1) { - return VAR_ERR_OUT_OF_MEMORY; - } - memcpy(buf, var_ptr, var_len); - buf[var_len] = 0; - LockRes(); - for (COUNTER *counter=NULL; (counter = (COUNTER *)GetNextRes(R_COUNTER, (RES *)counter)); ) { - if (strcmp(counter->hdr.name, buf) == 0) { - bsnprintf(buf, sizeof(buf), "%d", counter->CurrentValue); - *val_ptr = bstrdup(buf); - *val_len = strlen(buf); - *val_size = *val_len; - if (var_inc) { - COUNTER_DBR cr; - JCR *jcr = (JCR *)my_ctx; - memset(&cr, 0, sizeof(cr)); - bstrncpy(cr.Counter, counter->hdr.name, sizeof(cr.Counter)); - cr.MinValue = counter->MinValue; - cr.MaxValue = counter->MaxValue; - cr.CurrentValue = ++counter->CurrentValue; - bstrncpy(cr.WrapCounter, counter->WrapCounter->hdr.name, sizeof(cr.WrapCounter)); - if (!db_update_counter_record(jcr, jcr->db, &cr)) { - Jmsg(jcr, M_ERROR, 0, _("Count not update counter %s: ERR=%s\n"), - counter->hdr.name, db_strerror(jcr->db)); - } - } - stat = VAR_OK; - break; - } - } - UnlockRes(); - return stat; -} - - -/* - * Called here to look up a variable - */ -static var_rc_t lookup_var(var_t *ctx, void *my_ctx, - const char *var_ptr, int var_len, int var_inc, int var_index, - const char **val_ptr, int *val_len, int *val_size) -{ - char buf[MAXSTRING], *val, *p, *v; - var_rc_t stat; - int count; - - if ((stat = lookup_built_in_var(ctx, my_ctx, var_ptr, var_len, var_index, - val_ptr, val_len, val_size)) == VAR_OK) { - return VAR_OK; - } - - if ((stat = lookup_counter_var(ctx, my_ctx, var_ptr, var_len, var_inc, var_index, - val_ptr, val_len, val_size)) == VAR_OK) { - return VAR_OK; - } - - /* Look in environment */ - if (var_len > (int)sizeof(buf) - 1) { - return VAR_ERR_OUT_OF_MEMORY; - } - memcpy(buf, var_ptr, var_len + 1); - buf[var_len] = 0; -// Dmsg1(000, "Var=%s\n", buf); - - if ((val = getenv(buf)) == NULL) { - return VAR_ERR_UNDEFINED_VARIABLE; - } - if (var_index == 0) { - *val_ptr = val; - *val_len = strlen(val); - *val_size = 0; - return VAR_OK; - } - /* He wants to index the "array" */ - count = 0; - /* Find the size of the "array" - * each element is separated by a | - */ - for (p = val; *p; p++) { - if (*p == '|') { - count++; - } - } - count++; -// Dmsg3(000, "For %s, reqest index=%d have=%d\n", -// buf, var_index, count); - if (var_index < 0 || var_index > count) { - return VAR_ERR_SUBMATCH_OUT_OF_RANGE; - } - /* Now find the particular item (var_index) he wants */ - count = 1; - for (p=val; *p; ) { - if (*p == '|') { - if (count < var_index) { - val = ++p; - count++; - continue; - } - break; - } - p++; - } - if (p-val > (int)sizeof(buf) - 1) { - return VAR_ERR_OUT_OF_MEMORY; - } -// Dmsg2(000, "val=%s len=%d\n", val, p-val); - /* Make a copy of item, and pass it back */ - v = (char *)malloc(p-val+1); - memcpy(v, val, p-val); - v[p-val] = 0; - *val_ptr = v; - *val_len = p-val; - *val_size = p-val; -// Dmsg1(000, "v=%s\n", v); - return VAR_OK; -} - -/* - * Called here to do a special operation on a variable - * op_ptr points to the special operation code (not EOS terminated) - * arg_ptr points to argument to special op code - * val_ptr points to the value string - * out_ptr points to string to be returned - */ -static var_rc_t operate_var(var_t *var, void *my_ctx, - const char *op_ptr, int op_len, - const char *arg_ptr, int arg_len, - const char *val_ptr, int val_len, - char **out_ptr, int *out_len, int *out_size) -{ - var_rc_t stat = VAR_ERR_UNDEFINED_OPERATION; - Dmsg0(000, "Enter operate_var\n"); - if (!val_ptr) { - *out_size = 0; - return stat; - } - if (op_len == 3 && strncmp(op_ptr, "inc", 3) == 0) { - char buf[MAXSTRING]; - if (val_len > (int)sizeof(buf) - 1) { - return VAR_ERR_OUT_OF_MEMORY; - } - memcpy(buf, arg_ptr, arg_len); - buf[arg_len] = 0; - Dmsg1(000, "Arg=%s\n", buf); - memcpy(buf, val_ptr, val_len); - buf[val_len] = 0; - Dmsg1(000, "Val=%s\n", buf); - LockRes(); - for (COUNTER *counter=NULL; (counter = (COUNTER *)GetNextRes(R_COUNTER, (RES *)counter)); ) { - if (strcmp(counter->hdr.name, buf) == 0) { - Dmsg2(000, "counter=%s val=%s\n", counter->hdr.name, buf); - break; - } - } - UnlockRes(); - return stat; - } - *out_size = 0; - return stat; -} - /* * Perform full substitution on Label */ static int perform_full_name_substitution(JCR *jcr, MEDIA_DBR *mr, POOL_DBR *pr) { - var_t *var_ctx; - var_rc_t stat; - char *inp, *outp; - int in_len, out_len; - int rtn_stat = 0; - - inp = pr->LabelFormat; - in_len = strlen(inp); - - outp = NULL; - out_len = 0; - + int stat = 0; + POOLMEM *label = get_pool_memory(PM_FNAME); jcr->NumVols = pr->NumVols; - /* create context */ - if ((stat = var_create(&var_ctx)) != VAR_OK) { - Jmsg(jcr, M_ERROR, 0, _("Cannot create var context: ERR=%s\n"), var_strerror(var_ctx, stat)); - goto bail_out; - } - /* define callback */ - if ((stat = var_config(var_ctx, VAR_CONFIG_CB_VALUE, lookup_var, (void *)jcr)) != VAR_OK) { - Jmsg(jcr, M_ERROR, 0, _("Cannot set var callback: ERR=%s\n"), var_strerror(var_ctx, stat)); - goto bail_out; + if (variable_expansion(jcr, pr->LabelFormat, &label)) { + bstrncpy(mr->VolumeName, label, sizeof(mr->VolumeName)); + stat = 1; } - - - /* define special operations */ - if ((stat = var_config(var_ctx, VAR_CONFIG_CB_OPERATION, operate_var, (void *)jcr)) != VAR_OK) { - Jmsg(jcr, M_ERROR, 0, _("Cannot set var operate: ERR=%s\n"), var_strerror(var_ctx, stat)); - goto bail_out; - } - - /* unescape in place */ - if ((stat = var_unescape(var_ctx, inp, in_len, inp, in_len+1, 0)) != VAR_OK) { - Jmsg(jcr, M_ERROR, 0, _("Cannot unescape string: ERR=%s\n"), var_strerror(var_ctx, stat)); - goto bail_out; - } - - in_len = strlen(inp); - - /* expand variables */ - if ((stat = var_expand(var_ctx, inp, in_len, &outp, &out_len, 1)) != VAR_OK) { - Jmsg(jcr, M_ERROR, 0, _("Cannot expand LabelFormat \"%s\": ERR=%s\n"), - inp, var_strerror(var_ctx, stat)); - goto bail_out; - } - - /* unescape once more in place */ - if ((stat = var_unescape(var_ctx, outp, out_len, outp, out_len+1, 1)) != VAR_OK) { - Jmsg(jcr, M_ERROR, 0, _("Cannot unescape string: ERR=%s\n"), var_strerror(var_ctx, stat)); - goto bail_out; - } - - bstrncpy(mr->VolumeName, outp, sizeof(mr->VolumeName)); - - rtn_stat = 1; - -bail_out: - /* destroy expansion context */ - if ((stat = var_destroy(var_ctx)) != VAR_OK) { - Jmsg(jcr, M_ERROR, 0, _("Cannot destroy var context: ERR=%s\n"), var_strerror(var_ctx, stat)); - } - if (outp) { - free(outp); - } - return rtn_stat; + free_pool_memory(label); + return stat; } diff --git a/bacula/src/dird/protos.h b/bacula/src/dird/protos.h index 3aed86ca04..364f958e8c 100644 --- a/bacula/src/dird/protos.h +++ b/bacula/src/dird/protos.h @@ -31,8 +31,6 @@ extern int authenticate_user_agent(BSOCK *ua); /* autoprune.c */ extern int do_autoprune(JCR *jcr); extern int prune_volumes(JCR *jcr); -void create_ua_context(JCR *jcr, UAContext *ua); -void free_ua_context(UAContext *ua); /* autorecycle.c */ extern int recycle_oldest_purged_volume(JCR *jcr, MEDIA_DBR *mr); @@ -57,16 +55,20 @@ extern void catalog_update(JCR *jcr, BSOCK *bs, char *buf); /* dird_conf.c */ extern char *level_to_str(int level); +/* expand.c */ +int variable_expansion(JCR *jcr, char *inp, POOLMEM **exp); + + /* 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 send_bootstrap_file(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); /* getmsg.c */ enum e_prtmsg { @@ -86,7 +88,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 int bget_dirmsg(BSOCK *bs); @@ -122,30 +124,32 @@ void prtit(void *ctx, char *msg); /* ua_server.c */ void bsendmsg(void *sock, char *fmt, ...); +UAContext *new_ua_context(JCR *jcr); +void free_ua_context(UAContext *ua); /* 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_media_dbr(UAContext *ua, 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 *automsg, 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_media_dbr(UAContext *ua, 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 *automsg, char *msg, char *prompt, int max_prompt); +CAT *get_catalog_resource(UAContext *ua); STORE *get_storage_resource(UAContext *ua, int use_default); -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 find_arg(UAContext *ua, char *keyword); diff --git a/bacula/src/dird/ua_cmds.c b/bacula/src/dird/ua_cmds.c index 5430903d66..acd33b5d37 100644 --- a/bacula/src/dird/ua_cmds.c +++ b/bacula/src/dird/ua_cmds.c @@ -64,6 +64,8 @@ extern int update_slots(UAContext *ua); /* ua_label.c */ /* Forward referenced functions */ static int add_cmd(UAContext *ua, char *cmd), createcmd(UAContext *ua, char *cmd), cancelcmd(UAContext *ua, char *cmd); static int setdebug_cmd(UAContext *ua, char *cmd); +static int var_cmd(UAContext *ua, char *cmd); +static int estimate_cmd(UAContext *ua, char *cmd); static int help_cmd(UAContext *ua, char *cmd); static int delete_cmd(UAContext *ua, char *cmd); static int use_cmd(UAContext *ua, char *cmd), unmount_cmd(UAContext *ua, char *cmd); @@ -101,6 +103,8 @@ static struct cmdstruct commands[] = { { N_("purge"), purgecmd, _("purge records from catalog")}, { N_("run"), runcmd, _("run ")}, { N_("setdebug"), setdebug_cmd, _("sets debug level")}, + { N_("estimate"), estimate_cmd, _("performs FileSet estimate debug=1 give full listing")}, + { N_("var"), var_cmd, _("does variable expansion")}, { N_("show"), show_cmd, _("show (resource records) [jobs | pools | ... | all]")}, { N_("sqlquery"), sqlquerycmd, _("use SQL to query catalog")}, { N_("status"), statuscmd, _("status [storage | client]=")}, @@ -1161,6 +1165,25 @@ static int setdebug_cmd(UAContext *ua, char *cmd) return 1; } +static int var_cmd(UAContext *ua, char *cmd) +{ + POOLMEM *var = get_pool_memory(PM_FNAME); + for (int i=1; iargc; i++) { + if (ua->argk[i] && variable_expansion(ua->jcr, ua->argk[i], &var)) { + bsendmsg(ua, "%s\n", var); + } + } + free_pool_memory(var); + return 1; +} + +static int estimate_cmd(UAContext *ua, char *cmd) +{ + bsendmsg(ua, "Not yet implemented\n"); + return 1; +} + + /* * print time */ diff --git a/bacula/src/dird/ua_server.c b/bacula/src/dird/ua_server.c index 9c737011a1..070a31575d 100644 --- a/bacula/src/dird/ua_server.c +++ b/bacula/src/dird/ua_server.c @@ -91,6 +91,36 @@ static void *connect_thread(void *arg) return NULL; } +/* + * Create a Job Control Record for a console "job" + * filling in all the appropriate fields. + */ +static JCR *create_console_jcr() +{ + JCR *jcr; + jcr = new_jcr(sizeof(JCR), dird_free_jcr); + jcr->sd_auth_key = bstrdup("dummy"); /* dummy Storage daemon key */ + create_unique_job_name(jcr, "*Console*"); + jcr->sched_time = jcr->start_time; + jcr->JobType = JT_CONSOLE; + jcr->JobLevel = L_FULL; + jcr->JobStatus = JS_Running; + /* None of these are really defined for the Console, so we + * simply take the first of each one. This ensures that there + * will be no null pointer references. + */ + LockRes(); + jcr->job = (JOB *)GetNextRes(R_JOB, NULL); + jcr->messages = (MSGS *)GetNextRes(R_MSGS, NULL); + jcr->client = (CLIENT *)GetNextRes(R_CLIENT, NULL); + jcr->pool = (POOL *)GetNextRes(R_POOL, NULL); + jcr->catalog = (CAT *)GetNextRes(R_CATALOG, NULL); + jcr->store = (STORE *)GetNextRes(R_STORAGE, NULL); + jcr->fileset = (FILESET *)GetNextRes(R_FILESET, NULL); + UnlockRes(); + return jcr; +} + /* * Handle Director User Agent commands * @@ -98,83 +128,103 @@ static void *connect_thread(void *arg) static void *handle_UA_client_request(void *arg) { int stat; - UAContext ua; - BSOCK *UA_sock = (BSOCK *) arg; + UAContext *ua; + JCR *jcr; + BSOCK *UA_sock = (BSOCK *)arg; pthread_detach(pthread_self()); - memset(&ua, 0, sizeof(ua)); - ua.automount = TRUE; - ua.verbose = 1; - ua.jcr = new_jcr(sizeof(JCR), dird_free_jcr); - ua.jcr->sd_auth_key = bstrdup("dummy"); /* dummy Storage daemon key */ - ua.UA_sock = UA_sock; - ua.cmd = get_pool_memory(PM_FNAME); - ua.args = get_pool_memory(PM_FNAME); - - create_unique_job_name(ua.jcr, "*Console*"); - ua.jcr->sched_time = ua.jcr->start_time; - ua.jcr->JobType = JT_CONSOLE; - - bnet_recv(ua.UA_sock); /* Get first message */ - if (!authenticate_user_agent(ua.UA_sock)) { + jcr = create_console_jcr(); + + ua = new_ua_context(jcr); + ua->UA_sock = UA_sock; + + bnet_recv(ua->UA_sock); /* Get first message */ + if (!authenticate_user_agent(ua->UA_sock)) { goto getout; } - while (!ua.quit) { - stat = bnet_recv(ua.UA_sock); + while (!ua->quit) { + stat = bnet_recv(ua->UA_sock); if (stat >= 0) { - ua.cmd = check_pool_memory_size(ua.cmd, ua.UA_sock->msglen+1); - bstrncpy(ua.cmd, ua.UA_sock->msg, ua.UA_sock->msglen+1); - parse_ua_args(&ua); - if (ua.argc > 0 && ua.argk[0][0] == '.') { - do_a_dot_command(&ua, ua.cmd); + ua->cmd = check_pool_memory_size(ua->cmd, ua->UA_sock->msglen+1); + bstrncpy(ua->cmd, ua->UA_sock->msg, ua->UA_sock->msglen+1); + parse_ua_args(ua); + if (ua->argc > 0 && ua->argk[0][0] == '.') { + do_a_dot_command(ua, ua->cmd); } else { - do_a_command(&ua, ua.cmd); + do_a_command(ua, ua->cmd); } - if (!ua.quit) { - if (ua.auto_display_messages) { - strcpy(ua.cmd, "messages"); - qmessagescmd(&ua, ua.cmd); - ua.user_notified_msg_pending = FALSE; - } else if (!ua.user_notified_msg_pending && console_msg_pending) { - bsendmsg(&ua, _("You have messages.\n")); - ua.user_notified_msg_pending = TRUE; + if (!ua->quit) { + if (ua->auto_display_messages) { + strcpy(ua->cmd, "messages"); + qmessagescmd(ua, ua->cmd); + ua->user_notified_msg_pending = FALSE; + } else if (!ua->user_notified_msg_pending && console_msg_pending) { + bsendmsg(ua, _("You have messages.\n")); + ua->user_notified_msg_pending = TRUE; } - bnet_sig(ua.UA_sock, BNET_EOD); /* send end of command */ + bnet_sig(ua->UA_sock, BNET_EOD); /* send end of command */ } - } else if (is_bnet_stop(ua.UA_sock)) { - ua.quit = TRUE; + } else if (is_bnet_stop(ua->UA_sock)) { + ua->quit = TRUE; break; } else { /* signal */ - bnet_sig(ua.UA_sock, BNET_POLL); + bnet_sig(ua->UA_sock, BNET_POLL); } } getout: - if (ua.UA_sock) { - bnet_close(ua.UA_sock); - ua.UA_sock = NULL; - } - close_db(&ua); /* do this before freeing JCR */ + close_db(ua); /* do this before freeing JCR */ + free_ua_context(ua); + free_jcr(jcr); + + return NULL; +} - if (ua.jcr) { - free_jcr(ua.jcr); - ua.jcr = NULL; +/* + * Create a UAContext for a Job that is running so that + * it can the User Agent routines and + * to ensure that the Job gets the proper output. + * This is a sort of mini-kludge, and should be + * unified at some point. + */ +UAContext *new_ua_context(JCR *jcr) +{ + UAContext *ua; + + ua = (UAContext *)malloc(sizeof(UAContext)); + memset(ua, 0, sizeof(UAContext)); + ua->jcr = jcr; + ua->db = jcr->db; + ua->cmd = get_pool_memory(PM_FNAME); + ua->args = get_pool_memory(PM_FNAME); + ua->verbose = 1; + ua->automount = TRUE; + return ua; +} + +void free_ua_context(UAContext *ua) +{ + if (ua->cmd) { + free_pool_memory(ua->cmd); } - if (ua.prompt) { - free(ua.prompt); + if (ua->args) { + free_pool_memory(ua->args); } - if (ua.cmd) { - free_pool_memory(ua.cmd); + if (ua->prompt) { + free(ua->prompt); } - if (ua.args) { - free_pool_memory(ua.args); + + if (ua->UA_sock) { + bnet_close(ua->UA_sock); } - return NULL; + + free(ua); } + /* * Called from main Bacula thread */ diff --git a/bacula/src/dird/verify.c b/bacula/src/dird/verify.c index 605d668d94..7c7c14c354 100644 --- a/bacula/src/dird/verify.c +++ b/bacula/src/dird/verify.c @@ -143,19 +143,19 @@ int do_verify(JCR *jcr) */ if (jcr->JobLevel == L_VERIFY_VOLUME_TO_CATALOG) { RBSR *bsr = new_bsr(); - UAContext ua; + UAContext *ua; bsr->JobId = jr.JobId; - create_ua_context(jcr, &ua); - complete_bsr(&ua, bsr); + ua = new_ua_context(jcr); + complete_bsr(ua, bsr); bsr->fi = new_findex(); bsr->fi->findex = 1; bsr->fi->findex2 = jr.JobFiles; - if (!write_bsr_file(&ua, bsr)) { - free_ua_context(&ua); + if (!write_bsr_file(ua, bsr)) { + free_ua_context(ua); free_bsr(bsr); goto bail_out; } - free_ua_context(&ua); + free_ua_context(ua); free_bsr(bsr); if (jcr->RestoreBootstrap) { free(jcr->RestoreBootstrap); diff --git a/bacula/src/version.h b/bacula/src/version.h index d3d5656088..59137f6c30 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -1,8 +1,8 @@ /* */ #define VERSION "1.31" #define VSTRING "1" -#define BDATE "20 Jun 2003" -#define LSMDATE "20Jun03" +#define BDATE "21 Jun 2003" +#define LSMDATE "21Jun03" /* Debug flags */ #define DEBUG 1 -- 2.39.5