From 86863983d476fd6f640f0bf44d26a10c5d1e10a3 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Sun, 9 Nov 2003 20:07:39 +0000 Subject: [PATCH] See kes-1.33 09Nov03 for details; fix multiple slots, | in Include git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@803 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/kernstodo | 49 ++++++++++++++++++++---------------- bacula/src/cats/protos.h | 5 ++-- bacula/src/cats/sql_create.c | 6 ++++- bacula/src/cats/sql_update.c | 24 ++++++++++++++++-- bacula/src/dird/fd_cmds.c | 1 + bacula/src/dird/next_vol.c | 31 ++++++++++++++++++----- bacula/src/dird/ua_cmds.c | 36 +++++++++++++++----------- bacula/src/filed/job.c | 1 + bacula/src/lib/daemon.c | 2 +- bacula/src/version.h | 4 +-- 10 files changed, 108 insertions(+), 51 deletions(-) diff --git a/bacula/kernstodo b/bacula/kernstodo index 34093ca3d3..6459cf9e2d 100644 --- a/bacula/kernstodo +++ b/bacula/kernstodo @@ -24,6 +24,33 @@ Testing to do: (painful) - Figure out how to use ssh or stunnel to protect Bacula communications. For 1.33 Testing/Documentation: +- Document new alias records in Director. SDAddress SDDeviceName, SDPassword. + FDPassword, FDAddress, DBAddress, DBPort, DBPassword. +- Document new Include/Exclude ... +- Add test of exclusion, test multiple Include {} statements. +- Add counter variable test. +- Document ln -sf /usr/lib/libncurses.so /usr/lib/libtermcap.so + and install the esound-dev  package for compiling Console on SuSE. +- Add an example of using a FIFO in dirdconf.wml +- Add an item to the FAQ about running jobs in different timezones. +- Add some examples of job editing codes. +- Add Dan's 31 Oct 2003 email on tcpwrappers to Tips. +- Add to supported autochangers + OS             : FreeBSD-4.9 + Auto-Changer    : QUALSTAR TLS-4210 +   Manufufactur  : Qualstar +   Tapes         : 12 (AIT1: 36GB, AIT2: 50GB all uncompressed) +   Drives        : 2xAIT2 (installed in the Qualstar: SONY SDX-500C AIT2) +- Setup a standard job that builds a bootstrap file and saves + it with the catalog database. +- Document Dan's new --with-dir-user, ... options. + + +For 1.33 +- Add a default DB password to MySQL. + GRANT all privileges ON bacula.* TO bacula@localhost IDENTIFIED BY + 'bacula_password'; + FLUSH PRIVILEGES; - Define week of year for scheduler. W01, W02, ... Week 01 of a year is per definition the first week that has the Thursday in this year, which is equivalent to the week that contains the @@ -63,28 +90,6 @@ For 1.33 Testing/Documentation: it to tape. - Scratch Pool where the volumes can be re-assigned to any Pool. - bextract is sending everything to the log file ****FIXME**** -- Document new alias records in Director. SDAddress SDDeviceName, SDPassword. - FDPassword, FDAddress, DBAddress, DBPort, DBPassword. -- Document new Include/Exclude ... -- Add test of exclusion, test multiple Include {} statements. -- Add counter variable test. -- Document ln -sf /usr/lib/libncurses.so /usr/lib/libtermcap.so - and install the esound-dev  package for compiling Console on SuSE. -- Add an example of using a FIFO in dirdconf.wml -- Add an item to the FAQ about running jobs in different timezones. -- Add some examples of job editing codes. -- Add Dan's 31 Oct 2003 email on tcpwrappers to Tips. -- Add to supported autochangers - OS             : FreeBSD-4.9 - Auto-Changer    : QUALSTAR TLS-4210 -   Manufufactur  : Qualstar -   Tapes         : 12 (AIT1: 36GB, AIT2: 50GB all uncompressed) -   Drives        : 2xAIT2 (installed in the Qualstar: SONY SDX-500C AIT2) -- Setup a standard job that builds a bootstrap file and saves - it with the catalog database. -- Document Dan's new --with-dir-user, ... options. - -For 1.33 - Add Progress command that periodically reports the progress of a job or all jobs. - Restrict characters permitted in a Resource name, and don't permit diff --git a/bacula/src/cats/protos.h b/bacula/src/cats/protos.h index ab233e474a..441947369c 100644 --- a/bacula/src/cats/protos.h +++ b/bacula/src/cats/protos.h @@ -31,7 +31,7 @@ /* sql.c */ B_DB *db_init_database(JCR *jcr, char *db_name, char *db_user, char *db_password, - char *db_address, int db_port, char *db_socket); + char *db_address, int db_port, char *db_socket); int db_open_database(JCR *jcr, B_DB *db); void db_close_database(JCR *jcr, B_DB *db); void db_escape_string(char *snew, char *old, int len); @@ -51,7 +51,7 @@ int db_create_job_record(JCR *jcr, B_DB *db, JOB_DBR *jr); int db_create_media_record(JCR *jcr, B_DB *db, MEDIA_DBR *media_dbr); int db_create_client_record(JCR *jcr, B_DB *db, CLIENT_DBR *cr); int db_create_fileset_record(JCR *jcr, B_DB *db, FILESET_DBR *fsr); -int db_create_pool_record(JCR *jcr, B_DB *db, POOL_DBR *pool_dbr); +int db_create_pool_record(JCR *jcr, B_DB *db, POOL_DBR *pool_dbr); int db_create_jobmedia_record(JCR *jcr, B_DB *mdb, JOBMEDIA_DBR *jr); int db_create_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr); @@ -105,5 +105,6 @@ int db_update_media_record(JCR *jcr, B_DB *db, MEDIA_DBR *mr); int db_update_counter_record(JCR *jcr, B_DB *mdb, COUNTER_DBR *cr); int db_add_SIG_to_file_record(JCR *jcr, B_DB *mdb, FileId_t FileId, char *SIG, int type); int db_mark_file_record(JCR *jcr, B_DB *mdb, FileId_t FileId, JobId_t JobId); +void db_make_slot_unique(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr); #endif /* __SQL_PROTOS_H */ diff --git a/bacula/src/cats/sql_create.c b/bacula/src/cats/sql_create.c index 80ea509e25..2cca2d6e4c 100644 --- a/bacula/src/cats/sql_create.c +++ b/bacula/src/cats/sql_create.c @@ -227,7 +227,8 @@ VALUES ('%s',%u,%u,%d,%d,%d,%d,%d,%s,%s,%u,%u,%s,'%s','%s')", /* - * Create Unique Media record + * Create Media record. VolumeName and non-zero Slot must be unique + * * Returns: 0 on failure * 1 on success */ @@ -255,6 +256,9 @@ db_create_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr) sql_free_result(mdb); } + /* Make sur Slot, if non-zero, is unique */ + db_make_slot_unique(jcr, mdb, mr); + /* Must create it */ if (mr->LabelDate) { localtime_r(&mr->LabelDate, &tm); diff --git a/bacula/src/cats/sql_update.c b/bacula/src/cats/sql_update.c index 4acb2b8f59..b37efec6c5 100644 --- a/bacula/src/cats/sql_update.c +++ b/bacula/src/cats/sql_update.c @@ -267,10 +267,13 @@ db_update_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr) } localtime_r(&ttime, &tm); strftime(dt, sizeof(dt), "%Y-%m-%d %T", &tm); - Mmsg(&mdb->cmd, "UPDATE Media SET LabelDate='%s'\ - WHERE VolumeName='%s'", dt, mr->VolumeName); + Mmsg(&mdb->cmd, "UPDATE Media SET LabelDate='%s' " + "WHERE VolumeName='%s'", dt, mr->VolumeName); stat = UPDATE_DB(jcr, mdb, mdb->cmd); } + + /* Make sure Slot, if non-zero, is unique */ + db_make_slot_unique(jcr, mdb, mr); ttime = mr->LastWritten; localtime_r(&ttime, &tm); @@ -292,4 +295,21 @@ db_update_media_record(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr) return stat; } +/* + * If we have a non-zero Slot, ensure that no other Media + * record in this Pool has the same Slot by setting Slot=0. + * + * This routine assumes the database is already locked. + */ +void +db_make_slot_unique(JCR *jcr, B_DB *mdb, MEDIA_DBR *mr) +{ + if (mr->Slot != 0) { + Mmsg(&mdb->cmd, "UPDATE Media SET Slot=0 WHERE PoolId=%u " + "AND Slot=%d\n", mr->PoolId, mr->Slot); + Dmsg1(400, "%s\n", mdb->cmd); + UPDATE_DB(jcr, mdb, mdb->cmd); + } +} + #endif /* HAVE_MYSQL || HAVE_SQLITE */ diff --git a/bacula/src/dird/fd_cmds.c b/bacula/src/dird/fd_cmds.c index 386aba318c..25c3b9cf05 100644 --- a/bacula/src/dird/fd_cmds.c +++ b/bacula/src/dird/fd_cmds.c @@ -251,6 +251,7 @@ static int send_list(JCR *jcr, int list) p = (char *)ie->name_list.get(j); switch (*p) { case '|': + p++; /* skip over the | */ fd->msg = edit_job_codes(jcr, fd->msg, p, ""); bpipe = open_bpipe(fd->msg, 0, "r"); if (!bpipe) { diff --git a/bacula/src/dird/next_vol.c b/bacula/src/dird/next_vol.c index 65a9a3bfa8..0213c3c2e1 100644 --- a/bacula/src/dird/next_vol.c +++ b/bacula/src/dird/next_vol.c @@ -42,7 +42,8 @@ */ int find_next_volume_for_append(JCR *jcr, MEDIA_DBR *mr, int create) { - int ok, retry = 0; + int retry = 0; + bool ok; mr->PoolId = jcr->PoolId; bstrncpy(mr->MediaType, jcr->store->media_type, sizeof(mr->MediaType)); @@ -53,22 +54,35 @@ int find_next_volume_for_append(JCR *jcr, MEDIA_DBR *mr, int create) db_lock(jcr->db); for ( ;; ) { bstrncpy(mr->VolStatus, "Append", sizeof(mr->VolStatus)); /* want only appendable volumes */ + /* + * 1. Look for volume with "Append" status. + */ ok = db_find_next_volume(jcr, jcr->db, 1, mr); Dmsg2(100, "catreq after find_next_vol ok=%d FW=%d\n", ok, mr->FirstWritten); if (!ok) { - /* Well, try finding recycled volumes */ + /* + * 2. Try finding a recycled volume + */ ok = find_recycled_volume(jcr, mr); Dmsg2(100, "find_recycled_volume %d FW=%d\n", ok, mr->FirstWritten); if (!ok) { + /* + * 3. Try pruning Volumes + */ prune_volumes(jcr); ok = recycle_oldest_purged_volume(jcr, mr); Dmsg2(200, "find_recycled_volume2 %d FW=%d\n", ok, mr->FirstWritten); if (!ok && create) { - /* See if we can create a new Volume */ + /* + * 4. Try "creating" a new Volume + */ ok = newVolume(jcr, mr); } } + /* + * Look at more drastic ways to find an Appendable Volume + */ if (!ok && (jcr->pool->purge_oldest_volume || jcr->pool->recycle_oldest_volume)) { Dmsg2(200, "No next volume found. PurgeOldest=%d\n RecyleOldest=%d", @@ -79,12 +93,17 @@ int find_next_volume_for_append(JCR *jcr, MEDIA_DBR *mr, int create) if (ok) { UAContext *ua; Dmsg0(400, "Try purge.\n"); - /* Try to purge oldest volume */ + /* + * 5. Try to purging oldest volume only if not UA calling us. + */ ua = new_ua_context(jcr); - if (jcr->pool->purge_oldest_volume) { + if (jcr->pool->purge_oldest_volume && create) { Jmsg(jcr, M_INFO, 0, _("Purging oldest volume \"%s\"\n"), mr->VolumeName); ok = purge_jobs_from_volume(ua, mr); - } else { + /* + * 5. or try recycling the oldest volume + */ + } else if (jcr->pool->recycle_oldest_volume) { Jmsg(jcr, M_INFO, 0, _("Pruning oldest volume \"%s\"\n"), mr->VolumeName); ok = prune_volume(ua, mr); } diff --git a/bacula/src/dird/ua_cmds.c b/bacula/src/dird/ua_cmds.c index 1a5b426a3a..0e36adb67d 100644 --- a/bacula/src/dird/ua_cmds.c +++ b/bacula/src/dird/ua_cmds.c @@ -804,20 +804,22 @@ static void update_volrecycle(UAContext *ua, char *val, MEDIA_DBR *mr) static void update_volpool(UAContext *ua, char *val, MEDIA_DBR *mr) { POOL_DBR pr; - POOLMEM *query; + memset(&pr, 0, sizeof(pr)); bstrncpy(pr.Name, val, sizeof(pr.Name)); if (!get_pool_dbr(ua, &pr)) { return; } - query = get_pool_memory(PM_MESSAGE); - Mmsg(&query, "UPDATE Media SET PoolId=%u WHERE MediaId=%u", pr.PoolId, mr->MediaId); - if (!db_sql_query(ua->db, query, NULL, NULL)) { - bsendmsg(ua, "%s", db_strerror(ua->db)); - } else { + mr->PoolId = pr.PoolId; /* set new PoolId */ + /* + * Make sure to use db_update... rather than doing this directly, + * so that any Slot is handled correctly. + */ + if (!db_update_media_record(ua->jcr, ua->db, mr)) { + bsendmsg(ua, _("Error updating media record Pool: ERR=%s"), db_strerror(ua->db)); + } else { bsendmsg(ua, _("New Pool is: %s\n"), pr.Name); } - free_pool_memory(query); } /* @@ -987,15 +989,16 @@ static int update_volume(UAContext *ua) pr.MaxVols); break; } - query = get_pool_memory(PM_MESSAGE); - Mmsg(&query, "UPDATE Media SET Slot=%d WHERE MediaId=%u", - slot, mr.MediaId); - if (!db_sql_query(ua->db, query, NULL, NULL)) { - bsendmsg(ua, "%s", db_strerror(ua->db)); + mr.Slot = slot; + /* + * Make sure to use db_update... rather than doing this directly, + * so that any Slot is handled correctly. + */ + if (!db_update_media_record(ua->jcr, ua->db, &mr)) { + bsendmsg(ua, _("Error updating media record Slot: ERR=%s"), db_strerror(ua->db)); } else { - bsendmsg(ua, "New Slot is: %d\n", slot); + bsendmsg(ua, _("New Slot is: %s\n"), mr.Slot); } - free_pool_memory(query); break; case 8: /* Volume Files */ @@ -1755,6 +1758,9 @@ void close_db(UAContext *ua) { if (ua->db) { db_close_database(ua->jcr, ua->db); + ua->db = NULL; + if (ua->jcr) { + ua->jcr->db = NULL; + } } - ua->db = NULL; } diff --git a/bacula/src/filed/job.c b/bacula/src/filed/job.c index 411a22f5e8..fb0b90ab11 100644 --- a/bacula/src/filed/job.c +++ b/bacula/src/filed/job.c @@ -436,6 +436,7 @@ static void add_fname_to_list(JCR *jcr, char *fname, int list) switch (*p) { case '|': + p++; /* skip over | */ fn = get_pool_memory(PM_FNAME); fn = edit_job_codes(jcr, fn, p, ""); bpipe = open_bpipe(fn, 0, "r"); diff --git a/bacula/src/lib/daemon.c b/bacula/src/lib/daemon.c index 7008d129ba..20dc2fdf52 100644 --- a/bacula/src/lib/daemon.c +++ b/bacula/src/lib/daemon.c @@ -41,7 +41,7 @@ daemon_start() { #ifndef HAVE_CYGWIN int i; - int cpid; + pid_t cpid; mode_t oldmask; /* * Become a daemon. diff --git a/bacula/src/version.h b/bacula/src/version.h index 12cbc3be1a..898808ce96 100644 --- a/bacula/src/version.h +++ b/bacula/src/version.h @@ -2,8 +2,8 @@ #undef VERSION #define VERSION "1.33" #define VSTRING "1" -#define BDATE "06 Nov 2003" -#define LSMDATE "06Nov03" +#define BDATE "09 Nov 2003" +#define LSMDATE "09Nov03" /* Debug flags */ #undef DEBUG -- 2.39.5