]> git.sur5r.net Git - bacula/bacula/commitdiff
Fix SIGTSTP loop in Console, complete hash code
authorKern Sibbald <kern@sibbald.com>
Mon, 28 Jul 2003 20:14:58 +0000 (20:14 +0000)
committerKern Sibbald <kern@sibbald.com>
Mon, 28 Jul 2003 20:14:58 +0000 (20:14 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@649 91ce42f0-d328-0410-95d8-f526ca767f89

bacula/ChangeLog
bacula/kernstodo
bacula/src/console/console.c
bacula/src/dird/jobq.c
bacula/src/findlib/attribs.c
bacula/src/lib/htable.c
bacula/src/lib/htable.h
bacula/src/version.h

index a1fb5767e20ce4a1dde9dfee662916cf01716a69..bec153b2e2294170773ea270f17f45c74399b218 100644 (file)
@@ -1,4 +1,12 @@
 
+2003-07-xx Version 1.31 Beta 28Jul03
+- Add sleep(1) to console when it gets a SIGTSTP signal 
+  to prevent it from using 100% of the CPU.
+- Improve description of Priorities.
+- Add a bit more documentation to jobq.c
+- Complete hash table routine htable.c htable.h
+- Change M_INFO to M_ERROR in attribs.c for Windows errors.
+
 2003-07-23 Version 1.31 Beta 22Jul03
 - Apply a patch from Nic Bellamy that clarifies the error messages 
   during recycling volumes.
index 0a111a1cdcf7f443604f2e287508e2f4d7d08efa..f950c6b98aa1048fcb9e2dcee463c50e36c0c11c 100644 (file)
@@ -1,5 +1,5 @@
                  Kern's ToDo List
-                   14 July 2003 
+                   28 July 2003 
 
 Documentation to do: (any release a little bit at a time)
 - Document running a test version.
@@ -18,6 +18,30 @@ Documentation to do: (any release a little bit at a time)
   (./create_mys... ./make_my...).
 - Document all the status codes JobLevel, JobType, JobStatus.
 - Document dynamic DNS
+- On Fri, 2003-07-25 at 22:39, Thiago Lima wrote:
+    I've just noticed that bacula uses the server time to scan the
+    > clients for new files since the last backup in incremental backup.
+    >     So if server and client clocks aren't synced you may not backup all
+    > files.
+    > 
+    >     Example :
+    > 
+    >     Server time : 16:05
+    >     Client time : 16:00
+    >     runs full backup
+    > 
+    >     Server time : 16:15
+    >     Client time : 16:10 
+    >     runs incremental backup
+    > 
+    >     If there's any file created/changed between 16:00 and 16:05 (client
+    > clock) they will never be backuped.
+    >     The solution is keep all your machines clocks synced.
+    > 
+    >     Is that right? Does anybody have any comments on that? Maybe this
+    > could go to the FAQ?
+    > 
+    > 
           
 Testing to do: (painful)
 - that ALL console command line options work and are always implemented
@@ -32,6 +56,7 @@ Testing to do: (painful)
 For 1.31 release:
 
 
+
 For 1.32:
 - Maybe remove multiple simultaneous devices code in SD.
 - On Windows with very long path names, it may be impossible to create 
@@ -1032,4 +1057,3 @@ Done: (see kernsdone for more)
   (Phil's problem).
 - Increment DB version prior to releasing.
 - Turn off FULL_DEBUG prior to releasing.
-
index b036edc30d70a62ae76b2eafc270dee8b0acd797..769ae122a5139babe1c6bb8dc4838cf31a0696f5 100644 (file)
@@ -442,21 +442,21 @@ wait_for_data(int fd, int sec)
    fd_set fdset;
    struct timeval tv;
 
-   FD_ZERO(&fdset);
-   FD_SET(fd, &fdset);
    tv.tv_sec = sec;
    tv.tv_usec = 0;
    for ( ;; ) {
+      FD_ZERO(&fdset);
+      FD_SET(fd, &fdset);
       switch(select(fd + 1, &fdset, NULL, NULL, &tv)) {
-        case 0:                         /* timeout */
-           return 0;
-        case -1:
-           if (errno == EINTR || errno == EAGAIN) {
-              continue;
-           }
-           return -1;                  /* error return */
-        default:
-           return 1;
+      case 0:                        /* timeout */
+        return 0;
+      case -1:
+        if (errno == EINTR || errno == EAGAIN) {
+           continue;
+        }
+        return -1;                  /* error return */
+      default:
+        return 1;
       }
    }
 }
