Index: trunk/ippTools/src/pstamptool.c
===================================================================
--- trunk/ippTools/src/pstamptool.c	(revision 29248)
+++ trunk/ippTools/src/pstamptool.c	(revision 29289)
@@ -64,4 +64,7 @@
     break;
 
+// XXX make this a configurable parameter
+#define PSTAMP_MAX_JOB_FAULTS 5
+#define PSTAMP_MAX_DEP_FAULTS 5
 
 int main(int argc, char **argv)
@@ -717,5 +720,6 @@
             outputBase,
             options,
-            dep_id
+            dep_id,
+            0   // fault_count
             )) {
         psError(PS_ERR_UNKNOWN, false, "database error");
@@ -911,4 +915,5 @@
         psStringAppend(&query, "\n %c pstampJob.fault = %d", c, fault);
         c = ',';
+        psStringAppend(&query, ", pstampJob.fault_count = pstampJob.fault_count+ 1");
     }
     
@@ -984,5 +989,8 @@
     pxAddLabelSearchArgs(config, where, "-label", "pstampRequest.label", "LIKE");
 
+    PXOPT_LOOKUP_BOOL(clear_fault_count, config->args, "-clear_fault_count", false);
+
     PXOPT_LOOKUP_BOOL(all, config->args, "-all", false);
+
     // XXX: we don't actually use -limit. It doesn't work for UPDATE
     // it's an allowed arg because add_poll_args adds it
@@ -992,5 +1000,5 @@
     // By default only revert faults < PSTAMP_FIRST_ERROR_CODE which are our "ipp exit codes"
     // codes larger than that are the pstamp request interface.
-    // Don't fault those unless -fault waa provided
+    // Don't fault those unless -fault was explicitly provided
     psString faultClause = psStringCopy("");
     if (!fault) {
@@ -1011,5 +1019,15 @@
     psFree(where);
 
-    if (!p_psDBRunQueryF(config->dbh, query, faultClause)) {
+    // don't keep reverting once the number of faults reaches some value unless 
+    // a parameter asking us to clear that count is provided
+    psString faultCountClause = NULL;
+    if (clear_fault_count) {
+        psStringAppend(&faultCountClause, "\n, pstampJob.fault_count = 0");
+    } else {
+        psStringAppend(&query, " AND pstampJob.fault_count < %d", PSTAMP_MAX_JOB_FAULTS);
+    }
+
+    if (!p_psDBRunQueryF(config->dbh, query, faultCountClause, faultClause)) {
+        psFree(faultCountClause);
         psFree(faultClause);
         psFree(query);
@@ -1019,4 +1037,6 @@
 
     psFree(faultClause);
+    psFree(faultCountClause);
+    psFree(query);
 
     return true;
@@ -1223,5 +1243,6 @@
         need_magic,
         outdir,
-        0               // fault
+        0,              // fault
+        0               // fault_count
         )) {
         if (!psDBRollback(config->dbh)) {
@@ -1345,4 +1366,5 @@
         psStringAppend(&query, "%s fault = %d", needComma ? ", " : "", fault);
         needComma = true;
+        psStringAppend(&query, ", pstampDependent.fault_count = pstampDependent.fault_count + 1");
     }
     psStringAppend(&query, " WHERE dep_id = %" PRId64, dep_id);
@@ -1373,4 +1395,5 @@
     PXOPT_COPY_S64(config->args, where, "-req_id", "req_id", "==");
     pxAddLabelSearchArgs(config, where, "-label", "pstampRequest.label", "==");
+    PXOPT_LOOKUP_BOOL(clear_fault_count, config->args, "-clear_fault_count", false);
 
     // XXX: we don't actually use -limit. It doesn't work for UPDATE
@@ -1403,5 +1426,15 @@
     }
 
-    if (!p_psDBRunQuery(config->dbh, query)) {
+    // don't keep reverting once the number of faults reaches some value unless 
+    // a parameter asking us to clear that count is provided
+    psString faultCountClause = NULL;
+    if (clear_fault_count) {
+        psStringAppend(&faultCountClause, "\n, pstampDependent.fault_count = 0");
+    } else {
+        psStringAppend(&faultCountClause, " ");
+        psStringAppend(&query, " AND pstampDependent.fault_count < %d", PSTAMP_MAX_DEP_FAULTS);
+    }
+
+    if (!p_psDBRunQueryF(config->dbh, query, faultCountClause)) {
         psError(PS_ERR_UNKNOWN, false, "database error");
         psFree(query);
