From 665a0db38571e8d3d30ce42daa23b723b06e2d33 Mon Sep 17 00:00:00 2001 From: Kern Sibbald Date: Tue, 21 Jan 2003 21:31:22 +0000 Subject: [PATCH] Timer code + misc git-svn-id: https://bacula.svn.sourceforge.net/svnroot/bacula/trunk@309 91ce42f0-d328-0410-95d8-f526ca767f89 --- bacula/kernstodo | 11 +++ bacula/src/dird/sql_cmds.c | 2 +- bacula/src/lib/btime.c | 12 ++- bacula/src/lib/watchdog.c | 7 +- bacula/src/stored/dev.c | 20 +++- bacula/src/stored/dev.h | 183 +++++++++++++++++++------------------ 6 files changed, 137 insertions(+), 98 deletions(-) diff --git a/bacula/kernstodo b/bacula/kernstodo index 301e933791..59a39d1415 100644 --- a/bacula/kernstodo +++ b/bacula/kernstodo @@ -7,6 +7,9 @@ Documentation to do: (a little bit at a time) - Document static linking - Document fifo and | and < - Document how to automatically backup all local partitions +- Document problems with Verify and pruning. +- Document how to use multiple databases. +- Document FIFO storage device. Testing to do: (painful) @@ -241,6 +244,14 @@ Longer term to do: is NOT currently the case). Must detect socket error, buffer messages for later. - Enhance time/duration input to allow multiple qualifiers e.g. 3d2h +- Add ability to backup to two Storage devices (two SD sessions) at + the same time -- e.g. onsite, offsite. +- Add the ability to consolidate old backup sets (basically do a restore + to tape and appropriately update the catalog). Compress Volume sets. + Might need to spool via file is only one drive is available. +- Compress or consolidate Volumes of old possibly deleted files. Perhaps + someway to do so with every volume that has less than x% valid + files. Projects: diff --git a/bacula/src/dird/sql_cmds.c b/bacula/src/dird/sql_cmds.c index f2e7b3abca..cc7b5b028c 100644 --- a/bacula/src/dird/sql_cmds.c +++ b/bacula/src/dird/sql_cmds.c @@ -44,7 +44,7 @@ char *sel_JobMedia = "SELECT JobId FROM JobMedia WHERE MediaId=%u"; /* Select JobIds for File deletion. */ char *select_job = "SELECT JobId from Job " - "WHERE JobTDate < %s " + "WHERE JobTDate<%s " "AND ClientId=%u " "AND PurgedFiles=0"; diff --git a/bacula/src/lib/btime.c b/bacula/src/lib/btime.c index 5f78f2430c..6bd0e71515 100644 --- a/bacula/src/lib/btime.c +++ b/bacula/src/lib/btime.c @@ -4,7 +4,7 @@ * Version $Id$ */ /* - Copyright (C) 2000, 2001, 2002 Kern Sibbald and John Walker + Copyright (C) 2000-2003 Kern Sibbald and John Walker This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as @@ -30,7 +30,8 @@ * be used, and in general, Unix time time_t should no longer be used, * it is being phased out. * - * Epoch is the base of Unix time (time_t, ...) and is 1 Jan 1970 at 0:0 + * Epoch is the base of Unix time in seconds (time_t, ...) + * and is 1 Jan 1970 at 0:0 * * The major two times that should be left are: * btime_t (64 bit integer in microseconds base Epoch) @@ -53,6 +54,7 @@ void bstrftime(char *dt, int maxlen, utime_t tim) utime_t str_to_utime(char *str) { struct tm tm; + time_t ttime; if (sscanf(str, "%d-%d-%d %d:%d:%d", &tm.tm_year, &tm.tm_mon, &tm.tm_mday, &tm.tm_hour, &tm.tm_min, &tm.tm_sec) != 6) { @@ -68,7 +70,11 @@ utime_t str_to_utime(char *str) } else { return 0; } - return (utime_t)mktime(&tm); + ttime = mktime(&tm); + if (ttime == -1) { + ttime = 0; + } + return (utime_t)ttime; } void get_current_time(struct date_time *dt) diff --git a/bacula/src/lib/watchdog.c b/bacula/src/lib/watchdog.c index a8272d23f6..214f45892d 100755 --- a/bacula/src/lib/watchdog.c +++ b/bacula/src/lib/watchdog.c @@ -204,6 +204,7 @@ static void *btimer_thread(void *arg) kill(wid->pid, SIGTERM); killed = TRUE; } else { + Dmsg1(200, "watchdog kill thread %d\n", wid->tid); pthread_kill(wid->tid, TIMEOUT_SIGNAL); wid->killed = TRUE; } @@ -243,6 +244,7 @@ btimer_id start_child_timer(pid_t pid, uint32_t wait) wid = btimer_start_common(wait); wid->pid = pid; wid->type = TYPE_CHILD; + Dmsg2(200, "Start child timer 0x%x for %d secs.\n", wid, wait); return wid; } @@ -259,6 +261,7 @@ btimer_id start_thread_timer(pthread_t tid, uint32_t wait) wid = btimer_start_common(wait); wid->tid = tid; wid->type = TYPE_PTHREAD; + Dmsg2(200, "Start thread timer 0x%x for %d secs.\n", wid, wait); return wid; } @@ -277,7 +280,6 @@ static btimer_id btimer_start_common(uint32_t wait) wid->start_time = time(NULL); wid->wait = wait; wid->killed = FALSE; - Dmsg2(200, "Start child timer 0x%x for %d secs.\n", wid, wait); V(mutex); return wid; } @@ -287,6 +289,7 @@ static btimer_id btimer_start_common(uint32_t wait) */ void stop_child_timer(btimer_id wid) { + Dmsg2(200, "Stop child timer 0x%x for %d secs.\n", wid, wid->wait); stop_btimer(wid); } @@ -295,6 +298,7 @@ void stop_child_timer(btimer_id wid) */ void stop_thread_timer(btimer_id wid) { + Dmsg2(200, "Stop thread timer 0x%x for %d secs.\n", wid, wid->wait); stop_btimer(wid); } @@ -318,6 +322,5 @@ static void stop_btimer(btimer_id wid) wid->next->prev = wid->prev; /* unlink it */ } V(mutex); - Dmsg2(200, "Stop timer 0x%x for %d secs.\n", wid, wid->wait); free(wid); } diff --git a/bacula/src/stored/dev.c b/bacula/src/stored/dev.c index 695acd5541..24572066b4 100644 --- a/bacula/src/stored/dev.c +++ b/bacula/src/stored/dev.c @@ -248,6 +248,10 @@ open_dev(DEVICE *dev, char *VolName, int mode) } timeout = dev->max_open_wait; errno = 0; + if (dev->state & ST_FIFO && timeout) { + /* Set open timer */ + dev->tid = start_thread_timer(pthread_self(), timeout); + } /* If busy retry each second for max_open_wait seconds */ while ((dev->fd = open(dev->dev_name, dev->mode, MODE_RW)) < 0) { if (errno == EAGAIN) { @@ -261,6 +265,11 @@ open_dev(DEVICE *dev, char *VolName, int mode) dev->dev_errno = errno; Mmsg2(&dev->errmsg, _("stored: unable to open device %s: ERR=%s\n"), dev->dev_name, strerror(dev->dev_errno)); + /* Stop any open timer we set */ + if (dev->tid) { + stop_thread_timer(dev->tid); + dev->tid = 0; + } Emsg0(M_FATAL, 0, dev->errmsg); break; } @@ -270,6 +279,11 @@ open_dev(DEVICE *dev, char *VolName, int mode) dev->use_count++; update_pos_dev(dev); /* update position */ } + /* Stop any open() timer we started */ + if (dev->tid) { + stop_thread_timer(dev->tid); + dev->tid = 0; + } Dmsg1(29, "open_dev: tape %d opened\n", dev->fd); } else { /* @@ -1007,6 +1021,10 @@ static void do_close(DEVICE *dev) memset(&dev->VolCatInfo, 0, sizeof(dev->VolCatInfo)); memset(&dev->VolHdr, 0, sizeof(dev->VolHdr)); dev->use_count--; + if (dev->tid) { + stop_thread_timer(dev->tid); + dev->tid = 0; + } } /* @@ -1096,7 +1114,7 @@ term_dev(DEVICE *dev) Emsg0(M_FATAL, 0, dev->errmsg); return; } - close_dev(dev); + do_close(dev); Dmsg0(29, "term_dev\n"); if (dev->dev_name) { free_memory(dev->dev_name); diff --git a/bacula/src/stored/dev.h b/bacula/src/stored/dev.h index bdf13ad35b..7f91545a70 100644 --- a/bacula/src/stored/dev.h +++ b/bacula/src/stored/dev.h @@ -31,9 +31,9 @@ /* #define NEW_LOCK 1 */ -#define new_lock_device(dev) _new_lock_device(__FILE__, __LINE__, (dev)) +#define new_lock_device(dev) _new_lock_device(__FILE__, __LINE__, (dev)) #define new_lock_device_state(dev,state) _new_lock_device(__FILE__, __LINE__, (dev), (state)) -#define new_unlock_device(dev) _new_unlock_device(__FILE__, __LINE__, (dev)) +#define new_unlock_device(dev) _new_unlock_device(__FILE__, __LINE__, (dev)) #define lock_device(d) _lock_device(__FILE__, __LINE__, (d)) #define unlock_device(d) _unlock_device(__FILE__, __LINE__, (d)) @@ -46,64 +46,64 @@ #define READ_WRITE 0 #define READ_ONLY 1 #define OPEN_READ_WRITE 0 -#define OPEN_READ_ONLY 1 +#define OPEN_READ_ONLY 1 #define OPEN_WRITE_ONLY 2 /* Generic status bits returned from status_dev() */ -#define MT_TAPE (1<<0) /* is tape device */ -#define MT_EOF (1<<1) /* just read EOF */ -#define MT_BOT (1<<2) /* at beginning of tape */ -#define MT_EOT (1<<3) /* end of tape reached */ -#define MT_SM (1<<4) /* DDS setmark */ -#define MT_EOD (1<<5) /* DDS at end of data */ -#define MT_WR_PROT (1<<6) /* tape write protected */ -#define MT_ONLINE (1<<7) /* tape online */ -#define MT_DR_OPEN (1<<8) /* tape door open */ -#define MT_IM_REP_EN (1<<9) /* immediate report enabled */ +#define MT_TAPE (1<<0) /* is tape device */ +#define MT_EOF (1<<1) /* just read EOF */ +#define MT_BOT (1<<2) /* at beginning of tape */ +#define MT_EOT (1<<3) /* end of tape reached */ +#define MT_SM (1<<4) /* DDS setmark */ +#define MT_EOD (1<<5) /* DDS at end of data */ +#define MT_WR_PROT (1<<6) /* tape write protected */ +#define MT_ONLINE (1<<7) /* tape online */ +#define MT_DR_OPEN (1<<8) /* tape door open */ +#define MT_IM_REP_EN (1<<9) /* immediate report enabled */ /* Test capabilities */ #define dev_cap(dev, cap) ((dev)->capabilities & (cap)) /* Bits for device capabilities */ -#define CAP_EOF 0x0001 /* has MTWEOF */ -#define CAP_BSR 0x0002 /* has MTBSR */ -#define CAP_BSF 0x0004 /* has MTBSF */ -#define CAP_FSR 0x0008 /* has MTFSR */ -#define CAP_FSF 0x0010 /* has MTFSF */ -#define CAP_EOM 0x0020 /* has MTEOM */ -#define CAP_REM 0x0040 /* is removable media */ -#define CAP_RACCESS 0x0080 /* is random access device */ -#define CAP_AUTOMOUNT 0x0100 /* Read device at start to see what is there */ -#define CAP_LABEL 0x0200 /* Label blank tapes */ -#define CAP_ANONVOLS 0x0400 /* Mount without knowing volume name */ -#define CAP_ALWAYSOPEN 0x0800 /* always keep device open */ +#define CAP_EOF 0x0001 /* has MTWEOF */ +#define CAP_BSR 0x0002 /* has MTBSR */ +#define CAP_BSF 0x0004 /* has MTBSF */ +#define CAP_FSR 0x0008 /* has MTFSR */ +#define CAP_FSF 0x0010 /* has MTFSF */ +#define CAP_EOM 0x0020 /* has MTEOM */ +#define CAP_REM 0x0040 /* is removable media */ +#define CAP_RACCESS 0x0080 /* is random access device */ +#define CAP_AUTOMOUNT 0x0100 /* Read device at start to see what is there */ +#define CAP_LABEL 0x0200 /* Label blank tapes */ +#define CAP_ANONVOLS 0x0400 /* Mount without knowing volume name */ +#define CAP_ALWAYSOPEN 0x0800 /* always keep device open */ #define CAP_AUTOCHANGER 0x1000 /* AutoChanger */ #define CAP_OFFLINEUNMOUNT 0x2000 /* Offline before unmount */ -#define CAP_STREAM 0x4000 /* Stream device */ +#define CAP_STREAM 0x4000 /* Stream device */ /* Test state */ #define dev_state(dev, state) ((dev)->state & (state)) /* Device state bits */ -#define ST_OPENED 0x0001 /* set when device opened */ -#define ST_TAPE 0x0002 /* is a tape device */ -#define ST_FILE 0x0004 /* is a file device */ -#define ST_FIFO 0x0008 /* is a fifo device */ -#define ST_PROG 0x0010 /* is a program device */ -#define ST_LABEL 0x0020 /* label found */ +#define ST_OPENED 0x0001 /* set when device opened */ +#define ST_TAPE 0x0002 /* is a tape device */ +#define ST_FILE 0x0004 /* is a file device */ +#define ST_FIFO 0x0008 /* is a fifo device */ +#define ST_PROG 0x0010 /* is a program device */ +#define ST_LABEL 0x0020 /* label found */ #define ST_MALLOC 0x0040 /* dev packet malloc'ed in init_dev() */ -#define ST_APPEND 0x0080 /* ready for Bacula append */ -#define ST_READ 0x0100 /* ready for Bacula read */ -#define ST_EOT 0x0200 /* at end of tape */ -#define ST_WEOT 0x0400 /* Got EOT on write */ -#define ST_EOF 0x0800 /* Read EOF i.e. zero bytes */ -#define ST_NEXTVOL 0x1000 /* Start writing on next volume */ -#define ST_SHORT 0x2000 /* Short block read */ +#define ST_APPEND 0x0080 /* ready for Bacula append */ +#define ST_READ 0x0100 /* ready for Bacula read */ +#define ST_EOT 0x0200 /* at end of tape */ +#define ST_WEOT 0x0400 /* Got EOT on write */ +#define ST_EOF 0x0800 /* Read EOF i.e. zero bytes */ +#define ST_NEXTVOL 0x1000 /* Start writing on next volume */ +#define ST_SHORT 0x2000 /* Short block read */ /* dev_blocked states (mutually exclusive) */ #define BST_NOT_BLOCKED 0 /* not blocked */ -#define BST_UNMOUNTED 1 /* User unmounted device */ +#define BST_UNMOUNTED 1 /* User unmounted device */ #define BST_WAITING_FOR_SYSOP 2 /* Waiting for operator to mount tape */ #define BST_DOING_ACQUIRE 3 /* Opening/validating/moving tape */ #define BST_WRITING_LABEL 4 /* Labeling a tape */ @@ -112,68 +112,69 @@ /* Volume Catalog Information structure definition */ typedef struct s_volume_catalog_info { /* Media info for the current Volume */ - uint32_t VolCatJobs; /* number of jobs on this Volume */ - uint32_t VolCatFiles; /* Number of files */ - uint32_t VolCatBlocks; /* Number of blocks */ - uint64_t VolCatBytes; /* Number of bytes written */ - uint32_t VolCatMounts; /* Number of mounts this volume */ - uint32_t VolCatErrors; /* Number of errors this volume */ - uint32_t VolCatWrites; /* Number of writes this volume */ - uint32_t VolCatReads; /* Number of reads this volume */ - uint32_t VolCatRecycles; /* Number of recycles this volume */ - int32_t Slot; /* Slot in changer */ - uint32_t VolCatMaxJobs; /* Maximum Jobs to write to volume */ - uint32_t VolCatMaxFiles; /* Maximum files to write to volume */ - uint64_t VolCatMaxBytes; /* Max bytes to write to volume */ + uint32_t VolCatJobs; /* number of jobs on this Volume */ + uint32_t VolCatFiles; /* Number of files */ + uint32_t VolCatBlocks; /* Number of blocks */ + uint64_t VolCatBytes; /* Number of bytes written */ + uint32_t VolCatMounts; /* Number of mounts this volume */ + uint32_t VolCatErrors; /* Number of errors this volume */ + uint32_t VolCatWrites; /* Number of writes this volume */ + uint32_t VolCatReads; /* Number of reads this volume */ + uint32_t VolCatRecycles; /* Number of recycles this volume */ + int32_t Slot; /* Slot in changer */ + uint32_t VolCatMaxJobs; /* Maximum Jobs to write to volume */ + uint32_t VolCatMaxFiles; /* Maximum files to write to volume */ + uint64_t VolCatMaxBytes; /* Max bytes to write to volume */ uint64_t VolCatCapacityBytes; /* capacity estimate */ - char VolCatStatus[20]; /* Volume status */ + char VolCatStatus[20]; /* Volume status */ char VolCatName[MAX_NAME_LENGTH]; /* Desired volume to mount */ } VOLUME_CAT_INFO; typedef struct s_steal_lock { - pthread_t no_wait_id; /* id of no wait thread */ - int dev_blocked; /* state */ + pthread_t no_wait_id; /* id of no wait thread */ + int dev_blocked; /* state */ } bsteal_lock_t; /* Device structure definition */ typedef struct s_device { - struct s_device *next; /* pointer to next open device */ - void *attached_jcrs; /* attached JCR list */ - pthread_mutex_t mutex; /* access control */ - pthread_cond_t wait; /* thread wait variable */ + struct s_device *next; /* pointer to next open device */ + void *attached_jcrs; /* attached JCR list */ + pthread_mutex_t mutex; /* access control */ + pthread_cond_t wait; /* thread wait variable */ pthread_cond_t wait_next_vol; /* wait for tape to be mounted */ - pthread_t no_wait_id; /* this thread must not wait */ - int dev_blocked; /* set if we must wait (i.e. change tape) */ - int num_waiting; /* number of threads waiting */ - int num_writers; /* number of writing threads */ - int use_count; /* usage count on this device */ - int fd; /* file descriptor */ - int capabilities; /* capabilities mask */ - int state; /* state mask */ - int dev_errno; /* Our own errno */ - int mode; /* read/write modes */ - char *dev_name; /* device name */ - char *errmsg; /* nicely edited error message */ - uint32_t block_num; /* current block number base 0 */ - uint32_t file; /* current file number base 0 */ - uint64_t file_addr; /* Current file read/write address */ - uint32_t EndBlock; /* last block written */ - uint32_t EndFile; /* last file written */ - uint32_t min_block_size; /* min block size */ - uint32_t max_block_size; /* max block size */ - uint32_t max_volume_jobs; /* max jobs to put on one volume */ - uint64_t max_volume_files; /* max files to put on one volume */ - uint64_t max_volume_size; /* max bytes to put on one volume */ - uint64_t max_file_size; /* max file size to put in one file on volume */ - uint64_t volume_capacity; /* advisory capacity */ - uint32_t max_rewind_wait; /* max secs to allow for rewind */ - uint32_t max_open_wait; /* max secs to allow for open */ - void *device; /* pointer to Device Resource */ - - VOLUME_CAT_INFO VolCatInfo; /* Volume Catalog Information */ - VOLUME_LABEL VolHdr; /* Actual volume label */ + pthread_t no_wait_id; /* this thread must not wait */ + int dev_blocked; /* set if we must wait (i.e. change tape) */ + int num_waiting; /* number of threads waiting */ + int num_writers; /* number of writing threads */ + int use_count; /* usage count on this device */ + int fd; /* file descriptor */ + int capabilities; /* capabilities mask */ + int state; /* state mask */ + int dev_errno; /* Our own errno */ + int mode; /* read/write modes */ + char *dev_name; /* device name */ + char *errmsg; /* nicely edited error message */ + uint32_t block_num; /* current block number base 0 */ + uint32_t file; /* current file number base 0 */ + uint64_t file_addr; /* Current file read/write address */ + uint32_t EndBlock; /* last block written */ + uint32_t EndFile; /* last file written */ + uint32_t min_block_size; /* min block size */ + uint32_t max_block_size; /* max block size */ + uint32_t max_volume_jobs; /* max jobs to put on one volume */ + uint64_t max_volume_files; /* max files to put on one volume */ + uint64_t max_volume_size; /* max bytes to put on one volume */ + uint64_t max_file_size; /* max file size to put in one file on volume */ + uint64_t volume_capacity; /* advisory capacity */ + uint32_t max_rewind_wait; /* max secs to allow for rewind */ + uint32_t max_open_wait; /* max secs to allow for open */ + void *device; /* pointer to Device Resource */ + btimer_id tid; /* timer id */ + + VOLUME_CAT_INFO VolCatInfo; /* Volume Catalog Information */ + VOLUME_LABEL VolHdr; /* Actual volume label */ } DEVICE; @@ -212,7 +213,7 @@ typedef struct s_device { * dependent. Arrgggg! */ #ifndef MTEOM -#ifdef MTSEOD +#ifdef MTSEOD #define MTEOM MTSEOD #endif #ifdef MTEOD -- 2.39.5