@@ -480,19 +480,20 @@ get_cmd(FILE *input, char *prompt, BSOCK *sock, int sec)
    }
 again:
    switch (wait_for_data(fileno(input), sec)) {
-      case 0:
-        return 0;                    /* timeout */
-      case -1: 
-        return -1;                   /* error */
-      default:
-        len = sizeof_pool_memory(sock->msg) - 1;
-        if (stop) {
-           goto again;
-        }
-        if (fgets(sock->msg, len, input) == NULL) {
-           return -1;
-        }
-        break;
+   case 0:
+      return 0;                   /* timeout */
+   case -1: 
+      return -1;                  /* error */
+   default:
+      len = sizeof_pool_memory(sock->msg) - 1;
+      if (stop) {
+        sleep(1);
+        goto again;
+      }
+      if (fgets(sock->msg, len, input) == NULL) {
+        return -1;
+      }
+      break;
    }
    strip_trailing_junk(sock->msg);
    sock->msglen = strlen(sock->msg);
index 176893911858cfc1f0cd3b2001271d525f851af4..c416ee7e2bd3e78f3ccf9d06938dc3826d7bbbef 100755 (executable)
@@ -140,7 +140,11 @@ struct wait_pkt {
 };
 
 /*
- * Wait until schedule time arrives before starting
+ * Wait until schedule time arrives before starting. Normally
+ *  this routine is only used for jobs started from the console
+ *  for which the user explicitly specified a start time. Otherwise
+ *  most jobs are put into the job queue only when their
+ *  scheduled time arives.
  */
 static void *sched_wait(void *arg)
 {
@@ -236,6 +240,7 @@ int jobq_add(jobq_t *jq, JCR *jcr)
       }
    }
 
+   /* Ensure that at least one server looks at the queue. */
    stat = start_server(jq);
 
    if (stat == 0) {
@@ -246,7 +251,7 @@ int jobq_add(jobq_t *jq, JCR *jcr)
 }
 
 /*
- *  Remove a job from the job queue
+ *  Remove a job from the job queue. Used only by cancel Console command.
  *    jq is a queue that was created with jobq_init
  *    work_item is an element of work
  *
@@ -294,7 +299,7 @@ int jobq_remove(jobq_t *jq, JCR *jcr)
 
 
 /*
- * Start the server thread 
+ * Start the server thread if it isn't already running
  */
 static int start_server(jobq_t *jq)
 {
@@ -433,7 +438,7 @@ static void *jobq_server(void *arg)
               jobq_add(jq, jcr);     /* queue the job to run again */
               P(jq->mutex);
               free(je);              /* free the job entry */
-              continue;
+              continue;              /* look for another job to run */
            }
            /* 
             * Something was actually backed up, so we cannot reuse
@@ -451,7 +456,7 @@ static void *jobq_server(void *arg)
            njcr->messages = jcr->messages;
             Dmsg0(100, "Call to run new job\n");
            V(jq->mutex);
-           run_job(njcr);
+            run_job(njcr);            /* This creates a "new" job */
            P(jq->mutex);
             Dmsg0(100, "Back from running new job.\n");
         }
@@ -482,9 +487,11 @@ static void *jobq_server(void *arg)
             Dmsg1(100, "Set Job pri=%d\n", Priority);
         }
         /*
-         * Acquire locks
+         * Walk down the list of waiting jobs and attempt
+         *   to acquire the resources it needs.
          */
         for ( ; je;  ) {
+           /* je is current job item on the queue, jn is the next one */
            JCR *jcr = je->jcr;
            jobq_item_t *jn = (jobq_item_t *)jq->waiting_jobs->next(je);
             Dmsg3(100, "Examining Job=%d JobPri=%d want Pri=%d\n",
@@ -518,6 +525,9 @@ static void *jobq_server(void *arg)
               je = jn;
               continue;
            }
+           /* Got all locks, now remove it from wait queue and append it
+            *   to the ready queue  
+            */
            jcr->acquired_resource_locks = true;
            jq->waiting_jobs->remove(je);
            jq->ready_jobs->append(je);
index 9e192c0d01afc5e8c47bf1ea3826c743e035adba..27d92542624ebda39026ee08800cee9853a41d46 100755 (executable)
@@ -416,6 +416,10 @@ static int set_win32_attributes(JCR *jcr, ATTR *attr, BFILE *ofd)
    ULARGE_INTEGER li;
    POOLMEM *win32_ofile;
 
+   if (!p_GetFileAttributesEx) {                                
+      return 0;
+   }
+
    if (!p || !*p) {                  /* we should have attributes */
       Dmsg2(100, "Attributes missing. of=%s ofd=%d\n", attr->ofname, ofd->fid);
       if (is_bopen(ofd)) {
@@ -498,7 +502,7 @@ void win_error(JCR *jcr, char *prefix, POOLMEM *win32_ofile)
                 NULL);
    Dmsg3(100, "Error in %s on file %s: ERR=%s\n", prefix, win32_ofile, msg);
    strip_trailing_junk(msg);
-   Jmsg(jcr, M_INFO, 0, _("Error in %s file %s: ERR=%s\n"), prefix, win32_ofile, msg);
+   Jmsg(jcr, M_ERROR, 0, _("Error in %s file %s: ERR=%s\n"), prefix, win32_ofile, msg);
    LocalFree(msg);
 }
 
@@ -515,7 +519,7 @@ void win_error(JCR *jcr, char *prefix, DWORD lerror)
                 NULL);
    strip_trailing_junk(msg);
    if (jcr) {
-      Jmsg2(jcr, M_INFO, 0, _("Error in %s: ERR=%s\n"), prefix, msg);
+      Jmsg2(jcr, M_ERROR, 0, _("Error in %s: ERR=%s\n"), prefix, msg);
    } else {
       MessageBox(NULL, msg, prefix, MB_OK);
    }
