From ad1e0079e2572c8a4d17abd765ca3de291f7b8d7 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Tue, 24 Feb 2004 22:16:43 +0000 Subject: [PATCH] State file debug + full functionality for alist git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@1087 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/src/lib/alist.c | 84 +++++++++++++++++++++++++++++++++++++++++- bacula/src/lib/alist.h | 31 +++++++++++++++- bacula/src/lib/bsys.c | 40 ++++++++++++++------ bacula/src/lib/jcr.c | 14 +++++-- 4 files changed, 150 insertions(+), 19 deletions(-) diff --git a/bacula/src/lib/alist.c b/bacula/src/lib/alist.c index b9425c6114..ea60835b0d 100644 --- a/bacula/src/lib/alist.c +++ b/bacula/src/lib/alist.c @@ -33,9 +33,11 @@ #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) { diff --git a/bacula/src/lib/alist.h b/bacula/src/lib/alist.h index bcce8abe9a..5f02222ced 100644 --- a/bacula/src/lib/alist.h +++ b/bacula/src/lib/alist.h @@ -24,13 +24,28 @@ */ +/* + * 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 diff --git a/bacula/src/lib/bsys.c b/bacula/src/lib/bsys.c index 13a5f8295b..7f1cfa1804 100644 --- a/bacula/src/lib/bsys.c +++ b/bacula/src/lib/bsys.c @@ -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); diff --git a/bacula/src/lib/jcr.c b/bacula/src/lib/jcr.c index 6a283b6537..00cd0307d9 100755 --- a/bacula/src/lib/jcr.c +++ b/bacula/src/lib/jcr.c @@ -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; } } -- 2.39.2