]> git.sur5r.net Git - bacula/bacula/commitdiff
State file debug + full functionality for alist
authorKern Sibbald <kern@sibbald.com>
Tue, 24 Feb 2004 22:16:43 +0000 (22:16 +0000)
committerKern Sibbald <kern@sibbald.com>
Tue, 24 Feb 2004 22:16:43 +0000 (22:16 +0000)
git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@1087 91ce42f0-d328-0410-95d8-f526ca767f89

bacula/src/lib/alist.c
bacula/src/lib/alist.h
bacula/src/lib/bsys.c
bacula/src/lib/jcr.c

index b9425c61143b3e3080ee7b5bd88c82912ca659b7..ea60835b0d771411ef0217d03a8a1b3ed424dcb4 100644 (file)
 #include "bacula.h"
 
 /*
- * Append an item to the list
+ * Private grow list function. Used to insure that 
+ *   at least one more "slot" is available.
  */
-void alist::append(void *item) {
+void alist::grow_list()
+{
    if (num_items == 0) {
       if (num_grow == 0) {
         num_grow = 1;                /* default if not initialized */
@@ -46,9 +48,87 @@ void alist::append(void *item) {
       max_items += num_grow;
       items = (void **)realloc(items, max_items * sizeof(void *));
    }
+}
+
+void *alist::first()
+{
+   cur_item = 1;
+   if (num_items == 0) {
+      return NULL;
+   } else {
+      return items[0];
+   }
+}
+
+void *alist::last()
+{
+   if (num_items == 0) {
+      return NULL;
+   } else {
+      cur_item = num_items;    
+      return items[num_items-1];
+   }
+}
+
+void *alist::next()
+{
+   if (cur_item >= num_items) {
+      return NULL;
+   } else {
+      return items[cur_item++];
+   }
+}
+
+void *alist::prev()
+{
+   if (cur_item <= 1) {
+      return NULL;
+   } else {
+      return items[--cur_item];
+   }
+}
+
+/*
+ * prepend an item to the list
+ */
+void alist::prepend(void *item) {
+   grow_list();
+   if (num_items == 0) {
+      items[num_items++] = item;
+      return;
+   }
+   for (int i=num_items; i > 0; i--) {
+      items[i] = items[i-1];
+   }
+   items[0] = item;
+   num_items++;
+}
+
+
+/*
+ * Append an item to the list
+ */
+void alist::append(void *item) {
+   grow_list();
    items[num_items++] = item;
 }
 
+/* Remove an item from the list */
+void * alist::remove(int index)
+{
+   void *item;
+   if (index < 0 || index >= num_items) {
+      return NULL;
+   }
+   item = items[index];
+   num_items--;
+   for (int i=index; i < num_items; i++) {
+      items[i] = items[i+1];
+   }
+   return item;
+}
+
+
 /* Get the index item -- we should probably allow real indexing here */
 void * alist::get(int index)
 {
index bcce8abe9aa1b322921ff90d13a4b1ca52f180d9..5f02222ced66f157dfee968fcb48c8692f69455b 100644 (file)
 
  */
 
+/* 
+ * There is a lot of extra casting here to work around the fact
+ * that some compilers (Sun and Visual C++) do not accept
+ * (void *) as an lvalue on the left side of an equal.
+ *
+ * Loop var through each member of list
+ */
+#define foreach_alist(var, list) \
+    for((*((void **)&(var))=(void*)((list)->first())); (var); (*((void **)&(var))=(void*)((list)->next())))
+
+#ifdef the_easy_way
+#define foreach_dlist(var, list) \
+        for((void*(var))=(list)->first(); (var); (void *(var))=(list)->next(var)); )
+#endif
+
+
 /* Second arg of init */
 enum {
   owned_by_alist = true,
   not_owned_by_alist = false
 };
 
-
 /* 
  * Array list -- much like a simplified STL vector
  *   array of pointers to inserted items
@@ -40,12 +55,21 @@ class alist {
    int num_items;
    int max_items;
    int num_grow;
+   int cur_item;
    bool own_items;
+   void grow_list(void);
 public:
    alist(int num = 1, bool own=true);
    void init(int num = 1, bool own=true);
    void append(void *item);
+   void prepend(void *item);
+   void *remove(int index);
    void *get(int index);
+   bool empty();
+   void *prev();
+   void *next();
+   void *first();
+   void *last();
    void * operator [](int index) const;
    int size();
    void destroy();
@@ -61,6 +85,11 @@ inline void * alist::operator [](int index) const {
    return items[index];
 }
 
+inline bool alist::empty()
+{
+   return num_items == 0;
+}
+
 /*                            
  * This allows us to do explicit initialization,
  *   allowing us to mix C++ classes inside malloc'ed
index 13a5f8295b71fe8f586a28424344e48bff9c4ed2..7f1cfa1804a1f27de4143649d09ccb9c79a1497b 100644 (file)
@@ -303,7 +303,7 @@ void create_pid_file(char *dir, const char *progname, int port)
    if (stat(mp_chr(fname), &statp) == 0) {
       /* File exists, see what we have */
       *pidbuf = 0;
-      if ((pidfd = open(mp_chr(fname), O_RDONLY)) < 0 || 
+      if ((pidfd = open(mp_chr(fname), O_RDONLY|O_BINARY, 0)) < 0 || 
           read(pidfd, &pidbuf, sizeof(pidbuf)) < 0 ||
            sscanf(pidbuf, "%d", &oldpid) != 1) {
          Emsg2(M_ERROR_TERM, 0, _("Cannot open pid file. %s ERR=%s\n"), fname, strerror(errno));
@@ -317,7 +317,7 @@ void create_pid_file(char *dir, const char *progname, int port)
       unlink(mp_chr(fname));                 /* remove stale pid file */
    }
    /* Create new pid file */
-   if ((pidfd = open(mp_chr(fname), O_CREAT | O_TRUNC | O_WRONLY, 0644)) >= 0) {
+   if ((pidfd = open(mp_chr(fname), O_CREAT | O_TRUNC | O_WRONLY | O_BINARY, 0644)) >= 0) {
       len = sprintf(pidbuf, "%d\n", (int)getpid());
       write(pidfd, pidbuf, len);
       close(pidfd);
@@ -369,23 +369,34 @@ static struct s_state_hdr state_hdr = {
 void read_state_file(char *dir, const char *progname, int port)
 {
    int sfd;
+   ssize_t stat;
    POOLMEM *fname = get_pool_memory(PM_FNAME);
    struct s_state_hdr hdr;
+   int hdr_size = sizeof(hdr);
 
    Mmsg(&fname, "%s/%s.%d.state", dir, progname, port);
    /* If file exists, see what we have */
-   if ((sfd = open(mp_chr(fname), O_RDONLY, 0)) < 0 ||
-       read(sfd, &hdr, sizeof(hdr)) < 0 ||
-       hdr.version != state_hdr.version) {
-      Dmsg2(000, "Could not open or read state file. sfd=%d: ERR=%s\n", 
-                   sfd, strerror(errno));
+   Dmsg1(10, "O_BINARY=%d\n", O_BINARY);
+   if ((sfd = open(mp_chr(fname), O_RDONLY|O_BINARY, 0)) < 0) {
+      Dmsg3(010, "Could not open state file. sfd=%d size=%d: ERR=%s\n", 
+                   sfd, sizeof(hdr), strerror(errno));
+          goto bail_out;
+   }
+   if ((stat=read(sfd, &hdr, hdr_size)) != hdr_size) {
+      Dmsg4(010, "Could not read state file. sfd=%d stat=%d size=%d: ERR=%s\n", 
+                   sfd, (int)stat, hdr_size, strerror(errno));
       goto bail_out;
    }
+   if (hdr.version != state_hdr.version) {
+      Dmsg2(010, "Bad hdr version. Wanted %d got %d\n", 
+        state_hdr.version, hdr.version);
+   }
    hdr.id[13] = 0;
    if (strcmp(hdr.id, state_hdr.id) != 0) {
-      Dmsg0(000, "State file header invalid.\n");
+      Dmsg0(000, "State file header id invalid.\n");
       goto bail_out;
    }
+   Dmsg1(010, "Read header of %d bytes.\n", sizeof(hdr));
    read_last_jobs_list(sfd, hdr.last_jobs_addr);
 bail_out:
    if (sfd >= 0) {
@@ -404,22 +415,27 @@ void write_state_file(char *dir, const char *progname, int port)
 
    Mmsg(&fname, "%s/%s.%d.state", dir, progname, port);
    /* Create new state file */
-   if ((sfd = open(mp_chr(fname), O_CREAT | O_TRUNC | O_WRONLY, 0640)) < 0) {
+   if ((sfd = open(mp_chr(fname), O_CREAT|O_TRUNC|O_WRONLY|O_BINARY, 0640)) < 0) {
       Dmsg2(000, _("Could not create state file. %s ERR=%s\n"), fname, strerror(errno));
       Emsg2(M_ERROR, 0, _("Could not create state file. %s ERR=%s\n"), fname, strerror(errno));
       goto bail_out;
    }
-   if (write(sfd, &state_hdr, sizeof(state_hdr)) < 0) {
-      Dmsg1(000, "Write error: ERR=%s\n", strerror(errno));
+   if (write(sfd, &state_hdr, sizeof(state_hdr)) != sizeof(state_hdr)) {
+      Dmsg1(000, "Write hdr error: ERR=%s\n", strerror(errno));
       goto bail_out;
    }
+   Dmsg1(010, "Wrote header of %d bytes\n", sizeof(state_hdr));
    state_hdr.last_jobs_addr = sizeof(state_hdr);
    state_hdr.reserved[0] = write_last_jobs_list(sfd, state_hdr.last_jobs_addr);   
+   Dmsg1(010, "write last job end = %d\n", (int)state_hdr.reserved[0]);
    if (lseek(sfd, 0, SEEK_SET) < 0) {
       Dmsg1(000, "lseek error: ERR=%s\n", strerror(errno));
       goto bail_out;
    }  
-   write(sfd, &state_hdr, sizeof(state_hdr));
+   if (write(sfd, &state_hdr, sizeof(state_hdr)) != sizeof(state_hdr)) {
+      Dmsg1(000, "Write final hdr error: ERR=%s\n", strerror(errno));
+   }
+
 bail_out:
    if (sfd >= 0) {
       close(sfd);
index 6a283b6537b176e1dde827e87dd61803e5893f2d..00cd0307d9fe4964b581099d183dd5d3a201f619 100755 (executable)
@@ -77,17 +77,20 @@ void read_last_jobs_list(int fd, uint64_t addr)
    struct s_last_job *je, job;
    uint32_t num;
 
+   Dmsg1(010, "read_last_jobs seek to %d\n", (int)addr);
    if (addr == 0 || lseek(fd, addr, SEEK_SET) < 0) {
       return;
    }
-   if (read(fd, &num, sizeof(num)) < 0) {
+   if (read(fd, &num, sizeof(num)) != sizeof(num)) {
       return;
    }
+   Dmsg1(010, "Read num_items=%d\n", num);
    if (num > 4 * MAX_LAST_JOBS) {  /* sanity check */
       return;
    }
    for ( ; num; num--) {
-      if (read(fd, &job, sizeof(job)) < 0) {
+      if (read(fd, &job, sizeof(job)) != sizeof(job)) {
+         Dmsg1(000, "Read job entry. ERR=%s\n", strerror(errno));
         return;
       }
       if (job.JobId > 0) {
@@ -109,17 +112,20 @@ uint64_t write_last_jobs_list(int fd, uint64_t addr)
    struct s_last_job *je;
    uint32_t num;
 
+   Dmsg1(010, "write_last_jobs seek to %d\n", (int)addr);
    if (lseek(fd, addr, SEEK_SET) < 0) {
       return 0;
    }
    if (last_jobs) {
       /* First record is number of entires */
       num = last_jobs->size();
-      if (write(fd, &num, sizeof(num)) < 0) {
+      if (write(fd, &num, sizeof(num)) != sizeof(num)) {
+         Dmsg1(000, "Error writing num_items: ERR=%s\n", strerror(errno));
         return 0;
       }
       foreach_dlist(je, last_jobs) {
-        if (write(fd, je, sizeof(struct s_last_job)) < 0) {
+        if (write(fd, je, sizeof(struct s_last_job)) != sizeof(struct s_last_job)) {
+            Dmsg1(000, "Error writing job: ERR=%s\n", strerror(errno));
            return 0;
         }
       }