index 790578fa7d6ef8ca29bd2d66e9c0c890f99d1b47..1c4c4bf639e511e681a46d677baaa1aa3c843d3e 100644 (file)
@@ -4,16 +4,17 @@
  *  htable is a hash table of items (pointers). This code is
  *    adapted and enhanced from code I wrote in 1982 for a
  *    relocatable linker.  At that time, the hash table size
- *    was fixed and a primary number, which essentially providing
- *    the hashing. In this program, the hash table can grow when
- *    it gets too full, so the table is a binary number. The
+ *    was fixed and a primary number, which essentially provides
+ *    the randomness. In this program, the hash table can grow when
+ *    it gets too full, so the table size here is a binary number. The
  *    hashing is provided using an idea from Tcl where the initial
- *    hash code is then "randomized" a simple calculation from
+ *    hash code is then "randomized" using a simple calculation from
  *    a random number generator that multiplies by a big number
+ *    (I multiply by a prime number, while Tcl did not)
  *    then shifts the results down and does the binary division
- *    by masking.  Increasing the size of the hash table is simple
- *    simply create a new larger table, walk the old table and
- *    insert each entry into the new table.
+ *    by masking.  Increasing the size of the hash table is simple.
+ *    Just create a new larger table, walk the old table and
+ *    re-hash insert each entry into the new table.
  *
  *               
  *   Kern Sibbald, July MMIII
@@ -65,18 +66,23 @@ void htable::hash_index(char *key)
    return;
 }
 
-htable::htable(void *item, void *link)
+htable::htable(void *item, void *link, int tsize)
 {
-   init(item, link);
+   init(item, link, tsize);
 }
 
-void htable::init(void *item, void *link)
+void htable::init(void *item, void *link, int tsize)
 {
+   int pwr;
+   tsize >>= 2;
+   for (pwr=0; tsize; pwr++) {
+      tsize >>= 1;
+   }
    loffset = (char *)link - (char *)item;
-   mask = 7;                         /* 3 bits => table size = 8 */
-   rshift = 27;                      /* start using bits 28, 29, 30 */
+   mask = ~((~0)<<pwr);              /* 3 bits => table size = 8 */
+   rshift = 30 - pwr;                /* start using bits 28, 29, 30 */
    num_items = 0;                    /* number of entries in table */
-   buckets = 8;                      /* hash table size -- power of two */
+   buckets = 1<<pwr;                 /* hash table size -- power of two */
    max_items = buckets * 4;          /* allow average 4 entries per chain */
    table = (hlink **)malloc(buckets * sizeof(hlink *));
    memset(table, 0, buckets * sizeof(hlink *));
@@ -84,6 +90,52 @@ void htable::init(void *item, void *link)
    walk_index = 0;
 }
 
