Kern's ToDo List
- 17 January 2003
+ 20 January 2003
Documentation to do: (a little bit at a time)
- Document running a test version.
- blocksize recognition code.
For 1.29 release:
+- Look at handling <> in smtp doesn't work with exim.
+- InitVerify is getting pruned and it shouldn't
- Priority job to go to top of list.
- Implement Bar code handling
- Why is catreq.c:111 Find vol called twice for a job?
Storage = DLTDrive
Messages = Standard
Pool = Default
+ Write Bootstrap = "@working_dir@/NightlySave.bsr"
}
# Backup the catalog database (after the nightly save)
RunBeforeJob = "@sysconfdir@/make_catalog_backup"
# This deletes the copy of the catalog
RunAfterJob = "@sysconfdir@/delete_catalog_backup"
+ Write Bootstrap = "@working_dir@/BackupCatalog.bsr"
}
# Standard Restore template, to be changed by Console program
}
}
-
# Client (File Services) to backup
Client {
Name = @hostname@-fd
FDPort = @fd_port@
Catalog = MyCatalog
Password = "@fd_password@" # password for FileDaemon
- File Retention = 180d # six months
- Job Retention = 365d # one year
+ File Retention = 30d # 30 days
+ Job Retention = 180d # six months
AutoPrune = yes # Prune expired Jobs/Files
}
mail = @job_email@ = all, !skipped
operator = @job_email@ = mount
console = all, !skipped, !saved
+#
+# WARNING! the following will create a file that you must cycle from
+# time to time as it will grow indefinitely. However, it will
+# also keep all your messages if the scroll off the console.
+#
+ append = "@working_dir@/log" = all, !skipped
}
# Default pool definition
next_volume:
strcpy(mr.VolStatus, "Append"); /* want only appendable volumes */
ok = db_find_next_volume(jcr, jcr->db, index, &mr);
- Dmsg1(200, "catreq after find_next_vol ok=%d\n", ok);
+ Dmsg2(100, "catreq after find_next_vol ok=%d FW=%d\n", ok, mr.FirstWritten);
if (!ok) {
/* Well, try finding recycled tapes */
ok = find_recycled_volume(jcr, &mr);
- Dmsg1(100, "find_recycled_volume1 %d\n", ok);
+ Dmsg2(100, "find_recycled_volume1 %d FW=%d\n", ok, mr.FirstWritten);
if (!ok) {
prune_volumes(jcr);
ok = recycle_a_volume(jcr, &mr);
- Dmsg1(100, "find_recycled_volume2 %d\n", ok);
+ Dmsg2(200, "find_recycled_volume2 %d FW=%d\n", ok, mr.FirstWritten);
if (!ok) {
/* See if we can create a new Volume */
ok = newVolume(jcr, &mr);
}
}
/* Check if use duration has expired */
- Dmsg2(200, "VolJobs=%d FirstWritten=%d\n", mr.VolJobs, mr.FirstWritten);
+ Dmsg2(100, "VolJobs=%d FirstWritten=%d\n", mr.VolJobs, mr.FirstWritten);
if (ok && mr.VolJobs > 0 && mr.VolUseDuration > 0 &&
strcmp(mr.VolStatus, "Recycle") != 0) {
utime_t now = time(NULL);
return 0;
}
if (tm.tm_year >= 1900) {
+ tm.tm_year -= 1900;
} else {
return 0;
}
/* watchdog.c */
int start_watchdog(void);
int stop_watchdog(void);
-void stop_child_timer(btimer_id wid);
btimer_t *start_child_timer(pid_t pid, uint32_t wait);
+void stop_child_timer(btimer_id wid);
+btimer_id start_thread_timer(pthread_t tid, uint32_t wait);
+void stop_thread_timer(btimer_id wid);
+
buf[nbytes - 1] = (((long) buf) & 0xFF) ^ 0xC5;
buf += HEAD_SIZE; /* Increment to user data start */
V(mutex);
+ } else {
+ Emsg0(M_ABORT, 0, _("Out of memory\n"));
}
Dmsg4(1150, "smalloc %d at %x from %s:%d\n", nbytes, buf, fname, lineno);
return (void *)buf;
"designer garbage" consisting of alternating bits. */
memset(buf, 0x55, (int) nbytes);
+ } else {
+ Emsg0(M_ABORT, 0, _("Out of memory\n"));
}
return buf;
}
if ((buf = smalloc(fname, lineno, nelem * elsize)) != NULL) {
memset(buf, 0, (int) (nelem * elsize));
+ } else {
+ Emsg0(M_ABORT, 0, _("Out of memory\n"));
}
return buf;
}
malloc(). SVID is silent on this, but many C libraries
permit this. */
- if (ptr == NULL)
+ if (ptr == NULL) {
return sm_malloc(fname, lineno, size);
+ }
/* If the old and new sizes are the same, be a nice guy and just
return the buffer passed in. */
/* Forward referenced functions */
static void *btimer_thread(void *arg);
+static void stop_btimer(btimer_id wid);
+static btimer_id btimer_start_common(uint32_t wait);
/* Static globals */
static pthread_mutex_t mutex;
static pthread_cond_t timer;
static int quit;
-static btimer_t *child_chain = NULL;
+static btimer_t *timer_chain = NULL;
/*
now = time(NULL);
/* Walk child chain killing off any process overdue */
- for (wid = child_chain; wid; wid=wid->next) {
+ for (wid = timer_chain; wid; wid=wid->next) {
int killed = FALSE;
/* First ask him politely to go away */
if (!wid->killed && now > (wid->start_time + wid->wait)) {
// Dmsg1(000, "Watchdog sigterm pid=%d\n", wid->pid);
- kill(wid->pid, SIGTERM);
- killed = TRUE;
+ if (wid->type == TYPE_CHILD) {
+ kill(wid->pid, SIGTERM);
+ killed = TRUE;
+ } else {
+ pthread_kill(wid->tid, TIMEOUT_SIGNAL);
+ wid->killed = TRUE;
+ }
}
- /* If we asked somone to die, wait 3 seconds and slam him */
+ /* If we asked a child to die, wait 3 seconds and slam him */
if (killed) {
btimer_t *wid1;
sleep(3);
- for (wid1 = child_chain; wid1; wid1=wid1->next) {
- if (!wid1->killed && now > (wid1->start_time + wid1->wait)) {
+ for (wid1 = timer_chain; wid1; wid1=wid1->next) {
+ if (wid->type == TYPE_CHILD &&
+ !wid1->killed && now > (wid1->start_time + wid1->wait)) {
kill(wid1->pid, SIGKILL);
// Dmsg1(000, "Watchdog killed pid=%d\n", wid->pid);
wid1->killed = TRUE;
* NULL on failure
*/
btimer_id start_child_timer(pid_t pid, uint32_t wait)
+{
+ btimer_t *wid;
+ wid = btimer_start_common(wait);
+ wid->pid = pid;
+ wid->type = TYPE_CHILD;
+ return wid;
+}
+
+/*
+ * Start a timer on a thread. kill it after wait seconds.
+ * NOTE! Granularity is SLEEP_TIME (i.e. 30 seconds)
+ *
+ * Returns: btimer_id (pointer to btimer_t struct) on success
+ * NULL on failure
+ */
+btimer_id start_thread_timer(pthread_t tid, uint32_t wait)
+{
+ btimer_t *wid;
+ wid = btimer_start_common(wait);
+ wid->tid = tid;
+ wid->type = TYPE_PTHREAD;
+ return wid;
+}
+
+static btimer_id btimer_start_common(uint32_t wait)
{
btimer_id wid = (btimer_id)malloc(sizeof(btimer_t));
P(mutex);
- /* Chain it into child_chain as the first item */
+ /* Chain it into timer_chain as the first item */
wid->prev = NULL;
- wid->next = child_chain;
- if (child_chain) {
- child_chain->prev = wid;
+ wid->next = timer_chain;
+ if (timer_chain) {
+ timer_chain->prev = wid;
}
- child_chain = wid;
+ timer_chain = wid;
wid->start_time = time(NULL);
wid->wait = wait;
- wid->pid = pid;
wid->killed = FALSE;
Dmsg2(200, "Start child timer 0x%x for %d secs.\n", wid, wait);
V(mutex);
* Stop child timer
*/
void stop_child_timer(btimer_id wid)
+{
+ stop_btimer(wid);
+}
+
+/*
+ * Stop thread timer
+ */
+void stop_thread_timer(btimer_id wid)
+{
+ stop_btimer(wid);
+}
+
+
+/*
+ * Stop btimer
+ */
+static void stop_btimer(btimer_id wid)
{
if (wid == NULL) {
Emsg0(M_ABORT, 0, _("NULL btimer_id.\n"));
}
P(mutex);
- /* Remove wid from child_chain */
+ /* Remove wid from timer_chain */
if (!wid->prev) { /* if no prev */
- child_chain = wid->next; /* set new head */
+ timer_chain = wid->next; /* set new head */
} else {
wid->prev->next = wid->next; /* update prev */
}
wid->next->prev = wid->prev; /* unlink it */
}
V(mutex);
- Dmsg2(200, "Stop child timer 0x%x for %d secs.\n", wid, wid->wait);
+ Dmsg2(200, "Stop timer 0x%x for %d secs.\n", wid, wid->wait);
free(wid);
}
*/
+#define TYPE_CHILD 1
+#define TYPE_PTHREAD 2
+
typedef struct s_btimer_t {
struct s_btimer_t *next;
struct s_btimer_t *prev;
time_t start_time;
int32_t wait;
- pid_t pid;
+ pid_t pid; /* process id if TYPE_CHILD */
int killed;
+ int type;
+ pthread_t tid; /* thread id if TYPE_PTHREAD */
} btimer_t;
#define btimer_id btimer_t *
/* */
#define VERSION "1.29"
#define VSTRING "1"
-#define DATE "18 January 2003"
-#define LSMDATE "18Jan03"
+#define DATE "20 January 2003"
+#define LSMDATE "20Jan03"
/* Debug flags */
#define DEBUG 1