--- /dev/null
+
+This patch try to cleanup MaxConcurrent checks from director
+It's not usable yet.
+
+
+
+Index: src/dird/jobq.c
+===================================================================
+--- src/dird/jobq.c (révision 6325)
++++ src/dird/jobq.c (copie de travail)
+@@ -477,14 +477,14 @@
+ * put into the ready queue.
+ */
+ if (jcr->acquired_resource_locks) {
+- if (jcr->rstore) {
+- jcr->rstore->NumConcurrentJobs = 0;
+- Dmsg1(200, "Dec rncj=%d\n", jcr->rstore->NumConcurrentJobs);
+- }
+- if (jcr->wstore) {
+- jcr->wstore->NumConcurrentJobs--;
+- Dmsg1(200, "Dec wncj=%d\n", jcr->wstore->NumConcurrentJobs);
+- }
++// if (jcr->rstore) {
++// jcr->rstore->NumConcurrentJobs = 0;
++// Dmsg1(200, "Dec rncj=%d\n", jcr->rstore->NumConcurrentJobs);
++// }
++// if (jcr->wstore) {
++// jcr->wstore->NumConcurrentJobs--;
++// Dmsg1(200, "Dec wncj=%d\n", jcr->wstore->NumConcurrentJobs);
++// }
+ jcr->client->NumConcurrentJobs--;
+ jcr->job->NumConcurrentJobs--;
+ jcr->acquired_resource_locks = false;
+@@ -678,69 +678,69 @@
+ */
+ static bool acquire_resources(JCR *jcr)
+ {
+- bool skip_this_jcr = false;
+-
+- jcr->acquired_resource_locks = false;
+- if (jcr->rstore) {
+- Dmsg1(200, "Rstore=%s\n", jcr->rstore->name());
+- /*
+- * Let only one Restore/Verify job run at a time regardless
+- * of MaxConcurrentjobs.
+- */
+- if (jcr->rstore->NumConcurrentJobs == 0) {
+- jcr->rstore->NumConcurrentJobs = 1;
+- Dmsg0(200, "Set rncj=1\n");
+- } else {
+- Dmsg1(200, "Fail rncj=%d\n", jcr->rstore->NumConcurrentJobs);
+- set_jcr_job_status(jcr, JS_WaitStoreRes);
+- return false;
+- }
+- }
+-
+- if (jcr->wstore) {
+- Dmsg1(200, "Wstore=%s\n", jcr->wstore->name());
+- if (jcr->rstore == jcr->wstore) { /* deadlock */
+- jcr->rstore->NumConcurrentJobs = 0; /* back out rstore */
+- Jmsg(jcr, M_FATAL, 0, _("Job canceled. Attempt to read and write same device.\n"
+- " Read storage \"%s\" (From %s) -- Write storage \"%s\" (From %s)\n"),
+- jcr->rstore->name(), jcr->rstore_source, jcr->wstore->name(), jcr->wstore_source);
+- set_jcr_job_status(jcr, JS_Canceled);
+- return false;
+- }
+- if (jcr->wstore->NumConcurrentJobs == 0 &&
+- jcr->wstore->NumConcurrentJobs < jcr->wstore->MaxConcurrentJobs) {
+- /* Simple case, first job */
+- jcr->wstore->NumConcurrentJobs = 1;
+- Dmsg0(200, "Set wncj=1\n");
+- } else if (jcr->wstore->NumConcurrentJobs < jcr->wstore->MaxConcurrentJobs) {
+- jcr->wstore->NumConcurrentJobs++;
+- Dmsg1(200, "Inc wncj=%d\n", jcr->wstore->NumConcurrentJobs);
+- } else if (jcr->rstore) {
+- jcr->rstore->NumConcurrentJobs = 0; /* back out rstore */
+- Dmsg1(200, "Fail wncj=%d\n", jcr->wstore->NumConcurrentJobs);
+- skip_this_jcr = true;
+- } else {
+- Dmsg1(200, "Fail wncj=%d\n", jcr->wstore->NumConcurrentJobs);
+- skip_this_jcr = true;
+- }
+- }
+- if (skip_this_jcr) {
+- set_jcr_job_status(jcr, JS_WaitStoreRes);
+- return false;
+- }
+-
++// bool skip_this_jcr = false;
++//
++// jcr->acquired_resource_locks = false;
++// if (jcr->rstore) {
++// Dmsg1(200, "Rstore=%s\n", jcr->rstore->name());
++// /*
++// * Let only one Restore/Verify job run at a time regardless
++// * of MaxConcurrentjobs.
++// */
++// if (jcr->rstore->NumConcurrentJobs == 0) {
++// jcr->rstore->NumConcurrentJobs = 1;
++// Dmsg0(200, "Set rncj=1\n");
++// } else {
++// Dmsg1(200, "Fail rncj=%d\n", jcr->rstore->NumConcurrentJobs);
++// set_jcr_job_status(jcr, JS_WaitStoreRes);
++// return false;
++// }
++// }
++//
++// if (jcr->wstore) {
++// Dmsg1(200, "Wstore=%s\n", jcr->wstore->name());
++// if (jcr->rstore == jcr->wstore) { /* deadlock */
++// jcr->rstore->NumConcurrentJobs = 0; /* back out rstore */
++// Jmsg(jcr, M_FATAL, 0, _("Job canceled. Attempt to read and write same device.\n"
++// " Read storage \"%s\" (From %s) -- Write storage \"%s\" (From %s)\n"),
++// jcr->rstore->name(), jcr->rstore_source, jcr->wstore->name(), jcr->wstore_source);
++// set_jcr_job_status(jcr, JS_Canceled);
++// return false;
++// }
++// if (jcr->wstore->NumConcurrentJobs == 0 &&
++// jcr->wstore->NumConcurrentJobs < jcr->wstore->MaxConcurrentJobs) {
++// /* Simple case, first job */
++// jcr->wstore->NumConcurrentJobs = 1;
++// Dmsg0(200, "Set wncj=1\n");
++// } else if (jcr->wstore->NumConcurrentJobs < jcr->wstore->MaxConcurrentJobs) {
++// jcr->wstore->NumConcurrentJobs++;
++// Dmsg1(200, "Inc wncj=%d\n", jcr->wstore->NumConcurrentJobs);
++// } else if (jcr->rstore) {
++// jcr->rstore->NumConcurrentJobs = 0; /* back out rstore */
++// Dmsg1(200, "Fail wncj=%d\n", jcr->wstore->NumConcurrentJobs);
++// skip_this_jcr = true;
++// } else {
++// Dmsg1(200, "Fail wncj=%d\n", jcr->wstore->NumConcurrentJobs);
++// skip_this_jcr = true;
++// }
++// }
++// if (skip_this_jcr) {
++// set_jcr_job_status(jcr, JS_WaitStoreRes);
++// return false;
++// }
++//
+ if (jcr->client->NumConcurrentJobs < jcr->client->MaxConcurrentJobs) {
+ jcr->client->NumConcurrentJobs++;
+ } else {
+- /* Back out previous locks */
+- if (jcr->wstore) {
+- jcr->wstore->NumConcurrentJobs--;
+- Dmsg1(200, "Dec wncj=%d\n", jcr->wstore->NumConcurrentJobs);
+- }
+- if (jcr->rstore) {
+- jcr->rstore->NumConcurrentJobs = 0;
+- Dmsg1(200, "Dec rncj=%d\n", jcr->rstore->NumConcurrentJobs);
+- }
++// /* Back out previous locks */
++// if (jcr->wstore) {
++// jcr->wstore->NumConcurrentJobs--;
++// Dmsg1(200, "Dec wncj=%d\n", jcr->wstore->NumConcurrentJobs);
++// }
++// if (jcr->rstore) {
++// jcr->rstore->NumConcurrentJobs = 0;
++// Dmsg1(200, "Dec rncj=%d\n", jcr->rstore->NumConcurrentJobs);
++// }
+ set_jcr_job_status(jcr, JS_WaitClientRes);
+ return false;
+ }
+@@ -748,14 +748,14 @@
+ jcr->job->NumConcurrentJobs++;
+ } else {
+ /* Back out previous locks */
+- if (jcr->wstore) {
+- jcr->wstore->NumConcurrentJobs--;
+- Dmsg1(200, "Dec wncj=%d\n", jcr->wstore->NumConcurrentJobs);
+- }
+- if (jcr->rstore) {
+- jcr->rstore->NumConcurrentJobs = 0;
+- Dmsg1(200, "Dec rncj=%d\n", jcr->rstore->NumConcurrentJobs);
+- }
++// if (jcr->wstore) {
++// jcr->wstore->NumConcurrentJobs--;
++// Dmsg1(200, "Dec wncj=%d\n", jcr->wstore->NumConcurrentJobs);
++// }
++// if (jcr->rstore) {
++// jcr->rstore->NumConcurrentJobs = 0;
++// Dmsg1(200, "Dec rncj=%d\n", jcr->rstore->NumConcurrentJobs);
++// }
+ jcr->client->NumConcurrentJobs--;
+ set_jcr_job_status(jcr, JS_WaitJobRes);
+ return false;
----
bweb :
+ - Voir les groupes d'un client
+ - Overview, pouvoir choisir entre la job_old et l'autre
+ - utiliser des noms de table plus proche (brestore -> bweb ?)
- Balloon
Btw., the vertical axis was the number of files
while the size of the ballon is the volume (in MB
Enable Statistic = yes/no
Statistic retention = 4 years
+ - Accurate backup (kern)
+1. Run bconsole
+2. Dir -> FD run job
+*3. FD does a normal backup and at the same time makes a list of all files on
+the system (in the FileSet), marking which ones were just now backed up.
+4. For each file backed up send attributes/data to SD. Note, this is done
+during step 3 above. Minor difference, the connection with the SD is not
+dropped at the end of the backup -- see later.
+*5. Send the list of all files including those backed up to the Dir
+ --> Send to SD and DIR at the same time ?
+ filed/backup.c/encode_and_send_attributes
+
+6. Dir computes files and deleted files.
+7. Dir sends list of additional files (new files) to backup, and list of files
+deleted.
+8. FD does backup of files Dir says to save.
+9. FD sends SD attrs of backed up files
+10. FD sends SD delete records for files Dir wants deleted.
+*11. FD connection to SD can be closed, this part of the backup is done.
+*12. FD sends new list of files just backed up to Dir
+*13. Dir adds newly backed up files to previous list sent by FD
+*14. Dir "batch" inserts complete new list in the catalog (I forgot the name
+of the new table). Note this table has nothing to do with the File table.
+*15. Dir deletes previous list in catalog.
+*16. Dir does normal batch insert of attributes from SD, but must handle
+deleted records. Note, this will probably happen at the same time as the
+items 13-15.
+
+
o Utiliser une alist dans les runscripts
--- /dev/null
+Index: src/lib/message.c
+===================================================================
+--- src/lib/message.c (révision 6325)
++++ src/lib/message.c (copie de travail)
+@@ -590,6 +590,55 @@
+ return true;
+ }
+
++static bool dispatch_it(JCR *jcr, int type, DEST *d)
++{
++ bool ret=true;
++
++ if (!bit_is_set(type, d->msg_types)) {
++ return false;
++ }
++
++ /* check if M_FILTER are set */
++ int max=0;
++ set_bit(M_MAX, max);
++
++ if (d->msg_types <= max) {
++ return true;
++ }
++
++ /* check this if msg_types contains a level */
++ switch (jcr->JobLevel) {
++ case L_FULL:
++ ret = bit_is_set(M_FILTER_FULL, d->msg_types);
++ break;
++
++ case L_DIFFERENTIAL:
++ ret = bit_is_set(M_FILTER_DIFFERENTIAL, d->msg_types);
++ break;
++
++ case L_INCREMENTAL:
++ ret = bit_is_set(M_FILTER_INCREMENTAL, d->msg_types);
++ break;
++ }
++
++ /* check this if msg_types contains a jobtype */
++ switch (jcr->JobType) {
++ case JT_BACKUP:
++ ret = bit_is_set(M_FILTER_BACKUP, d->msg_types);
++ break;
++ case JT_VERIFY:
++ ret = bit_is_set(M_FILTER_VERIFY, d->msg_types);
++ break;
++ case JT_RESTORE:
++ ret = bit_is_set(M_FILTER_RESTORE, d->msg_types);
++ break;
++ case JT_MIGRATED_JOB:
++ ret = bit_is_set(M_FILTER_MIGRATION, d->msg_types);
++ break;
++ }
++
++}
++
+ /*
+ * Handle sending the message to the appropriate place
+ */
+@@ -649,7 +698,8 @@
+ msgs = daemon_msgs;
+ }
+ for (d=msgs->dest_chain; d; d=d->next) {
+- if (bit_is_set(type, d->msg_types)) {
++ /* check for filter her */
++ if (dispatch_it(jcr, type, d)) {
+ switch (d->dest_code) {
+ case MD_CATALOG:
+ char ed1[50];
+Index: src/lib/message.h
+===================================================================
+--- src/lib/message.h (révision 6325)
++++ src/lib/message.h (copie de travail)
+@@ -97,15 +97,27 @@
+ M_RESTORED, /* ls -l of restored files */
+ M_SECURITY, /* security violation */
+ M_ALERT, /* tape alert messages */
+- M_VOLMGMT /* Volume management messages */
+-};
++ M_VOLMGMT, /* Volume management messages */
+
++ /* following options are used as filter */
++ M_FILTER_VERIFY, /* verify job */
++ M_FILTER_ADMIN, /* admin job */
++ M_FILTER_RESTORE, /* restore job */
++ M_FILTER_MIGRATION, /* migration job */
++ M_FILTER_BACKUP, /* backup job */
++ M_FILTER_INCREMENTAL, /* incremental backup job */
++ M_FILTER_DIFFERENTIAL, /* differential backup job */
++ M_FILTER_FULL, /* full backup job */
++ M_FILTER_ALL /* all */
++};
++
+ #define M_MAX M_VOLMGMT /* keep this updated ! */
+
+ /* Define message destination structure */
+ /* *** FIXME **** where should be extended to handle multiple values */
+ typedef struct s_dest {
+ struct s_dest *next;
++ int filter; /* message filter (M_FILTER_) */
+ int dest_code; /* destination (one of the MD_ codes) */
+ int max_len; /* max mail line length */
+ FILE *fd; /* file descriptor */
+Index: src/lib/parse_conf.c
+===================================================================
+--- src/lib/parse_conf.c (révision 6325)
++++ src/lib/parse_conf.c (copie de travail)
+@@ -152,6 +152,16 @@
+ {"all", M_MAX+1},
+ {NULL, 0}
+ };
++/* following types are used as message filter */
++static struct s_mfilters msg_filters[] = {
++ {"admin", M_FILTER_ADMIN},
++ {"verify" M_FILTER_VERIFY},
++ {"restore", M_FILTER_RESTORE},
++ {"full", M_FILTER_FULL},
++ {"incremental", M_FILTER_INCREMENTAL},
++ {"differential", M_FILTER_DIFFERENTIAL},
++ {NULL, 0}
++};
+
+ /* Used for certain KeyWord tables */
+ struct s_kw {
+@@ -331,6 +341,7 @@
+ int i;
+ bool found, is_not;
+ int msg_type = 0;
++ int msg_filter = 0;
+ char *str;
+
+ for ( ;; ) {