+void * htable::operator new(size_t)
+{
+   return malloc(sizeof(htable));
+}
+
+void htable::operator delete(void *tbl) 
+{
+   ((htable *)tbl)->destroy();
+   free(tbl);
+}
+
+uint32_t htable::size()
+{
+   return num_items;
+}
+
+void htable::stats() 
+{
+   int count[10];
+   int max = 0;
+   int i, j;
+   hlink *p;
+   printf("\n\nNumItems=%d\nBuckets=%d\n", num_items, buckets);
+   for (i=0; i<10; i++) {
+      count[i] = 0;
+   }
+   for (i=0; i<(int)buckets; i++) {
+      p = table[i];
+      j = 0;    
+      while (p) {
+        p = (hlink *)(p->next);
+        j++;
+      }
+      if (j > max) {
+        max = j;
+      }
+      if (j < 10) {
+        count[j]++;
+      }
+   }
+   for (i=0; i<10; i++) {
+      printf("%2d: %d\n",i, count[i]);
+   }
+   printf("max = %d\n", max);
+}
+
 void htable::grow_table()
 {
    Dmsg1(000, "Grow called old size = %d\n", buckets);
@@ -246,11 +298,11 @@ int main()
    MYJCR *save_jcr = NULL, *item;
    MYJCR *jcr = NULL;
    int count = 0;
-
+    
    jcrtbl = (htable *)malloc(sizeof(htable));
-   jcrtbl->init(jcr, &jcr->link);
+   jcrtbl->init(jcr, &jcr->link, NITEMS);
     
-   Dmsg0(000, "Insert NITEMS items 0-19\n");
+   Dmsg1(000, "Inserting %d items\n", NITEMS);
    for (int i=0; i<NITEMS; i++) {
       sprintf(mkey, "This is htable item %d", i);
       jcr = (MYJCR *)malloc(sizeof(MYJCR));
@@ -268,9 +320,10 @@ int main()
       printf("Item 10's key is: %s\n", item->key);
    }
 
+   jcrtbl->stats();
    printf("Walk the hash table:\n");
    for (MYJCR *jcr=(MYJCR *)jcrtbl->first(); jcr; jcr=(MYJCR *)jcrtbl->next() ) {
-      printf("htable item = %s\n", jcr->key);
+//    printf("htable item = %s\n", jcr->key);
       free(jcr->key);
       count++;
    }
index d1bd82301b9a2dda99169ec7fbaaacaf4775a5cb..e2cb3c3a73d85c466e03c15cf4174fdc70281506 100644 (file)
  *
  */
 
-#define OFFSET(item,link) ((char *)link - (char *)item)
-
 struct hlink {
-   void *next;                       /* next hash item */
-   char *key;                        /* key this item */
-   uint32_t hash;                    /* hash for this key */
+   void *next;                        /* next hash item */
+   char *key;                         /* key this item */
+   uint32_t hash;                     /* hash for this key */
 };
 
 class htable {
-   hlink **table;                    /* hash table */
-   int loffset;                      /* link offset in item */
-   uint32_t num_items;               /* current number of items */
-   uint32_t max_items;               /* maximum items before growing */
-   uint32_t buckets;                 /* size of hash table */
-   uint32_t hash;                    /* temp storage */
-   uint32_t index;                   /* temp storage */
+   hlink **table;                     /* hash table */
+   int loffset;                       /* link offset in item */
+   uint32_t num_items;                /* current number of items */
+   uint32_t max_items;                /* maximum items before growing */
+   uint32_t buckets;                  /* size of hash table */
+   uint32_t hash;                     /* temp storage */
+   uint32_t index;                    /* temp storage */
    uint32_t mask;                     /* "remainder" mask */
-   uint32_t rshift;                  /* amount to shift down */
-   hlink *walkptr;                   /* table walk pointer */
-   uint32_t walk_index;              /* table walk index */
-   void hash_index(char *key);       /* produce hash key,index */
-   void grow_table();                /* grow the table */
+   uint32_t rshift;                   /* amount to shift down */
+   hlink *walkptr;                    /* table walk pointer */
+   uint32_t walk_index;               /* table walk index */
+   void hash_index(char *key);        /* produce hash key,index */
+   void grow_table();                 /* grow the table */
 public:
-   htable(void *item, void *link);
-   void init(void *item, void *link);
+   htable(void *item, void *link, int tsize = 31);
+   void init(void *item, void *link, int tsize = 31);
    bool  insert(char *key, void *item);
    void *lookup(char *key);
-   void *first();                    /* get first item in table */
-   void *next();                     /* get next item in table */
+   void *first();                     /* get first item in table */
+   void *next();                      /* get next item in table */
    void destroy();
+   void stats();                      /* print stats about the table */
+   uint32_t size();                   /* return size of table */
    void * operator new(size_t);
    void operator delete(void *);
 };
index 33f1fd21a35a9c377059cda96bc00225e42aed16..02135eb2704e6332235964d2d7fd9e8b090a6268 100644 (file)
@@ -1,8 +1,8 @@
 /* */
 #define VERSION "1.31"
 #define VSTRING "1"
-#define BDATE   "22 Jul 2003"
-#define LSMDATE "22Jul03"
+#define BDATE   "28 Jul 2003"
+#define LSMDATE "28Jul03"
 
 /* Debug flags */
 #define DEBUG 1